r.c

Go to the documentation of this file.
00001 /*
00002  * a small awk clone
00003  *
00004  * (C) 1989 Saeko Hirabauashi & Kouichi Hirabayashi
00005  *
00006  * Absolutely no warranty. Use this software with your own risk.
00007  *
00008  * Permission to use, copy, modify and distribute this software for any
00009  * purpose and without fee is hereby granted, provided that the above
00010  * copyright and disclaimer notice.
00011  *
00012  * This program was written to fit into 64K+64K memory of the Minix 1.2.
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])        /* read into var */
00062         s = str;
00063   else
00064         s = NULL;
00065   if ((int) p->n_arg[1]) {      /* file name */
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') {    /* multi line record */
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 if (infileno == (int)*ARGC - 1)
00148                         ifp = stdin;
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;  /* for further "getline" */
00171   *FILENAME = "-";
00172   return 0;     /* EOF */
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         /* fall through */
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   int i, j;
00361   char *s, str[BUFSIZ];
00362 
00363   for (*str = '\0', i = 1, j = (int) *NF; i <= j; i++) {
00364         if (i > 1)
00365                 strcat(str, *OFS);
00366         s = getsval(field[i]);
00367         strcat(str, s);
00368   }
00369   strcat(str, *ORS);
00370   fputs(str, stdout);
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 printf("fmt(%s)\n", s);
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 printf("val(%d)(%s)\n", v->c_type, v->c_sval);
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                 /*r = getsval(v);*/
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; /* file 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";   /* MS-DOS */
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         spawnl(P_WAIT, "/usr/bin/sh", "sh", "-c", filetab[i].f_name, (char *) 0)) == -1)
00568                 fprintf(stderr, "can't spawn /bin/sh\n");
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 }

Generated on Fri Apr 14 22:56:41 2006 for minix by  doxygen 1.4.6