121638Sdist /* 221638Sdist * Copyright (c) 1980 Regents of the University of California. 3*34664Sbostic * All rights reserved. 4*34664Sbostic * 5*34664Sbostic * Redistribution and use in source and binary forms are permitted 6*34664Sbostic * provided that this notice is preserved and that due credit is given 7*34664Sbostic * to the University of California at Berkeley. The name of the University 8*34664Sbostic * may not be used to endorse or promote products derived from this 9*34664Sbostic * software without specific prior written permission. This software 10*34664Sbostic * is provided ``as is'' without express or implied warranty. 1121638Sdist */ 1221638Sdist 1321638Sdist #ifndef lint 14*34664Sbostic static char sccsid[] = "@(#)subr.c 5.2 (Berkeley) 06/06/88"; 15*34664Sbostic #endif /* not lint */ 1621638Sdist 171459Sroot #include <stdio.h> 181459Sroot #include <ctype.h> 191459Sroot #include "error.h" 201459Sroot /* 215594Srrh * Arrayify a list of rules 221459Sroot */ 231459Sroot arrayify(e_length, e_array, header) 245594Srrh int *e_length; 255594Srrh Eptr **e_array; 265594Srrh Eptr header; 271459Sroot { 285594Srrh reg Eptr errorp; 295594Srrh reg Eptr *array; 305594Srrh reg int listlength; 315594Srrh reg int listindex; 321459Sroot 331459Sroot for (errorp = header, listlength = 0; 341459Sroot errorp; errorp = errorp->error_next, listlength++) 351459Sroot continue; 365594Srrh array = (Eptr*)Calloc(listlength+1, sizeof (Eptr)); 371459Sroot for(listindex = 0, errorp = header; 381459Sroot listindex < listlength; 391459Sroot listindex++, errorp = errorp->error_next){ 401459Sroot array[listindex] = errorp; 411459Sroot errorp->error_position = listindex; 421459Sroot } 435594Srrh array[listindex] = (Eptr)0; 441459Sroot *e_length = listlength; 451459Sroot *e_array = array; 461459Sroot } 471459Sroot 481459Sroot /*VARARGS1*/ 491459Sroot error(msg, a1, a2, a3) 501459Sroot char *msg; 511459Sroot { 521459Sroot fprintf(stderr, "Error: "); 531459Sroot fprintf(stderr, msg, a1, a2, a3); 541459Sroot fprintf(stderr, "\n"); 551459Sroot fflush(stdout); 561459Sroot fflush(stderr); 571459Sroot exit(6); 581459Sroot } 591459Sroot /*ARGSUSED*/ 601459Sroot char *Calloc(nelements, size) 611459Sroot int nelements; 621459Sroot int size; 631459Sroot { 641459Sroot char *back; 651459Sroot if ( (back = (char *)calloc(nelements, size)) == (char *)NULL){ 661459Sroot error("Ran out of memory.\n"); 671459Sroot exit(1); 681459Sroot } 691459Sroot return(back); 701459Sroot } 711459Sroot 721459Sroot char *strsave(instring) 731459Sroot char *instring; 741459Sroot { 751459Sroot char *outstring; 765594Srrh (void)strcpy(outstring = (char *)Calloc(1, strlen(instring) + 1), 775594Srrh instring); 781459Sroot return(outstring); 791459Sroot } 801459Sroot /* 811459Sroot * find the position of a given character in a string 821459Sroot * (one based) 831459Sroot */ 841459Sroot int position(string, ch) 855594Srrh reg char *string; 865594Srrh reg char ch; 871459Sroot { 885594Srrh reg int i; 8910830Ssam if (string) 901459Sroot for (i=1; *string; string++, i++){ 911459Sroot if (*string == ch) 921459Sroot return(i); 931459Sroot } 941459Sroot return(-1); 951459Sroot } 961459Sroot /* 971459Sroot * clobber the first occurance of ch in string by the new character 981459Sroot */ 991459Sroot char *substitute(string, chold, chnew) 1001459Sroot char *string; 1011459Sroot char chold, chnew; 1021459Sroot { 1035594Srrh reg char *cp = string; 1041459Sroot 10510830Ssam if (cp) 1061459Sroot while (*cp){ 1071459Sroot if (*cp == chold){ 1081459Sroot *cp = chnew; 1091459Sroot break; 1101459Sroot } 1111459Sroot cp++; 1121459Sroot } 1131459Sroot return(string); 1141459Sroot } 1151459Sroot 1161459Sroot char lastchar(string) 1171459Sroot char *string; 1181459Sroot { 1191459Sroot int length; 12010830Ssam if (string == 0) return('\0'); 1211459Sroot length = strlen(string); 1221459Sroot if (length >= 1) 1231459Sroot return(string[length-1]); 1241459Sroot else 1251459Sroot return('\0'); 1261459Sroot } 1271459Sroot 1281459Sroot char firstchar(string) 1291459Sroot char *string; 1301459Sroot { 13110830Ssam if (string) 13210830Ssam return(string[0]); 13310830Ssam else 13410830Ssam return('\0'); 1351459Sroot } 1361459Sroot 1371459Sroot char next_lastchar(string) 1381459Sroot char *string; 1391459Sroot { 1401459Sroot int length; 14110830Ssam if (string == 0) return('\0'); 1421459Sroot length = strlen(string); 1431459Sroot if (length >= 2) 1441459Sroot return(string[length - 2]); 1451459Sroot else 1461459Sroot return('\0'); 1471459Sroot } 1481459Sroot 1491459Sroot clob_last(string, newstuff) 1501459Sroot char *string, newstuff; 1511459Sroot { 15210830Ssam int length = 0; 15310830Ssam if (string) 15410830Ssam length = strlen(string); 1551459Sroot if (length >= 1) 1561459Sroot string[length - 1] = newstuff; 1571459Sroot } 1581459Sroot 1591459Sroot /* 1601459Sroot * parse a string that is the result of a format %s(%d) 1611459Sroot * return TRUE if this is of the proper format 1621459Sroot */ 1631459Sroot boolean persperdexplode(string, r_perd, r_pers) 1641459Sroot char *string; 1651459Sroot char **r_perd, **r_pers; 1661459Sroot { 1675594Srrh reg char *cp; 16810830Ssam int length = 0; 1691459Sroot 17010830Ssam if (string) 17110830Ssam length = strlen(string); 1721459Sroot if ( (length >= 4) 1731459Sroot && (string[length - 1] == ')' ) ){ 1741459Sroot for (cp = &string[length - 2]; 1751459Sroot (isdigit(*cp)) && (*cp != '('); 1761459Sroot --cp) 1771459Sroot continue; 1781459Sroot if (*cp == '('){ 1791459Sroot string[length - 1] = '\0'; /* clobber the ) */ 1801459Sroot *r_perd = strsave(cp+1); 1811459Sroot string[length - 1] = ')'; 1821459Sroot *cp = '\0'; /* clobber the ( */ 1831459Sroot *r_pers = strsave(string); 1841459Sroot *cp = '('; 1851459Sroot return(TRUE); 1861459Sroot } 1871459Sroot } 1881459Sroot return(FALSE); 1891459Sroot } 1901459Sroot /* 1911459Sroot * parse a quoted string that is the result of a format \"%s\"(%d) 1921459Sroot * return TRUE if this is of the proper format 1931459Sroot */ 1941459Sroot boolean qpersperdexplode(string, r_perd, r_pers) 1951459Sroot char *string; 1961459Sroot char **r_perd, **r_pers; 1971459Sroot { 1985594Srrh reg char *cp; 19910830Ssam int length = 0; 2001459Sroot 20110830Ssam if (string) 20210830Ssam length = strlen(string); 2031459Sroot if ( (length >= 4) 2041459Sroot && (string[length - 1] == ')' ) ){ 2051459Sroot for (cp = &string[length - 2]; 2061459Sroot (isdigit(*cp)) && (*cp != '('); 2071459Sroot --cp) 2081459Sroot continue; 2091459Sroot if (*cp == '(' && *(cp - 1) == '"'){ 2101459Sroot string[length - 1] = '\0'; 2111459Sroot *r_perd = strsave(cp+1); 2121459Sroot string[length - 1] = ')'; 2131459Sroot *(cp - 1) = '\0'; /* clobber the " */ 2141459Sroot *r_pers = strsave(string + 1); 2151459Sroot *(cp - 1) = '"'; 2161459Sroot return(TRUE); 2171459Sroot } 2181459Sroot } 2191459Sroot return(FALSE); 2201459Sroot } 2211459Sroot 2221459Sroot static char cincomment[] = CINCOMMENT; 2231459Sroot static char coutcomment[] = COUTCOMMENT; 2241459Sroot static char fincomment[] = FINCOMMENT; 2251459Sroot static char foutcomment[] = FOUTCOMMENT; 2261459Sroot static char newline[] = NEWLINE; 2271459Sroot static char piincomment[] = PIINCOMMENT; 2281459Sroot static char pioutcomment[] = PIOUTCOMMENT; 2291459Sroot static char lispincomment[] = LISPINCOMMENT; 2301459Sroot static char riincomment[] = RIINCOMMENT; 2311459Sroot static char rioutcomment[] = RIOUTCOMMENT; 23213106Srrh static char troffincomment[] = TROFFINCOMMENT; 23313106Srrh static char troffoutcomment[] = TROFFOUTCOMMENT; 23417499Srrh static char mod2incomment[] = MOD2INCOMMENT; 23517499Srrh static char mod2outcomment[] = MOD2OUTCOMMENT; 2361459Sroot 2371459Sroot struct lang_desc lang_table[] = { 2381459Sroot /*INUNKNOWN 0*/ "unknown", cincomment, coutcomment, 2391459Sroot /*INCPP 1*/ "cpp", cincomment, coutcomment, 2401459Sroot /*INCC 2*/ "cc", cincomment, coutcomment, 2411459Sroot /*INAS 3*/ "as", ASINCOMMENT, newline, 2421459Sroot /*INLD 4*/ "ld", cincomment, coutcomment, 2431459Sroot /*INLINT 5*/ "lint", cincomment, coutcomment, 2441459Sroot /*INF77 6*/ "f77", fincomment, foutcomment, 2451459Sroot /*INPI 7*/ "pi", piincomment, pioutcomment, 2461459Sroot /*INPC 8*/ "pc", piincomment, pioutcomment, 2471459Sroot /*INFRANZ 9*/ "franz",lispincomment, newline, 2481459Sroot /*INLISP 10*/ "lisp", lispincomment, newline, 2491459Sroot /*INVAXIMA 11*/ "vaxima",lispincomment,newline, 2501459Sroot /*INRATFOR 12*/ "ratfor",fincomment, foutcomment, 2511459Sroot /*INLEX 13*/ "lex", cincomment, coutcomment, 2521459Sroot /*INYACC 14*/ "yacc", cincomment, coutcomment, 2531459Sroot /*INAPL 15*/ "apl", ".lm", newline, 2541459Sroot /*INMAKE 16*/ "make", ASINCOMMENT, newline, 2551459Sroot /*INRI 17*/ "ri", riincomment, rioutcomment, 25613106Srrh /*INTROFF 18*/ "troff",troffincomment,troffoutcomment, 25717499Srrh /*INMOD2 19*/ "mod2", mod2incomment, mod2outcomment, 2581459Sroot 0, 0, 0 2591459Sroot }; 2601459Sroot 2611459Sroot printerrors(look_at_subclass, errorc, errorv) 2621459Sroot boolean look_at_subclass; 2631459Sroot int errorc; 2645594Srrh Eptr errorv[]; 2651459Sroot { 2665594Srrh reg int i; 2675594Srrh reg Eptr errorp; 2685594Srrh 2691459Sroot for (errorp = errorv[i = 0]; i < errorc; errorp = errorv[++i]){ 2701459Sroot if (errorp->error_e_class == C_IGNORE) 2711459Sroot continue; 2721459Sroot if (look_at_subclass && errorp->error_s_class == C_DUPL) 2731459Sroot continue; 2741459Sroot printf("Error %d, (%s error) [%s], text = \"", 2751459Sroot i, 2761459Sroot class_table[errorp->error_e_class], 2771459Sroot lang_table[errorp->error_language].lang_name); 2781459Sroot wordvprint(stdout,errorp->error_lgtext,errorp->error_text); 2791459Sroot printf("\"\n"); 2801459Sroot } 2811459Sroot } 2821459Sroot 2831459Sroot wordvprint(fyle, wordc, wordv) 2841459Sroot FILE *fyle; 2851459Sroot int wordc; 2861459Sroot char *wordv[]; 2871459Sroot { 2881459Sroot int i; 28913539Ssam char *sep = ""; 29013539Ssam 29113539Ssam for(i = 0; i < wordc; i++) 29213539Ssam if (wordv[i]) { 29313539Ssam fprintf(fyle, "%s%s",sep,wordv[i]); 29413539Ssam sep = " "; 29513539Ssam } 2961459Sroot } 2971459Sroot 2981459Sroot /* 2991459Sroot * Given a string, parse it into a number of words, and build 3001459Sroot * a wordc wordv combination pointing into it. 3011459Sroot */ 3021459Sroot wordvbuild(string, r_wordc, r_wordv) 3031459Sroot char *string; 3041459Sroot int *r_wordc; 3051459Sroot char ***r_wordv; 3061459Sroot { 3075594Srrh reg char *cp; 3085594Srrh char *saltedbuffer; 3095594Srrh char **wordv; 3105594Srrh int wordcount; 3115594Srrh int wordindex; 3121459Sroot 3131459Sroot saltedbuffer = strsave(string); 3141459Sroot for (wordcount = 0, cp = saltedbuffer; *cp; wordcount++){ 3151459Sroot while (*cp && isspace(*cp)) 3161459Sroot cp++; 3171459Sroot if (*cp == 0) 3181459Sroot break; 3191459Sroot while (!isspace(*cp)) 3201459Sroot cp++; 3211459Sroot } 3221459Sroot wordv = (char **)Calloc(wordcount + 1, sizeof (char *)); 3231459Sroot for (cp=saltedbuffer,wordindex=0; wordcount; wordindex++,--wordcount){ 3241459Sroot while (*cp && isspace(*cp)) 3251459Sroot cp++; 3261459Sroot if (*cp == 0) 3271459Sroot break; 3281459Sroot wordv[wordindex] = cp; 3291459Sroot while(!isspace(*cp)) 3301459Sroot cp++; 3311459Sroot *cp++ = '\0'; 3321459Sroot } 3331459Sroot if (wordcount != 0) 3341459Sroot error("Initial miscount of the number of words in a line\n"); 3351459Sroot wordv[wordindex] = (char *)0; 3361459Sroot #ifdef FULLDEBUG 3371459Sroot for (wordcount = 0; wordcount < wordindex; wordcount++) 3381459Sroot printf("Word %d = \"%s\"\n", wordcount, wordv[wordcount]); 3391459Sroot printf("\n"); 3401459Sroot #endif 3411459Sroot *r_wordc = wordindex; 3421459Sroot *r_wordv = wordv; 3431459Sroot } 3441459Sroot /* 3451459Sroot * Compare two 0 based wordvectors 3461459Sroot */ 3471459Sroot int wordvcmp(wordv1, wordc, wordv2) 3481459Sroot char **wordv1; 3491459Sroot int wordc; 3501459Sroot char **wordv2; 3511459Sroot { 3525594Srrh reg int i; 3535594Srrh int back; 3541459Sroot for (i = 0; i < wordc; i++){ 35510830Ssam if (wordv1[i] == 0 || wordv2[i] == 0) 35610830Ssam return(-1); 3571459Sroot if (back = strcmp(wordv1[i], wordv2[i])){ 3581459Sroot return(back); 3591459Sroot } 3601459Sroot } 3611459Sroot return(0); /* they are equal */ 3621459Sroot } 3631459Sroot 3641459Sroot /* 3651459Sroot * splice a 0 basedword vector onto the tail of a 3661459Sroot * new wordv, allowing the first emptyhead slots to be empty 3671459Sroot */ 3681459Sroot char **wordvsplice(emptyhead, wordc, wordv) 3691459Sroot int emptyhead; 3701459Sroot int wordc; 3711459Sroot char **wordv; 3721459Sroot { 3735594Srrh reg char **nwordv; 3745594Srrh int nwordc = emptyhead + wordc; 3755594Srrh reg int i; 3761459Sroot 3771459Sroot nwordv = (char **)Calloc(nwordc, sizeof (char *)); 3781459Sroot for (i = 0; i < emptyhead; i++) 3791459Sroot nwordv[i] = 0; 3801459Sroot for(i = emptyhead; i < nwordc; i++){ 3811459Sroot nwordv[i] = wordv[i-emptyhead]; 3821459Sroot } 3831459Sroot return(nwordv); 3841459Sroot } 3855594Srrh /* 3865594Srrh * plural'ize and verb forms 3875594Srrh */ 3885594Srrh static char *S = "s"; 3895594Srrh static char *N = ""; 3905594Srrh char *plural(n) 3915594Srrh int n; 3925594Srrh { 3935594Srrh return( n > 1 ? S : N); 3945594Srrh } 3955594Srrh char *verbform(n) 3965594Srrh int n; 3975594Srrh { 3985594Srrh return( n > 1 ? N : S); 3995594Srrh } 4005594Srrh 401