📄 rcslex.c
字号:
GETC(frew, c); switch (c) { case '\n': ++rcsline; break; case SDELIM: GETC(frew, c); if (c != SDELIM) { /* end of string */ nextc = c; uncache(fin); return; } break; } }} voidprintstring()/* Function: copy a string to stdout, until terminated with a single SDELIM. * Does not advance nextlex at the end. */{ register c; declarecache; register FILE *fout; register RILE *fin; fin=finptr; fout = stdout; setupcache(fin); cache(fin); for (;;) { cacheget(c); switch (c) { case '\n': ++rcsline; break; case SDELIM: cacheget(c); if (c != SDELIM) { nextc=c; uncache(fin); return; } break; } aputc(c,fout); }} struct cbufsavestring(target) struct buf *target;/* Copies a string terminated with SDELIM from file finptr to buffer target. * Double SDELIM is replaced with SDELIM. * If foutptr is set, the string is also copied unchanged to foutptr. * Does not advance nextlex at the end. * Yield a copy of *TARGET, except with exact length. */{ register c; declarecache; register FILE *frew; register char *tp; register RILE *fin; char const *limit; struct cbuf r; fin=finptr; frew=foutptr; setupcache(fin); cache(fin); tp = target->string; limit = tp + target->size; for (;;) { GETC(frew, c); switch (c) { case '\n': ++rcsline; break; case SDELIM: GETC(frew, c); if (c != SDELIM) { /* end of string */ nextc=c; r.string = target->string; r.size = tp - r.string; uncache(fin); return r; } break; } if (tp == limit) tp = bufenlarge(target, &limit); *tp++ = c; }} char *checkid(id, delimiter) register char *id; int delimiter;/* Function: check whether the string starting at id is an *//* identifier and return a pointer to the delimiter*//* after the identifier. White space, delim and 0 *//* are legal delimiters. Aborts the program if not*//* a legal identifier. Useful for checking commands*//* If !delim, the only delimiter is 0. */{ register enum tokens d; register char *temp; register char c,tc; register char delim = delimiter; temp = id; if ((d = ctab[(unsigned char)(c = *id)])==LETTER || d==Letter) { while ((d = ctab[(unsigned char)(c = *++id)])==LETTER || d==Letter || d==DIGIT || d==IDCHAR ) ; if (c && (!delim || c!=delim && c!=' ' && c!='\t' && c!='\n')) { /* append \0 to end of id before error message */ tc = c; while( (c=(*++id))!=' ' && c!='\t' && c!='\n' && c!='\0' && c!=delim) ; *id = '\0'; faterror("invalid character %c in identifier `%s'",tc,temp); } } else { /* append \0 to end of id before error message */ while( (c=(*++id))!=' ' && c!='\t' && c!='\n' && c!='\0' && c!=delim) ; *id = '\0'; faterror("identifier `%s' doesn't start with letter", temp); } return id;} voidchecksid(id) char *id;/* Check whether the string ID is an identifier. */{ VOID checkid(id, 0);} static RILE *#if has_mmap && large_memoryfd2_RILE(fd, filename, status)#elsefd2RILE(fd, filename, mode, status) char const *mode;#endif int fd; char const *filename; register struct stat *status;{ struct stat st; if (!status) status = &st; if (fstat(fd, status) != 0) efaterror(filename); if (!S_ISREG(status->st_mode)) { error("`%s' is not a regular file", filename); VOID close(fd); errno = EINVAL; return 0; } else {# if ! (has_mmap && large_memory) FILE *stream; if (!(stream = fdopen(fd, mode))) efaterror(filename);# endif# if !large_memory return stream;# else# define RILES 3 { static RILE rilebuf[RILES]; register RILE *f; size_t s = status->st_size; if (s != status->st_size) faterror("`%s' is enormous", filename); for (f = rilebuf; f->base; f++) if (f == rilebuf+RILES) faterror("too many RILEs"); if (!s) { static unsigned char dummy; f->base = &dummy; } else {# if has_mmap if ( (f->base = (unsigned char *)mmap( (caddr_t)0, s, PROT_READ, MAP_SHARED, fd, (off_t)0 )) == (unsigned char *)-1 ) efaterror("mmap");# else f->base = tnalloc(unsigned char, s);# endif } f->ptr = f->base; f->lim = f->base + s;# if has_mmap f->fd = fd;# else f->readlim = f->base; f->stream = stream;# endif if_advise_access(s, f, MADV_SEQUENTIAL); return f; }# endif }}#if !has_mmap && large_memory intIgetmore(f) register RILE *f;{ register fread_type r; register size_t s = f->lim - f->readlim; if (BUFSIZ < s) s = BUFSIZ; if (!(r = Fread(f->readlim, sizeof(*f->readlim), s, f->stream))) { testIerror(f->stream); f->lim = f->readlim; /* The file might have shrunk! */ return 0; } f->readlim += r; return 1;}#endif#if has_madvise && has_mmap && large_memory voidadvise_access(f, advice) register RILE *f; int advice;{ if (madvise((caddr_t)f->base, (size_t)(f->lim - f->base), advice) != 0) efaterror("madvise");}#endif RILE *#if has_mmap && large_memoryI_open(filename, status)#elseIopen(filename, mode, status) char const *mode;#endif char const *filename; struct stat *status;/* Open FILENAME for reading, yield its descriptor, and set *STATUS. */{ int fd; if ((fd = open(filename,O_RDONLY|O_BINARY)) < 0) return 0;# if has_mmap && large_memory return fd2_RILE(fd, filename, status);# else return fd2RILE(fd, filename, mode, status);# endif}#if !large_memory# define Iclose(f) fclose(f)#else static int Iclose(f) register RILE *f; {# if has_mmap size_t s = f->lim - f->base; if (s && munmap((caddr_t)f->base, s) != 0) return -1; f->base = 0; return close(f->fd);# else tfree(f->base); f->base = 0; return fclose(f->stream);# endif }#endifstatic int Oerrloop; exiting voidOerror(){ if (Oerrloop) exiterr(); Oerrloop = true; efaterror("output error");}exiting void Ieof() { fatserror("unexpected end of file"); }exiting void Ierror() { efaterror("input error"); }void testIerror(f) FILE *f; { if (ferror(f)) Ierror(); }void testOerror(o) FILE *o; { if (ferror(o)) Oerror(); }void Ifclose(f) RILE *f; { if (f && Iclose(f)!=0) Ierror(); }void Ofclose(f) FILE *f; { if (f && fclose(f)!=0) Oerror(); }void Izclose(p) RILE **p; { Ifclose(*p); *p = 0; }void Ozclose(p) FILE **p; { Ofclose(*p); *p = 0; }#if !large_memory voidtestIeof(f) FILE *f;{ testIerror(f); if (feof(f)) Ieof();}void Irewind(f) FILE *f; { if (fseek(f,0L,SEEK_SET) != 0) Ierror(); }#endifvoid eflush(){ if (fflush(stderr) != 0 && !Oerrloop) Oerror();}void oflush(){ if (fflush(workstdout ? workstdout : stdout) != 0 && !Oerrloop) Oerror();} static exiting voidfatcleanup(already_newline) int already_newline;{ VOID fprintf(stderr, already_newline+"\n%s aborted\n", cmdid); exiterr();}static void errsay() { oflush(); aprintf(stderr,"%s error: ",cmdid); nerror++; }static void fatsay() { oflush(); VOID fprintf(stderr,"%s error: ",cmdid); }void eerror(s) char const *s; { enerror(errno,s); } voidenerror(e,s) int e; char const *s;{ errsay(); errno = e; perror(s); eflush();}exiting void efaterror(s) char const *s; { enfaterror(errno,s); } exiting voidenfaterror(e,s) int e; char const *s;{ fatsay(); errno = e; perror(s); fatcleanup(true);}#if has_prototypes voiderror(char const *format,...)#else /*VARARGS1*/ void error(format, va_alist) char const *format; va_dcl#endif/* non-fatal error */{ va_list args; errsay(); vararg_start(args, format); fvfprintf(stderr, format, args); va_end(args); afputc('\n',stderr); eflush();}#if has_prototypes exiting voidfatserror(char const *format,...)#else /*VARARGS1*/ exiting void fatserror(format, va_alist) char const *format; va_dcl#endif/* fatal syntax error */{ va_list args; oflush(); VOID fprintf(stderr, "%s: %s:%lu: ", cmdid, RCSfilename, rcsline); vararg_start(args, format); fvfprintf(stderr, format, args); va_end(args); fatcleanup(false);}#if has_prototypes exiting voidfaterror(char const *format,...)#else /*VARARGS1*/ exiting void faterror(format, va_alist) char const *format; va_dcl#endif/* fatal error, terminates program after cleanup */{ va_list args; fatsay(); vararg_start(args, format); fvfprintf(stderr, format, args); va_end(args); fatcleanup(false);}#if has_prototypes voidwarn(char const *format,...)#else /*VARARGS1*/ void warn(format, va_alist) char const *format; va_dcl#endif/* prints a warning message */{ va_list args; oflush(); aprintf(stderr,"%s warning: ",cmdid); vararg_start(args, format); fvfprintf(stderr, format, args); va_end(args); afputc('\n',stderr); eflush();} voidredefined(c) int c;{ warn("redefinition of -%c option", c);}#if has_prototypes voiddiagnose(char const *format,...)#else /*VARARGS1*/ void diagnose(format, va_alist) char const *format; va_dcl#endif/* prints a diagnostic message *//* Unlike the other routines, it does not append a newline. *//* This lets some callers suppress the newline, and is faster *//* in implementations that flush stderr just at the end of each printf. */{ va_list args; if (!quietflag) { oflush(); vararg_start(args, format); fvfprintf(stderr, format, args); va_end(args); eflush(); }} voidafputc(c, f)/* Function: afputc(c,f) acts like aputc(c,f), but is smaller and slower. */ int c; register FILE *f;{ aputc(c,f);} voidaputs(s, iop) char const *s; FILE *iop;/* Function: Put string s on file iop, abort on error. */{#if has_fputs if (fputs(s, iop) < 0) Oerror();#else awrite(s, strlen(s), iop);#endif} void#if has_prototypesfvfprintf(FILE *stream, char const *format, va_list args)#else fvfprintf(stream,format,args) FILE *stream; char *format; va_list args;#endif/* like vfprintf, except abort program on error */{#if has_vfprintf if (vfprintf(stream, format, args) < 0)#else# if has__doprintf _doprintf(stream, format, args);# else# if has__doprnt _doprnt(format, args, stream);# else int *a = (int *)args; VOID fprintf(stream, format, a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9] );# endif# endif if (ferror(stream))#endif Oerror();}#if has_prototypes voidaprintf(FILE *iop, char const *fmt, ...)#else /*VARARGS2*/ voidaprintf(iop, fmt, va_alist)FILE *iop;char const *fmt;va_dcl#endif/* Function: formatted output. Same as fprintf in stdio, * but aborts program on error */{ va_list ap; vararg_start(ap, fmt); fvfprintf(iop, fmt, ap); va_end(ap);}#ifdef LEXDB/* test program reading a stream of lexemes and printing the tokens. */ intmain(argc,argv)int argc; char * argv[];{ cmdid="lextest"; if (argc<2) { aputs("No input file\n",stderr); exitmain(EXIT_FAILURE); } if (!(finptr=Iopen(argv[1], FOPEN_R, (struct stat*)0))) { faterror("can't open input file %s",argv[1]); } Lexinit(); while (!eoflex()) { switch (nexttok) { case ID: VOID printf("ID: %s",NextString); break; case NUM: if (hshenter) VOID printf("NUM: %s, index: %d",nexthsh->num, nexthsh-hshtab); else VOID printf("NUM, unentered: %s",NextString); hshenter = !hshenter; /*alternate between dates and numbers*/ break; case COLON: VOID printf("COLON"); break; case SEMI: VOID printf("SEMI"); break; case STRING: readstring(); VOID printf("STRING"); break; case UNKN: VOID printf("UNKN"); break; default: VOID printf("DEFAULT"); break; } VOID printf(" | "); nextlex(); } exitmain(EXIT_SUCCESS);}exiting void exiterr() { _exit(EXIT_FAILURE); }#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -