1*21638Sdist /* 2*21638Sdist * Copyright (c) 1980 Regents of the University of California. 3*21638Sdist * All rights reserved. The Berkeley software License Agreement 4*21638Sdist * specifies the terms and conditions for redistribution. 5*21638Sdist */ 6*21638Sdist 7*21638Sdist #ifndef lint 8*21638Sdist static char sccsid[] = "@(#)subr.c 5.1 (Berkeley) 05/31/85"; 9*21638Sdist #endif not lint 10*21638Sdist 111459Sroot #include <stdio.h> 121459Sroot #include <ctype.h> 131459Sroot #include "error.h" 141459Sroot /* 155594Srrh * Arrayify a list of rules 161459Sroot */ 171459Sroot arrayify(e_length, e_array, header) 185594Srrh int *e_length; 195594Srrh Eptr **e_array; 205594Srrh Eptr header; 211459Sroot { 225594Srrh reg Eptr errorp; 235594Srrh reg Eptr *array; 245594Srrh reg int listlength; 255594Srrh reg int listindex; 261459Sroot 271459Sroot for (errorp = header, listlength = 0; 281459Sroot errorp; errorp = errorp->error_next, listlength++) 291459Sroot continue; 305594Srrh array = (Eptr*)Calloc(listlength+1, sizeof (Eptr)); 311459Sroot for(listindex = 0, errorp = header; 321459Sroot listindex < listlength; 331459Sroot listindex++, errorp = errorp->error_next){ 341459Sroot array[listindex] = errorp; 351459Sroot errorp->error_position = listindex; 361459Sroot } 375594Srrh array[listindex] = (Eptr)0; 381459Sroot *e_length = listlength; 391459Sroot *e_array = array; 401459Sroot } 411459Sroot 421459Sroot /*VARARGS1*/ 431459Sroot error(msg, a1, a2, a3) 441459Sroot char *msg; 451459Sroot { 461459Sroot fprintf(stderr, "Error: "); 471459Sroot fprintf(stderr, msg, a1, a2, a3); 481459Sroot fprintf(stderr, "\n"); 491459Sroot fflush(stdout); 501459Sroot fflush(stderr); 511459Sroot exit(6); 521459Sroot } 531459Sroot /*ARGSUSED*/ 541459Sroot char *Calloc(nelements, size) 551459Sroot int nelements; 561459Sroot int size; 571459Sroot { 581459Sroot char *back; 591459Sroot if ( (back = (char *)calloc(nelements, size)) == (char *)NULL){ 601459Sroot error("Ran out of memory.\n"); 611459Sroot exit(1); 621459Sroot } 631459Sroot return(back); 641459Sroot } 651459Sroot 661459Sroot char *strsave(instring) 671459Sroot char *instring; 681459Sroot { 691459Sroot char *outstring; 705594Srrh (void)strcpy(outstring = (char *)Calloc(1, strlen(instring) + 1), 715594Srrh instring); 721459Sroot return(outstring); 731459Sroot } 741459Sroot /* 751459Sroot * find the position of a given character in a string 761459Sroot * (one based) 771459Sroot */ 781459Sroot int position(string, ch) 795594Srrh reg char *string; 805594Srrh reg char ch; 811459Sroot { 825594Srrh reg int i; 8310830Ssam if (string) 841459Sroot for (i=1; *string; string++, i++){ 851459Sroot if (*string == ch) 861459Sroot return(i); 871459Sroot } 881459Sroot return(-1); 891459Sroot } 901459Sroot /* 911459Sroot * clobber the first occurance of ch in string by the new character 921459Sroot */ 931459Sroot char *substitute(string, chold, chnew) 941459Sroot char *string; 951459Sroot char chold, chnew; 961459Sroot { 975594Srrh reg char *cp = string; 981459Sroot 9910830Ssam if (cp) 1001459Sroot while (*cp){ 1011459Sroot if (*cp == chold){ 1021459Sroot *cp = chnew; 1031459Sroot break; 1041459Sroot } 1051459Sroot cp++; 1061459Sroot } 1071459Sroot return(string); 1081459Sroot } 1091459Sroot 1101459Sroot char lastchar(string) 1111459Sroot char *string; 1121459Sroot { 1131459Sroot int length; 11410830Ssam if (string == 0) return('\0'); 1151459Sroot length = strlen(string); 1161459Sroot if (length >= 1) 1171459Sroot return(string[length-1]); 1181459Sroot else 1191459Sroot return('\0'); 1201459Sroot } 1211459Sroot 1221459Sroot char firstchar(string) 1231459Sroot char *string; 1241459Sroot { 12510830Ssam if (string) 12610830Ssam return(string[0]); 12710830Ssam else 12810830Ssam return('\0'); 1291459Sroot } 1301459Sroot 1311459Sroot char next_lastchar(string) 1321459Sroot char *string; 1331459Sroot { 1341459Sroot int length; 13510830Ssam if (string == 0) return('\0'); 1361459Sroot length = strlen(string); 1371459Sroot if (length >= 2) 1381459Sroot return(string[length - 2]); 1391459Sroot else 1401459Sroot return('\0'); 1411459Sroot } 1421459Sroot 1431459Sroot clob_last(string, newstuff) 1441459Sroot char *string, newstuff; 1451459Sroot { 14610830Ssam int length = 0; 14710830Ssam if (string) 14810830Ssam length = strlen(string); 1491459Sroot if (length >= 1) 1501459Sroot string[length - 1] = newstuff; 1511459Sroot } 1521459Sroot 1531459Sroot /* 1541459Sroot * parse a string that is the result of a format %s(%d) 1551459Sroot * return TRUE if this is of the proper format 1561459Sroot */ 1571459Sroot boolean persperdexplode(string, r_perd, r_pers) 1581459Sroot char *string; 1591459Sroot char **r_perd, **r_pers; 1601459Sroot { 1615594Srrh reg char *cp; 16210830Ssam int length = 0; 1631459Sroot 16410830Ssam if (string) 16510830Ssam length = strlen(string); 1661459Sroot if ( (length >= 4) 1671459Sroot && (string[length - 1] == ')' ) ){ 1681459Sroot for (cp = &string[length - 2]; 1691459Sroot (isdigit(*cp)) && (*cp != '('); 1701459Sroot --cp) 1711459Sroot continue; 1721459Sroot if (*cp == '('){ 1731459Sroot string[length - 1] = '\0'; /* clobber the ) */ 1741459Sroot *r_perd = strsave(cp+1); 1751459Sroot string[length - 1] = ')'; 1761459Sroot *cp = '\0'; /* clobber the ( */ 1771459Sroot *r_pers = strsave(string); 1781459Sroot *cp = '('; 1791459Sroot return(TRUE); 1801459Sroot } 1811459Sroot } 1821459Sroot return(FALSE); 1831459Sroot } 1841459Sroot /* 1851459Sroot * parse a quoted string that is the result of a format \"%s\"(%d) 1861459Sroot * return TRUE if this is of the proper format 1871459Sroot */ 1881459Sroot boolean qpersperdexplode(string, r_perd, r_pers) 1891459Sroot char *string; 1901459Sroot char **r_perd, **r_pers; 1911459Sroot { 1925594Srrh reg char *cp; 19310830Ssam int length = 0; 1941459Sroot 19510830Ssam if (string) 19610830Ssam length = strlen(string); 1971459Sroot if ( (length >= 4) 1981459Sroot && (string[length - 1] == ')' ) ){ 1991459Sroot for (cp = &string[length - 2]; 2001459Sroot (isdigit(*cp)) && (*cp != '('); 2011459Sroot --cp) 2021459Sroot continue; 2031459Sroot if (*cp == '(' && *(cp - 1) == '"'){ 2041459Sroot string[length - 1] = '\0'; 2051459Sroot *r_perd = strsave(cp+1); 2061459Sroot string[length - 1] = ')'; 2071459Sroot *(cp - 1) = '\0'; /* clobber the " */ 2081459Sroot *r_pers = strsave(string + 1); 2091459Sroot *(cp - 1) = '"'; 2101459Sroot return(TRUE); 2111459Sroot } 2121459Sroot } 2131459Sroot return(FALSE); 2141459Sroot } 2151459Sroot 2161459Sroot static char cincomment[] = CINCOMMENT; 2171459Sroot static char coutcomment[] = COUTCOMMENT; 2181459Sroot static char fincomment[] = FINCOMMENT; 2191459Sroot static char foutcomment[] = FOUTCOMMENT; 2201459Sroot static char newline[] = NEWLINE; 2211459Sroot static char piincomment[] = PIINCOMMENT; 2221459Sroot static char pioutcomment[] = PIOUTCOMMENT; 2231459Sroot static char lispincomment[] = LISPINCOMMENT; 2241459Sroot static char riincomment[] = RIINCOMMENT; 2251459Sroot static char rioutcomment[] = RIOUTCOMMENT; 22613106Srrh static char troffincomment[] = TROFFINCOMMENT; 22713106Srrh static char troffoutcomment[] = TROFFOUTCOMMENT; 22817499Srrh static char mod2incomment[] = MOD2INCOMMENT; 22917499Srrh static char mod2outcomment[] = MOD2OUTCOMMENT; 2301459Sroot 2311459Sroot struct lang_desc lang_table[] = { 2321459Sroot /*INUNKNOWN 0*/ "unknown", cincomment, coutcomment, 2331459Sroot /*INCPP 1*/ "cpp", cincomment, coutcomment, 2341459Sroot /*INCC 2*/ "cc", cincomment, coutcomment, 2351459Sroot /*INAS 3*/ "as", ASINCOMMENT, newline, 2361459Sroot /*INLD 4*/ "ld", cincomment, coutcomment, 2371459Sroot /*INLINT 5*/ "lint", cincomment, coutcomment, 2381459Sroot /*INF77 6*/ "f77", fincomment, foutcomment, 2391459Sroot /*INPI 7*/ "pi", piincomment, pioutcomment, 2401459Sroot /*INPC 8*/ "pc", piincomment, pioutcomment, 2411459Sroot /*INFRANZ 9*/ "franz",lispincomment, newline, 2421459Sroot /*INLISP 10*/ "lisp", lispincomment, newline, 2431459Sroot /*INVAXIMA 11*/ "vaxima",lispincomment,newline, 2441459Sroot /*INRATFOR 12*/ "ratfor",fincomment, foutcomment, 2451459Sroot /*INLEX 13*/ "lex", cincomment, coutcomment, 2461459Sroot /*INYACC 14*/ "yacc", cincomment, coutcomment, 2471459Sroot /*INAPL 15*/ "apl", ".lm", newline, 2481459Sroot /*INMAKE 16*/ "make", ASINCOMMENT, newline, 2491459Sroot /*INRI 17*/ "ri", riincomment, rioutcomment, 25013106Srrh /*INTROFF 18*/ "troff",troffincomment,troffoutcomment, 25117499Srrh /*INMOD2 19*/ "mod2", mod2incomment, mod2outcomment, 2521459Sroot 0, 0, 0 2531459Sroot }; 2541459Sroot 2551459Sroot printerrors(look_at_subclass, errorc, errorv) 2561459Sroot boolean look_at_subclass; 2571459Sroot int errorc; 2585594Srrh Eptr errorv[]; 2591459Sroot { 2605594Srrh reg int i; 2615594Srrh reg Eptr errorp; 2625594Srrh 2631459Sroot for (errorp = errorv[i = 0]; i < errorc; errorp = errorv[++i]){ 2641459Sroot if (errorp->error_e_class == C_IGNORE) 2651459Sroot continue; 2661459Sroot if (look_at_subclass && errorp->error_s_class == C_DUPL) 2671459Sroot continue; 2681459Sroot printf("Error %d, (%s error) [%s], text = \"", 2691459Sroot i, 2701459Sroot class_table[errorp->error_e_class], 2711459Sroot lang_table[errorp->error_language].lang_name); 2721459Sroot wordvprint(stdout,errorp->error_lgtext,errorp->error_text); 2731459Sroot printf("\"\n"); 2741459Sroot } 2751459Sroot } 2761459Sroot 2771459Sroot wordvprint(fyle, wordc, wordv) 2781459Sroot FILE *fyle; 2791459Sroot int wordc; 2801459Sroot char *wordv[]; 2811459Sroot { 2821459Sroot int i; 28313539Ssam char *sep = ""; 28413539Ssam 28513539Ssam for(i = 0; i < wordc; i++) 28613539Ssam if (wordv[i]) { 28713539Ssam fprintf(fyle, "%s%s",sep,wordv[i]); 28813539Ssam sep = " "; 28913539Ssam } 2901459Sroot } 2911459Sroot 2921459Sroot /* 2931459Sroot * Given a string, parse it into a number of words, and build 2941459Sroot * a wordc wordv combination pointing into it. 2951459Sroot */ 2961459Sroot wordvbuild(string, r_wordc, r_wordv) 2971459Sroot char *string; 2981459Sroot int *r_wordc; 2991459Sroot char ***r_wordv; 3001459Sroot { 3015594Srrh reg char *cp; 3025594Srrh char *saltedbuffer; 3035594Srrh char **wordv; 3045594Srrh int wordcount; 3055594Srrh int wordindex; 3061459Sroot 3071459Sroot saltedbuffer = strsave(string); 3081459Sroot for (wordcount = 0, cp = saltedbuffer; *cp; wordcount++){ 3091459Sroot while (*cp && isspace(*cp)) 3101459Sroot cp++; 3111459Sroot if (*cp == 0) 3121459Sroot break; 3131459Sroot while (!isspace(*cp)) 3141459Sroot cp++; 3151459Sroot } 3161459Sroot wordv = (char **)Calloc(wordcount + 1, sizeof (char *)); 3171459Sroot for (cp=saltedbuffer,wordindex=0; wordcount; wordindex++,--wordcount){ 3181459Sroot while (*cp && isspace(*cp)) 3191459Sroot cp++; 3201459Sroot if (*cp == 0) 3211459Sroot break; 3221459Sroot wordv[wordindex] = cp; 3231459Sroot while(!isspace(*cp)) 3241459Sroot cp++; 3251459Sroot *cp++ = '\0'; 3261459Sroot } 3271459Sroot if (wordcount != 0) 3281459Sroot error("Initial miscount of the number of words in a line\n"); 3291459Sroot wordv[wordindex] = (char *)0; 3301459Sroot #ifdef FULLDEBUG 3311459Sroot for (wordcount = 0; wordcount < wordindex; wordcount++) 3321459Sroot printf("Word %d = \"%s\"\n", wordcount, wordv[wordcount]); 3331459Sroot printf("\n"); 3341459Sroot #endif 3351459Sroot *r_wordc = wordindex; 3361459Sroot *r_wordv = wordv; 3371459Sroot } 3381459Sroot /* 3391459Sroot * Compare two 0 based wordvectors 3401459Sroot */ 3411459Sroot int wordvcmp(wordv1, wordc, wordv2) 3421459Sroot char **wordv1; 3431459Sroot int wordc; 3441459Sroot char **wordv2; 3451459Sroot { 3465594Srrh reg int i; 3475594Srrh int back; 3481459Sroot for (i = 0; i < wordc; i++){ 34910830Ssam if (wordv1[i] == 0 || wordv2[i] == 0) 35010830Ssam return(-1); 3511459Sroot if (back = strcmp(wordv1[i], wordv2[i])){ 3521459Sroot return(back); 3531459Sroot } 3541459Sroot } 3551459Sroot return(0); /* they are equal */ 3561459Sroot } 3571459Sroot 3581459Sroot /* 3591459Sroot * splice a 0 basedword vector onto the tail of a 3601459Sroot * new wordv, allowing the first emptyhead slots to be empty 3611459Sroot */ 3621459Sroot char **wordvsplice(emptyhead, wordc, wordv) 3631459Sroot int emptyhead; 3641459Sroot int wordc; 3651459Sroot char **wordv; 3661459Sroot { 3675594Srrh reg char **nwordv; 3685594Srrh int nwordc = emptyhead + wordc; 3695594Srrh reg int i; 3701459Sroot 3711459Sroot nwordv = (char **)Calloc(nwordc, sizeof (char *)); 3721459Sroot for (i = 0; i < emptyhead; i++) 3731459Sroot nwordv[i] = 0; 3741459Sroot for(i = emptyhead; i < nwordc; i++){ 3751459Sroot nwordv[i] = wordv[i-emptyhead]; 3761459Sroot } 3771459Sroot return(nwordv); 3781459Sroot } 3795594Srrh /* 3805594Srrh * plural'ize and verb forms 3815594Srrh */ 3825594Srrh static char *S = "s"; 3835594Srrh static char *N = ""; 3845594Srrh char *plural(n) 3855594Srrh int n; 3865594Srrh { 3875594Srrh return( n > 1 ? S : N); 3885594Srrh } 3895594Srrh char *verbform(n) 3905594Srrh int n; 3915594Srrh { 3925594Srrh return( n > 1 ? N : S); 3935594Srrh } 3945594Srrh 395