Corrected msgs.c that it does function now, thanks to mte@hpy.fi.
[unix-history] / usr.bin / error / subr.c
CommitLineData
15637ed4
RG
1/*
2 * Copyright (c) 1980 Regents of the University of California.
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#ifndef lint
35static char sccsid[] = "@(#)subr.c 5.5 (Berkeley) 2/26/91";
36#endif /* not lint */
37
38#include <stdio.h>
39#include <ctype.h>
40#include <stdlib.h>
41#include <string.h>
42#include "error.h"
43/*
44 * Arrayify a list of rules
45 */
46arrayify(e_length, e_array, header)
47 int *e_length;
48 Eptr **e_array;
49 Eptr header;
50{
51 reg Eptr errorp;
52 reg Eptr *array;
53 reg int listlength;
54 reg int listindex;
55
56 for (errorp = header, listlength = 0;
57 errorp; errorp = errorp->error_next, listlength++)
58 continue;
59 array = (Eptr*)Calloc(listlength+1, sizeof (Eptr));
60 for(listindex = 0, errorp = header;
61 listindex < listlength;
62 listindex++, errorp = errorp->error_next){
63 array[listindex] = errorp;
64 errorp->error_position = listindex;
65 }
66 array[listindex] = (Eptr)0;
67 *e_length = listlength;
68 *e_array = array;
69}
70
71/*VARARGS1*/
72error(msg, a1, a2, a3)
73 char *msg;
74{
75 fprintf(stderr, "Error: ");
76 fprintf(stderr, msg, a1, a2, a3);
77 fprintf(stderr, "\n");
78 fflush(stdout);
79 fflush(stderr);
80 exit(6);
81}
82/*ARGSUSED*/
83char *Calloc(nelements, size)
84 int nelements;
85 int size;
86{
87 char *back;
88 if ( (back = (char *)calloc(nelements, size)) == (char *)NULL){
89 error("Ran out of memory.\n");
90 exit(1);
91 }
92 return(back);
93}
94
95char *strsave(instring)
96 char *instring;
97{
98 char *outstring;
99 (void)strcpy(outstring = (char *)Calloc(1, strlen(instring) + 1),
100 instring);
101 return(outstring);
102}
103/*
104 * find the position of a given character in a string
105 * (one based)
106 */
107int position(string, ch)
108 reg char *string;
109 reg char ch;
110{
111 reg int i;
112 if (string)
113 for (i=1; *string; string++, i++){
114 if (*string == ch)
115 return(i);
116 }
117 return(-1);
118}
119/*
120 * clobber the first occurance of ch in string by the new character
121 */
122char *substitute(string, chold, chnew)
123 char *string;
124 char chold, chnew;
125{
126 reg char *cp = string;
127
128 if (cp)
129 while (*cp){
130 if (*cp == chold){
131 *cp = chnew;
132 break;
133 }
134 cp++;
135 }
136 return(string);
137}
138
139char lastchar(string)
140 char *string;
141{
142 int length;
143 if (string == 0) return('\0');
144 length = strlen(string);
145 if (length >= 1)
146 return(string[length-1]);
147 else
148 return('\0');
149}
150
151char firstchar(string)
152 char *string;
153{
154 if (string)
155 return(string[0]);
156 else
157 return('\0');
158}
159
160char next_lastchar(string)
161 char *string;
162{
163 int length;
164 if (string == 0) return('\0');
165 length = strlen(string);
166 if (length >= 2)
167 return(string[length - 2]);
168 else
169 return('\0');
170}
171
172clob_last(string, newstuff)
173 char *string, newstuff;
174{
175 int length = 0;
176 if (string)
177 length = strlen(string);
178 if (length >= 1)
179 string[length - 1] = newstuff;
180}
181
182/*
183 * parse a string that is the result of a format %s(%d)
184 * return TRUE if this is of the proper format
185 */
186boolean persperdexplode(string, r_perd, r_pers)
187 char *string;
188 char **r_perd, **r_pers;
189{
190 reg char *cp;
191 int length = 0;
192
193 if (string)
194 length = strlen(string);
195 if ( (length >= 4)
196 && (string[length - 1] == ')' ) ){
197 for (cp = &string[length - 2];
198 (isdigit(*cp)) && (*cp != '(');
199 --cp)
200 continue;
201 if (*cp == '('){
202 string[length - 1] = '\0'; /* clobber the ) */
203 *r_perd = strsave(cp+1);
204 string[length - 1] = ')';
205 *cp = '\0'; /* clobber the ( */
206 *r_pers = strsave(string);
207 *cp = '(';
208 return(TRUE);
209 }
210 }
211 return(FALSE);
212}
213/*
214 * parse a quoted string that is the result of a format \"%s\"(%d)
215 * return TRUE if this is of the proper format
216 */
217boolean qpersperdexplode(string, r_perd, r_pers)
218 char *string;
219 char **r_perd, **r_pers;
220{
221 reg char *cp;
222 int length = 0;
223
224 if (string)
225 length = strlen(string);
226 if ( (length >= 4)
227 && (string[length - 1] == ')' ) ){
228 for (cp = &string[length - 2];
229 (isdigit(*cp)) && (*cp != '(');
230 --cp)
231 continue;
232 if (*cp == '(' && *(cp - 1) == '"'){
233 string[length - 1] = '\0';
234 *r_perd = strsave(cp+1);
235 string[length - 1] = ')';
236 *(cp - 1) = '\0'; /* clobber the " */
237 *r_pers = strsave(string + 1);
238 *(cp - 1) = '"';
239 return(TRUE);
240 }
241 }
242 return(FALSE);
243}
244
245static char cincomment[] = CINCOMMENT;
246static char coutcomment[] = COUTCOMMENT;
247static char fincomment[] = FINCOMMENT;
248static char foutcomment[] = FOUTCOMMENT;
249static char newline[] = NEWLINE;
250static char piincomment[] = PIINCOMMENT;
251static char pioutcomment[] = PIOUTCOMMENT;
252static char lispincomment[] = LISPINCOMMENT;
253static char riincomment[] = RIINCOMMENT;
254static char rioutcomment[] = RIOUTCOMMENT;
255static char troffincomment[] = TROFFINCOMMENT;
256static char troffoutcomment[] = TROFFOUTCOMMENT;
257static char mod2incomment[] = MOD2INCOMMENT;
258static char mod2outcomment[] = MOD2OUTCOMMENT;
259
260struct lang_desc lang_table[] = {
261 /*INUNKNOWN 0*/ "unknown", cincomment, coutcomment,
262 /*INCPP 1*/ "cpp", cincomment, coutcomment,
263 /*INCC 2*/ "cc", cincomment, coutcomment,
264 /*INAS 3*/ "as", ASINCOMMENT, newline,
265 /*INLD 4*/ "ld", cincomment, coutcomment,
266 /*INLINT 5*/ "lint", cincomment, coutcomment,
267 /*INF77 6*/ "f77", fincomment, foutcomment,
268 /*INPI 7*/ "pi", piincomment, pioutcomment,
269 /*INPC 8*/ "pc", piincomment, pioutcomment,
270 /*INFRANZ 9*/ "franz",lispincomment, newline,
271 /*INLISP 10*/ "lisp", lispincomment, newline,
272 /*INVAXIMA 11*/ "vaxima",lispincomment,newline,
273 /*INRATFOR 12*/ "ratfor",fincomment, foutcomment,
274 /*INLEX 13*/ "lex", cincomment, coutcomment,
275 /*INYACC 14*/ "yacc", cincomment, coutcomment,
276 /*INAPL 15*/ "apl", ".lm", newline,
277 /*INMAKE 16*/ "make", ASINCOMMENT, newline,
278 /*INRI 17*/ "ri", riincomment, rioutcomment,
279 /*INTROFF 18*/ "troff",troffincomment,troffoutcomment,
280 /*INMOD2 19*/ "mod2", mod2incomment, mod2outcomment,
281 0, 0, 0
282};
283
284printerrors(look_at_subclass, errorc, errorv)
285 boolean look_at_subclass;
286 int errorc;
287 Eptr errorv[];
288{
289 reg int i;
290 reg Eptr errorp;
291
292 for (errorp = errorv[i = 0]; i < errorc; errorp = errorv[++i]){
293 if (errorp->error_e_class == C_IGNORE)
294 continue;
295 if (look_at_subclass && errorp->error_s_class == C_DUPL)
296 continue;
297 printf("Error %d, (%s error) [%s], text = \"",
298 i,
299 class_table[errorp->error_e_class],
300 lang_table[errorp->error_language].lang_name);
301 wordvprint(stdout,errorp->error_lgtext,errorp->error_text);
302 printf("\"\n");
303 }
304}
305
306wordvprint(fyle, wordc, wordv)
307 FILE *fyle;
308 int wordc;
309 char *wordv[];
310{
311 int i;
312 char *sep = "";
313
314 for(i = 0; i < wordc; i++)
315 if (wordv[i]) {
316 fprintf(fyle, "%s%s",sep,wordv[i]);
317 sep = " ";
318 }
319}
320
321/*
322 * Given a string, parse it into a number of words, and build
323 * a wordc wordv combination pointing into it.
324 */
325wordvbuild(string, r_wordc, r_wordv)
326 char *string;
327 int *r_wordc;
328 char ***r_wordv;
329{
330 reg char *cp;
331 char *saltedbuffer;
332 char **wordv;
333 int wordcount;
334 int wordindex;
335
336 saltedbuffer = strsave(string);
337 for (wordcount = 0, cp = saltedbuffer; *cp; wordcount++){
338 while (*cp && isspace(*cp))
339 cp++;
340 if (*cp == 0)
341 break;
342 while (!isspace(*cp))
343 cp++;
344 }
345 wordv = (char **)Calloc(wordcount + 1, sizeof (char *));
346 for (cp=saltedbuffer,wordindex=0; wordcount; wordindex++,--wordcount){
347 while (*cp && isspace(*cp))
348 cp++;
349 if (*cp == 0)
350 break;
351 wordv[wordindex] = cp;
352 while(!isspace(*cp))
353 cp++;
354 *cp++ = '\0';
355 }
356 if (wordcount != 0)
357 error("Initial miscount of the number of words in a line\n");
358 wordv[wordindex] = (char *)0;
359#ifdef FULLDEBUG
360 for (wordcount = 0; wordcount < wordindex; wordcount++)
361 printf("Word %d = \"%s\"\n", wordcount, wordv[wordcount]);
362 printf("\n");
363#endif
364 *r_wordc = wordindex;
365 *r_wordv = wordv;
366}
367/*
368 * Compare two 0 based wordvectors
369 */
370int wordvcmp(wordv1, wordc, wordv2)
371 char **wordv1;
372 int wordc;
373 char **wordv2;
374{
375 reg int i;
376 int back;
377 for (i = 0; i < wordc; i++){
378 if (wordv1[i] == 0 || wordv2[i] == 0)
379 return(-1);
380 if (back = strcmp(wordv1[i], wordv2[i])){
381 return(back);
382 }
383 }
384 return(0); /* they are equal */
385}
386
387/*
388 * splice a 0 basedword vector onto the tail of a
389 * new wordv, allowing the first emptyhead slots to be empty
390 */
391char **wordvsplice(emptyhead, wordc, wordv)
392 int emptyhead;
393 int wordc;
394 char **wordv;
395{
396 reg char **nwordv;
397 int nwordc = emptyhead + wordc;
398 reg int i;
399
400 nwordv = (char **)Calloc(nwordc, sizeof (char *));
401 for (i = 0; i < emptyhead; i++)
402 nwordv[i] = 0;
403 for(i = emptyhead; i < nwordc; i++){
404 nwordv[i] = wordv[i-emptyhead];
405 }
406 return(nwordv);
407}
408/*
409 * plural'ize and verb forms
410 */
411static char *S = "s";
412static char *N = "";
413char *plural(n)
414 int n;
415{
416 return( n > 1 ? S : N);
417}
418char *verbform(n)
419 int n;
420{
421 return( n > 1 ? N : S);
422}
423