1 static char *sccsid = "@(#)subr.c 1.6 (Berkeley) 12/11/84"; 2 #include <stdio.h> 3 #include <ctype.h> 4 #include "error.h" 5 /* 6 * Arrayify a list of rules 7 */ 8 arrayify(e_length, e_array, header) 9 int *e_length; 10 Eptr **e_array; 11 Eptr header; 12 { 13 reg Eptr errorp; 14 reg Eptr *array; 15 reg int listlength; 16 reg int listindex; 17 18 for (errorp = header, listlength = 0; 19 errorp; errorp = errorp->error_next, listlength++) 20 continue; 21 array = (Eptr*)Calloc(listlength+1, sizeof (Eptr)); 22 for(listindex = 0, errorp = header; 23 listindex < listlength; 24 listindex++, errorp = errorp->error_next){ 25 array[listindex] = errorp; 26 errorp->error_position = listindex; 27 } 28 array[listindex] = (Eptr)0; 29 *e_length = listlength; 30 *e_array = array; 31 } 32 33 /*VARARGS1*/ 34 error(msg, a1, a2, a3) 35 char *msg; 36 { 37 fprintf(stderr, "Error: "); 38 fprintf(stderr, msg, a1, a2, a3); 39 fprintf(stderr, "\n"); 40 fflush(stdout); 41 fflush(stderr); 42 exit(6); 43 } 44 /*ARGSUSED*/ 45 char *Calloc(nelements, size) 46 int nelements; 47 int size; 48 { 49 char *back; 50 if ( (back = (char *)calloc(nelements, size)) == (char *)NULL){ 51 error("Ran out of memory.\n"); 52 exit(1); 53 } 54 return(back); 55 } 56 57 char *strsave(instring) 58 char *instring; 59 { 60 char *outstring; 61 (void)strcpy(outstring = (char *)Calloc(1, strlen(instring) + 1), 62 instring); 63 return(outstring); 64 } 65 /* 66 * find the position of a given character in a string 67 * (one based) 68 */ 69 int position(string, ch) 70 reg char *string; 71 reg char ch; 72 { 73 reg int i; 74 if (string) 75 for (i=1; *string; string++, i++){ 76 if (*string == ch) 77 return(i); 78 } 79 return(-1); 80 } 81 /* 82 * clobber the first occurance of ch in string by the new character 83 */ 84 char *substitute(string, chold, chnew) 85 char *string; 86 char chold, chnew; 87 { 88 reg char *cp = string; 89 90 if (cp) 91 while (*cp){ 92 if (*cp == chold){ 93 *cp = chnew; 94 break; 95 } 96 cp++; 97 } 98 return(string); 99 } 100 101 char lastchar(string) 102 char *string; 103 { 104 int length; 105 if (string == 0) return('\0'); 106 length = strlen(string); 107 if (length >= 1) 108 return(string[length-1]); 109 else 110 return('\0'); 111 } 112 113 char firstchar(string) 114 char *string; 115 { 116 if (string) 117 return(string[0]); 118 else 119 return('\0'); 120 } 121 122 char next_lastchar(string) 123 char *string; 124 { 125 int length; 126 if (string == 0) return('\0'); 127 length = strlen(string); 128 if (length >= 2) 129 return(string[length - 2]); 130 else 131 return('\0'); 132 } 133 134 clob_last(string, newstuff) 135 char *string, newstuff; 136 { 137 int length = 0; 138 if (string) 139 length = strlen(string); 140 if (length >= 1) 141 string[length - 1] = newstuff; 142 } 143 144 /* 145 * parse a string that is the result of a format %s(%d) 146 * return TRUE if this is of the proper format 147 */ 148 boolean persperdexplode(string, r_perd, r_pers) 149 char *string; 150 char **r_perd, **r_pers; 151 { 152 reg char *cp; 153 int length = 0; 154 155 if (string) 156 length = strlen(string); 157 if ( (length >= 4) 158 && (string[length - 1] == ')' ) ){ 159 for (cp = &string[length - 2]; 160 (isdigit(*cp)) && (*cp != '('); 161 --cp) 162 continue; 163 if (*cp == '('){ 164 string[length - 1] = '\0'; /* clobber the ) */ 165 *r_perd = strsave(cp+1); 166 string[length - 1] = ')'; 167 *cp = '\0'; /* clobber the ( */ 168 *r_pers = strsave(string); 169 *cp = '('; 170 return(TRUE); 171 } 172 } 173 return(FALSE); 174 } 175 /* 176 * parse a quoted string that is the result of a format \"%s\"(%d) 177 * return TRUE if this is of the proper format 178 */ 179 boolean qpersperdexplode(string, r_perd, r_pers) 180 char *string; 181 char **r_perd, **r_pers; 182 { 183 reg char *cp; 184 int length = 0; 185 186 if (string) 187 length = strlen(string); 188 if ( (length >= 4) 189 && (string[length - 1] == ')' ) ){ 190 for (cp = &string[length - 2]; 191 (isdigit(*cp)) && (*cp != '('); 192 --cp) 193 continue; 194 if (*cp == '(' && *(cp - 1) == '"'){ 195 string[length - 1] = '\0'; 196 *r_perd = strsave(cp+1); 197 string[length - 1] = ')'; 198 *(cp - 1) = '\0'; /* clobber the " */ 199 *r_pers = strsave(string + 1); 200 *(cp - 1) = '"'; 201 return(TRUE); 202 } 203 } 204 return(FALSE); 205 } 206 207 static char cincomment[] = CINCOMMENT; 208 static char coutcomment[] = COUTCOMMENT; 209 static char fincomment[] = FINCOMMENT; 210 static char foutcomment[] = FOUTCOMMENT; 211 static char newline[] = NEWLINE; 212 static char piincomment[] = PIINCOMMENT; 213 static char pioutcomment[] = PIOUTCOMMENT; 214 static char lispincomment[] = LISPINCOMMENT; 215 static char riincomment[] = RIINCOMMENT; 216 static char rioutcomment[] = RIOUTCOMMENT; 217 static char troffincomment[] = TROFFINCOMMENT; 218 static char troffoutcomment[] = TROFFOUTCOMMENT; 219 static char mod2incomment[] = MOD2INCOMMENT; 220 static char mod2outcomment[] = MOD2OUTCOMMENT; 221 222 struct lang_desc lang_table[] = { 223 /*INUNKNOWN 0*/ "unknown", cincomment, coutcomment, 224 /*INCPP 1*/ "cpp", cincomment, coutcomment, 225 /*INCC 2*/ "cc", cincomment, coutcomment, 226 /*INAS 3*/ "as", ASINCOMMENT, newline, 227 /*INLD 4*/ "ld", cincomment, coutcomment, 228 /*INLINT 5*/ "lint", cincomment, coutcomment, 229 /*INF77 6*/ "f77", fincomment, foutcomment, 230 /*INPI 7*/ "pi", piincomment, pioutcomment, 231 /*INPC 8*/ "pc", piincomment, pioutcomment, 232 /*INFRANZ 9*/ "franz",lispincomment, newline, 233 /*INLISP 10*/ "lisp", lispincomment, newline, 234 /*INVAXIMA 11*/ "vaxima",lispincomment,newline, 235 /*INRATFOR 12*/ "ratfor",fincomment, foutcomment, 236 /*INLEX 13*/ "lex", cincomment, coutcomment, 237 /*INYACC 14*/ "yacc", cincomment, coutcomment, 238 /*INAPL 15*/ "apl", ".lm", newline, 239 /*INMAKE 16*/ "make", ASINCOMMENT, newline, 240 /*INRI 17*/ "ri", riincomment, rioutcomment, 241 /*INTROFF 18*/ "troff",troffincomment,troffoutcomment, 242 /*INMOD2 19*/ "mod2", mod2incomment, mod2outcomment, 243 0, 0, 0 244 }; 245 246 printerrors(look_at_subclass, errorc, errorv) 247 boolean look_at_subclass; 248 int errorc; 249 Eptr errorv[]; 250 { 251 reg int i; 252 reg Eptr errorp; 253 254 for (errorp = errorv[i = 0]; i < errorc; errorp = errorv[++i]){ 255 if (errorp->error_e_class == C_IGNORE) 256 continue; 257 if (look_at_subclass && errorp->error_s_class == C_DUPL) 258 continue; 259 printf("Error %d, (%s error) [%s], text = \"", 260 i, 261 class_table[errorp->error_e_class], 262 lang_table[errorp->error_language].lang_name); 263 wordvprint(stdout,errorp->error_lgtext,errorp->error_text); 264 printf("\"\n"); 265 } 266 } 267 268 wordvprint(fyle, wordc, wordv) 269 FILE *fyle; 270 int wordc; 271 char *wordv[]; 272 { 273 int i; 274 char *sep = ""; 275 276 for(i = 0; i < wordc; i++) 277 if (wordv[i]) { 278 fprintf(fyle, "%s%s",sep,wordv[i]); 279 sep = " "; 280 } 281 } 282 283 /* 284 * Given a string, parse it into a number of words, and build 285 * a wordc wordv combination pointing into it. 286 */ 287 wordvbuild(string, r_wordc, r_wordv) 288 char *string; 289 int *r_wordc; 290 char ***r_wordv; 291 { 292 reg char *cp; 293 char *saltedbuffer; 294 char **wordv; 295 int wordcount; 296 int wordindex; 297 298 saltedbuffer = strsave(string); 299 for (wordcount = 0, cp = saltedbuffer; *cp; wordcount++){ 300 while (*cp && isspace(*cp)) 301 cp++; 302 if (*cp == 0) 303 break; 304 while (!isspace(*cp)) 305 cp++; 306 } 307 wordv = (char **)Calloc(wordcount + 1, sizeof (char *)); 308 for (cp=saltedbuffer,wordindex=0; wordcount; wordindex++,--wordcount){ 309 while (*cp && isspace(*cp)) 310 cp++; 311 if (*cp == 0) 312 break; 313 wordv[wordindex] = cp; 314 while(!isspace(*cp)) 315 cp++; 316 *cp++ = '\0'; 317 } 318 if (wordcount != 0) 319 error("Initial miscount of the number of words in a line\n"); 320 wordv[wordindex] = (char *)0; 321 #ifdef FULLDEBUG 322 for (wordcount = 0; wordcount < wordindex; wordcount++) 323 printf("Word %d = \"%s\"\n", wordcount, wordv[wordcount]); 324 printf("\n"); 325 #endif 326 *r_wordc = wordindex; 327 *r_wordv = wordv; 328 } 329 /* 330 * Compare two 0 based wordvectors 331 */ 332 int wordvcmp(wordv1, wordc, wordv2) 333 char **wordv1; 334 int wordc; 335 char **wordv2; 336 { 337 reg int i; 338 int back; 339 for (i = 0; i < wordc; i++){ 340 if (wordv1[i] == 0 || wordv2[i] == 0) 341 return(-1); 342 if (back = strcmp(wordv1[i], wordv2[i])){ 343 return(back); 344 } 345 } 346 return(0); /* they are equal */ 347 } 348 349 /* 350 * splice a 0 basedword vector onto the tail of a 351 * new wordv, allowing the first emptyhead slots to be empty 352 */ 353 char **wordvsplice(emptyhead, wordc, wordv) 354 int emptyhead; 355 int wordc; 356 char **wordv; 357 { 358 reg char **nwordv; 359 int nwordc = emptyhead + wordc; 360 reg int i; 361 362 nwordv = (char **)Calloc(nwordc, sizeof (char *)); 363 for (i = 0; i < emptyhead; i++) 364 nwordv[i] = 0; 365 for(i = emptyhead; i < nwordc; i++){ 366 nwordv[i] = wordv[i-emptyhead]; 367 } 368 return(nwordv); 369 } 370 /* 371 * plural'ize and verb forms 372 */ 373 static char *S = "s"; 374 static char *N = ""; 375 char *plural(n) 376 int n; 377 { 378 return( n > 1 ? S : N); 379 } 380 char *verbform(n) 381 int n; 382 { 383 return( n > 1 ? N : S); 384 } 385 386