home *** CD-ROM | disk | FTP | other *** search
/ pc.louisiana.edu/pub/unix/ / Louisiana_UNIX.tar / Louisiana_UNIX / xspread3.0.zoo / psc.c < prev    next >
C/C++ Source or Header  |  1994-03-25  |  7KB  |  379 lines

  1. /* Sc parse routine
  2.  *
  3.  * usage psc options
  4.  * options:
  5.  *   -L        Left justify strings.  Default is right justify.
  6.  *   -r        Assemble data into rows first, not columns.
  7.  *   -R    n    Increment by n between rows 
  8.  *   -C n    Increment by n between columns
  9.  *   -n n    Length of the row (column) should be n.
  10.  *   -s v    Top left location in the spreadsheet should be v; eg, k5
  11.  *   -d c       Use c as the delimiter between the fields.
  12.  *   -k         Keep all delimiters - Default is strip multiple delimiters to 1.
  13.  *   -f         suppress 'format' lines in output
  14.  *   -S        Use strings vs numbers for numbers
  15.  *   -P        Use numbers only when there is no [-+eE] (plain numbers only)
  16.  *
  17.  *  Author: Robert Bond
  18.  *  Adjustments: Jeff Buhrt and Eric Putz
  19.  */
  20. char *rev = "$Revision: 6.21 A $";
  21.  
  22. #include <ctype.h>
  23. #include <stdio.h>
  24. #include "config.h"
  25. #include "sc.h"
  26.  
  27. #define END    0
  28. #define NUM    1
  29. #define ALPHA    2
  30. #define SPACE    3
  31. #define EOL    4
  32.  
  33. extern char *optarg;
  34. extern int   optind, getopt(), atoi();
  35. char    *coltoa();
  36. char    *progname;
  37. int    getrow(), getcol(), scan();
  38.  
  39. #if defined(SYSV3) || defined(SUNOS4)
  40. extern void exit();
  41. #else
  42. extern int exit();
  43. #endif
  44.  
  45. int *fwidth;
  46. int *precision;
  47. int maxcols;
  48. int *realfmt;
  49.  
  50. /* option flags reset */
  51. int colfirst = FALSE;
  52. int leftadj = FALSE;
  53. int r0 = 0;
  54. int c0 = 0;
  55. int rinc = 1;
  56. int cinc = 1;
  57. int len = 20000;
  58. char delim1 = ' ';
  59. char delim2 = '\t';
  60. int strip_delim = TRUE;
  61. int drop_format = FALSE;
  62. int strnums    = FALSE;
  63. int plainnums    = FALSE;
  64.  
  65. char token[1000];
  66.  
  67. int main(argc, argv)
  68. int argc;
  69. char **argv;
  70. {
  71.     int curlen;
  72.     int curcol, coff;
  73.     int currow, roff;
  74.     int first;
  75.     int c;
  76.     register effr, effc;
  77.     int i,j;
  78.     register char *p;
  79.  
  80.     progname = argv[0];
  81.     while ((c = getopt(argc, argv, "rfLks:R:C:n:d:SPv")) != EOF) {
  82.     switch(c) {
  83.     case 'r':
  84.         colfirst = TRUE;
  85.         break;
  86.     case 'L':
  87.         leftadj = TRUE;
  88.         break;
  89.     case 's':
  90.         c0 = getcol(optarg);
  91.         r0 = getrow(optarg);
  92.         break;
  93.     case 'R':
  94.         rinc = atoi(optarg);
  95.         break;
  96.     case 'C':
  97.         cinc = atoi(optarg);
  98.         break;
  99.     case 'n':
  100.         len = atoi(optarg);
  101.         break;
  102.     case 'd':
  103.         delim1 = optarg[0];
  104.         delim2 = '\0';
  105.         break;
  106.     case 'k':
  107.         strip_delim = FALSE;
  108.         break;
  109.     case 'f':
  110.         drop_format = TRUE;
  111.         break;
  112.     case 'S':
  113.         strnums = TRUE;
  114.         break;
  115.     case 'P':
  116.         plainnums = TRUE;
  117.         break;
  118.     case 'v':
  119.         (void) fprintf(stderr,"%s: %s\n", progname, rev);
  120.     default:
  121.         (void) fprintf(stderr,"Usage: %s [-rkfLSPv] [-s v] [-R i] [-C i] [-n i] [-d c]\n", progname);
  122.         exit(1);
  123.         }
  124.     }
  125.  
  126.     if (optind < argc) {
  127.         (void) fprintf(stderr,"Usage: %s [-rL] [-s v] [-R i] [-C i] [-n i] [-d c]\n", progname);
  128.         exit(1);
  129.     }
  130.  
  131.     /* setup the spreadsheet arrays */
  132.     if (!growtbl(GROWNEW, 0, 0))
  133.     exit(1);
  134.  
  135.     curlen = 0;
  136.     curcol = c0; coff = 0;
  137.     currow = r0; roff = 0;
  138.     first = TRUE;
  139.  
  140.     while(TRUE) {
  141.  
  142.     effr = currow+roff;
  143.     effc = curcol+coff;
  144.  
  145.     switch(scan()) {
  146.     case END:
  147.         if(drop_format) exit(0);
  148.         for (i = 0; i<maxcols; i++) {
  149.         if (fwidth[i])
  150.             (void) printf("format %s %d %d\n", coltoa(i), 
  151.             fwidth[i]+1, precision[i]);
  152.         }
  153.         exit(0);
  154.     case NUM:
  155.         first = FALSE;
  156.         (void) printf("let %s%d = %s\n", coltoa(effc), effr, token);
  157.         if (effc >= maxcols - 1)
  158.         {    if (!growtbl(GROWCOL, 0, effc))
  159.         {    (void) fprintf(stderr, "Invalid column used: %s\n", coltoa(effc));
  160.             continue;
  161.         }
  162.         }
  163.         i = 0;
  164.         j = 0;
  165.         p = token;
  166.         while (*p && *p != '.') {
  167.         p++; i++;
  168.         }
  169.         if (*p) {
  170.         p++; i++;
  171.         }
  172.         while (*p) {
  173.         p++; i++; j++;
  174.         }
  175.         {   int    ow, nw;
  176.  
  177.         ow = fwidth[effc] - precision[effc];
  178.         if (precision[effc] < j)
  179.             precision[effc] = j;
  180.     
  181.         if (fwidth[effc] < i)
  182.             fwidth[effc] = i;
  183.  
  184.         /* now make sure:
  185.          *    1234.567890 (format 11 6)
  186.          *    1234567.890 (format 11 3)
  187.          *    both show (format 14 6)
  188.          *        (really it uses 15 6 to separate columns)
  189.          */
  190.         if ((nw = i - j) > ow)
  191.             fwidth[effc] += nw - (fwidth[effc] - precision[effc]);
  192.         }
  193.         break;
  194.     case ALPHA:
  195.         first = FALSE;
  196.         if (leftadj)
  197.         (void) printf("leftstring %s%d = \"%s\"\n", coltoa(effc),effr,token); 
  198.         else
  199.         (void) printf("rightstring %s%d = \"%s\"\n",coltoa(effc),effr,token); 
  200.         if (effc >= maxcols - 1)
  201.         {    if (!growtbl(GROWCOL, 0, effc))
  202.         {    (void) fprintf(stderr, "Invalid column used: %s\n", coltoa(effc));
  203.             continue;
  204.         }
  205.         }
  206.         i = strlen(token);
  207.         if (i > fwidth[effc])
  208.         fwidth[effc] = i;
  209.         break;
  210.     case SPACE:
  211.         if (first && strip_delim)
  212.         break;
  213.         if (colfirst)
  214.         roff++;
  215.         else
  216.         coff++;
  217.         break;
  218.     case EOL:
  219.         curlen++;
  220.         roff = 0;
  221.         coff = 0;
  222.         first = TRUE;
  223.         if (colfirst) {
  224.         if (curlen >= len) {
  225.             curcol = c0;
  226.             currow += rinc;
  227.             curlen = 0;
  228.         } else {
  229.             curcol += cinc;
  230.         }
  231.         } else {
  232.         if (curlen >= len) {
  233.             currow = r0;
  234.             curcol += cinc;
  235.             curlen = 0;
  236.         } else {
  237.             currow += rinc;
  238.         }
  239.         }
  240.         break;
  241.     }
  242.     }
  243.     exit(1);
  244. }
  245.  
  246. int
  247. scan()
  248. {
  249.     register int c;
  250.     register char *p;
  251.     register int founddigit;
  252. #ifndef __STDC__
  253.     extern int    ungetc();
  254. #endif
  255.  
  256.     p = token;
  257.     c = getchar();
  258.  
  259.     if (c == EOF)
  260.     return(END);
  261.  
  262.     if (c == '\n')
  263.     return(EOL);
  264.  
  265.     if (c == delim1 || c == delim2) {
  266.         if (strip_delim) {
  267.         while ((c = getchar()) && (c == delim1 || c == delim2))
  268.             ;
  269.         (void)ungetc(c, stdin);
  270.     } 
  271.     return(SPACE);
  272.     }
  273.  
  274.     if (c == '\"') {
  275.     while ((c = getchar()) && c != '\"' && c != '\n' && c != EOF)
  276.         *p++ = c;
  277.     if (c != '\"')
  278.         (void)ungetc(c, stdin);
  279.     *p = '\0';
  280.     return(ALPHA);
  281.     }
  282.  
  283.     while (c != delim1 && c != delim2 && c!= '\n' && c != EOF) {
  284.     *p++ = c;
  285.     c = getchar();
  286.     }
  287.     *p = '\0';
  288.     (void)ungetc(c, stdin);
  289.  
  290.     p = token;
  291.     c = *p;
  292.     founddigit = FALSE;
  293.     /*
  294.      * str_nums always returns numbers as strings
  295.      * plainnums returns 'numbers' with [-+eE] in them as strings
  296.      * lastprtnum makes sure a number ends in one of [0-9eE.]
  297.      */
  298.     if (!strnums && (isdigit(c) || c == '.' || c == '-' || c == '+')) {
  299.     int    lastprtnum = FALSE;
  300.  
  301.     while(isdigit(c) || c == '.' || (!plainnums && (c == '-' ||
  302.                     c == '+' || c == 'e' || c == 'E'))) {
  303.         if (isdigit(c)) 
  304.             lastprtnum = founddigit = TRUE;
  305.         else
  306.         if (!(c == '.' || c == 'e' || c == 'E'))
  307.             lastprtnum = FALSE;
  308.         c = *p++;
  309.     }
  310.     if (c == '\0' && founddigit && lastprtnum)
  311.         return(NUM);
  312.     else
  313.         return(ALPHA);
  314.     }
  315.  
  316.     return(ALPHA);
  317. }
  318.     
  319. /* turns [A-Z][A-Z] into a number */
  320. int
  321. getcol(p)
  322. char *p;
  323. {
  324.     register  col;
  325.  
  326.     col = 0;
  327.     if (!p)
  328.     return(0);
  329.     while(*p && !isalpha(*p)) 
  330.     p++; 
  331.     if (!*p)
  332.     return(0);
  333.     col = ((*p & 0137) - 'A');
  334.     if (isalpha(*++p)) 
  335.     col = (col + 1)*26 + ((*p & 0137) - 'A');
  336.     return(col);
  337. }
  338.  
  339. /* given a string turn it into a row number */
  340. int
  341. getrow(p)
  342. char *p;
  343. {
  344.     int row;
  345.  
  346.     row = 0;
  347.     if (!p)
  348.     return(0);
  349.     while(*p && !isdigit(*p))
  350.     p++; 
  351.     if (!*p)
  352.     return(0);
  353.     while(*p && isdigit(*p))
  354.     {    row = row * 10 + *p - '0';
  355.     p++;
  356.     }
  357.     return(row);
  358. }
  359.  
  360. /* turns a column number into [A-Z][A-Z] */
  361. char *
  362. coltoa(col)
  363. int col;
  364. {
  365.     static char rname[3];
  366.     register char *p = rname;
  367.  
  368.     if (col < 0 || col > 27*26)    /* A-Z, AA-ZZ */
  369.     (void) fprintf(stderr,"coltoa: invalid col: %d", col);
  370.  
  371.     if (col > 25) {
  372.     *p++ = col/26 + 'A' - 1;
  373.     col %= 26;
  374.     }
  375.     *p++ = col+'A';
  376.     *p = '\0';
  377.     return(rname);
  378. }
  379.