home *** CD-ROM | disk | FTP | other *** search
- /* Sc parse routine
- *
- * usage psc options
- * options:
- * -L Left justify strings. Default is right justify.
- * -r Assemble data into rows first, not columns.
- * -R n Increment by n between rows
- * -C n Increment by n between columns
- * -n n Length of the row (column) should be n.
- * -s v Top left location in the spreadsheet should be v; eg, k5
- * -d c Use c as the delimiter between the fields.
- * -k Keep all delimiters - Default is strip multiple delimiters to 1.
- * -f suppress 'format' lines in output
- * -S Use strings vs numbers for numbers
- * -P Use numbers only when there is no [-+eE] (plain numbers only)
- *
- * Author: Robert Bond
- * Adjustments: Jeff Buhrt and Eric Putz
- */
- char *rev = "$Revision: 6.21 $";
-
- #include <ctype.h>
- #include <stdio.h>
- #include "sc.h"
-
- #define END 0
- #define NUM 1
- #define ALPHA 2
- #define SPACE 3
- #define EOL 4
-
- extern char *optarg;
- extern int optind, getopt(), atoi();
- char *coltoa();
- char *progname;
- int getrow(), getcol(), scan();
-
- #ifdef SYSV3
- extern void exit();
- #else
- extern int exit();
- #endif
-
- int *fwidth;
- int *precision;
- int maxcols;
- int *realfmt;
-
- /* option flags reset */
- int colfirst = FALSE;
- int leftadj = FALSE;
- int r0 = 0;
- int c0 = 0;
- int rinc = 1;
- int cinc = 1;
- int len = 20000;
- char delim1 = ' ';
- char delim2 = '\t';
- int strip_delim = TRUE;
- int drop_format = FALSE;
- int strnums = FALSE;
- int plainnums = FALSE;
-
- char token[1000];
-
- main(argc, argv)
- int argc;
- char **argv;
- {
- int curlen;
- int curcol, coff;
- int currow, roff;
- int first;
- int c;
- register effr, effc;
- int i,j;
- register char *p;
-
- progname = argv[0];
- while ((c = getopt(argc, argv, "rfLks:R:C:n:d:SPv")) != EOF) {
- switch(c) {
- case 'r':
- colfirst = TRUE;
- break;
- case 'L':
- leftadj = TRUE;
- break;
- case 's':
- c0 = getcol(optarg);
- r0 = getrow(optarg);
- break;
- case 'R':
- rinc = atoi(optarg);
- break;
- case 'C':
- cinc = atoi(optarg);
- break;
- case 'n':
- len = atoi(optarg);
- break;
- case 'd':
- delim1 = optarg[0];
- delim2 = '\0';
- break;
- case 'k':
- strip_delim = FALSE;
- break;
- case 'f':
- drop_format = TRUE;
- break;
- case 'S':
- strnums = TRUE;
- break;
- case 'P':
- plainnums = TRUE;
- break;
- case 'v':
- (void) fprintf(stderr,"%s: %s\n", progname, rev);
- default:
- (void) fprintf(stderr,"Usage: %s [-rkfLSPv] [-s v] [-R i] [-C i] [-n i] [-d c]\n", progname);
- exit(1);
- }
- }
-
- if (optind < argc) {
- (void) fprintf(stderr,"Usage: %s [-rL] [-s v] [-R i] [-C i] [-n i] [-d c]\n", progname);
- exit(1);
- }
-
- /* setup the spreadsheet arrays */
- if (!growtbl(GROWNEW, 0, 0))
- exit(1);
-
- curlen = 0;
- curcol = c0; coff = 0;
- currow = r0; roff = 0;
- first = TRUE;
-
- while(1) {
-
- effr = currow+roff;
- effc = curcol+coff;
-
- switch(scan()) {
- case END:
- if(drop_format) exit(0);
- for (i = 0; i<maxcols; i++) {
- if (fwidth[i])
- (void) printf("format %s %d %d\n", coltoa(i),
- fwidth[i]+1, precision[i]);
- }
- exit(0);
- case NUM:
- first = FALSE;
- (void) printf("let %s%d = %s\n", coltoa(effc), effr, token);
- if (effc >= maxcols - 1)
- { if (!growtbl(GROWCOL, 0, effc))
- { (void) fprintf(stderr, "Invalid column used: %s\n", coltoa(effc));
- continue;
- }
- }
- i = 0;
- j = 0;
- p = token;
- while (*p && *p != '.') {
- p++; i++;
- }
- if (*p) {
- p++; i++;
- }
- while (*p) {
- p++; i++; j++;
- }
- { int ow, nw;
-
- ow = fwidth[effc] - precision[effc];
- if (precision[effc] < j)
- precision[effc] = j;
-
- if (fwidth[effc] < i)
- fwidth[effc] = i;
-
- /* now make sure:
- * 1234.567890 (format 11 6)
- * 1234567.890 (format 11 3)
- * both show (format 14 6)
- * (really it uses 15 6 to separate columns)
- */
- if ((nw = i - j) > ow)
- fwidth[effc] += nw - (fwidth[effc] - precision[effc]);
- }
- break;
- case ALPHA:
- first = FALSE;
- if (leftadj)
- (void) printf("leftstring %s%d = \"%s\"\n", coltoa(effc),effr,token);
- else
- (void) printf("rightstring %s%d = \"%s\"\n",coltoa(effc),effr,token);
- if (effc >= maxcols - 1)
- { if (!growtbl(GROWCOL, 0, effc))
- { (void) fprintf(stderr, "Invalid column used: %s\n", coltoa(effc));
- continue;
- }
- }
- i = strlen(token);
- if (i > fwidth[effc])
- fwidth[effc] = i;
- break;
- case SPACE:
- if (first && strip_delim)
- break;
- if (colfirst)
- roff++;
- else
- coff++;
- break;
- case EOL:
- curlen++;
- roff = 0;
- coff = 0;
- first = TRUE;
- if (colfirst) {
- if (curlen >= len) {
- curcol = c0;
- currow += rinc;
- curlen = 0;
- } else {
- curcol += cinc;
- }
- } else {
- if (curlen >= len) {
- currow = r0;
- curcol += cinc;
- curlen = 0;
- } else {
- currow += rinc;
- }
- }
- break;
- }
- }
- }
-
- int
- scan()
- {
- register int c;
- register char *p;
- register int founddigit;
-
- p = token;
- c = getchar();
-
- if (c == EOF)
- return(END);
-
- if (c == '\n')
- return(EOL);
-
- if (c == delim1 || c == delim2) {
- if (strip_delim) {
- while ((c = getchar()) && (c == delim1 || c == delim2))
- ;
- (void)ungetc(c, stdin);
- }
- return(SPACE);
- }
-
- if (c == '\"') {
- while ((c = getchar()) && c != '\"' && c != '\n' && c != EOF)
- *p++ = c;
- if (c != '\"')
- (void)ungetc(c, stdin);
- *p = '\0';
- return(ALPHA);
- }
-
- while (c != delim1 && c != delim2 && c!= '\n' && c != EOF) {
- *p++ = c;
- c = getchar();
- }
- *p = '\0';
- (void)ungetc(c, stdin);
-
- p = token;
- c = *p;
- founddigit = FALSE;
- /*
- * str_nums always returns numbers as strings
- * plainnums returns 'numbers' with [-+eE] in them as strings
- * lastprtnum makes sure a number ends in one of [0-9eE.]
- */
- if (!strnums && (isdigit(c) || c == '.' || c == '-' || c == '+')) {
- int lastprtnum = FALSE;
-
- while(isdigit(c) || c == '.' || (!plainnums && (c == '-' ||
- c == '+' || c == 'e' || c == 'E'))) {
- if (isdigit(c))
- lastprtnum = founddigit = TRUE;
- else
- if (!(c == '.' || c == 'e' || c == 'E'))
- lastprtnum = FALSE;
- c = *p++;
- }
- if (c == '\0' && founddigit && lastprtnum)
- return(NUM);
- else
- return(ALPHA);
- }
-
- return(ALPHA);
- }
-
- /* turns [A-Z][A-Z] into a number */
- int
- getcol(p)
- char *p;
- {
- register col;
-
- col = 0;
- if (!p)
- return(0);
- while(*p && !isalpha(*p))
- p++;
- if (!*p)
- return(0);
- col = ((*p & 0137) - 'A');
- if (isalpha(*++p))
- col = (col + 1)*26 + ((*p & 0137) - 'A');
- return(col);
- }
-
- /* given a string turn it into a row number */
- int
- getrow(p)
- char *p;
- {
- int row;
-
- row = 0;
- if (!p)
- return(0);
- while(*p && !isdigit(*p))
- p++;
- if (!*p)
- return(0);
- while(*p && isdigit(*p))
- { row = row * 10 + *p - '0';
- p++;
- }
- return(row);
- }
-
- /* turns a column number into [A-Z][A-Z] */
- char *
- coltoa(col)
- int col;
- {
- static char rname[3];
- register char *p = rname;
-
- if (col < 0 || col > 27*26) /* A-Z, AA-ZZ */
- (void) fprintf(stderr,"coltoa: invalid col: %d", col);
-
- if (col > 25) {
- *p++ = col/26 + 'A' - 1;
- col %= 26;
- }
- *p++ = col+'A';
- *p = '\0';
- return(rname);
- }
-