xref: /illumos-gate/usr/src/cmd/sgs/error/common/errorsubr.c (revision c686756220120076a07be0dcce54be698101a3d1)
17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate  * CDDL HEADER START
37c478bd9Sstevel@tonic-gate  *
47c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5d321a33cSab196087  * Common Development and Distribution License (the "License").
6d321a33cSab196087  * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate  *
87c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate  * and limitations under the License.
127c478bd9Sstevel@tonic-gate  *
137c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate  *
197c478bd9Sstevel@tonic-gate  * CDDL HEADER END
207c478bd9Sstevel@tonic-gate  */
219fb11590Smike_s 
229fb11590Smike_s /*
23d321a33cSab196087  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
249fb11590Smike_s  * Use is subject to license terms.
259fb11590Smike_s  */
267c478bd9Sstevel@tonic-gate 
277c478bd9Sstevel@tonic-gate #include <stdio.h>
287c478bd9Sstevel@tonic-gate #include <ctype.h>
299fb11590Smike_s #include <stdlib.h>
309fb11590Smike_s #include <unistd.h>
319fb11590Smike_s #include <stdarg.h>
329fb11590Smike_s #include <string.h>
337c478bd9Sstevel@tonic-gate #include "error.h"
349fb11590Smike_s 
357c478bd9Sstevel@tonic-gate /*
367c478bd9Sstevel@tonic-gate  *	Arrayify a list of rules
377c478bd9Sstevel@tonic-gate  */
389fb11590Smike_s void
arrayify(int * e_length,Eptr ** e_array,Eptr header)399fb11590Smike_s arrayify(int *e_length, Eptr **e_array, Eptr header)
407c478bd9Sstevel@tonic-gate {
419fb11590Smike_s 	Eptr	errorp;
429fb11590Smike_s 	Eptr	*array;
439fb11590Smike_s 	int	listlength;
449fb11590Smike_s 	int	listindex;
457c478bd9Sstevel@tonic-gate 
467c478bd9Sstevel@tonic-gate 	for (errorp = header, listlength = 0;
477c478bd9Sstevel@tonic-gate 	    errorp; errorp = errorp->error_next, listlength++)
487c478bd9Sstevel@tonic-gate 		continue;
499fb11590Smike_s 	array = Calloc(listlength+1, sizeof (Eptr));
507c478bd9Sstevel@tonic-gate 	for (listindex = 0, errorp = header;
517c478bd9Sstevel@tonic-gate 	    listindex < listlength;
527c478bd9Sstevel@tonic-gate 	    listindex++, errorp = errorp->error_next) {
537c478bd9Sstevel@tonic-gate 		array[listindex] = errorp;
547c478bd9Sstevel@tonic-gate 		errorp->error_position = listindex;
557c478bd9Sstevel@tonic-gate 	}
567c478bd9Sstevel@tonic-gate 	array[listindex] = (Eptr)0;
577c478bd9Sstevel@tonic-gate 	*e_length = listlength;
587c478bd9Sstevel@tonic-gate 	*e_array = array;
597c478bd9Sstevel@tonic-gate }
607c478bd9Sstevel@tonic-gate 
619fb11590Smike_s /*PRINTFLIKE1*/
629fb11590Smike_s static void
error(char * format,...)639fb11590Smike_s error(char *format, ...)
647c478bd9Sstevel@tonic-gate {
659fb11590Smike_s 	va_list	args;
669fb11590Smike_s 
679fb11590Smike_s 	va_start(args, format);
689fb11590Smike_s 	(void) fprintf(stderr, "Error: ");
699fb11590Smike_s 	(void) vfprintf(stderr, format, args);
709fb11590Smike_s 	(void) fprintf(stderr, "\n");
719fb11590Smike_s 	(void) fflush(stdout);
729fb11590Smike_s 	(void) fflush(stderr);
739fb11590Smike_s 	va_end(args);
747c478bd9Sstevel@tonic-gate 	exit(6);
757c478bd9Sstevel@tonic-gate }
769fb11590Smike_s 
779fb11590Smike_s void *
Calloc(int nelements,int size)789fb11590Smike_s Calloc(int nelements, int size)
797c478bd9Sstevel@tonic-gate {
809fb11590Smike_s 	void	*back;
819fb11590Smike_s 	if ((back = calloc(nelements, size)) == NULL) {
827c478bd9Sstevel@tonic-gate 		error("Ran out of memory.\n");
837c478bd9Sstevel@tonic-gate 		exit(1);
847c478bd9Sstevel@tonic-gate 	}
857c478bd9Sstevel@tonic-gate 	return (back);
867c478bd9Sstevel@tonic-gate }
877c478bd9Sstevel@tonic-gate 
889fb11590Smike_s char *
strsave(char * instring)899fb11590Smike_s strsave(char *instring)
907c478bd9Sstevel@tonic-gate {
917c478bd9Sstevel@tonic-gate 	char	*outstring;
929fb11590Smike_s 	(void) strcpy(outstring = Calloc(1, strlen(instring) + 1),
937c478bd9Sstevel@tonic-gate 	    instring);
947c478bd9Sstevel@tonic-gate 	return (outstring);
957c478bd9Sstevel@tonic-gate }
967c478bd9Sstevel@tonic-gate /*
977c478bd9Sstevel@tonic-gate  *	find the position of a given character in a string
987c478bd9Sstevel@tonic-gate  *		(one based)
997c478bd9Sstevel@tonic-gate  */
1009fb11590Smike_s int
position(char * string,char ch)1019fb11590Smike_s position(char *string, char ch)
1027c478bd9Sstevel@tonic-gate {
1039fb11590Smike_s 	int	i;
104*c6867562SToomas Soome 
105*c6867562SToomas Soome 	if (string) {
1067c478bd9Sstevel@tonic-gate 		for (i = 1; *string; string++, i++) {
1077c478bd9Sstevel@tonic-gate 			if (*string == ch)
1087c478bd9Sstevel@tonic-gate 				return (i);
1097c478bd9Sstevel@tonic-gate 		}
110*c6867562SToomas Soome 	}
1117c478bd9Sstevel@tonic-gate 	return (-1);
1127c478bd9Sstevel@tonic-gate }
1137c478bd9Sstevel@tonic-gate /*
1147c478bd9Sstevel@tonic-gate  *	clobber the first occurance of ch in string by the new character
1157c478bd9Sstevel@tonic-gate  */
1169fb11590Smike_s char *
substitute(char * string,char chold,char chnew)1179fb11590Smike_s substitute(char *string, char chold, char chnew)
1187c478bd9Sstevel@tonic-gate {
1199fb11590Smike_s 	char	*cp = string;
1207c478bd9Sstevel@tonic-gate 
121*c6867562SToomas Soome 	if (cp) {
1227c478bd9Sstevel@tonic-gate 		while (*cp) {
1237c478bd9Sstevel@tonic-gate 			if (*cp == chold) {
1247c478bd9Sstevel@tonic-gate 				*cp = chnew;
1257c478bd9Sstevel@tonic-gate 				break;
1267c478bd9Sstevel@tonic-gate 			}
1277c478bd9Sstevel@tonic-gate 			cp++;
1287c478bd9Sstevel@tonic-gate 		}
129*c6867562SToomas Soome 	}
1307c478bd9Sstevel@tonic-gate 	return (string);
1317c478bd9Sstevel@tonic-gate }
1327c478bd9Sstevel@tonic-gate 
1339fb11590Smike_s char
lastchar(char * string)1349fb11590Smike_s lastchar(char *string)
1357c478bd9Sstevel@tonic-gate {
1367c478bd9Sstevel@tonic-gate 	int	length;
1379fb11590Smike_s 
1389fb11590Smike_s 	if (string == NULL)
1399fb11590Smike_s 		return ('\0');
1407c478bd9Sstevel@tonic-gate 	length = strlen(string);
1417c478bd9Sstevel@tonic-gate 	if (length >= 1)
1427c478bd9Sstevel@tonic-gate 		return (string[length-1]);
1437c478bd9Sstevel@tonic-gate 	else
1447c478bd9Sstevel@tonic-gate 		return ('\0');
1457c478bd9Sstevel@tonic-gate }
1467c478bd9Sstevel@tonic-gate 
1479fb11590Smike_s char
firstchar(char * string)1489fb11590Smike_s firstchar(char *string)
1497c478bd9Sstevel@tonic-gate {
1507c478bd9Sstevel@tonic-gate 	if (string)
1517c478bd9Sstevel@tonic-gate 		return (string[0]);
1527c478bd9Sstevel@tonic-gate 	else
1537c478bd9Sstevel@tonic-gate 		return ('\0');
1547c478bd9Sstevel@tonic-gate }
1557c478bd9Sstevel@tonic-gate 
1569fb11590Smike_s char
next_lastchar(char * string)1579fb11590Smike_s next_lastchar(char *string)
1587c478bd9Sstevel@tonic-gate {
1597c478bd9Sstevel@tonic-gate 	int	length;
1609fb11590Smike_s 
1619fb11590Smike_s 	if (string == NULL)
1629fb11590Smike_s 		return ('\0');
1637c478bd9Sstevel@tonic-gate 	length = strlen(string);
1647c478bd9Sstevel@tonic-gate 	if (length >= 2)
1657c478bd9Sstevel@tonic-gate 		return (string[length - 2]);
1667c478bd9Sstevel@tonic-gate 	else
1677c478bd9Sstevel@tonic-gate 		return ('\0');
1687c478bd9Sstevel@tonic-gate }
1697c478bd9Sstevel@tonic-gate 
1709fb11590Smike_s void
clob_last(char * string,char newstuff)1719fb11590Smike_s clob_last(char *string, char newstuff)
1727c478bd9Sstevel@tonic-gate {
1737c478bd9Sstevel@tonic-gate 	int	length = 0;
1747c478bd9Sstevel@tonic-gate 	if (string)
1757c478bd9Sstevel@tonic-gate 		length = strlen(string);
1767c478bd9Sstevel@tonic-gate 	if (length >= 1)
1777c478bd9Sstevel@tonic-gate 		string[length - 1] = newstuff;
1787c478bd9Sstevel@tonic-gate }
1797c478bd9Sstevel@tonic-gate 
1807c478bd9Sstevel@tonic-gate /*
1817c478bd9Sstevel@tonic-gate  *	parse a string that is the result of a format %s(%d)
1827c478bd9Sstevel@tonic-gate  *	return TRUE if this is of the proper format
1837c478bd9Sstevel@tonic-gate  */
1849fb11590Smike_s boolean
persperdexplode(char * string,char ** r_perd,char ** r_pers)1859fb11590Smike_s persperdexplode(char *string, char **r_perd, char **r_pers)
1867c478bd9Sstevel@tonic-gate {
1879fb11590Smike_s 	char	*cp;
1887c478bd9Sstevel@tonic-gate 	int	length = 0;
1897c478bd9Sstevel@tonic-gate 
1907c478bd9Sstevel@tonic-gate 	if (string)
1917c478bd9Sstevel@tonic-gate 		length = strlen(string);
1929fb11590Smike_s 	if ((length >= 4) && (string[length - 1] == ')')) {
1937c478bd9Sstevel@tonic-gate 		for (cp = &string[length - 2];
1949fb11590Smike_s 		    (isdigit(*cp)) && (*cp != '('); --cp)
1957c478bd9Sstevel@tonic-gate 			continue;
1967c478bd9Sstevel@tonic-gate 		if (*cp == '(') {
1977c478bd9Sstevel@tonic-gate 			string[length - 1] = '\0';	/* clobber the ) */
1987c478bd9Sstevel@tonic-gate 			*r_perd = strsave(cp+1);
1997c478bd9Sstevel@tonic-gate 			string[length - 1] = ')';
2007c478bd9Sstevel@tonic-gate 			*cp = '\0';			/* clobber the ( */
2017c478bd9Sstevel@tonic-gate 			*r_pers = strsave(string);
2027c478bd9Sstevel@tonic-gate 			*cp = '(';
2037c478bd9Sstevel@tonic-gate 			return (TRUE);
2047c478bd9Sstevel@tonic-gate 		}
2057c478bd9Sstevel@tonic-gate 	}
2067c478bd9Sstevel@tonic-gate 	return (FALSE);
2077c478bd9Sstevel@tonic-gate }
2087c478bd9Sstevel@tonic-gate 
2097c478bd9Sstevel@tonic-gate static	char	cincomment[] = CINCOMMENT;
2107c478bd9Sstevel@tonic-gate static	char	coutcomment[] = COUTCOMMENT;
2117c478bd9Sstevel@tonic-gate static	char	fincomment[] = FINCOMMENT;
2127c478bd9Sstevel@tonic-gate static	char	foutcomment[] = FOUTCOMMENT;
2137c478bd9Sstevel@tonic-gate static	char	newline[] = NEWLINE;
2147c478bd9Sstevel@tonic-gate static	char	piincomment[] = PIINCOMMENT;
2157c478bd9Sstevel@tonic-gate static	char	pioutcomment[] = PIOUTCOMMENT;
2167c478bd9Sstevel@tonic-gate static	char	lispincomment[] = LISPINCOMMENT;
2177c478bd9Sstevel@tonic-gate static	char	riincomment[] = RIINCOMMENT;
2187c478bd9Sstevel@tonic-gate static	char	rioutcomment[] = RIOUTCOMMENT;
2197c478bd9Sstevel@tonic-gate static	char	troffincomment[] = TROFFINCOMMENT;
2207c478bd9Sstevel@tonic-gate static	char	troffoutcomment[] = TROFFOUTCOMMENT;
2217c478bd9Sstevel@tonic-gate static	char	mod2incomment[] = MOD2INCOMMENT;
2227c478bd9Sstevel@tonic-gate static	char	mod2outcomment[] = MOD2OUTCOMMENT;
2237c478bd9Sstevel@tonic-gate 
2247c478bd9Sstevel@tonic-gate struct lang_desc lang_table[] = {
2257c478bd9Sstevel@tonic-gate 	/* INUNKNOWN	0 */	"unknown", cincomment,	coutcomment,
2267c478bd9Sstevel@tonic-gate 	/* INCPP	1 */	"cpp",	cincomment,    coutcomment,
2277c478bd9Sstevel@tonic-gate 	/* INCC		2 */	"cc",	cincomment,    coutcomment,
2287c478bd9Sstevel@tonic-gate 	/* INAS		3 */	"as",	ASINCOMMENT,   newline,
2297c478bd9Sstevel@tonic-gate 	/* INLD		4 */	"ld",	cincomment,    coutcomment,
2307c478bd9Sstevel@tonic-gate 	/* INLINT	5 */	"lint",	cincomment,    coutcomment,
2317c478bd9Sstevel@tonic-gate 	/* INF77	6 */	"f77",	fincomment,    foutcomment,
2327c478bd9Sstevel@tonic-gate 	/* INPI		7 */	"pi",	piincomment,   pioutcomment,
2337c478bd9Sstevel@tonic-gate 	/* INPC		8 */	"pc",	piincomment,   pioutcomment,
2347c478bd9Sstevel@tonic-gate 	/* INFRANZ	9 */	"franz", lispincomment, newline,
2357c478bd9Sstevel@tonic-gate 	/* INLISP	10 */	"lisp",	lispincomment, newline,
2367c478bd9Sstevel@tonic-gate 	/* INVAXIMA	11 */	"vaxima", lispincomment, newline,
2377c478bd9Sstevel@tonic-gate 	/* INRATFOR	12 */	"ratfor", fincomment,   foutcomment,
2387c478bd9Sstevel@tonic-gate 	/* INLEX	13 */	"lex",	cincomment,    coutcomment,
2397c478bd9Sstevel@tonic-gate 	/* INYACC	14 */	"yacc",	cincomment,    coutcomment,
2407c478bd9Sstevel@tonic-gate 	/* INAPL	15 */	"apl",	".lm", newline,
2417c478bd9Sstevel@tonic-gate 	/* INMAKE	16 */	"make",	ASINCOMMENT,   newline,
2427c478bd9Sstevel@tonic-gate 	/* INRI		17 */	"ri",	riincomment,   rioutcomment,
2437c478bd9Sstevel@tonic-gate 	/* INTROFF	18 */	"troff", troffincomment, troffoutcomment,
2447c478bd9Sstevel@tonic-gate 	/* INMOD2	19 */	"mod2",	mod2incomment, mod2outcomment,
2457c478bd9Sstevel@tonic-gate 	/* INSUNF77	20 */	"Sunf77", fincomment,   foutcomment,
2467c478bd9Sstevel@tonic-gate 	0,	0,	0
2477c478bd9Sstevel@tonic-gate };
2487c478bd9Sstevel@tonic-gate 
2499fb11590Smike_s void
printerrors(boolean look_at_subclass,int errorc,Eptr errorv[])2509fb11590Smike_s printerrors(boolean look_at_subclass, int errorc, Eptr errorv[])
2517c478bd9Sstevel@tonic-gate {
2529fb11590Smike_s 	int	i;
2539fb11590Smike_s 	Eptr	errorp;
2547c478bd9Sstevel@tonic-gate 
2557c478bd9Sstevel@tonic-gate 	for (errorp = errorv[i = 0]; i < errorc; errorp = errorv[++i]) {
2567c478bd9Sstevel@tonic-gate 		if (errorp->error_e_class == C_IGNORE)
2577c478bd9Sstevel@tonic-gate 			continue;
2587c478bd9Sstevel@tonic-gate 		if (look_at_subclass && errorp->error_s_class == C_DUPL)
2597c478bd9Sstevel@tonic-gate 			continue;
2609fb11590Smike_s 		(void) printf("Error %d, (%s error) [%s], text = \"",
2617c478bd9Sstevel@tonic-gate 		    i,
2627c478bd9Sstevel@tonic-gate 		    class_table[errorp->error_e_class],
2637c478bd9Sstevel@tonic-gate 		    lang_table[errorp->error_language].lang_name);
2647c478bd9Sstevel@tonic-gate 		wordvprint(stdout, errorp->error_lgtext, errorp->error_text);
2659fb11590Smike_s 		(void) printf("\"\n");
2667c478bd9Sstevel@tonic-gate 	}
2677c478bd9Sstevel@tonic-gate }
2687c478bd9Sstevel@tonic-gate 
2699fb11590Smike_s void
wordvprint(FILE * fyle,int wordc,char * wordv[])2709fb11590Smike_s wordvprint(FILE *fyle, int wordc, char *wordv[])
2717c478bd9Sstevel@tonic-gate {
2727c478bd9Sstevel@tonic-gate 	int	i;
2737c478bd9Sstevel@tonic-gate 	char *sep = "";
2747c478bd9Sstevel@tonic-gate 
2757c478bd9Sstevel@tonic-gate 	for (i = 0; i < wordc; i++)
2767c478bd9Sstevel@tonic-gate 		if (wordv[i]) {
2779fb11590Smike_s 			(void) fprintf(fyle, "%s%s", sep, wordv[i]);
2787c478bd9Sstevel@tonic-gate 			sep = " ";
2797c478bd9Sstevel@tonic-gate 		}
2807c478bd9Sstevel@tonic-gate }
2817c478bd9Sstevel@tonic-gate 
2827c478bd9Sstevel@tonic-gate /*
2837c478bd9Sstevel@tonic-gate  *	Given a string, parse it into a number of words, and build
2847c478bd9Sstevel@tonic-gate  *	a wordc wordv combination pointing into it.
2857c478bd9Sstevel@tonic-gate  */
2869fb11590Smike_s void
wordvbuild(char * string,int * r_wordc,char *** r_wordv)2879fb11590Smike_s wordvbuild(char *string, int *r_wordc, char ***r_wordv)
2887c478bd9Sstevel@tonic-gate {
2899fb11590Smike_s 	char	*cp;
2907c478bd9Sstevel@tonic-gate 	char	*saltedbuffer;
2917c478bd9Sstevel@tonic-gate 	char	**wordv;
2927c478bd9Sstevel@tonic-gate 	int	wordcount;
2937c478bd9Sstevel@tonic-gate 	int	wordindex;
2947c478bd9Sstevel@tonic-gate 
2957c478bd9Sstevel@tonic-gate 	saltedbuffer = strsave(string);
2967c478bd9Sstevel@tonic-gate 	for (wordcount = 0, cp = saltedbuffer; *cp; wordcount++) {
2977c478bd9Sstevel@tonic-gate 		while (*cp && isspace(*cp))
2987c478bd9Sstevel@tonic-gate 			cp++;
299968633adSMatthew Jacob 		if (*cp == 0)
300968633adSMatthew Jacob 			break;
301d321a33cSab196087 		while (*cp && !isspace(*cp))
3027c478bd9Sstevel@tonic-gate 			cp++;
3037c478bd9Sstevel@tonic-gate 	}
3049fb11590Smike_s 	wordv = Calloc(wordcount + 1, sizeof (char *));
3059fb11590Smike_s 	for (cp = saltedbuffer, wordindex = 0; wordcount;
3069fb11590Smike_s 	    wordindex++, --wordcount) {
3077c478bd9Sstevel@tonic-gate 		while (*cp && isspace(*cp))
3087c478bd9Sstevel@tonic-gate 			cp++;
3097c478bd9Sstevel@tonic-gate 		if (*cp == 0)
3107c478bd9Sstevel@tonic-gate 			break;
3117c478bd9Sstevel@tonic-gate 		wordv[wordindex] = cp;
312d321a33cSab196087 		while (*cp && !isspace(*cp))
3137c478bd9Sstevel@tonic-gate 			cp++;
3147c478bd9Sstevel@tonic-gate 		*cp++ = '\0';
3157c478bd9Sstevel@tonic-gate 	}
3167c478bd9Sstevel@tonic-gate 	if (wordcount != 0)
3177c478bd9Sstevel@tonic-gate 		error("Initial miscount of the number of words in a line\n");
3189fb11590Smike_s 	wordv[wordindex] = NULL;
3197c478bd9Sstevel@tonic-gate #ifdef FULLDEBUG
3207c478bd9Sstevel@tonic-gate 	for (wordcount = 0; wordcount < wordindex; wordcount++)
3219fb11590Smike_s 		(void) printf("Word %d = \"%s\"\n", wordcount,
3229fb11590Smike_s 		    wordv[wordcount]);
3239fb11590Smike_s 	(void) printf("\n");
3247c478bd9Sstevel@tonic-gate #endif
3257c478bd9Sstevel@tonic-gate 	*r_wordc = wordindex;
3267c478bd9Sstevel@tonic-gate 	*r_wordv = wordv;
3277c478bd9Sstevel@tonic-gate }
3287c478bd9Sstevel@tonic-gate /*
3297c478bd9Sstevel@tonic-gate  *	Compare two 0 based wordvectors
3307c478bd9Sstevel@tonic-gate  */
3319fb11590Smike_s int
wordvcmp(char ** wordv1,int wordc,char ** wordv2)3329fb11590Smike_s wordvcmp(char **wordv1, int wordc, char **wordv2)
3337c478bd9Sstevel@tonic-gate {
3349fb11590Smike_s 	int i;
3357c478bd9Sstevel@tonic-gate 	int	back;
3369fb11590Smike_s 
3377c478bd9Sstevel@tonic-gate 	for (i = 0; i < wordc; i++) {
3387c478bd9Sstevel@tonic-gate 		if (wordv1[i] == 0 || wordv2[i] == 0)
3397c478bd9Sstevel@tonic-gate 				return (-1);
3407c478bd9Sstevel@tonic-gate 		if (back = strcmp(wordv1[i], wordv2[i])) {
3417c478bd9Sstevel@tonic-gate 			return (back);
3427c478bd9Sstevel@tonic-gate 		}
3437c478bd9Sstevel@tonic-gate 	}
3447c478bd9Sstevel@tonic-gate 	return (0);	/* they are equal */
3457c478bd9Sstevel@tonic-gate }
3467c478bd9Sstevel@tonic-gate 
3477c478bd9Sstevel@tonic-gate /*
3487c478bd9Sstevel@tonic-gate  *	splice a 0 basedword vector onto the tail of a
3497c478bd9Sstevel@tonic-gate  *	new wordv, allowing the first emptyhead slots to be empty
3507c478bd9Sstevel@tonic-gate  */
3519fb11590Smike_s char **
wordvsplice(int emptyhead,int wordc,char ** wordv)3529fb11590Smike_s wordvsplice(int emptyhead, int wordc, char **wordv)
3537c478bd9Sstevel@tonic-gate {
3549fb11590Smike_s 	char	**nwordv;
3557c478bd9Sstevel@tonic-gate 	int	nwordc = emptyhead + wordc;
3569fb11590Smike_s 	int	i;
3577c478bd9Sstevel@tonic-gate 
3589fb11590Smike_s 	nwordv = Calloc(nwordc, sizeof (char *));
3597c478bd9Sstevel@tonic-gate 	for (i = 0; i < emptyhead; i++)
3607c478bd9Sstevel@tonic-gate 		nwordv[i] = 0;
3617c478bd9Sstevel@tonic-gate 	for (i = emptyhead; i < nwordc; i++) {
3627c478bd9Sstevel@tonic-gate 		nwordv[i] = wordv[i-emptyhead];
3637c478bd9Sstevel@tonic-gate 	}
3647c478bd9Sstevel@tonic-gate 	return (nwordv);
3657c478bd9Sstevel@tonic-gate }
3669fb11590Smike_s 
3677c478bd9Sstevel@tonic-gate /*
3687c478bd9Sstevel@tonic-gate  *	plural'ize and verb forms
3697c478bd9Sstevel@tonic-gate  */
3707c478bd9Sstevel@tonic-gate static	char	*S = "s";
3717c478bd9Sstevel@tonic-gate static	char	*N = "";
3729fb11590Smike_s 
3739fb11590Smike_s char *
plural(int n)3749fb11590Smike_s plural(int n)
3757c478bd9Sstevel@tonic-gate {
3767c478bd9Sstevel@tonic-gate 	return (n > 1 ? S : N);
3777c478bd9Sstevel@tonic-gate }
3789fb11590Smike_s 
3799fb11590Smike_s char *
verbform(int n)3809fb11590Smike_s verbform(int n)
3817c478bd9Sstevel@tonic-gate {
3827c478bd9Sstevel@tonic-gate 	return (n > 1 ? N : S);
3837c478bd9Sstevel@tonic-gate }
384