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