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