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