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