/** * Write a File to disk * * @param lsdd * Set the Output to be a SDD file * @param nerr * Error Return Flag * - 0 on Success * * @date 970702: Changed lckey and lkchar to lckeyExact and lkcharExact * throughout xw.c. This will allow files to begin with * the same string as the various options (eg. sacxz.021.z) * maf. * @date 910731: Bug fixed in options PREPEND, DELETE, CHANGE. * @date 900904: Added SDD as a format for write. * @date 881228: Added four new options for generating write file list * from data file list: APPEND, PREPEND, CHANGE, DELETE. * @date 880204: Fixed logic involving use of DIR option in READ and WRITE * by adding an ON/OFF flag as well as a directory name. * @date 880115: Deleted call that forced default directory to lowercase. * @date 870626: Added default directory option. * @date 860917: Changed to character lists for storing data file names. * @date 850730: Deleted SOCKITTOME format. * @date 830120: Added SOCK and CI output formats. * @date 820721: Changed to newest set of parsing and checking functions. * @date 810120: Changed to output message retrieval from disk. * @date 810203: Fixed bug in file overwrite option. * */ void xw(int lsdd, int *nerr) { int i; char delimiter[2], kcdir[9], kchange[MCPFN+1], kdirpart[MCPFN+1]; char kfile[MCPFN+1], kpdir[9], kstring[MCPFN+1], ktemp[9]; int lexpnd; int jdfl, nchange, nchar, nchg, ndx1, ndx2; int nlen, nstr, nstring, nwrdir; static int lwrdir = FALSE; char *cattemp; char *strtemp1, *strtemp2, *strtemp3; char *file; string_list *list, *files; kschan[12]='\0'; kschdr[80]='\0'; ksclas[4]='\0'; kscom[40]='\0'; ksevnm[8]='\0'; ksfrmt[8]='\0'; ksstnm[8]='\0'; memset(kfile, 0, sizeof(kfile)); memset(kdirpart, 0, sizeof(kdirpart)); memset(kchange, 0, sizeof(kchange)); memset(ktemp, 0, sizeof(ktemp)); memset(kstring, 0, sizeof(kstring)); memset(kpdir, 0, sizeof(kpdir)); memset(kcdir, 0, sizeof(kcdir)); memset(delimiter, 0, sizeof(delimiter)); lexpnd = FALSE; *nerr = 0; files = string_list_init(); list = NULL; if( lsdd ) cmdfm.iwfmt = 3; /* PARSING PHASE: */ /* - Loop on each token in command: */ while ( lcmore( nerr ) ){ /* -- "SAC|ALPHA": set format to be used in writing files. */ if( lckeyExact( "SAC#$",6 ) ) cmdfm.iwfmt = 1; else if( lckeyExact( "ALPHA#$",8 ) ) cmdfm.iwfmt = 2; else if( lckeyExact( "CI#$",5 ) ) cmdfm.iwfmt = 2; else if( lckeyExact( "SDD#$",6 ) ) cmdfm.iwfmt = 3; else if( lckeyExact( "XDR#$",6 ) ) { cmdfm.iwfmt = 4; } else if( lckeyExact( "SEGY#$", 7 ) ) cmdfm.iwfmt = 5; /* -- "OVER": overwrite files from previous READ command. */ else if( lckeyExact( "OVER#$",7 ) ){ cmdfm.lovrrq = TRUE; lexpnd = FALSE; string_list_extend(files, datafiles); } /* generate names from the KSTCMP header field */ else if( lckeyExact( "KSTCMP#$",9 ) ){ lexpnd = FALSE; gennames("KSTCMP ",7,files,string_list_length(datafiles),nerr); if(*nerr != 0) goto L_8888; } /* -- "APPEND string": append string to filenames from READ command. */ else if( lkcharExact( "APPEND#$",9, MCPFN, kstring,MCPFN+1, &nstring ) ){ for(i = 0; i < cmdfm.ndfl; i++) { strtemp1 = string_list_get(datafiles, i); appendstring( kstring,MCPFN+1, strtemp1, strlen(strtemp1)+2, kfile,MCPFN+1 ); string_list_put(files, kfile, MCPFN+1); if( *nerr != 0 ) goto L_8888; } cmdfm.lovrrq = FALSE; lexpnd = TRUE; } /* -- "PREPEND string": prepend string to filenames from READ command. */ else if( lkcharExact( "PREPEND#$",10, MCPFN, kstring,MCPFN+1, &nstring ) ){ for(i = 0; i < cmdfm.ndfl; i++) { strtemp1 = malloc(nstring+1); strncpy(strtemp1,kstring,nstring); strtemp1[nstring] = '\0'; strtemp2 = string_list_get(datafiles, i); prependstring( strtemp1, nstring+1, strtemp2, strlen(strtemp2)+2, kfile,MCPFN+1); free(strtemp1); string_list_put(files, kfile, MCPFN+1); if( *nerr != 0 ) goto L_8888; } cmdfm.lovrrq = FALSE; lexpnd = TRUE; } /* -- "DELETE string": delete string from filenames from READ command. */ else if( lkcharExact( "DELETE#$",9, MCPFN, kstring,MCPFN+1, &nstring ) ){ for(i = 0; i < cmdfm.ndfl; i++) { strtemp1 = malloc(nstring+1); strncpy(strtemp1,kstring,nstring); strtemp1[nstring] = '\0'; strtemp2 = string_list_get(datafiles, i); deletestring( strtemp1, nstring+1, strtemp2, strlen(strtemp2)+2, kfile,MCPFN+1); free(strtemp1); string_list_put(files, kfile, MCPFN+1); if( *nerr != 0 ) goto L_8888; } cmdfm.lovrrq = FALSE; lexpnd = TRUE; } /* -- "CHANGE string1 string2": change string1 to string2 in READ filenames. */ else if( lkcharExact( "CHANGE#$",9, MCPFN, kstring,MCPFN+1, &nstring ) ){ lcchar( MCPFN, kchange,MCPFN+1, &nchange ); for(i = 0; i < cmdfm.ndfl; i++) { nstr = indexb( kstring,MCPFN+1 ); nchg = indexb( kchange,MCPFN+1 ); strtemp1 = malloc(nstr+1); strtemp2 = malloc(nchg+1); strncpy(strtemp1,kstring,nstr); strncpy(strtemp2,kchange,nchg); strtemp1[nstr] = '\0'; strtemp2[nchg] = '\0'; strtemp3 = string_list_get(datafiles, i); changestring( strtemp1, nstr+1, strtemp2, nchg+1, strtemp3, strlen(strtemp3)+2, kfile,MCPFN+1 ); free(strtemp1); free(strtemp2); string_list_put(files, kfile, MCPFN+1); if( *nerr != 0 ) goto L_8888; } cmdfm.lovrrq = FALSE; lexpnd = TRUE; } /* -- "DIR ON|OFF|CURRENT|name": set the name of the default subdirectory. */ else if( lkcharExact( "DIR#$",6, MCPFN, kmdfm.kwrdir,MCPFN+1, &nchar ) ){ modcase( TRUE, kmdfm.kwrdir, MCPW, ktemp ); if( strncmp(ktemp,"OFF ",8) == 0 ) { lwrdir = FALSE; } else if( strncmp(ktemp,"CURRENT ",8) == 0 ){ lwrdir = TRUE; fstrncpy( kmdfm.kwrdir, MCPFN, " ", 1); } else if( kmdfm.kwrdir[nchar - 1] != KDIRDL ){ /* If the string is mising the "/" path separator */ lwrdir = TRUE; delimiter[0] = KDIRDL; delimiter[1] = '\0'; subscpy( kmdfm.kwrdir, nchar, -1, MCPFN, delimiter ); } else { /* Path is not OFF, CURRENT and has the "/" at the end */ lwrdir = TRUE; } } /* -- "COMMIT|RECALLTRACE|ROLLBACK": how to treat existing data */ else if ( lckeyExact ( "COMMIT" , 7 ) ) cmdfm.icomORroll = COMMIT ; else if (lckeyExact ( "RECALLTRACE" , 12 ) ) cmdfm.icomORroll = RECALL ; else if ( lckeyExact ( "RECALL" , 7 ) ) cmdfm.icomORroll = RECALL ; else if ( lckeyExact ( "ROLLBACK" , 9 ) ) cmdfm.icomORroll = ROLLBACK ; /* -- "filelist": write files using names in new filelist. */ else if( ( list = lcdfl() ) ){ cmdfm.lovrrq = FALSE; lexpnd = FALSE; } /* -- Bad syntax. */ else{ cfmt( "ILLEGAL OPTION:",17 ); cresp(); } } /* end while ( lcmore( nerr ) ) */ /* - The above loop is over when one of two conditions has been met: * (1) An error in parsing has occurred. In this case NERR is > 0 . * (2) All the tokens in the command have been successfully parsed. */ if( *nerr != 0 ) goto L_8888; /* CHECKING PHASE: */ if(!list) { list = files; } else { /* List + Modifiers :: Use List */ string_list_free(files); files = NULL; } /* - Check for null write filelist. */ if( string_list_length(list) <= 0 ){ *nerr = 1311; setmsg( "ERROR", *nerr ); goto L_8888; } /* - Make sure the write filelist has as many entries as read filelist. */ if( string_list_length(list) != cmdfm.ndfl ){ *nerr = 1312; error(1312, "%d %d", string_list_length(list), cmdfm.ndfl); goto L_8888; } /* EXECUTION PHASE: */ /* - Commit or rollback data according to cmdfm.icomORroll */ alignFiles ( nerr ) ; if ( *nerr ) return ; /* - Echo expanded filelist if requested. */ if( cmdfm.lechof && lexpnd ){ setmsg( "OUTPUT", 0 ); for(i = 0; i < string_list_length(list); i++) { file = string_list_get(list, i); getdir( file, strlen(file)+1, kcdir,9, kfile,MCPFN+1 ); /* -- Echo the filename part if there is no directory part. */ if( strcmp(kcdir," ") == 0 ) apcmsg( kfile,MCPFN+1 ); /* -- Prepend the filename part with some special characters if * directory part is same as that of the previous file. */ else if( memcmp(kcdir,kpdir,min(strlen(kcdir),strlen(kpdir))) == 0 ){ cattemp = malloc(3+strlen(kfile)+1); strcpy(cattemp, "..."); strcat(cattemp,kfile); apcmsg( cattemp, 3+strlen(kfile)+1 ); free(cattemp); } /* -- Echo complete pathname if directory part is different. */ else{ apcmsg2(file, strlen(file)+1); strcpy( kpdir, kcdir ); } } wrtmsg( MUNOUT ); } /* - Write each file in memory to disk. */ nwrdir = indexb( kmdfm.kwrdir,MCPFN+1 ); for( jdfl = 1; jdfl <= cmdfm.ndfl; jdfl++ ){ /* -- Get file from memory manager. */ file = string_list_get(list, jdfl-1); getfil( jdfl, TRUE, &nlen, &ndx1, &ndx2, nerr ); if( *nerr != 0 ) goto L_8888; /* isolate file name */ file = string_list_get(list, jdfl-1); /* -- Check overwrite-protect flag in header record. */ if( cmdfm.lovrrq && !*lovrok ){ *nerr = 1303; setmsg( "ERROR", *nerr ); apcmsg2(file, strlen(file)+1); outmsg () ; clrmsg () ; goto L_8888; } /* -- Prepare output file name: * --- If directory option is ON (lwrdir=.TRUE. and nwrdir>0), * concatenate directory name with file name part of write file list. * --- If directory option is CURRENT (lwrdir=.TRUE. and nwrdir=0), * use file name part of write file list. * --- If directory option is OFF, use write file list. */ if( lwrdir ){ if( nwrdir > 0 ){ fstrncpy( kfile, MCPFN, kmdfm.kwrdir,min(nwrdir,MCPFN)); strtemp1 = file; strtemp2 = malloc(130-(nwrdir+1)); strncpy(strtemp2,kfile+nwrdir,MCPFN+1-(nwrdir + 1)); strtemp2[MCPFN+1-(nwrdir+1)] = '\0'; getdir( strtemp1, strlen(strtemp1)+1, kdirpart, MCPFN+1, strtemp2,-(nwrdir+1)+130); subscpy(kfile,nwrdir,-1,MCPFN,strtemp2); free(strtemp2); } else{ fstrncpy( kfile, MCPFN, " ", 1); getdir( file, strlen(file)+1, kdirpart,MCPFN+1, kfile,MCPFN+1 ); } } else { fstrncpy( kfile, MCPFN, file, strlen(file)); } /* -- Write file in appropriate format. */ if( cmdfm.iwfmt == 2 ) wrci( jdfl, kfile,MCPFN+1, "%#15.7g", nerr ); else if( cmdfm.iwfmt == 3 ) wrsdd( jdfl, kfile,MCPFN+1, TRUE, nerr ); else if( cmdfm.iwfmt == 4 ) wrxdr( jdfl, kfile,MCPFN+1, TRUE, nerr ); else if( cmdfm.iwfmt == 5 ) wrsegy( jdfl , kfile , nerr ) ; else wrsac( jdfl, kfile,MCPFN+1, TRUE, nerr ); if( *nerr != 0 ) goto L_8888; } /* end for ( jdfl ) */ L_8888: return; }
BOOL command(int commandc) { char filename[PATHLEN + 1]; /* file path name */ MOUSEEVENT *p; /* mouse data */ int c, i; FILE *file; HISTORY *curritem, *item; /* command history */ char *s; switch (commandc) { case ctrl('C'): /* toggle caseless mode */ if (caseless == NO) { caseless = YES; putmsg2("Caseless mode is now ON"); } else { caseless = NO; putmsg2("Caseless mode is now OFF"); } egrepcaseless(caseless); /* turn on/off -i flag */ return (NO); case ctrl('R'): /* rebuild the cross reference */ if (isuptodate == YES) { putmsg("The -d option prevents rebuilding the " "symbol database"); return (NO); } exitcurses(); freefilelist(); /* remake the source file list */ makefilelist(); rebuild(); if (errorsfound == YES) { errorsfound = NO; askforreturn(); } entercurses(); putmsg(""); /* clear any previous message */ totallines = 0; topline = nextline = 1; break; case ctrl('X'): /* mouse selection */ if ((p = getmouseevent()) == NULL) { return (NO); /* unknown control sequence */ } /* if the button number is a scrollbar tag */ if (p->button == '0') { scrollbar(p); break; } /* ignore a sweep */ if (p->x2 >= 0) { return (NO); } /* if this is a line selection */ if (p->y1 < FLDLINE) { /* find the selected line */ /* note: the selection is forced into range */ for (i = disprefs - 1; i > 0; --i) { if (p->y1 >= displine[i]) { break; } } /* display it in the file with the editor */ editref(i); } else { /* this is an input field selection */ field = mouseselection(p, FLDLINE, FIELDS); setfield(); resetcmd(); return (NO); } break; case '\t': /* go to next input field */ case '\n': case '\r': case ctrl('N'): case KEY_DOWN: case KEY_ENTER: case KEY_RIGHT: field = (field + 1) % FIELDS; setfield(); resetcmd(); return (NO); case ctrl('P'): /* go to previous input field */ case KEY_UP: case KEY_LEFT: field = (field + (FIELDS - 1)) % FIELDS; setfield(); resetcmd(); return (NO); case KEY_HOME: /* go to first input field */ field = 0; setfield(); resetcmd(); return (NO); case KEY_LL: /* go to last input field */ field = FIELDS - 1; setfield(); resetcmd(); return (NO); case ' ': /* display next page */ case '+': case ctrl('V'): case KEY_NPAGE: /* don't redisplay if there are no lines */ if (totallines == 0) { return (NO); } /* * note: seekline() is not used to move to the next * page because display() leaves the file pointer at * the next page to optimize paging forward */ break; case '-': /* display previous page */ case KEY_PPAGE: /* don't redisplay if there are no lines */ if (totallines == 0) { return (NO); } i = topline; /* save the current top line */ nextline = topline; /* go back to this page */ /* if on first page but not at beginning, go to beginning */ if (nextline > 1 && nextline <= mdisprefs) { nextline = 1; } else { /* go back the maximum displayable lines */ nextline -= mdisprefs; /* if this was the first page, go to the last page */ if (nextline < 1) { nextline = totallines - mdisprefs + 1; if (nextline < 1) { nextline = 1; } /* old top is past last line */ i = totallines + 1; } } /* * move down til the bottom line is just before the * previous top line */ c = nextline; for (;;) { seekline(nextline); display(); if (i - bottomline <= 0) { break; } nextline = ++c; } return (NO); /* display already up to date */ case '>': /* write or append the lines to a file */ if (totallines == 0) { putmsg("There are no lines to write to a file"); } else { /* get the file name */ (void) move(PRLINE, 0); (void) addstr("Write to file: "); s = "w"; if ((c = mygetch()) == '>') { (void) move(PRLINE, 0); (void) addstr(appendprompt); c = '\0'; s = "a"; } if (c != '\r' && c != '\n' && c != KEY_ENTER && c != KEY_BREAK && getaline(newpat, COLS - sizeof (appendprompt), c, NO) > 0) { shellpath(filename, sizeof (filename), newpat); if ((file = fopen(filename, s)) == NULL) { cannotopen(filename); } else { seekline(1); while ((c = getc(refsfound)) != EOF) { (void) putc(c, file); } seekline(topline); (void) fclose(file); } } clearprompt(); } return (NO); /* return to the previous field */ case '<': /* read lines from a file */ (void) move(PRLINE, 0); (void) addstr(readprompt); if (getaline(newpat, COLS - sizeof (readprompt), '\0', NO) > 0) { clearprompt(); shellpath(filename, sizeof (filename), newpat); if (readrefs(filename) == NO) { putmsg2("Ignoring an empty file"); return (NO); } return (YES); } clearprompt(); return (NO); case '^': /* pipe the lines through a shell command */ case '|': /* pipe the lines to a shell command */ if (totallines == 0) { putmsg("There are no lines to pipe to a shell command"); return (NO); } /* get the shell command */ (void) move(PRLINE, 0); (void) addstr(pipeprompt); if (getaline(newpat, COLS - sizeof (pipeprompt), '\0', NO) == 0) { clearprompt(); return (NO); } /* if the ^ command, redirect output to a temp file */ if (commandc == '^') { (void) strcat(strcat(newpat, " >"), temp2); } exitcurses(); if ((file = mypopen(newpat, "w")) == NULL) { (void) fprintf(stderr, "cscope: cannot open pipe to shell command: %s\n", newpat); } else { seekline(1); while ((c = getc(refsfound)) != EOF) { (void) putc(c, file); } seekline(topline); (void) mypclose(file); } if (commandc == '^') { if (readrefs(temp2) == NO) { putmsg("Ignoring empty output of ^ command"); } } askforreturn(); entercurses(); break; case ctrl('L'): /* redraw screen */ case KEY_CLEAR: (void) clearok(curscr, TRUE); (void) wrefresh(curscr); drawscrollbar(topline, bottomline, totallines); return (NO); case '!': /* shell escape */ (void) execute(shell, shell, (char *)NULL); seekline(topline); break; case '?': /* help */ (void) clear(); help(); (void) clear(); seekline(topline); break; case ctrl('E'): /* edit all lines */ editall(); break; case ctrl('A'): /* repeat last pattern */ case ctrl('Y'): /* (old command) */ if (*pattern != '\0') { (void) addstr(pattern); goto repeat; } break; case ctrl('B'): /* cmd history back */ case ctrl('F'): /* cmd history fwd */ curritem = currentcmd(); item = (commandc == ctrl('F')) ? nextcmd() : prevcmd(); clearmsg2(); if (curritem == item) { /* inform user that we're at history end */ putmsg2( "End of input field and search pattern history"); } if (item) { field = item->field; setfield(); atfield(); (void) addstr(item->text); (void) strcpy(pattern, item->text); switch (c = mygetch()) { case '\r': case '\n': case KEY_ENTER: goto repeat; default: ungetch(c); atfield(); (void) clrtoeol(); /* clear current field */ break; } } return (NO); case '\\': /* next character is not a command */ (void) addch('\\'); /* display the quote character */ /* get a character from the terminal */ if ((commandc = mygetch()) == EOF) { return (NO); /* quit */ } (void) addstr("\b \b"); /* erase the quote character */ goto ispat; case '.': atfield(); /* move back to the input field */ /* FALLTHROUGH */ default: /* edit a selected line */ if (isdigit(commandc) && commandc != '0' && !mouse) { if (returnrequired == NO) { editref(commandc - '1'); } else { (void) move(PRLINE, 0); (void) addstr(selectionprompt); if (getaline(newpat, COLS - sizeof (selectionprompt), commandc, NO) > 0 && (i = atoi(newpat)) > 0) { editref(i - 1); } clearprompt(); } } else if (isprint(commandc)) { /* this is the start of a pattern */ ispat: if (getaline(newpat, COLS - fldcolumn - 1, commandc, caseless) > 0) { (void) strcpy(pattern, newpat); resetcmd(); /* reset history */ repeat: addcmd(field, pattern); /* add to history */ if (field == CHANGE) { /* prompt for the new text */ (void) move(PRLINE, 0); (void) addstr(toprompt); (void) getaline(newpat, COLS - sizeof (toprompt), '\0', NO); } /* search for the pattern */ if (search() == YES) { switch (field) { case DEFINITION: case FILENAME: if (totallines > 1) { break; } topline = 1; editref(0); break; case CHANGE: return (changestring()); } } else if (field == FILENAME && access(newpat, READ) == 0) { /* try to edit the file anyway */ edit(newpat, "1"); } } else { /* no pattern--the input was erased */ return (NO); } } else { /* control character */ return (NO); } } return (YES); }