📄 lib.c
字号:
}}void newfld(int n) /* add field n after end of existing lastfld */{ if (n > nfields) growfldtab(n); cleanfld(lastfld+1, n); lastfld = n; setfval(nfloc, (Awkfloat) n);}Cell *fieldadr(int n) /* get nth field */{ if (n < 0) FATAL("trying to access field %d", n); if (n > nfields) /* fields after NF are empty */ growfldtab(n); /* but does not increase NF */ return(fldtab[n]);}void growfldtab(int n) /* make new fields up to at least $n */{ int nf = 2 * nfields; if (n > nf) nf = n; fldtab = (Cell **) realloc(fldtab, (nf+1) * (sizeof (struct Cell *))); if (fldtab == NULL) FATAL("out of space creating %d fields", nf); makefields(nfields+1, nf); nfields = nf;}int refldbld(char *rec, char *fs) /* build fields from reg expr in FS */{ /* this relies on having fields[] the same length as $0 */ /* the fields are all stored in this one array with \0's */ char *fr; void *p; int i, tempstat, n; n = strlen(rec); if (n > fieldssize) { xfree(fields); if ((fields = (char *) malloc(n+1)) == NULL) FATAL("out of space for fields in refldbld %d", n); fieldssize = n; } fr = fields; *fr = '\0'; if (*rec == '\0') return 0; p = compre(fs); dprintf( ("into refldbld, rec = <%s>, pat = <%s>\n", rec, fs) ); for (i = 1; ; i++) { if (i > nfields) growfldtab(i); if (freeable(fldtab[i])) xfree(fldtab[i]->sval); fldtab[i]->tval = FLD | STR | DONTFREE; fldtab[i]->sval = fr; dprintf( ("refldbld: i=%d\n", i) ); if (nematch(p, rec, rec)) { dprintf( ("match %s (%d chars)\n", patbeg, patlen) ); strncpy(fr, rec, patbeg-rec); fr += patbeg - rec + 1; *(fr-1) = '\0'; rec = patbeg + patlen; } else { dprintf( ("no match %s\n", rec) ); strcpy(fr, rec); break; } } return i; }void recbld(void) /* create $0 from $1..$NF if necessary */{ int i; char *r, *p; if (donerec == 1) return; r = record; for (i = 1; i <= *NF; i++) { p = getsval(fldtab[i]); if (!adjbuf(&record, &recsize, 1+strlen(p)+r-record, recsize, &r, "recbld 1")) FATAL("created $0 `%.30s...' too long", record); while ((*r = *p++) != 0) r++; if (i < *NF) { if (!adjbuf(&record, &recsize, 2+strlen(*OFS)+r-record, recsize, &r, "recbld 2")) FATAL("created $0 `%.30s...' too long", record); for (p = *OFS; (*r = *p++) != 0; ) r++; } } if (!adjbuf(&record, &recsize, 2+r-record, recsize, &r, "recbld 3")) FATAL("built giant record `%.30s...'", record); *r = '\0'; dprintf( ("in recbld inputFS=%s, fldtab[0]=%p\n", inputFS, fldtab[0]) ); if (freeable(fldtab[0])) xfree(fldtab[0]->sval); fldtab[0]->tval = REC | STR | DONTFREE; fldtab[0]->sval = record; dprintf( ("in recbld inputFS=%s, fldtab[0]=%p\n", inputFS, fldtab[0]) ); dprintf( ("recbld = |%s|\n", record) ); donerec = 1;}int errorflag = 0;void yyerror(char *s){ SYNTAX(s);}void SYNTAX(char *fmt, ...){ extern char *cmdname, *curfname; static int been_here = 0; va_list varg; if (been_here++ > 2) return; fprintf(stderr, "%s: ", cmdname); va_start(varg, fmt); vfprintf(stderr, fmt, varg); va_end(varg); if(compile_time == 1 && cursource() != NULL) fprintf(stderr, " at %s:%d", cursource(), lineno); else fprintf(stderr, " at line %d", lineno); if (curfname != NULL) fprintf(stderr, " in function %s", curfname); fprintf(stderr, "\n"); errorflag = 2; eprint();}void fpecatch(int n){ FATAL("floating point exception %d", n);}extern int bracecnt, brackcnt, parencnt;void bracecheck(void){ int c; static int beenhere = 0; if (beenhere++) return; while ((c = input()) != EOF && c != '\0') bclass(c); bcheck2(bracecnt, '{', '}'); bcheck2(brackcnt, '[', ']'); bcheck2(parencnt, '(', ')');}void bcheck2(int n, int c1, int c2){ if (n == 1) fprintf(stderr, "\tmissing %c\n", c2); else if (n > 1) fprintf(stderr, "\t%d missing %c's\n", n, c2); else if (n == -1) fprintf(stderr, "\textra %c\n", c2); else if (n < -1) fprintf(stderr, "\t%d extra %c's\n", -n, c2);}void FATAL(char *fmt, ...){ extern char *cmdname; va_list varg; fflush(stdout); fprintf(stderr, "%s: ", cmdname); va_start(varg, fmt); vfprintf(stderr, fmt, varg); va_end(varg); error(); if (dbg > 1) /* core dump if serious debugging on */ abort(); exit(2);}void WARNING(char *fmt, ...){ extern char *cmdname; va_list varg; fflush(stdout); fprintf(stderr, "%s: ", cmdname); va_start(varg, fmt); vfprintf(stderr, fmt, varg); va_end(varg); error();}void error(){ extern Node *curnode; int line; fprintf(stderr, "\n"); if (compile_time != 2 && NR && *NR > 0) { if (strcmp(*FILENAME, "-") != 0) fprintf(stderr, " input record %s:%d", *FILENAME, (int) (*FNR)); else fprintf(stderr, " input record number %d", (int) (*FNR)); fprintf(stderr, "\n"); } if (compile_time != 2 && curnode) line = curnode->lineno; else if (compile_time != 2 && lineno) line = lineno; else line = -1; if (compile_time == 1 && cursource() != NULL){ if(line >= 0) fprintf(stderr, " source %s:%d", cursource(), line); else fprintf(stderr, " source file %s", cursource()); }else if(line >= 0) fprintf(stderr, " source line %d", line); fprintf(stderr, "\n"); eprint();}void eprint(void) /* try to print context around error */{ char *p, *q; int c; static int been_here = 0; extern char ebuf[], *ep; if (compile_time == 2 || compile_time == 0 || been_here++ > 0) return; p = ep - 1; if (p > ebuf && *p == '\n') p--; for ( ; p > ebuf && *p != '\n' && *p != '\0'; p--) ; while (*p == '\n') p++; fprintf(stderr, " context is\n\t"); for (q=ep-1; q>=p && *q!=' ' && *q!='\t' && *q!='\n'; q--) ; for ( ; p < q; p++) if (*p) putc(*p, stderr); fprintf(stderr, " >>> "); for ( ; p < ep; p++) if (*p) putc(*p, stderr); fprintf(stderr, " <<< "); if (*ep) while ((c = input()) != '\n' && c != '\0' && c != EOF) { putc(c, stderr); bclass(c); } putc('\n', stderr); ep = ebuf;}void bclass(int c){ switch (c) { case '{': bracecnt++; break; case '}': bracecnt--; break; case '[': brackcnt++; break; case ']': brackcnt--; break; case '(': parencnt++; break; case ')': parencnt--; break; }}double errcheck(double x, char *s){ if (errno == EDOM) { errno = 0; WARNING("%s argument out of domain", s); x = 1; } else if (errno == ERANGE) { errno = 0; WARNING("%s result out of range", s); x = 1; } return x;}int isclvar(char *s) /* is s of form var=something ? */{ char *os = s; if (!isalpha(*s) && *s != '_') return 0; for ( ; *s; s++) if (!(isalnum(*s) || *s == '_')) break; return *s == '=' && s > os && *(s+1) != '=';}/* strtod is supposed to be a proper test of what's a valid number */#include <math.h>int is_number(char *s){ double r; char *ep; /* * fast could-it-be-a-number check before calling strtod, * which takes a surprisingly long time to reject non-numbers. */ switch (*s) { case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': case '8': case '9': case '\t': case '\n': case '\v': case '\f': case '\r': case ' ': case '-': case '+': case '.': case 'n': /* nans */ case 'N': case 'i': /* infs */ case 'I': break; default: return 0; /* can't be a number */ } errno = 0; r = strtod(s, &ep); if (ep == s || r == HUGE_VAL || errno == ERANGE) return 0; while (*ep == ' ' || *ep == '\t' || *ep == '\n') ep++; if (*ep == '\0') return 1; else return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -