00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #include <stdio.h>
00017 #include <ctype.h>
00018 #include <sys/types.h>
00019 #include <sys/stat.h>
00020 #include <fcntl.h>
00021 #ifdef DOS
00022 #include <process.h>
00023 #endif
00024 #include "awk.h"
00025 #include "regexp.h"
00026
00027 #define MAXFLD 100
00028
00029 extern char **FS, **RS, **OFS, **ORS, **FILENAME;
00030 extern double *NF, *NR;
00031 extern double *FNR;
00032 extern double *ARGC;
00033 extern SYMBOL *argtab[];
00034 extern CELL *getvar();
00035
00036 char *strsave(), *strcpy(), *getsval(), *jStrchr(), *strchr();
00037 double getfval(), atof();
00038 CELL *mkcell(), *mktmp(), *execute(), *patexec();
00039 FILE *efopen();
00040
00041 extern CELL truecell, falsecell;
00042
00043 extern int pateval;
00044
00045 int infileno = 1;
00046 FILE *ifp;
00047 char record[BUFSIZ];
00048 CELL *field[MAXFLD];
00049
00050 char *fs_str;
00051 regexp *fs_pat;
00052
00053 CELL *
00054 Getline(p) NODE *p;
00055 {
00056 CELL *u;
00057 char *fnam, *s, str[BUFSIZ];
00058 int i;
00059 FILE *fp, *getfp();
00060
00061 if ((int) p->n_arg[0])
00062 s = str;
00063 else
00064 s = NULL;
00065 if ((int) p->n_arg[1]) {
00066 u = execute(p->n_arg[1]);
00067 fnam = getsval(u);
00068 fp = getfp(fnam, (int) p->n_arg[2]);
00069 c_free(u);
00070 i = get1rec(s, fp);
00071 }
00072 else
00073 i = Getrec(s);
00074 if (s == str) {
00075 u = execute(p->n_arg[0]);
00076 setsval(u, str);
00077 }
00078 return mktmp(NUM, NULL, (double) i);
00079 }
00080
00081 static
00082 get1rec(buf, fp) char *buf; FILE *fp;
00083 {
00084 register int c;
00085 register char rs, *s;
00086 int mflg;
00087
00088 if (buf == NULL)
00089 buf = record;
00090 if ((rs = **RS) == '\0') {
00091 mflg = 1;
00092 rs = '\n';
00093 }
00094 else
00095 mflg = 0;
00096
00097 if (feof(fp) || (c = getc(fp)) == EOF)
00098 return 0;
00099 for (s = buf; ; ) {
00100 for ( ; c != rs && c != EOF; c = getc(fp)) {
00101 if (isKanji(c)) {
00102 *s++ = c; c = getc(fp);
00103 }
00104 *s++ = c;
00105 }
00106 if (mflg) {
00107 if ((c = getc(fp)) == '\n' || c == EOF)
00108 break;
00109 *s++ = '\n';
00110 }
00111 else
00112 break;
00113 }
00114 *s = '\0';
00115 #if 1
00116 if (buf == record) {
00117 #else
00118 if (buf == record && c != EOF) {
00119 #endif
00120 mkfld(record, *FS, field);
00121 (*NR)++;
00122 (*FNR)++;
00123 }
00124 return s > buf || c != EOF ? 1 : 0;
00125 }
00126
00127 Getrec(s) char *s;
00128 {
00129 CELL *u;
00130 char *file, str[8];
00131
00132 while (ifp == stdin || infileno < (int)*ARGC) {
00133 if (ifp == NULL) {
00134 *FNR = 0.0;
00135 if (infileno == (int)*ARGC)
00136 break;
00137 sprintf(str, "%d", infileno);
00138 u = getvar(str, argtab);
00139 file = getsval(u);
00140 if (strchr(file, '=') != NULL) {
00141 setvar(file);
00142 infileno++;
00143 continue;
00144 }
00145 else if (strcmp(file, "") == 0) {
00146
00147
00148
00149
00150 infileno++;
00151 continue;
00152 }
00153 else {
00154 if (strcmp(file, "-") == 0)
00155 ifp = stdin;
00156 else
00157 ifp = efopen(file, "r");
00158 *FILENAME = file;
00159 }
00160 }
00161 if (get1rec(s, ifp))
00162 return 1;
00163 else {
00164 if (ifp != stdin)
00165 fclose(ifp);
00166 ifp = NULL;
00167 infileno++;
00168 }
00169 }
00170 ifp = stdin;
00171 *FILENAME = "-";
00172 return 0;
00173 }
00174
00175 mkfld(rec, sep, fld) char *rec, *sep; CELL *fld[];
00176 {
00177 char *s, *t;
00178 char str[BUFSIZ];
00179 int i, j, n;
00180 int skip = 0;
00181
00182 if (strlen(sep) > 1)
00183 return r_mkfld(rec, sep, fld);
00184
00185 if (*sep == ' ' || *sep == '\0') {
00186 sep = " \t\n"; skip++;
00187 }
00188 for (i = 1, n = (int) *NF; i <= n; i++) {
00189 sfree(fld[i]->c_sval);
00190 sfree(fld[i]);
00191 fld[i] = NULL;
00192 }
00193 for (i = 0, s = rec; ; ) {
00194 t = str;
00195 if (skip) {
00196 while (*s && strchr(" \t\n", *s))
00197 s++;
00198 if (*s == '\0')
00199 break;
00200 }
00201 while (*s && !jStrchr(sep, *s)) {
00202 if (isKanji(*s))
00203 *t++ = *s++;
00204 *t++ = *s++;
00205 }
00206 *t = '\0';
00207 if (isnum(str))
00208 fld[++i] = mkcell(FLD|STR|NUM, str, atof(str));
00209 else
00210 fld[++i] = mkcell(FLD|STR, str, 0.0);
00211 if (*s)
00212 s++;
00213 else
00214 break;
00215 }
00216 *NF = (double) i;
00217 return i;
00218 }
00219
00220 static
00221 r_mkfld(rec, sep, fld) char *rec, *sep; CELL *fld[];
00222 {
00223 char *s, *t;
00224 char str[BUFSIZ];
00225 int i, n;
00226 regexp *mkpat();
00227 extern int r_start, r_length;
00228
00229 if (strcmp(*FS, fs_str) != 0) {
00230 sfree(fs_str); sfree(fs_pat);
00231 fs_str = strsave(*FS);
00232 fs_pat = mkpat(fs_str);
00233 }
00234 for (i = 1, n = (int) *NF; i <= n; i++) {
00235 sfree(fld[i]->c_sval);
00236 sfree(fld[i]);
00237 fld[i] = NULL;
00238 }
00239 for (i = 0, s = rec, t = str; *s; ) {
00240 if (match(fs_pat, s)) {
00241 for (n = r_start; --n > 0; )
00242 *t++ = *s++;
00243 }
00244 else {
00245 while (*s)
00246 *t++ = *s++;
00247 }
00248 *t = '\0';
00249 t = str;
00250 fld[++i] = mkcell(FLD|STR, str, 0.0);
00251 if (*s)
00252 s += r_length;
00253 }
00254 *NF = (double) i;
00255 return i;
00256 }
00257
00258 mkrec(u) CELL *u;
00259 {
00260 register char *s, *t;
00261 register int i, j;
00262
00263 for (j = (int)*NF, i = 1; i <= j; i++)
00264 if (field[i] == u)
00265 break;
00266 if (i > j) {
00267 for ( ; i < MAXFLD; i++)
00268 if (field[i] == u)
00269 break;
00270 if (i == MAXFLD)
00271 error("too many field (%d)", i);
00272 *NF = (double)i;
00273 }
00274 for (t = record, i = 1, j = (int) *NF; i <= j; i++) {
00275 if (i > 1)
00276 *t++ = **OFS;
00277 for (s = getsval(field[i]); *s; )
00278 *t++ = *s++;
00279 }
00280 *t++ = '\0';
00281 }
00282
00283 CELL *
00284 Field(p) NODE *p;
00285 {
00286 CELL *u;
00287 int i, j;
00288
00289 u = execute(p->n_arg[0]);
00290 i = (int) getfval(u);
00291 c_free(u);
00292 j = (int)*NF;
00293 if (i > j)
00294 for (++j; j <= i; j++) {
00295 if (field[j] == NULL)
00296 field[j] = mkcell(FLD|STR, "", 0.0);
00297 }
00298 return field[i];
00299 }
00300
00301 CELL *
00302 P1stat(p) NODE *p;
00303 {
00304 CELL *u;
00305 double x;
00306
00307 pateval++;
00308 u = execute(p->n_arg[0]);
00309 pateval = 0;
00310 x = getfval(u);
00311 c_free(u);
00312 if (x != 0.0)
00313 u = execute(p->n_arg[1]);
00314 else
00315 u = &truecell;
00316 return u;
00317 }
00318
00319 CELL *
00320 P2stat(p) NODE *p;
00321 {
00322 static stat = 0;
00323 CELL *u, *v;
00324 double x;
00325
00326 switch (stat) {
00327 case 0:
00328 pateval++;
00329 u = execute(p->n_arg[0]);
00330 pateval = 0;
00331 x = getfval(u);
00332 c_free(u);
00333 if (x == 0.0) {
00334 u = &truecell; break;
00335 }
00336 else
00337 stat++;
00338
00339 case 1:
00340 u = execute(p->n_arg[2]);
00341 c_free(u);
00342 pateval++;
00343 u = execute(p->n_arg[1]);
00344 pateval = 0;
00345 x = getfval(u);
00346 if (x != 0.0)
00347 stat = 0;
00348 break;
00349 default:
00350 u = &truecell;
00351 break;
00352 }
00353 return u;
00354 }
00355
00356 CELL *
00357 Print0()
00358 {
00359
00360
00361
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372 fprintf(stdout, "%s%s", record, *ORS);
00373 return &truecell;
00374 }
00375
00376 char *
00377 format(t, p) char *t; NODE *p;
00378 {
00379 CELL *u, *v;
00380 char *r, *s, *s0, fmt[BUFSIZ];
00381 double x;
00382 int i;
00383
00384 u = execute(p->n_arg[2]);
00385 s = s0 = getsval(u);
00386
00387
00388
00389 for (i = 3; *s; s++) {
00390 if (isKanji(*s)) {
00391 *t++ = *s++; *t++ = *s; continue;
00392 }
00393 if (*s != '%') {
00394 *t++ = *s; continue;
00395 }
00396 else if (*(s + 1) == '%') {
00397 *t++ = *s++; continue;
00398 }
00399 for (r = fmt, *r++ = *s++; *r++ = *s; s++) {
00400 if (strchr("%cdefgosux", *s))
00401 break;
00402 }
00403 *r = '\0';
00404 if (p->n_arg[i] == NULL)
00405 error("not enough args in printf(%s)", s0);
00406 v = execute(p->n_arg[i++]);
00407 if (*s == 's')
00408 r = getsval(v);
00409 else
00410 x = getfval(v);
00411
00412
00413
00414 switch (*s) {
00415 case 'c':
00416 sprintf(t, fmt, (int) x);
00417 break;
00418 case 'd':
00419 if (*(s - 1) != 'l') {
00420 *--r = 'l'; *++r = 'd'; *++r = '\0';
00421 }
00422 sprintf(t, fmt, (long) x);
00423 break;
00424 case 'e': case 'f': case 'g':
00425 sprintf(t, fmt, x);
00426 break;
00427 case 'o': case 'u': case 'x':
00428 if (*(s - 1) == 'l')
00429 sprintf(t, fmt, (long) x);
00430 else
00431 sprintf(t, fmt, (int) x);
00432 break;
00433 case 's':
00434
00435 sprintf(t, fmt, r);
00436 break;
00437 default:
00438 strcpy(t, fmt);
00439 break;
00440 }
00441 c_free(v);
00442 t += strlen(t);
00443 }
00444 c_free(u);
00445 *t = '\0';
00446 }
00447
00448 #define MAXFILE 10
00449 struct {
00450 char *f_name;
00451 FILE *f_fp;
00452 int f_type;
00453 } filetab[MAXFILE];
00454
00455 FILE *
00456 getfp(file, type) char *file;
00457 {
00458 register int i;
00459 register char *name, *mode;
00460 char *awktmp();
00461 FILE *fp, *efopen(), *epopen();
00462
00463 for (i = 0; i < MAXFILE; i++)
00464 if (filetab[i].f_name && strcmp(filetab[i].f_name, file) == 0)
00465 return filetab[i].f_fp;
00466 for (i = 0; i < MAXFILE; i++)
00467 if (!filetab[i].f_fp)
00468 break;
00469 if (i == MAXFILE)
00470 error("too many files to open");
00471 name = file;
00472 switch (type) {
00473 case R_OUT: mode = "w"; break;
00474 case R_APD: mode = "a"; break;
00475 case R_POUT:
00476 #ifdef DOS
00477 name = awktmp(i); mode = "w";
00478 #else
00479 fp = epopen(file, "w");
00480 goto g1;
00481 #endif
00482 break;
00483 case R_IN: mode = "r"; break;
00484 case R_PIN:
00485 #ifdef DOS
00486 {
00487 int savefd, fd, result;
00488
00489 name = awktmp(i);
00490 if ((fd = open(name,
00491 O_WRONLY|O_TEXT|O_CREAT|O_TRUNC,S_IREAD|S_IWRITE)) == -1)
00492 error("can't open %s", name);
00493 savefd = dup(1); dup2(fd, 1); close(fd);
00494 if ((result =
00495 system(file)) == -1)
00496 error("can't exec %s", file);
00497 dup2(savefd, 1); close(savefd); close(fd);
00498 mode = "r";
00499 }
00500 #else
00501 fp = epopen(file,"r");
00502 goto g1;
00503 #endif
00504 break;
00505 }
00506 fp = efopen(name, mode);
00507 g1:
00508 filetab[i].f_name = strsave(file);
00509 filetab[i].f_type = type;
00510 filetab[i].f_fp = fp;
00511 return fp;
00512 }
00513
00514 closeall()
00515 {
00516 register int i;
00517
00518 for (i = 0; i < MAXFILE; i++)
00519 close1(i);
00520 }
00521
00522 CELL *
00523 Close(s) char *s;
00524 {
00525 register int i;
00526
00527 for (i = 0; i < MAXFILE; i++)
00528 if (strcmp(s, filetab[i].f_name) == 0) {
00529 close1(i);
00530 break;
00531 }
00532 i = (i == MAXFILE) ? 0 : 1;
00533 return mktmp(NUM, NULL, (double) i);
00534 }
00535
00536 static
00537 close1(i)
00538 {
00539 int fd, result, savefd;
00540 char *awktmp();
00541
00542 if (filetab[i].f_fp == NULL)
00543 return;
00544 switch (filetab[i].f_type) {
00545 case R_PIN:
00546 #ifdef DOS
00547 fclose(filetab[i].f_fp);
00548 unlink(awktmp(i));
00549 #else
00550 pclose(filetab[i].f_fp);
00551 #endif
00552 break;
00553 case R_IN: case R_OUT: case R_APD:
00554 fclose(filetab[i].f_fp);
00555 break;
00556 case R_POUT:
00557 #ifdef DOS
00558 fclose(filetab[i].f_fp);
00559 if ((fd = open(awktmp(i), O_RDONLY)) == NULL)
00560 error("can't open %s", awktmp(i));
00561 savefd = dup(0);
00562 dup2(fd, 0);
00563 close(fd);
00564 if ((result =
00565 system(filetab[i].f_name)) == -1)
00566
00567
00568
00569
00570 error("can't exec %s", filetab[i].f_name);
00571 dup2(savefd, 0);
00572 close(savefd);
00573 unlink(awktmp(i));
00574 #else
00575 pclose(filetab[i].f_fp);
00576 #endif
00577 break;
00578 }
00579 sfree(filetab[i].f_name);
00580 filetab[i].f_type = 0;
00581 filetab[i].f_name = NULL;
00582 filetab[i].f_fp = NULL;
00583 }
00584
00585 #ifndef DOS
00586 FILE *
00587 epopen(file, mod) char *file, *mod;
00588 {
00589 FILE *fp, *popen();
00590
00591 if ((fp = popen(file, mod)) == NULL)
00592 error("can't poen %s", file);
00593 return fp;
00594 }
00595 #endif
00596
00597 static char *
00598 awktmp(i)
00599 {
00600 static char str[16];
00601
00602 sprintf(str, "awk000%02d.tmp", i);
00603 return str;
00604 }
00605
00606 Index(s, t) char *s, *t;
00607 {
00608 register char *u, *v;
00609 register int i;
00610
00611 for (i = 1; *s; s++, i++) {
00612 for (u = s, v = t; *v; u++, v++) {
00613 if (isKanji(*v)) {
00614 if (*u != *v)
00615 break;
00616 u++; v++;
00617 }
00618 if (*u != *v)
00619 break;
00620 }
00621 if (*v == '\0')
00622 return i;
00623 if (isKanji(*s))
00624 s++;
00625 }
00626 return 0;
00627 }