root/gtags-cscope/command.c

/* [previous][next][first][last][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. command
  2. clearprompt
  3. readrefs
  4. changestring
  5. mark
  6. scrollbar
  7. countrefs

   1 /*===========================================================================
   2  Copyright (c) 1998-2000, The Santa Cruz Operation 
   3  All rights reserved.
   4  
   5  Redistribution and use in source and binary forms, with or without
   6  modification, are permitted provided that the following conditions are met:
   7 
   8  *Redistributions of source code must retain the above copyright notice,
   9  this list of conditions and the following disclaimer.
  10 
  11  *Redistributions in binary form must reproduce the above copyright notice,
  12  this list of conditions and the following disclaimer in the documentation
  13  and/or other materials provided with the distribution.
  14 
  15  *Neither name of The Santa Cruz Operation nor the names of its contributors
  16  may be used to endorse or promote products derived from this software
  17  without specific prior written permission. 
  18 
  19  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS ``AS
  20  IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
  21  THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  22  PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE
  23  LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
  24  CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
  25  SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
  26  INTERRUPTION)
  27  HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  28  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  29  OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
  30  DAMAGE. 
  31  =========================================================================*/
  32 
  33 /**     @file
  34  *      command functions
  35  *
  36  *      @NAME{gtags-cscope} - interactive C symbol or text cross-reference (@NAME{cscope})
  37  */
  38 
  39 #include "global-cscope.h"
  40 #include "gparam.h"
  41 #include "pathconvert.h"
  42 #include "build.h"              /* for rebuild() */
  43 #include "alloc.h"
  44 
  45 #include <stdlib.h>
  46 #if defined(USE_NCURSES) && !defined(RENAMED_NCURSES)
  47 #include <ncurses.h>
  48 #else
  49 #include <curses.h>
  50 #endif
  51 #include <ctype.h>
  52 
  53 static char const rcsid[] = "$Id: command.c,v 1.9 2012/10/13 07:01:58 shigio Exp $";
  54 
  55 
  56 int     selecting;
  57 unsigned int   curdispline = 0;
  58 
  59 BOOL    caseless;               /**< ignore letter case when searching */
  60 BOOL    *change;                /**< change this line */
  61 BOOL    changing;               /**< changing text */
  62 char    newpat[PATLEN + 1];     /**< new pattern */
  63 /* HBB 20040430: renamed to avoid lots of clashes with function arguments
  64  * also named 'pattern' */
  65 char    Pattern[PATLEN + 1];    /**< symbol or text pattern */
  66 
  67 /* HBB FIXME 20060419: these should almost certainly be const */
  68 static  char    appendprompt[] = "Append to file: ";
  69 static  char    pipeprompt[] = "Pipe to shell command: ";
  70 static  char    readprompt[] = "Read from file: ";
  71 static  char    globalprompt[] = "Read from: global ";
  72 static  char    globaloption[] = "--encode-path=\" \t\" --result=cscope";
  73 static  char    globalcommand[MAXFILLEN];
  74 static  char    toprompt[] = "To: ";
  75 
  76 
  77 /* Internal prototypes: */
  78 static  BOOL    changestring(void);
  79 static  void    clearprompt(void);
  80 static  void    mark(unsigned int i);
  81 static  void    scrollbar(MOUSE *p);
  82 
  83 
  84 /** execute the command */
  85 BOOL
  86 command(int commandc)
  87 {
  88     char filename[PATHLEN + 1]; /* file path name */
  89     MOUSE *p;                   /* mouse data */
  90     int c, i;
  91     FILE *file;
  92     struct cmd *curritem, *item;        /* command history */
  93     char *s;
  94 
  95     switch (commandc) {
  96     case ctrl('C'):     /* toggle caseless mode */
  97         if (caseless == NO) {
  98             caseless = YES;
  99             postmsg2("Caseless mode is now ON");
 100         } else {
 101             caseless = NO;
 102             postmsg2("Caseless mode is now OFF");
 103         }
 104         return(NO);
 105 
 106     case ctrl('R'):     /* rebuild the cross reference */
 107         if (isuptodate == YES) {
 108             postmsg("The -d option prevents rebuilding the symbol database");
 109             return(NO);
 110         }
 111         postmsg("Rebuilding cross-reference...");
 112         rebuild();
 113         postmsg("");
 114         totallines = 0;
 115         disprefs = 0;   
 116         topline = nextline = 1;
 117         selecting = 0;
 118         break;
 119 
 120 #if UNIXPC
 121     case ESC:   /* possible unixpc mouse selection */
 122 #endif
 123     case ctrl('X'):     /* mouse selection */
 124         if ((p = getmouseaction(DUMMYCHAR)) == NULL) {
 125             return(NO); /* unknown control sequence */
 126         }
 127         /* if the button number is a scrollbar tag */
 128         if (p->button == '0') {
 129             scrollbar(p);
 130             break;
 131         } 
 132         /* ignore a sweep */
 133         if (p->x2 >= 0) {
 134             return(NO);
 135         }
 136         /* if this is a line selection */
 137         if (p->y1 < FLDLINE) {
 138 
 139             /* find the selected line */
 140             /* note: the selection is forced into range */
 141             for (i = disprefs - 1; i > 0; --i) {
 142                 if (p->y1 >= displine[i]) {
 143                     break;
 144                 }
 145             }
 146             /* display it in the file with the editor */
 147             editref(i);
 148         } else {        /* this is an input field selection */
 149             field = p->y1 - FLDLINE;
 150             /* force it into range */
 151             if (field >= FIELDS) {
 152                 field = FIELDS - 1;
 153             }
 154             setfield();
 155             resetcmd();
 156             return(NO);
 157         }
 158         break;
 159 
 160     case '\t':  /* go to next input field */
 161         if (disprefs) {
 162             selecting = !selecting;
 163             if (selecting) {
 164                 move(displine[curdispline], 0);
 165                 refresh();
 166             } else {
 167                 atfield();
 168                 resetcmd();
 169             }
 170         }
 171         return(NO);
 172 
 173 #ifdef KEY_ENTER
 174     case KEY_ENTER:
 175 #endif
 176     case '\r':
 177     case '\n':  /* go to reference */
 178         if (selecting) {
 179             editref(curdispline);
 180             return(YES);
 181         }
 182         /* FALLTHROUGH */
 183 
 184     case ctrl('N'):
 185 #ifdef KEY_DOWN
 186     case KEY_DOWN:
 187 #endif          
 188 #ifdef KEY_RIGHT
 189     case KEY_RIGHT:
 190 #endif
 191         if (selecting) {
 192             if ((curdispline + 1) < disprefs) {
 193                 move(displine[++curdispline], 0);
 194                 refresh();
 195             }
 196         } else {
 197             field = (field + 1) % FIELDS;
 198             if (field == 2)
 199                 field = 3;
 200             setfield();
 201             atfield();
 202             resetcmd();
 203         }
 204         return(NO);
 205 
 206     case ctrl('P'):     /* go to previous input field */
 207 #ifdef KEY_UP
 208     case KEY_UP:
 209 #endif
 210 #ifdef KEY_LEFT         
 211     case KEY_LEFT:
 212 #endif
 213         if (selecting) {
 214             if (curdispline) {
 215                 move(displine[--curdispline], 0);
 216                 refresh();
 217             }
 218         } else {
 219             field = (field + (FIELDS - 1)) % FIELDS;
 220             if (field == 2)
 221                 field = 1;
 222             setfield();
 223             atfield();
 224             resetcmd();
 225         }
 226         return(NO);
 227 #ifdef KEY_HOME
 228     case KEY_HOME:      /* go to first input field */
 229         if (selecting) {
 230             curdispline = 0;
 231             move(REFLINE, 0);
 232             refresh();
 233         } else {
 234             field = 0;
 235             setfield();
 236             atfield();
 237             resetcmd();
 238         }
 239         return(NO);
 240 #endif
 241 
 242 #ifdef KEY_LL
 243     case KEY_LL:        /* go to last input field */
 244         if (selecting) {
 245             move(displine[disprefs - 1], 0);
 246             refresh();
 247         } else {
 248             field = FIELDS - 1;
 249             setfield();
 250             atfield();
 251             resetcmd();
 252         }
 253         return(NO);
 254 #endif /* def(KEY_LL) */
 255 
 256     case ' ':   /* display next page */
 257     case '+':
 258     case ctrl('V'):
 259 #ifdef KEY_NPAGE
 260     case KEY_NPAGE:
 261 #endif
 262         /* don't redisplay if there are no lines */
 263         if (totallines == 0) {
 264             return(NO);
 265         }
 266         /* note: seekline() is not used to move to the next 
 267          * page because display() leaves the file pointer at
 268          * the next page to optimize paging forward
 269          */
 270         curdispline = 0;
 271         break;
 272 
 273     case ctrl('H'):
 274     case '-':   /* display previous page */
 275 #ifdef KEY_PPAGE
 276     case KEY_PPAGE:
 277 #endif
 278         /* don't redisplay if there are no lines */
 279         if (totallines == 0) {
 280             return(NO);
 281         }
 282 
 283         curdispline = 0;
 284 
 285         /* if there are only two pages, just go to the other one */
 286         if (totallines <= 2 * mdisprefs) {
 287             break;
 288         }
 289         /* if on first page but not at beginning, go to beginning */
 290         nextline -= mdisprefs;  /* already at next page */
 291         if (nextline > 1 && nextline <= mdisprefs) {
 292             nextline = 1;
 293         } else {
 294             nextline -= mdisprefs;
 295             if (nextline < 1) {
 296                 nextline = totallines - mdisprefs + 1;
 297                 if (nextline < 1) {
 298                     nextline = 1;
 299                 }
 300             }
 301         }
 302         seekline(nextline);
 303         break;
 304 
 305     case '>':   /* write or append the lines to a file */
 306         if (totallines == 0) {
 307             postmsg("There are no lines to write to a file");
 308         } else {        /* get the file name */
 309             move(PRLINE, 0);
 310             addstr("Write to file: ");
 311             s = "w";
 312             if ((c = mygetch()) == '>') {
 313                 move(PRLINE, 0);
 314                 addstr(appendprompt);
 315                 c = '\0';
 316                 s = "a";
 317             }
 318             if (c != '\r' && 
 319                 mygetline("", newpat,
 320                           COLS - sizeof(appendprompt), c, NO) > 0
 321                 ) {
 322                 shellpath(filename, sizeof(filename), newpat);
 323                 if ((file = myfopen(filename, s)) == NULL) {
 324                     cannotopen(filename);
 325                 } else {
 326                     seekline(1);
 327                     while ((c = getc(refsfound)) != EOF) {
 328                         putc(c, file);
 329                     }
 330                     seekline(topline);
 331                     fclose(file);
 332                 }
 333             }
 334             clearprompt();
 335         }
 336         return(NO);     /* return to the previous field */
 337 
 338     case '<':   /* read lines from a file */
 339         move(PRLINE, 0);
 340         addstr(readprompt);
 341         if (mygetline("", newpat, COLS - sizeof(readprompt),
 342                       '\0', NO) > 0) {
 343             clearprompt();
 344             shellpath(filename, sizeof(filename), newpat);
 345             if (readrefs(filename) == NO) {
 346                 postmsg2("Ignoring an empty file");
 347                 return(NO);
 348             }
 349             return(YES);
 350         }
 351         clearprompt();
 352         return(NO);
 353 
 354     case '^':   /* pipe the lines through a shell command */
 355     case '|':   /* pipe the lines to a shell command */
 356         if (totallines == 0) {
 357             postmsg("There are no lines to pipe to a shell command");
 358             return(NO);
 359         }
 360         /* get the shell command */
 361         move(PRLINE, 0);
 362         addstr(pipeprompt);
 363         if (mygetline("", newpat, COLS - sizeof(pipeprompt), '\0', NO)
 364             == 0) {
 365             clearprompt();
 366             return(NO);
 367         }
 368         /* if the ^ command, redirect output to a temp file */
 369         if (commandc == '^') {
 370             strcat(strcat(newpat, " >"), temp2);
 371             /* HBB 20020708: somebody might have even
 372              * their non-interactive default shells
 373              * complain about clobbering
 374              * redirections... --> delete before
 375              * overwriting */
 376             remove(temp2);
 377         }
 378         exitcurses();
 379         if ((file = mypopen(newpat, "w")) == NULL) {
 380             fprintf(stderr, "\
 381 cscope: cannot open pipe to shell command: %s\n", newpat);
 382         } else {
 383             seekline(1);
 384             while ((c = getc(refsfound)) != EOF) {
 385                 putc(c, file);
 386             }
 387             seekline(topline);
 388             mypclose(file);
 389         }
 390         if (commandc == '^') {
 391             if (readrefs(temp2) == NO) {
 392                 postmsg("Ignoring empty output of ^ command");
 393             }
 394         }
 395         askforreturn();
 396         entercurses();
 397         break;
 398     case ctrl('G'):     /* read from the result of global command */
 399         /* get the shell command */
 400         move(PRLINE, 0);
 401         addstr(globalprompt);
 402         /* addstr(globaloption);*/
 403         if (mygetline("", newpat, COLS - sizeof(globalprompt), '\0', NO) == 0) {
 404             clearprompt();
 405             return(NO);
 406         }
 407         snprintf(globalcommand, sizeof(globalcommand), "%s %s %s > %s", global_command, globaloption, newpat, temp2);
 408         remove(temp2);
 409         postmsg("Searching ...");
 410         if (system(globalcommand) != 0) {
 411             postmsg("Ignoring failed output of global command");
 412             clearprompt();
 413             return(NO);
 414         }
 415         if (readrefs(temp2) == NO) {
 416             postmsg("Ignoring empty output of global command");
 417             clearprompt();
 418             return(NO);
 419         }
 420         curdispline = 0;
 421         return(YES);
 422         break;
 423 #if defined(KEY_RESIZE) && !defined(__DJGPP__)
 424     case KEY_RESIZE:
 425         exitcurses();
 426         initscr();
 427         entercurses();
 428 #if TERMINFO
 429         keypad(stdscr, TRUE);   /* enable the keypad */
 430 #ifdef HAVE_FIXKEYPAD
 431         fixkeypad();    /* fix for getch() intermittently returning garbage */
 432 #endif
 433 #endif
 434 #if UNIXPC
 435         standend();     /* turn off reverse video */
 436 #endif
 437         dispinit();     /* initialize display parameters */
 438         setfield();     /* set the initial cursor position */
 439         postmsg("");    /* clear any build progress message */
 440         display();      /* display the version number and input fields */
 441         break;
 442 #endif
 443     case ctrl('L'):     /* redraw screen */
 444 #ifdef KEY_CLEAR
 445     case KEY_CLEAR:
 446 #endif
 447         clearmsg2();
 448         clearok(curscr, TRUE);
 449         wrefresh(curscr);
 450         drawscrollbar(topline, bottomline);
 451         return(NO);
 452 
 453     case '!':   /* shell escape */
 454         execute(shell, shell, NULL);
 455         seekline(topline);
 456         break;
 457 
 458     case '?':   /* help */
 459         clear();
 460         help();
 461         clear();
 462         seekline(topline);
 463         break;
 464 
 465     case ctrl('E'):     /* edit all lines */
 466         editall();
 467         break;
 468 
 469     case ctrl('A'):             /* HBB 20050428: added alt. keymapping */
 470     case ctrl('Y'):     /* repeat last pattern */
 471         if (*Pattern != '\0') {
 472             addstr(Pattern);
 473             goto repeat;
 474         }
 475         break;
 476 
 477     case ctrl('B'):             /* cmd history back */
 478     case ctrl('F'):             /* cmd history fwd */
 479         if (selecting)
 480             return(NO);
 481 
 482         curritem = currentcmd();
 483         item = (commandc == ctrl('F')) ? nextcmd() : prevcmd();
 484         clearmsg2();
 485         if (curritem == item) { /* inform user that we're at history end */
 486             postmsg2("End of input field and search pattern history");
 487         }
 488         if (item) {
 489             field = item->field;
 490             setfield();
 491             atfield();
 492             addstr(item->text);
 493             strcpy(Pattern, item->text);
 494             switch (c = mygetch()) {
 495             case '\r':
 496             case '\n':
 497                 goto repeat;
 498             case ctrl('F'):
 499             case ctrl('B'):
 500                 myungetch(c);
 501                 atfield();
 502                 clrtoeol();     /* clear current field */
 503                 break;
 504             default:
 505                 myungetch(c);
 506                 if (mygetline(Pattern, newpat, COLS - fldcolumn - 1, '\0', caseless )) {
 507                     strcpy (Pattern, newpat);
 508                     resetcmd();
 509                 }
 510                 goto repeat;
 511                 break;
 512             }
 513         }
 514         return(NO);
 515 
 516     case '\\':  /* next character is not a command */
 517         addch('\\');    /* display the quote character */
 518 
 519         /* get a character from the terminal */
 520         if ((commandc = mygetch()) == EOF) {
 521             return(NO); /* quit */
 522         }
 523         addstr("\b \b");        /* erase the quote character */
 524         goto ispat;
 525 
 526     case '.':
 527         postmsg("The . command has been replaced by ^Y");
 528         atfield();      /* move back to the input field */
 529         /* FALLTHROUGH */
 530     default:
 531         if (selecting && !mouse) {
 532             char                *c;
 533 
 534             if ((c = strchr(dispchars, commandc)))
 535                 editref(c - dispchars);
 536 
 537             /* if this is the start of a pattern */
 538         } else if (isprint(commandc)) {
 539         ispat:
 540             if (mygetline("", newpat, COLS - fldcolumn - 1,
 541                           commandc, caseless) > 0) {
 542                 strcpy(Pattern, newpat);
 543                 resetcmd();     /* reset command history */
 544             repeat:
 545                 addcmd(field, Pattern); /* add to command history */
 546                 if (field == CHANGE) {
 547                     /* prompt for the new text */
 548                     move(PRLINE, 0);
 549                     addstr(toprompt);
 550                     mygetline("", newpat,
 551                               COLS - sizeof(toprompt),
 552                               '\0', NO);
 553                 }
 554                 /* search for the pattern */
 555                 if (search() == YES) {
 556                     curdispline = 0;
 557                     ++selecting;
 558 
 559                     switch (field) {
 560                     case DEFINITION:
 561                     case FILENAME:
 562                         if (totallines > 1) {
 563                             break;
 564                         }
 565                         topline = 1;
 566                         editref(0);
 567                         break;
 568                     case CHANGE:
 569                         return(changestring());
 570                     }
 571 
 572                 } else if (field == FILENAME && 
 573                            access(newpat, READ) == 0) {
 574                     /* try to edit the file anyway */
 575                     edit(newpat, "1");
 576                 }
 577             } else {    /* no pattern--the input was erased */
 578                 return(NO);
 579             }
 580         } else {        /* control character */
 581             return(NO);
 582         }
 583     } /* switch(commandc) */
 584     return(YES);
 585 }
 586 
 587 /** clear the prompt line */
 588 
 589 static void
 590 clearprompt(void)
 591 {
 592         move(PRLINE, 0);
 593         clrtoeol();
 594 }
 595 
 596 /** read references from a file */
 597 
 598 BOOL
 599 readrefs(char *filename)
 600 {
 601         FILE    *file;
 602         int     c;
 603 
 604         if ((file = myfopen(filename, "rb")) == NULL) {
 605                 cannotopen(filename);
 606                 return(NO);
 607         }
 608         if ((c = getc(file)) == EOF) {  /* if file is empty */
 609                 return(NO);
 610         }
 611         totallines = 0;
 612         disprefs = 0;
 613         nextline = 1;
 614         if (writerefsfound() == YES) {
 615                 putc(c, refsfound);
 616                 while ((c = getc(file)) != EOF) {
 617                         putc(c, refsfound);
 618                 }
 619                 fclose(file);
 620                 fclose(refsfound);
 621                 if ( (refsfound = myfopen(temp1, "rb")) == NULL) {
 622                         cannotopen(temp1);
 623                         return(NO);
 624                 }
 625                 countrefs();
 626         }
 627         return(YES);
 628 }
 629 
 630 /** change one text string to another */
 631 
 632 static BOOL
 633 changestring(void)
 634 {
 635     char    newfile[PATHLEN + 1];   /* new file name */
 636     char    oldfile[PATHLEN + 1];   /* old file name */
 637     char    linenum[NUMLEN + 1];    /* file line number */
 638     char    msg[MSGLEN + 1];        /* message */
 639     FILE    *script;                /* shell script file */
 640     BOOL    anymarked = NO;         /* any line marked */
 641     MOUSE *p;                       /* mouse data */
 642     int     c;
 643     unsigned int i;
 644     char    *s;
 645 
 646     /* open the temporary file */
 647     if ((script = myfopen(temp2, "w")) == NULL) {
 648         cannotopen(temp2);
 649         return(NO);
 650     }
 651     /* create the line change indicators */
 652     change = mycalloc(totallines, sizeof(BOOL));
 653     changing = YES;
 654     mousemenu();
 655 
 656     /* until the quit command is entered */
 657     for (;;) {
 658         /* display the current page of lines */
 659         display();
 660     same:
 661         atchange();
 662                 
 663         /* get a character from the terminal */
 664         if ((c = mygetch()) == EOF
 665             || c == ctrl('D') 
 666             || c == ctrl('Z')) {
 667             break;      /* change lines */
 668         }
 669         /* see if the input character is a command */
 670         switch (c) {
 671         case ' ':       /* display next page */
 672         case '+':
 673         case ctrl('V'):
 674 #ifdef KEY_NPAGE
 675         case KEY_NPAGE:
 676 #endif
 677         case '-':       /* display previous page */
 678 #ifdef KEY_PPAGE
 679         case KEY_PPAGE:
 680 #endif
 681         case '!':       /* shell escape */
 682         case '?':       /* help */
 683             command(c);
 684             break;
 685 
 686         case ctrl('L'): /* redraw screen */
 687 #ifdef KEY_CLEAR
 688         case KEY_CLEAR:
 689 #endif
 690             command(c);
 691             goto same;
 692 
 693         case ESC:       /* don't change lines */
 694 #if UNIXPC
 695             if((p = getmouseaction(DUMMYCHAR)) == NULL) {
 696                 goto nochange;  /* unknown escape sequence */
 697             }
 698             break;
 699 #endif
 700         case ctrl('G'):
 701             goto nochange;
 702 
 703         case '*':       /* mark/unmark all displayed lines */
 704             for (i = 0; topline + i < nextline; ++i) {
 705                 mark(i);
 706             }
 707             goto same;
 708 
 709         case ctrl('A'): /* mark/unmark all lines */
 710             for (i = 0; i < totallines; ++i) {
 711                 if (change[i] == NO) {
 712                     change[i] = YES;
 713                 } else {
 714                     change[i] = NO;
 715                 }
 716             }
 717             /* show that all have been marked */
 718             seekline(totallines);
 719             break;
 720 
 721         case ctrl('X'): /* mouse selection */
 722             if ((p = getmouseaction(DUMMYCHAR)) == NULL) {
 723                 goto same;      /* unknown control sequence */
 724             }
 725             /* if the button number is a scrollbar tag */
 726             if (p->button == '0') {
 727                 scrollbar(p);
 728                 break;
 729             }
 730             /* find the selected line */
 731             /* note: the selection is forced into range */
 732             for (i = disprefs - 1; i > 0; --i) {
 733                 if (p->y1 >= displine[i]) {
 734                     break;
 735                 }
 736             }
 737             mark(i);
 738             goto same;
 739 
 740         default:
 741             {
 742                 /* if a line was selected */
 743                 char            *cc;
 744 
 745                 if ((cc = strchr(dispchars, c)))
 746                     mark(cc - dispchars);
 747 
 748                 goto same;
 749             } /* default case */
 750         } /* switch(change code character) */
 751     } /* for(ever) */
 752 
 753     /* for each line containing the old text */
 754     fprintf(script, "ed - <<\\!\n");
 755     *oldfile = '\0';
 756     seekline(1);
 757     for (i = 0; 
 758          fscanf(refsfound, "%" PATHLEN_STR "s%*s%" NUMLEN_STR "s%*[^\n]", newfile, linenum) == 2;
 759          ++i) {
 760         strcpy(newfile, decode_path(newfile));
 761         /* see if the line is to be changed */
 762         if (change[i] == YES) {
 763             anymarked = YES;
 764                 
 765             /* if this is a new file */
 766             if (strcmp(newfile, oldfile) != 0) {
 767                                 
 768                 /* make sure it can be changed */
 769                 if (access(newfile, WRITE) != 0) {
 770                     snprintf(msg, sizeof(msg), "Cannot write to file %s", newfile);
 771                     postmsg(msg);
 772                     anymarked = NO;
 773                     break;
 774                 }
 775                 /* if there was an old file */
 776                 if (*oldfile != '\0') {
 777                     fprintf(script, "w\n");     /* save it */
 778                 }
 779                 /* edit the new file */
 780                 strcpy(oldfile, newfile);
 781                 fprintf(script, "e %s\n", oldfile);
 782             }
 783             /* output substitute command */
 784             fprintf(script, "%ss/", linenum);   /* change */
 785             for (s = Pattern; *s != '\0'; ++s) {
 786                 /* old text */
 787                 if (strchr("/\\[.^*", *s) != NULL) {
 788                     putc('\\', script);
 789                 }
 790                 if (caseless == YES && isalpha((unsigned char)*s)) {
 791                     putc('[', script);
 792                     if(islower((unsigned char)*s)) {
 793                         putc(toupper((unsigned char)*s), script);
 794                         putc(*s, script);
 795                     } else {
 796                         putc(*s, script);
 797                         putc(tolower((unsigned char)*s), script);
 798                     }
 799                     putc(']', script);
 800                 } else  
 801                     putc(*s, script);
 802             }
 803             putc('/', script);                  /* to */
 804             for (s = newpat; *s != '\0'; ++s) { /* new text */
 805                 if (strchr("/\\&", *s) != NULL) {
 806                     putc('\\', script);
 807                 }
 808                 putc(*s, script);
 809             }
 810             fprintf(script, "/gp\n");   /* and print */
 811         }
 812     }
 813     fprintf(script, "w\nq\n!\n");       /* write and quit */
 814     fclose(script);
 815 
 816     /* if any line was marked */
 817     if (anymarked == YES) {
 818                 
 819         /* edit the files */
 820         clearprompt();
 821         refresh();
 822         fprintf(stderr, "Changed lines:\n\r");
 823         execute("sh", "sh", temp2, NULL);
 824         askforreturn();
 825         seekline(1);
 826     } else {
 827     nochange:
 828         clearprompt();
 829     }
 830     changing = NO;
 831     mousemenu();
 832     free(change);
 833     return(anymarked);
 834 }
 835 
 836 
 837 /** mark/unmark this displayed line to be changed */
 838 static void
 839 mark(unsigned int i)
 840 {
 841     unsigned int j;
 842         
 843     j = i + topline - 1;
 844     if (j < totallines) {
 845         move(displine[i], 1);
 846 
 847         if (change[j] == NO) {
 848             change[j] = YES;
 849             addch('>');
 850         } else {
 851             change[j] = NO;
 852             addch(' ');
 853         }
 854     }
 855 }
 856 
 857 
 858 /** scrollbar actions */
 859 static void
 860 scrollbar(MOUSE *p)
 861 {
 862     /* reposition list if it makes sense */
 863     if (totallines == 0) {
 864         return;
 865     }
 866     switch (p->percent) {
 867                 
 868     case 101: /* scroll down one page */
 869         if (nextline + mdisprefs > totallines) {
 870             nextline = totallines - mdisprefs + 1;
 871         }
 872         break;
 873                 
 874     case 102: /* scroll up one page */
 875         nextline = topline - mdisprefs;
 876         if (nextline < 1) {
 877             nextline = 1;
 878         }
 879         break;
 880 
 881     case 103: /* scroll down one line */
 882         nextline = topline + 1;
 883         break;
 884                 
 885     case 104: /* scroll up one line */
 886         if (topline > 1) {
 887             nextline = topline - 1;
 888         }
 889         break;
 890     default:
 891         nextline = p->percent * totallines / 100;
 892     }
 893     seekline(nextline);
 894 }
 895 
 896 
 897 /** count the references found */
 898 void
 899 countrefs(void)
 900 {
 901     char    *subsystem;             /* OGS subsystem name */
 902     char    *book;                  /* OGS book name */
 903     char    file[PATHLEN + 1];      /* file name */
 904     char    function[PATLEN + 1];   /* function name */
 905     char    linenum[NUMLEN + 1];    /* line number */
 906     int     i;
 907 
 908     /* count the references found and find the length of the file,
 909        function, and line number display fields */
 910     subsystemlen = 9;   /* strlen("Subsystem") */
 911     booklen = 4;                /* strlen("Book") */
 912     filelen = 4;                /* strlen("File") */
 913     fcnlen = 8;         /* strlen("Function") */
 914     numlen = 0;
 915     while ((i = fscanf(refsfound, "%250s%250s%5s %5000[^\n]", file,
 916                        function, linenum, tempstring)) != EOF) {
 917         if (i != 4 ||
 918             !isgraph((unsigned char) *file) ||
 919             !isgraph((unsigned char) *function) ||
 920             !isdigit((unsigned char) *linenum)) {
 921             postmsg("File does not have expected format");
 922             totallines = 0;
 923             disprefs = 0;
 924             return;
 925         }
 926         if ((i = strlen(pathcomponents(file, dispcomponents))) > filelen) {
 927             filelen = i;
 928         }
 929         if (ogs == YES) {
 930             ogsnames(file, &subsystem, &book);
 931             if ((i = strlen(subsystem)) > subsystemlen) {
 932                 subsystemlen = i;
 933             }
 934             if ((i = strlen(book)) > booklen) {
 935                 booklen = i;
 936             }
 937         }
 938         if ((i = strlen(function)) > fcnlen) {
 939             fcnlen = i;
 940         }
 941         if ((i = strlen(linenum)) > numlen) {
 942             numlen = i;
 943         }
 944         ++totallines;
 945     }
 946     rewind(refsfound);
 947 
 948     /* restrict the width of displayed columns */
 949     /* HBB FIXME 20060419: magic number alert! */ 
 950     i = (COLS - 5) / 3;
 951     if (ogs == YES) {
 952         i = (COLS - 7) / 5;
 953     }
 954     if (filelen > i && i > 4) {
 955         filelen = i;
 956     }
 957     if (subsystemlen > i && i > 9) {
 958         subsystemlen = i;
 959     }
 960     if (booklen > i && i > 4) {
 961         booklen = i;
 962     }
 963     if (fcnlen > i && i > 8) {
 964         fcnlen = i;
 965     }
 966 }

/* [previous][next][first][last][top][bottom][index][help] */