121638Sdist /* 221638Sdist * Copyright (c) 1980 Regents of the University of California. 334664Sbostic * All rights reserved. 434664Sbostic * 542683Sbostic * %sccs.include.redist.c% 621638Sdist */ 721638Sdist 821638Sdist #ifndef lint 9*46694Sbostic static char sccsid[] = "@(#)subr.c 5.5 (Berkeley) 02/26/91"; 1034664Sbostic #endif /* not lint */ 1121638Sdist 121459Sroot #include <stdio.h> 131459Sroot #include <ctype.h> 14*46694Sbostic #include <stdlib.h> 15*46694Sbostic #include <string.h> 161459Sroot #include "error.h" 171459Sroot /* 185594Srrh * Arrayify a list of rules 191459Sroot */ 201459Sroot arrayify(e_length, e_array, header) 215594Srrh int *e_length; 225594Srrh Eptr **e_array; 235594Srrh Eptr header; 241459Sroot { 255594Srrh reg Eptr errorp; 265594Srrh reg Eptr *array; 275594Srrh reg int listlength; 285594Srrh reg int listindex; 291459Sroot 301459Sroot for (errorp = header, listlength = 0; 311459Sroot errorp; errorp = errorp->error_next, listlength++) 321459Sroot continue; 335594Srrh array = (Eptr*)Calloc(listlength+1, sizeof (Eptr)); 341459Sroot for(listindex = 0, errorp = header; 351459Sroot listindex < listlength; 361459Sroot listindex++, errorp = errorp->error_next){ 371459Sroot array[listindex] = errorp; 381459Sroot errorp->error_position = listindex; 391459Sroot } 405594Srrh array[listindex] = (Eptr)0; 411459Sroot *e_length = listlength; 421459Sroot *e_array = array; 431459Sroot } 441459Sroot 451459Sroot /*VARARGS1*/ 461459Sroot error(msg, a1, a2, a3) 471459Sroot char *msg; 481459Sroot { 491459Sroot fprintf(stderr, "Error: "); 501459Sroot fprintf(stderr, msg, a1, a2, a3); 511459Sroot fprintf(stderr, "\n"); 521459Sroot fflush(stdout); 531459Sroot fflush(stderr); 541459Sroot exit(6); 551459Sroot } 561459Sroot /*ARGSUSED*/ 571459Sroot char *Calloc(nelements, size) 581459Sroot int nelements; 591459Sroot int size; 601459Sroot { 611459Sroot char *back; 621459Sroot if ( (back = (char *)calloc(nelements, size)) == (char *)NULL){ 631459Sroot error("Ran out of memory.\n"); 641459Sroot exit(1); 651459Sroot } 661459Sroot return(back); 671459Sroot } 681459Sroot 691459Sroot char *strsave(instring) 701459Sroot char *instring; 711459Sroot { 721459Sroot char *outstring; 735594Srrh (void)strcpy(outstring = (char *)Calloc(1, strlen(instring) + 1), 745594Srrh instring); 751459Sroot return(outstring); 761459Sroot } 771459Sroot /* 781459Sroot * find the position of a given character in a string 791459Sroot * (one based) 801459Sroot */ 811459Sroot int position(string, ch) 825594Srrh reg char *string; 835594Srrh reg char ch; 841459Sroot { 855594Srrh reg int i; 8610830Ssam if (string) 871459Sroot for (i=1; *string; string++, i++){ 881459Sroot if (*string == ch) 891459Sroot return(i); 901459Sroot } 911459Sroot return(-1); 921459Sroot } 931459Sroot /* 941459Sroot * clobber the first occurance of ch in string by the new character 951459Sroot */ 961459Sroot char *substitute(string, chold, chnew) 971459Sroot char *string; 981459Sroot char chold, chnew; 991459Sroot { 1005594Srrh reg char *cp = string; 1011459Sroot 10210830Ssam if (cp) 1031459Sroot while (*cp){ 1041459Sroot if (*cp == chold){ 1051459Sroot *cp = chnew; 1061459Sroot break; 1071459Sroot } 1081459Sroot cp++; 1091459Sroot } 1101459Sroot return(string); 1111459Sroot } 1121459Sroot 1131459Sroot char lastchar(string) 1141459Sroot char *string; 1151459Sroot { 1161459Sroot int length; 11710830Ssam if (string == 0) return('\0'); 1181459Sroot length = strlen(string); 1191459Sroot if (length >= 1) 1201459Sroot return(string[length-1]); 1211459Sroot else 1221459Sroot return('\0'); 1231459Sroot } 1241459Sroot 1251459Sroot char firstchar(string) 1261459Sroot char *string; 1271459Sroot { 12810830Ssam if (string) 12910830Ssam return(string[0]); 13010830Ssam else 13110830Ssam return('\0'); 1321459Sroot } 1331459Sroot 1341459Sroot char next_lastchar(string) 1351459Sroot char *string; 1361459Sroot { 1371459Sroot int length; 13810830Ssam if (string == 0) return('\0'); 1391459Sroot length = strlen(string); 1401459Sroot if (length >= 2) 1411459Sroot return(string[length - 2]); 1421459Sroot else 1431459Sroot return('\0'); 1441459Sroot } 1451459Sroot 1461459Sroot clob_last(string, newstuff) 1471459Sroot char *string, newstuff; 1481459Sroot { 14910830Ssam int length = 0; 15010830Ssam if (string) 15110830Ssam length = strlen(string); 1521459Sroot if (length >= 1) 1531459Sroot string[length - 1] = newstuff; 1541459Sroot } 1551459Sroot 1561459Sroot /* 1571459Sroot * parse a string that is the result of a format %s(%d) 1581459Sroot * return TRUE if this is of the proper format 1591459Sroot */ 1601459Sroot boolean persperdexplode(string, r_perd, r_pers) 1611459Sroot char *string; 1621459Sroot char **r_perd, **r_pers; 1631459Sroot { 1645594Srrh reg char *cp; 16510830Ssam int length = 0; 1661459Sroot 16710830Ssam if (string) 16810830Ssam length = strlen(string); 1691459Sroot if ( (length >= 4) 1701459Sroot && (string[length - 1] == ')' ) ){ 1711459Sroot for (cp = &string[length - 2]; 1721459Sroot (isdigit(*cp)) && (*cp != '('); 1731459Sroot --cp) 1741459Sroot continue; 1751459Sroot if (*cp == '('){ 1761459Sroot string[length - 1] = '\0'; /* clobber the ) */ 1771459Sroot *r_perd = strsave(cp+1); 1781459Sroot string[length - 1] = ')'; 1791459Sroot *cp = '\0'; /* clobber the ( */ 1801459Sroot *r_pers = strsave(string); 1811459Sroot *cp = '('; 1821459Sroot return(TRUE); 1831459Sroot } 1841459Sroot } 1851459Sroot return(FALSE); 1861459Sroot } 1871459Sroot /* 1881459Sroot * parse a quoted string that is the result of a format \"%s\"(%d) 1891459Sroot * return TRUE if this is of the proper format 1901459Sroot */ 1911459Sroot boolean qpersperdexplode(string, r_perd, r_pers) 1921459Sroot char *string; 1931459Sroot char **r_perd, **r_pers; 1941459Sroot { 1955594Srrh reg char *cp; 19610830Ssam int length = 0; 1971459Sroot 19810830Ssam if (string) 19910830Ssam length = strlen(string); 2001459Sroot if ( (length >= 4) 2011459Sroot && (string[length - 1] == ')' ) ){ 2021459Sroot for (cp = &string[length - 2]; 2031459Sroot (isdigit(*cp)) && (*cp != '('); 2041459Sroot --cp) 2051459Sroot continue; 2061459Sroot if (*cp == '(' && *(cp - 1) == '"'){ 2071459Sroot string[length - 1] = '\0'; 2081459Sroot *r_perd = strsave(cp+1); 2091459Sroot string[length - 1] = ')'; 2101459Sroot *(cp - 1) = '\0'; /* clobber the " */ 2111459Sroot *r_pers = strsave(string + 1); 2121459Sroot *(cp - 1) = '"'; 2131459Sroot return(TRUE); 2141459Sroot } 2151459Sroot } 2161459Sroot return(FALSE); 2171459Sroot } 2181459Sroot 2191459Sroot static char cincomment[] = CINCOMMENT; 2201459Sroot static char coutcomment[] = COUTCOMMENT; 2211459Sroot static char fincomment[] = FINCOMMENT; 2221459Sroot static char foutcomment[] = FOUTCOMMENT; 2231459Sroot static char newline[] = NEWLINE; 2241459Sroot static char piincomment[] = PIINCOMMENT; 2251459Sroot static char pioutcomment[] = PIOUTCOMMENT; 2261459Sroot static char lispincomment[] = LISPINCOMMENT; 2271459Sroot static char riincomment[] = RIINCOMMENT; 2281459Sroot static char rioutcomment[] = RIOUTCOMMENT; 22913106Srrh static char troffincomment[] = TROFFINCOMMENT; 23013106Srrh static char troffoutcomment[] = TROFFOUTCOMMENT; 23117499Srrh static char mod2incomment[] = MOD2INCOMMENT; 23217499Srrh static char mod2outcomment[] = MOD2OUTCOMMENT; 2331459Sroot 2341459Sroot struct lang_desc lang_table[] = { 2351459Sroot /*INUNKNOWN 0*/ "unknown", cincomment, coutcomment, 2361459Sroot /*INCPP 1*/ "cpp", cincomment, coutcomment, 2371459Sroot /*INCC 2*/ "cc", cincomment, coutcomment, 2381459Sroot /*INAS 3*/ "as", ASINCOMMENT, newline, 2391459Sroot /*INLD 4*/ "ld", cincomment, coutcomment, 2401459Sroot /*INLINT 5*/ "lint", cincomment, coutcomment, 2411459Sroot /*INF77 6*/ "f77", fincomment, foutcomment, 2421459Sroot /*INPI 7*/ "pi", piincomment, pioutcomment, 2431459Sroot /*INPC 8*/ "pc", piincomment, pioutcomment, 2441459Sroot /*INFRANZ 9*/ "franz",lispincomment, newline, 2451459Sroot /*INLISP 10*/ "lisp", lispincomment, newline, 2461459Sroot /*INVAXIMA 11*/ "vaxima",lispincomment,newline, 2471459Sroot /*INRATFOR 12*/ "ratfor",fincomment, foutcomment, 2481459Sroot /*INLEX 13*/ "lex", cincomment, coutcomment, 2491459Sroot /*INYACC 14*/ "yacc", cincomment, coutcomment, 2501459Sroot /*INAPL 15*/ "apl", ".lm", newline, 2511459Sroot /*INMAKE 16*/ "make", ASINCOMMENT, newline, 2521459Sroot /*INRI 17*/ "ri", riincomment, rioutcomment, 25313106Srrh /*INTROFF 18*/ "troff",troffincomment,troffoutcomment, 25417499Srrh /*INMOD2 19*/ "mod2", mod2incomment, mod2outcomment, 2551459Sroot 0, 0, 0 2561459Sroot }; 2571459Sroot 2581459Sroot printerrors(look_at_subclass, errorc, errorv) 2591459Sroot boolean look_at_subclass; 2601459Sroot int errorc; 2615594Srrh Eptr errorv[]; 2621459Sroot { 2635594Srrh reg int i; 2645594Srrh reg Eptr errorp; 2655594Srrh 2661459Sroot for (errorp = errorv[i = 0]; i < errorc; errorp = errorv[++i]){ 2671459Sroot if (errorp->error_e_class == C_IGNORE) 2681459Sroot continue; 2691459Sroot if (look_at_subclass && errorp->error_s_class == C_DUPL) 2701459Sroot continue; 2711459Sroot printf("Error %d, (%s error) [%s], text = \"", 2721459Sroot i, 2731459Sroot class_table[errorp->error_e_class], 2741459Sroot lang_table[errorp->error_language].lang_name); 2751459Sroot wordvprint(stdout,errorp->error_lgtext,errorp->error_text); 2761459Sroot printf("\"\n"); 2771459Sroot } 2781459Sroot } 2791459Sroot 2801459Sroot wordvprint(fyle, wordc, wordv) 2811459Sroot FILE *fyle; 2821459Sroot int wordc; 2831459Sroot char *wordv[]; 2841459Sroot { 2851459Sroot int i; 28613539Ssam char *sep = ""; 28713539Ssam 28813539Ssam for(i = 0; i < wordc; i++) 28913539Ssam if (wordv[i]) { 29013539Ssam fprintf(fyle, "%s%s",sep,wordv[i]); 29113539Ssam sep = " "; 29213539Ssam } 2931459Sroot } 2941459Sroot 2951459Sroot /* 2961459Sroot * Given a string, parse it into a number of words, and build 2971459Sroot * a wordc wordv combination pointing into it. 2981459Sroot */ 2991459Sroot wordvbuild(string, r_wordc, r_wordv) 3001459Sroot char *string; 3011459Sroot int *r_wordc; 3021459Sroot char ***r_wordv; 3031459Sroot { 3045594Srrh reg char *cp; 3055594Srrh char *saltedbuffer; 3065594Srrh char **wordv; 3075594Srrh int wordcount; 3085594Srrh int wordindex; 3091459Sroot 3101459Sroot saltedbuffer = strsave(string); 3111459Sroot for (wordcount = 0, cp = saltedbuffer; *cp; wordcount++){ 3121459Sroot while (*cp && isspace(*cp)) 3131459Sroot cp++; 3141459Sroot if (*cp == 0) 3151459Sroot break; 3161459Sroot while (!isspace(*cp)) 3171459Sroot cp++; 3181459Sroot } 3191459Sroot wordv = (char **)Calloc(wordcount + 1, sizeof (char *)); 3201459Sroot for (cp=saltedbuffer,wordindex=0; wordcount; wordindex++,--wordcount){ 3211459Sroot while (*cp && isspace(*cp)) 3221459Sroot cp++; 3231459Sroot if (*cp == 0) 3241459Sroot break; 3251459Sroot wordv[wordindex] = cp; 3261459Sroot while(!isspace(*cp)) 3271459Sroot cp++; 3281459Sroot *cp++ = '\0'; 3291459Sroot } 3301459Sroot if (wordcount != 0) 3311459Sroot error("Initial miscount of the number of words in a line\n"); 3321459Sroot wordv[wordindex] = (char *)0; 3331459Sroot #ifdef FULLDEBUG 3341459Sroot for (wordcount = 0; wordcount < wordindex; wordcount++) 3351459Sroot printf("Word %d = \"%s\"\n", wordcount, wordv[wordcount]); 3361459Sroot printf("\n"); 3371459Sroot #endif 3381459Sroot *r_wordc = wordindex; 3391459Sroot *r_wordv = wordv; 3401459Sroot } 3411459Sroot /* 3421459Sroot * Compare two 0 based wordvectors 3431459Sroot */ 3441459Sroot int wordvcmp(wordv1, wordc, wordv2) 3451459Sroot char **wordv1; 3461459Sroot int wordc; 3471459Sroot char **wordv2; 3481459Sroot { 3495594Srrh reg int i; 3505594Srrh int back; 3511459Sroot for (i = 0; i < wordc; i++){ 35210830Ssam if (wordv1[i] == 0 || wordv2[i] == 0) 35310830Ssam return(-1); 3541459Sroot if (back = strcmp(wordv1[i], wordv2[i])){ 3551459Sroot return(back); 3561459Sroot } 3571459Sroot } 3581459Sroot return(0); /* they are equal */ 3591459Sroot } 3601459Sroot 3611459Sroot /* 3621459Sroot * splice a 0 basedword vector onto the tail of a 3631459Sroot * new wordv, allowing the first emptyhead slots to be empty 3641459Sroot */ 3651459Sroot char **wordvsplice(emptyhead, wordc, wordv) 3661459Sroot int emptyhead; 3671459Sroot int wordc; 3681459Sroot char **wordv; 3691459Sroot { 3705594Srrh reg char **nwordv; 3715594Srrh int nwordc = emptyhead + wordc; 3725594Srrh reg int i; 3731459Sroot 3741459Sroot nwordv = (char **)Calloc(nwordc, sizeof (char *)); 3751459Sroot for (i = 0; i < emptyhead; i++) 3761459Sroot nwordv[i] = 0; 3771459Sroot for(i = emptyhead; i < nwordc; i++){ 3781459Sroot nwordv[i] = wordv[i-emptyhead]; 3791459Sroot } 3801459Sroot return(nwordv); 3811459Sroot } 3825594Srrh /* 3835594Srrh * plural'ize and verb forms 3845594Srrh */ 3855594Srrh static char *S = "s"; 3865594Srrh static char *N = ""; 3875594Srrh char *plural(n) 3885594Srrh int n; 3895594Srrh { 3905594Srrh return( n > 1 ? S : N); 3915594Srrh } 3925594Srrh char *verbform(n) 3935594Srrh int n; 3945594Srrh { 3955594Srrh return( n > 1 ? N : S); 3965594Srrh } 3975594Srrh 398