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