xref: /csrg-svn/contrib/sc/psc.c (revision 45327)
1*45327Sbostic /* Sc parse routine
2*45327Sbostic  *
3*45327Sbostic  * usage psc options
4*45327Sbostic  * options:
5*45327Sbostic  *   -L		Left justify strings.  Default is right justify.
6*45327Sbostic  *   -r		Assemble data into rows first, not columns.
7*45327Sbostic  *   -R	n	Increment by n between rows
8*45327Sbostic  *   -C n	Increment by n between columns
9*45327Sbostic  *   -n n	Length of the row (column) should be n.
10*45327Sbostic  *   -s v	Top left location in the spreadsheet should be v; eg, k5
11*45327Sbostic  *   -d c       Use c as the delimiter between the fields.
12*45327Sbostic  *   -k         Keep all delimiters - Default is strip multiple delimiters to 1.
13*45327Sbostic  *   -f         suppress 'format' lines in output
14*45327Sbostic  *
15*45327Sbostic  *  Author: Robert Bond
16*45327Sbostic  *		$Revision: 6.8 $
17*45327Sbostic  */
18*45327Sbostic 
19*45327Sbostic #include <ctype.h>
20*45327Sbostic #include <stdio.h>
21*45327Sbostic #include "sc.h"
22*45327Sbostic 
23*45327Sbostic #define END 0
24*45327Sbostic #define NUM 1
25*45327Sbostic #define ALPHA 2
26*45327Sbostic #define SPACE 3
27*45327Sbostic #define EOL 4
28*45327Sbostic 
29*45327Sbostic extern char *optarg;
30*45327Sbostic extern int   optind;
31*45327Sbostic char *coltoa();
32*45327Sbostic char *progname;
33*45327Sbostic 
34*45327Sbostic #ifdef SYSV3
35*45327Sbostic extern void exit();
36*45327Sbostic #else
37*45327Sbostic extern int exit();
38*45327Sbostic #endif
39*45327Sbostic 
40*45327Sbostic int colfirst = 0;
41*45327Sbostic int r0 = 0;
42*45327Sbostic int c0 = 0;
43*45327Sbostic int rinc = 1;
44*45327Sbostic int cinc = 1;
45*45327Sbostic int leftadj = 0;
46*45327Sbostic int len = 20000;
47*45327Sbostic char delim1 = ' ';
48*45327Sbostic char delim2 = '\t';
49*45327Sbostic int strip_delim = 1;
50*45327Sbostic int drop_format = 0;
51*45327Sbostic int *fwidth;
52*45327Sbostic int *precision;
53*45327Sbostic int maxcols;
54*45327Sbostic 
55*45327Sbostic char token[1000];
56*45327Sbostic 
main(argc,argv)57*45327Sbostic main(argc, argv)
58*45327Sbostic int argc;
59*45327Sbostic char **argv;
60*45327Sbostic {
61*45327Sbostic     int curlen;
62*45327Sbostic     int curcol, coff;
63*45327Sbostic     int currow, roff;
64*45327Sbostic     int first;
65*45327Sbostic     int c;
66*45327Sbostic     register effr, effc;
67*45327Sbostic     int i,j;
68*45327Sbostic     register char *p;
69*45327Sbostic 
70*45327Sbostic     progname = argv[0];
71*45327Sbostic     while ((c = getopt(argc, argv, "rfLks:R:C:n:d:")) != EOF) {
72*45327Sbostic 	switch(c) {
73*45327Sbostic 	case 'r':
74*45327Sbostic 	    colfirst = 1;
75*45327Sbostic 	    break;
76*45327Sbostic 	case 'L':
77*45327Sbostic 	    leftadj = 1;
78*45327Sbostic 	    break;
79*45327Sbostic 	case 's':
80*45327Sbostic 	    c0 = getcol(optarg);
81*45327Sbostic 	    r0 = getrow(optarg);
82*45327Sbostic 	    break;
83*45327Sbostic 	case 'R':
84*45327Sbostic 	    rinc = atoi(optarg);
85*45327Sbostic 	    break;
86*45327Sbostic 	case 'C':
87*45327Sbostic 	    cinc = atoi(optarg);
88*45327Sbostic 	    break;
89*45327Sbostic 	case 'n':
90*45327Sbostic 	    len = atoi(optarg);
91*45327Sbostic 	    break;
92*45327Sbostic 	case 'd':
93*45327Sbostic 	    delim1 = optarg[0];
94*45327Sbostic 	    delim2 = 0;
95*45327Sbostic 	    break;
96*45327Sbostic 	case 'k':
97*45327Sbostic 	    strip_delim = 0;
98*45327Sbostic 	    break;
99*45327Sbostic 	case 'f':
100*45327Sbostic 	    drop_format = 1;
101*45327Sbostic 	    break;
102*45327Sbostic 	default:
103*45327Sbostic 	    (void) fprintf(stderr,"Usage: %s [-rkfL] [-s v] [-R i] [-C i] [-n i] [-d c]\n", progname);
104*45327Sbostic 	    exit(1);
105*45327Sbostic         }
106*45327Sbostic     }
107*45327Sbostic 
108*45327Sbostic     if (optind < argc) {
109*45327Sbostic 	    (void) fprintf(stderr,"Usage: %s [-rL] [-s v] [-R i] [-C i] [-n i] [-d c]\n", progname);
110*45327Sbostic 	    exit(1);
111*45327Sbostic     }
112*45327Sbostic 
113*45327Sbostic 	/* setup the spreadsheet arrays */
114*45327Sbostic     if (!growtbl(GROWNEW, 0, 0))
115*45327Sbostic 	exit(1);
116*45327Sbostic 
117*45327Sbostic     curlen = 0;
118*45327Sbostic     curcol = c0; coff = 0;
119*45327Sbostic     currow = r0; roff = 0;
120*45327Sbostic     first = 1;
121*45327Sbostic 
122*45327Sbostic     while(1) {
123*45327Sbostic 
124*45327Sbostic 	effr = currow+roff;
125*45327Sbostic 	effc = curcol+coff;
126*45327Sbostic 
127*45327Sbostic 	switch(scan()) {
128*45327Sbostic 	case END:
129*45327Sbostic 	    if(drop_format) exit(0);
130*45327Sbostic 	    for (i = 0; i<maxcols; i++) {
131*45327Sbostic 		if (precision[i])
132*45327Sbostic 		    (void) printf("format %s %d %d\n", coltoa(i),
133*45327Sbostic 			fwidth[i], precision[i]+1);
134*45327Sbostic 	    }
135*45327Sbostic 	    exit(0);
136*45327Sbostic 	case NUM:
137*45327Sbostic 	    first = 0;
138*45327Sbostic 	    (void) printf("let %s%d = %s\n", coltoa(effc), effr, token);
139*45327Sbostic 	    if (effc >= maxcols - 1)
140*45327Sbostic 	    {	if (!growtbl(GROWCOL, 0, 0))
141*45327Sbostic 		{	(void) fprintf(stderr, "Invalid column used: %s\n", coltoa(effc));
142*45327Sbostic 			continue;
143*45327Sbostic 		}
144*45327Sbostic 	    }
145*45327Sbostic 	    i = 0;
146*45327Sbostic 	    j = 0;
147*45327Sbostic 	    p = token;
148*45327Sbostic 	    while (*p && *p != '.') {
149*45327Sbostic 		p++; i++;
150*45327Sbostic 	    }
151*45327Sbostic 	    if (*p) {
152*45327Sbostic 		p++; i++;
153*45327Sbostic 	    }
154*45327Sbostic 	    while (*p) {
155*45327Sbostic 		p++; i++; j++;
156*45327Sbostic 	    }
157*45327Sbostic 	    if (precision[effc] < j)
158*45327Sbostic 		precision[effc] = j;
159*45327Sbostic 	    if (fwidth[effc] < i)
160*45327Sbostic 		fwidth[effc] = i;
161*45327Sbostic 	    break;
162*45327Sbostic 	case ALPHA:
163*45327Sbostic 	    first = 0;
164*45327Sbostic 	    if (leftadj)
165*45327Sbostic 		(void) printf("leftstring %s%d = \"%s\"\n", coltoa(effc),effr,token);
166*45327Sbostic 	    else
167*45327Sbostic 		(void) printf("rightstring %s%d = \"%s\"\n",coltoa(effc),effr,token);
168*45327Sbostic 	    if (effc >= maxcols - 1)
169*45327Sbostic 	    {	if (!growtbl(GROWCOL, 0, 0))
170*45327Sbostic 		{	(void) fprintf(stderr, "Invalid column used: %s\n", coltoa(effc));
171*45327Sbostic 			continue;
172*45327Sbostic 		}
173*45327Sbostic 	    }
174*45327Sbostic 	    i = strlen(token);
175*45327Sbostic 	    if (i > precision[effc])
176*45327Sbostic 		precision[effc] = i;
177*45327Sbostic 	    break;
178*45327Sbostic 	case SPACE:
179*45327Sbostic 	    if (first && strip_delim)
180*45327Sbostic 		break;
181*45327Sbostic 	    if (colfirst)
182*45327Sbostic 		roff++;
183*45327Sbostic 	    else
184*45327Sbostic 		coff++;
185*45327Sbostic 	    break;
186*45327Sbostic 	case EOL:
187*45327Sbostic 	    curlen++;
188*45327Sbostic 	    roff = 0;
189*45327Sbostic 	    coff = 0;
190*45327Sbostic 	    first = 1;
191*45327Sbostic 	    if (colfirst) {
192*45327Sbostic 		if (curlen >= len) {
193*45327Sbostic 		    curcol = c0;
194*45327Sbostic 		    currow += rinc;
195*45327Sbostic 		    curlen = 0;
196*45327Sbostic 		} else {
197*45327Sbostic 		    curcol += cinc;
198*45327Sbostic 		}
199*45327Sbostic 	    } else {
200*45327Sbostic 		if (curlen >= len) {
201*45327Sbostic 		    currow = r0;
202*45327Sbostic 		    curcol += cinc;
203*45327Sbostic 		    curlen = 0;
204*45327Sbostic 		} else {
205*45327Sbostic 		    currow += rinc;
206*45327Sbostic 		}
207*45327Sbostic 	    }
208*45327Sbostic 	    break;
209*45327Sbostic 	}
210*45327Sbostic     }
211*45327Sbostic }
212*45327Sbostic 
scan()213*45327Sbostic scan()
214*45327Sbostic {
215*45327Sbostic     register int c;
216*45327Sbostic     register char *p;
217*45327Sbostic 
218*45327Sbostic     p = token;
219*45327Sbostic     c = getchar();
220*45327Sbostic 
221*45327Sbostic     if (c == EOF)
222*45327Sbostic 	return(END);
223*45327Sbostic 
224*45327Sbostic     if (c == '\n')
225*45327Sbostic 	return(EOL);
226*45327Sbostic 
227*45327Sbostic     if (c == delim1 || c == delim2) {
228*45327Sbostic         if (strip_delim) {
229*45327Sbostic 	    while ((c = getchar()) && (c == delim1 || c == delim2))
230*45327Sbostic 	        ;
231*45327Sbostic 	    (void)ungetc(c, stdin);
232*45327Sbostic 	}
233*45327Sbostic 	return(SPACE);
234*45327Sbostic     }
235*45327Sbostic 
236*45327Sbostic     if (c == '\"') {
237*45327Sbostic 	while ((c = getchar()) && c != '\"' && c != '\n' && c != EOF)
238*45327Sbostic 	    *p++ = c;
239*45327Sbostic 	if (c != '\"')
240*45327Sbostic 	    (void)ungetc(c, stdin);
241*45327Sbostic 	*p = 0;
242*45327Sbostic 	return(ALPHA);
243*45327Sbostic     }
244*45327Sbostic 
245*45327Sbostic     while (c != delim1 && c != delim2 && c!= '\n' && c != EOF) {
246*45327Sbostic 	*p++ = c;
247*45327Sbostic 	c = getchar();
248*45327Sbostic     }
249*45327Sbostic     *p = 0;
250*45327Sbostic     (void)ungetc(c, stdin);
251*45327Sbostic 
252*45327Sbostic     p = token;
253*45327Sbostic     c = *p;
254*45327Sbostic     if (isdigit(c) || c == '.' || c == '-' || c == '+') {
255*45327Sbostic 	while(isdigit(c) || c == '.' || c == '-' || c == '+' || c == 'e'
256*45327Sbostic 	    || c == 'E') {
257*45327Sbostic 		c = *p++;
258*45327Sbostic 	}
259*45327Sbostic 	if (c == 0)
260*45327Sbostic 	    return(NUM);
261*45327Sbostic 	else
262*45327Sbostic 	    return(ALPHA);
263*45327Sbostic     }
264*45327Sbostic 
265*45327Sbostic     return(ALPHA);
266*45327Sbostic }
267*45327Sbostic 
getcol(p)268*45327Sbostic getcol(p)
269*45327Sbostic char *p;
270*45327Sbostic {
271*45327Sbostic     register  col;
272*45327Sbostic 
273*45327Sbostic     if (!p)
274*45327Sbostic 	return(0);
275*45327Sbostic     while(*p && !isalpha(*p))
276*45327Sbostic 	p++;
277*45327Sbostic     if (!*p)
278*45327Sbostic 	return(0);
279*45327Sbostic     col = ((*p & 0137) - 'A');
280*45327Sbostic     if (isalpha(*++p))
281*45327Sbostic 	col = (col + 1)*26 + ((*p & 0137) - 'A');
282*45327Sbostic     return(col);
283*45327Sbostic }
284*45327Sbostic 
getrow(p)285*45327Sbostic getrow(p)
286*45327Sbostic char *p;
287*45327Sbostic {
288*45327Sbostic     int row;
289*45327Sbostic 
290*45327Sbostic     if (!p)
291*45327Sbostic 	return(0);
292*45327Sbostic     while(*p && !isdigit(*p))
293*45327Sbostic 	p++;
294*45327Sbostic     if (!*p)
295*45327Sbostic 	return(0);
296*45327Sbostic     if (sscanf(p, "%d", &row) != 1)
297*45327Sbostic 	return(0);
298*45327Sbostic     return(row);
299*45327Sbostic }
300*45327Sbostic 
301*45327Sbostic char *
coltoa(col)302*45327Sbostic coltoa(col)
303*45327Sbostic int col;
304*45327Sbostic {
305*45327Sbostic     static char rname[3];
306*45327Sbostic     register char *p = rname;
307*45327Sbostic 
308*45327Sbostic     if (col < 0 || col > 25*26)
309*45327Sbostic 	(void) fprintf(stderr,"coltoa: invalid col: %d", col);
310*45327Sbostic 
311*45327Sbostic     if (col > 25) {
312*45327Sbostic 	*p++ = col/26 + 'A' - 1;
313*45327Sbostic 	col %= 26;
314*45327Sbostic     }
315*45327Sbostic     *p++ = col+'A';
316*45327Sbostic     *p = 0;
317*45327Sbostic     return(rname);
318*45327Sbostic }
319*45327Sbostic 
320