xref: /original-bsd/contrib/sc/psc.c (revision 31e799e3)
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 
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 
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 
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 
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 *
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