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