/** * nsf :- nakamura version of sf (see unix magagine 89.7 page 122- ) **/ #include #include #include #include #define MAIN #include "nsf.h" static int usage(){ fprintf(stderr,"usage: nsf [-flags] < infile > outfile\n"); fprintf(stderr,"\t-b\toutput is for bsh (default csh)\n"); fprintf(stderr,"\t-c 3\tcursol initial postion.\n"); fprintf(stderr,"\t-m message\tinitial wornning.\n"); fprintf(stderr,"\t-i infile\tuse infile instead of stdin.\n"); fprintf(stderr,"\t-o outfile\tuse outfile instead of stdout.\n"); fprintf(stderr,"\t-u \tuse under line for input field.\n"); exit(0); } /** * done() **/ void done(){ move(LINES-1,0); clrtoeol(); refresh(); endwin(); } /** * laydef() **/ void laydef(){ void user_interrupt(); int y,x; unsigned char c; int sts; struct INFLD *p; char buf[BUFSIZ]; char *s,*gets(); signal(SIGINT,user_interrupt); /* interrupt proc */ initscr(); /* initialize curses */ keypad(stdscr,TRUE); /* use of arrow keys */ noecho(); /* no echo on input */ cbreak(); /* character operation on input */ meta(stdscr,TRUE); /* enable 8 bit handling */ nonl(); /* disable nl <--> cr,lf */ leaveok(stdscr,TRUE); /* do not care the cursor position */ while(1){ if ((s = fgets(buf,sizeof(buf),fpin)) == NULL) break; if (*s == 0x0c) break; if (*s == '@' && (*(s+1) == '\n' || *(s+1) == '\0')) break; sts = 0; for(;(c = *s) != '\0' && c != '\n' ; ++s){ if (c == '~'){ if (sts == 0){ /* new field */ if (nfld >= MAXFLD){ done(); fprintf(stderr,"\ntoo many field\n"); exit(1); } if (use_uline) attron(A_UNDERLINE); getyx(stdscr,y,x); addch(' '); sts = 1; p = &fld[nfld]; p->y = y; p->x = x; p->len = 1; p->nopt = 0; p->attr = 0; p->help[0] = '\0'; p->ver[0] = '\0'; p->def[0] = '\0'; p->inp[0] = '\0'; nfld++; }else{ if (p->len >= MAXLEN){ done(); fprintf(stderr,"\ntoo long field\n"); exit(1); } addch(' '); p->len++; } }else{ if (sts == 1){ sts = 0; if (use_uline) attroff(A_UNDERLINE); } addch(c); } } if (sts == 1){ if (use_uline) attroff(A_UNDERLINE); sts = 0; } addch('\n'); } refresh(); } void user_interrupt(){ done(); exit(0); } static void perse_option(i,s) int i; char *s; { char dlm,*t; int n; s += 2; /* skip "s=" of "s=:opt1:opt2:opt3" */ dlm = *s++; /* get ":" */ for (n = 0 ;;){ t = strchr(s,dlm); if (t != NULL) *t = '\0'; if (n >= MAXOPT) break; strcpy(fld[i].opt[n++],s); /* get "opt1" "opt2" .. */ if (t == NULL) break; s = ++t; } fld[i].nopt = n; } /** * flddef() **/ void flddef(){ char dlm; char buf[BUFSIZ],*s,*t,*gets(),*strchr(); int i,j,k; i = 0; while (1){ if (i >= nfld) break; if ((s = fgets(buf,sizeof(buf),fpin)) == NULL) goto error; dlm = *s++; for(j = i ; ((j+1) < nfld) && (fld[j+1].y == fld[i].y) ; ++j) ; k = j-i+1; while(1){ if ((t = strchr(s,dlm)) != NULL) *t = '\0'; if (!memcmp(s,"v=",2)){ if (fld[i].ver[0] != '\0') i++; if (--k < 0) goto error; strcpy(fld[i].ver,s+2); }else if (!memcmp(s,"d=",2)){ strcpy(fld[i].def,s+2); }else if (!memcmp(s,"h=",2)){ strcpy(fld[i].help,s+2); }else if (!memcmp(s,"s=",2)){ perse_option(i,s); fld[i].attr |= SF_SELECT; }else if (!memcmp(s,"a=",2)){ for(s+=2;*s != '\0';++s) switch(*s){ case 'a': fld[i].attr |= SF_ASCEND; break; case 'd': fld[i].attr |= SF_DIGITS; break; case 'u': fld[i].attr |= SF_UCASE; break; case 'l': fld[i].attr |= SF_LCASE; break; case 'f': fld[i].attr |= SF_FORCE; break; case 'r': fld[i].attr |= SF_REAL; break; } }else if (*s == '\0' || *s == '\n'){ break; }else{ goto error; } if (t == NULL) break; s = ++t; } if (k > 0) goto error; ++i; } /* field def result check */ for(i = 0 ; i < nfld ; ++i){ if ((fld[i].attr & SF_SELECT) && fld[i].nopt < 0) goto error; if (fld[i].ver[0] == '\0') goto error; } return; error: done(); fprintf(stderr,"\nfield definition format error.\n"); exit(1); } /** * datout() **/ void datout(){ int i; FILE *fp; if (fout == NULL ) fp = stdout; else fp = fopen(fout,"w"); if (fp == NULL){ perror(fout); exit(1); } for (i = 0 ; i < nfld ; ++i) if (bsh_format) fprintf(fp,"%s=%s\n",fld[i].ver,fld[i].inp); else fprintf(fp,"set %s = %s\n",fld[i].ver,fld[i].inp); if (fp != stdout) fclose(fp); } /** * main() **/ int main(argc,argv) int argc; char *argv[]; { int opt; extern char *optarg; extern void iloop(); while ((opt = getopt(argc,argv,"um:dc:bi:o:")) != EOF) switch(opt){ case 'b': bsh_format = 1; break; case 'c': cfld = atoi(optarg); break; case 'd': debug_on = 1; break; case 'i': fpin = fopen(optarg,"r"); if (fpin == NULL){ perror(optarg); exit(1); } break; case 'o': fout = optarg; break; case 'm': strcpy(initmesg,optarg); break; case 'u': use_uline = 1; break; case '?': usage(); } if (fpin == NULL) fpin = stdin; laydef(); /* perse layout definition part of stdin data */ flddef(); /* perse field definition part of stdin data */ if (fpin == stdin){ /* for the case of stdin is redirected. */ if (freopen("/dev/tty","r",stdin) == NULL){ perror("/dev/tty"); exit(1); } } iloop(); /* loop proccess for user input */ done(); /* end curses */ datout(); /* output the result */ exit(0); }