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