sh.err.c revision 167465
1219820Sjeff/* $Header: /p/tcsh/cvsroot/tcsh/sh.err.c,v 3.48 2006/03/02 18:46:44 christos Exp $ */
2230135Suqs/*
3219820Sjeff * sh.err.c: Error printing routines.
4219820Sjeff */
5219820Sjeff/*-
6219820Sjeff * Copyright (c) 1980, 1991 The Regents of the University of California.
7219820Sjeff * All rights reserved.
8219820Sjeff *
9219820Sjeff * Redistribution and use in source and binary forms, with or without
10219820Sjeff * modification, are permitted provided that the following conditions
11219820Sjeff * are met:
12219820Sjeff * 1. Redistributions of source code must retain the above copyright
13219820Sjeff *    notice, this list of conditions and the following disclaimer.
14219820Sjeff * 2. Redistributions in binary form must reproduce the above copyright
15219820Sjeff *    notice, this list of conditions and the following disclaimer in the
16219820Sjeff *    documentation and/or other materials provided with the distribution.
17219820Sjeff * 3. Neither the name of the University nor the names of its contributors
18219820Sjeff *    may be used to endorse or promote products derived from this software
19219820Sjeff *    without specific prior written permission.
20219820Sjeff *
21219820Sjeff * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22219820Sjeff * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23219820Sjeff * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24219820Sjeff * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25219820Sjeff * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26219820Sjeff * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27219820Sjeff * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28219820Sjeff * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29219820Sjeff * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30219820Sjeff * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31219820Sjeff * SUCH DAMAGE.
32219820Sjeff */
33219820Sjeff#define _h_sh_err		/* Don't redefine the errors	 */
34219820Sjeff#include "sh.h"
35219820Sjeff#include <assert.h>
36219820Sjeff
37219820SjeffRCSID("$tcsh: sh.err.c,v 3.48 2006/03/02 18:46:44 christos Exp $")
38219820Sjeff
39219820Sjeff/*
40219820Sjeff * C Shell
41219820Sjeff */
42219820Sjeff
43219820Sjeff#ifdef lint
44219820Sjeff#undef va_arg
45219820Sjeff#define va_arg(a, b) (a ? (b) 0 : (b) 0)
46219820Sjeff#endif
47219820Sjeff
48219820Sjeffchar   *seterr = NULL;	/* Holds last error if there was one */
49219820Sjeff
50219820Sjeff#define ERR_FLAGS	0xf0000000
51219820Sjeff#define ERR_NAME	0x10000000
52219820Sjeff#define ERR_SILENT	0x20000000
53219820Sjeff#define ERR_OLD		0x40000000
54219820Sjeff
55219820Sjeff#define ERR_SYNTAX	0
56219820Sjeff#define ERR_NOTALLOWED	1
57219820Sjeff#define ERR_WTOOLONG	2
58219820Sjeff#define ERR_LTOOLONG	3
59219820Sjeff#define ERR_DOLZERO	4
60219820Sjeff#define ERR_INCBR	5
61219820Sjeff#define ERR_EXPORD	6
62219820Sjeff#define ERR_BADMOD	7
63219820Sjeff#define ERR_SUBSCRIPT	8
64219820Sjeff#define ERR_BADNUM	9
65219820Sjeff#define ERR_NOMORE	10
66219820Sjeff#define ERR_FILENAME	11
67219820Sjeff#define ERR_GLOB	12
68219820Sjeff#define ERR_COMMAND	13
69219820Sjeff#define ERR_TOOFEW	14
70219820Sjeff#define ERR_TOOMANY	15
71219820Sjeff#define ERR_DANGER	16
72219820Sjeff#define ERR_EMPTYIF	17
73219820Sjeff#define ERR_IMPRTHEN	18
74219820Sjeff#define ERR_NOPAREN	19
75219820Sjeff#define ERR_NOTFOUND	20
76219820Sjeff#define ERR_MASK	21
77219820Sjeff#define ERR_LIMIT	22
78219820Sjeff#define ERR_TOOLARGE	23
79219820Sjeff#define ERR_SCALEF	24
80219820Sjeff#define ERR_UNDVAR	25
81219820Sjeff#define ERR_DEEP	26
82219820Sjeff#define ERR_BADSIG	27
83219820Sjeff#define ERR_UNKSIG	28
84219820Sjeff#define ERR_VARBEGIN	29
85219820Sjeff#define ERR_VARTOOLONG	30
86219820Sjeff#define ERR_VARALNUM	31
87219820Sjeff#define ERR_JOBCONTROL	32
88219820Sjeff#define ERR_EXPRESSION	33
89219820Sjeff#define ERR_NOHOMEDIR	34
90219820Sjeff#define ERR_CANTCHANGE	35
91219820Sjeff#define ERR_NULLCOM	36
92219820Sjeff#define ERR_ASSIGN	37
93219820Sjeff#define ERR_UNKNOWNOP	38
94219820Sjeff#define ERR_AMBIG	39
95219820Sjeff#define ERR_EXISTS	40
96219820Sjeff#define ERR_ARGC	41
97219820Sjeff#define ERR_INTR	42
98219820Sjeff#define ERR_RANGE	43
99219820Sjeff#define ERR_OVERFLOW	44
100219820Sjeff#define ERR_NOSUCHJOB	45
101219820Sjeff#define ERR_TERMINAL	46
102219820Sjeff#define ERR_NOTWHILE	47
103219820Sjeff#define ERR_NOPROC	48
104219820Sjeff#define ERR_NOMATCH	49
105219820Sjeff#define ERR_MISSING	50
106219820Sjeff#define ERR_UNMATCHED	51
107219820Sjeff#define ERR_NOMEM	52
108219820Sjeff#define ERR_PIPE	53
109219820Sjeff#define ERR_SYSTEM	54
110219820Sjeff#define ERR_STRING	55
111219820Sjeff#define ERR_JOBS	56
112219820Sjeff#define ERR_JOBARGS	57
113219820Sjeff#define ERR_JOBCUR	58
114219820Sjeff#define ERR_JOBPREV	59
115219820Sjeff#define ERR_JOBPAT	60
116219820Sjeff#define ERR_NESTING	61
117219820Sjeff#define ERR_JOBCTRLSUB	62
118219820Sjeff#define ERR_SYNC	63
119219820Sjeff#define ERR_STOPPED	64
120219820Sjeff#define ERR_NODIR	65
121219820Sjeff#define ERR_EMPTY	66
122219820Sjeff#define ERR_BADDIR	67
123219820Sjeff#define ERR_DIRUS	68
124219820Sjeff#define ERR_HFLAG	69
125219820Sjeff#define ERR_NOTLOGIN	70
126219820Sjeff#define ERR_DIV0	71
127219820Sjeff#define ERR_MOD0	72
128219820Sjeff#define ERR_BADSCALE	73
129219820Sjeff#define ERR_SUSPLOG	74
130219820Sjeff#define ERR_UNKUSER	75
131219820Sjeff#define ERR_NOHOME	76
132219820Sjeff#define ERR_HISTUS	77
133219820Sjeff#define ERR_SPDOLLT	78
134219820Sjeff#define ERR_NEWLINE	79
135219820Sjeff#define ERR_SPSTAR	80
136219820Sjeff#define ERR_DIGIT	81
137219820Sjeff#define ERR_VARILL	82
138219820Sjeff#define ERR_NLINDEX	83
139219820Sjeff#define ERR_EXPOVFL	84
140219820Sjeff#define ERR_VARSYN	85
141219820Sjeff#define ERR_BADBANG	86
142219820Sjeff#define ERR_NOSUBST	87
143219820Sjeff#define ERR_BADSUBST	88
144219820Sjeff#define ERR_LHS		89
145219820Sjeff#define ERR_RHSLONG	90
146219820Sjeff#define ERR_BADBANGMOD	91
147219820Sjeff#define ERR_MODFAIL	92
148219820Sjeff#define ERR_SUBOVFL	93
149219820Sjeff#define ERR_BADBANGARG	94
150219820Sjeff#define ERR_NOSEARCH	95
151219820Sjeff#define ERR_NOEVENT	96
152219820Sjeff#define ERR_TOOMANYRP	97
153219820Sjeff#define ERR_TOOMANYLP	98
154219820Sjeff#define ERR_BADPLP	99
155219820Sjeff#define ERR_MISRED	100
156219820Sjeff#define ERR_OUTRED	101
157219820Sjeff#define ERR_REDPAR	102
158219820Sjeff#define ERR_INRED	103
159219820Sjeff#define ERR_BADPLPS	104
160219820Sjeff#define ERR_ALIASLOOP	105
161219820Sjeff#define ERR_NOWATCH	106
162219820Sjeff#define ERR_NOSCHED	107
163219820Sjeff#define ERR_SCHEDUSAGE	108
164219820Sjeff#define ERR_SCHEDEV	109
165219820Sjeff#define ERR_SCHEDCOM	110
166219820Sjeff#define ERR_SCHEDTIME	111
167219820Sjeff#define ERR_SCHEDREL	112
168219820Sjeff#define ERR_TCNOSTR	113
169219820Sjeff#define ERR_SETTCUS	114
170219820Sjeff#define ERR_TCCAP	115
171219820Sjeff#define ERR_TCPARM	116
172219820Sjeff#define ERR_TCARGS	117
173219820Sjeff#define ERR_TCNARGS	118
174219820Sjeff#define ERR_TCUSAGE	119
175219820Sjeff#define ERR_ARCH	120
176219820Sjeff#define ERR_HISTLOOP	121
177219820Sjeff#define ERR_FILEINQ	122
178219820Sjeff#define ERR_SELOVFL	123
179219820Sjeff#define ERR_TCSHUSAGE   124
180219820Sjeff#define ERR_COMPCOM	125
181219820Sjeff#define ERR_COMPINV	126
182219820Sjeff#define ERR_COMPMIS	127
183219820Sjeff#define ERR_COMPINC	128
184219820Sjeff#define ERR_MFLAG	129
185219820Sjeff#define ERR_ULIMUS	130
186219820Sjeff#define ERR_READONLY	131
187219820Sjeff#define ERR_BADJOB	132
188219820Sjeff#define ERR_INVALID	133
189219820Sjeff#define ERR_BADCOLORVAR	134
190219820Sjeff#define NO_ERRORS	135
191219820Sjeff
192219820Sjeffstatic const char *elst[NO_ERRORS] INIT_ZERO_STRUCT;
193219820Sjeff
194219820Sjeff/*
195219820Sjeff * Init the elst depending on the locale
196219820Sjeff */
197219820Sjeffvoid
198219820Sjefferrinit(void)
199219820Sjeff{
200219820Sjeff#ifdef NLS_CATALOGS
201219820Sjeff    size_t i;
202219820Sjeff
203219820Sjeff    for (i = 0; i < NO_ERRORS; i++)
204219820Sjeff	xfree((char *)(intptr_t)elst[i]);
205219820Sjeff#  if defined(__FreeBSD__) || defined(hpux)
206219820Sjeff#  define NLS_MAXSET 30
207219820Sjeff    for (i = 1; i <= NLS_MAXSET; i++)
208219820Sjeff	CGETS(i, 1, "" );
209219820Sjeff#  endif
210219820Sjeff#endif
211219820Sjeff
212219820Sjeff    elst[ERR_SYNTAX] = CSAVS(1, 1, "Syntax Error");
213219820Sjeff    elst[ERR_NOTALLOWED] = CSAVS(1, 2, "%s is not allowed");
214219820Sjeff    elst[ERR_WTOOLONG] = CSAVS(1, 3, "Word too long");
215219820Sjeff    elst[ERR_LTOOLONG] = CSAVS(1, 4, "$< line too long");
216219820Sjeff    elst[ERR_DOLZERO] = CSAVS(1, 5, "No file for $0");
217219820Sjeff    elst[ERR_INCBR] = CSAVS(1, 6, "Incomplete [] modifier");
218219820Sjeff    elst[ERR_EXPORD] = CSAVS(1, 7, "$ expansion must end before ]");
219219820Sjeff    elst[ERR_BADMOD] = CSAVS(1, 8, "Bad : modifier in $ (%c)");
220219820Sjeff    elst[ERR_SUBSCRIPT] = CSAVS(1, 9, "Subscript error");
221219820Sjeff    elst[ERR_BADNUM] = CSAVS(1, 10, "Badly formed number");
222219820Sjeff    elst[ERR_NOMORE] = CSAVS(1, 11, "No more words");
223219820Sjeff    elst[ERR_FILENAME] = CSAVS(1, 12, "Missing file name");
224219820Sjeff    elst[ERR_GLOB] = CSAVS(1, 13, "Internal glob error");
225219820Sjeff    elst[ERR_COMMAND] = CSAVS(1, 14, "Command not found");
226219820Sjeff    elst[ERR_TOOFEW] = CSAVS(1, 15, "Too few arguments");
227219820Sjeff    elst[ERR_TOOMANY] = CSAVS(1, 16, "Too many arguments");
228219820Sjeff    elst[ERR_DANGER] = CSAVS(1, 17, "Too dangerous to alias that");
229219820Sjeff    elst[ERR_EMPTYIF] = CSAVS(1, 18, "Empty if");
230219820Sjeff    elst[ERR_IMPRTHEN] = CSAVS(1, 19, "Improper then");
231219820Sjeff    elst[ERR_NOPAREN] = CSAVS(1, 20, "Words not parenthesized");
232219820Sjeff    elst[ERR_NOTFOUND] = CSAVS(1, 21, "%s not found");
233219820Sjeff    elst[ERR_MASK] = CSAVS(1, 22, "Improper mask");
234219820Sjeff    elst[ERR_LIMIT] = CSAVS(1, 23, "No such limit");
235219820Sjeff    elst[ERR_TOOLARGE] = CSAVS(1, 24, "Argument too large");
236219820Sjeff    elst[ERR_SCALEF] = CSAVS(1, 25, "Improper or unknown scale factor");
237219820Sjeff    elst[ERR_UNDVAR] = CSAVS(1, 26, "Undefined variable");
238219820Sjeff    elst[ERR_DEEP] = CSAVS(1, 27, "Directory stack not that deep");
239219820Sjeff    elst[ERR_BADSIG] = CSAVS(1, 28, "Bad signal number");
240219820Sjeff    elst[ERR_UNKSIG] = CSAVS(1, 29, "Unknown signal; kill -l lists signals");
241219820Sjeff    elst[ERR_VARBEGIN] = CSAVS(1, 30, "Variable name must begin with a letter");
242219820Sjeff    elst[ERR_VARTOOLONG] = CSAVS(1, 31, "Variable name too long");
243219820Sjeff    elst[ERR_VARALNUM] = CSAVS(1, 32,
244219820Sjeff	"Variable name must contain alphanumeric characters");
245219820Sjeff    elst[ERR_JOBCONTROL] = CSAVS(1, 33, "No job control in this shell");
246219820Sjeff    elst[ERR_EXPRESSION] = CSAVS(1, 34, "Expression Syntax");
247219820Sjeff    elst[ERR_NOHOMEDIR] = CSAVS(1, 35, "No home directory");
248219820Sjeff    elst[ERR_CANTCHANGE] = CSAVS(1, 36, "Can't change to home directory");
249219820Sjeff    elst[ERR_NULLCOM] = CSAVS(1, 37, "Invalid null command");
250219820Sjeff    elst[ERR_ASSIGN] = CSAVS(1, 38, "Assignment missing expression");
251219820Sjeff    elst[ERR_UNKNOWNOP] = CSAVS(1, 39, "Unknown operator");
252219820Sjeff    elst[ERR_AMBIG] = CSAVS(1, 40, "Ambiguous");
253219820Sjeff    elst[ERR_EXISTS] = CSAVS(1, 41, "%s: File exists");
254219820Sjeff    elst[ERR_ARGC] = CSAVS(1, 42, "Argument for -c ends in backslash");
255219820Sjeff    elst[ERR_INTR] = CSAVS(1, 43, "Interrupted");
256219820Sjeff    elst[ERR_RANGE] = CSAVS(1, 44, "Subscript out of range");
257219820Sjeff    elst[ERR_OVERFLOW] = CSAVS(1, 45, "Line overflow");
258219820Sjeff    elst[ERR_NOSUCHJOB] = CSAVS(1, 46, "No such job");
259219820Sjeff    elst[ERR_TERMINAL] = CSAVS(1, 47, "Can't from terminal");
260219820Sjeff    elst[ERR_NOTWHILE] = CSAVS(1, 48, "Not in while/foreach");
261219820Sjeff    elst[ERR_NOPROC] = CSAVS(1, 49, "No more processes");
262219820Sjeff    elst[ERR_NOMATCH] = CSAVS(1, 50, "No match");
263219820Sjeff    elst[ERR_MISSING] = CSAVS(1, 51, "Missing %c");
264219820Sjeff    elst[ERR_UNMATCHED] = CSAVS(1, 52, "Unmatched %c");
265219820Sjeff    elst[ERR_NOMEM] = CSAVS(1, 53, "Out of memory");
266219820Sjeff    elst[ERR_PIPE] = CSAVS(1, 54, "Can't make pipe");
267219820Sjeff    elst[ERR_SYSTEM] = CSAVS(1, 55, "%s: %s");
268219820Sjeff    elst[ERR_STRING] = CSAVS(1, 56, "%s");
269219820Sjeff    elst[ERR_JOBS] = CSAVS(1, 57, "Usage: jobs [ -l ]");
270219820Sjeff    elst[ERR_JOBARGS] = CSAVS(1, 58, "Arguments should be jobs or process id's");
271219820Sjeff    elst[ERR_JOBCUR] = CSAVS(1, 59, "No current job");
272219820Sjeff    elst[ERR_JOBPREV] = CSAVS(1, 60, "No previous job");
273219820Sjeff    elst[ERR_JOBPAT] = CSAVS(1, 61, "No job matches pattern");
274219820Sjeff    elst[ERR_NESTING] = CSAVS(1, 62, "Fork nesting > %d; maybe `...` loop");
275219820Sjeff    elst[ERR_JOBCTRLSUB] = CSAVS(1, 63, "No job control in subshells");
276219820Sjeff    elst[ERR_SYNC] = CSAVS(1, 64, "Sync fault: Process %d not found");
277219820Sjeff    elst[ERR_STOPPED] =
278219820Sjeff#ifdef SUSPENDED
279219820Sjeff	CSAVS(1, 65, "%sThere are suspended jobs");
280219820Sjeff#else
281219820Sjeff	CSAVS(1, 66, "%sThere are stopped jobs");
282219820Sjeff#endif /* SUSPENDED */
283219820Sjeff    elst[ERR_NODIR] = CSAVS(1, 67, "No other directory");
284219820Sjeff    elst[ERR_EMPTY] = CSAVS(1, 68, "Directory stack empty");
285219820Sjeff    elst[ERR_BADDIR] = CSAVS(1, 69, "Bad directory");
286219820Sjeff    elst[ERR_DIRUS] = CSAVS(1, 70, "Usage: %s [-%s]%s");
287219820Sjeff    elst[ERR_HFLAG] = CSAVS(1, 71, "No operand for -h flag");
288219820Sjeff    elst[ERR_NOTLOGIN] = CSAVS(1, 72, "Not a login shell");
289219820Sjeff    elst[ERR_DIV0] = CSAVS(1, 73, "Division by 0");
290219820Sjeff    elst[ERR_MOD0] = CSAVS(1, 74, "Mod by 0");
291219820Sjeff    elst[ERR_BADSCALE] = CSAVS(1, 75, "Bad scaling; did you mean \"%s\"?");
292219820Sjeff    elst[ERR_SUSPLOG] = CSAVS(1, 76, "Can't suspend a login shell (yet)");
293219820Sjeff    elst[ERR_UNKUSER] = CSAVS(1, 77, "Unknown user: %s");
294219820Sjeff    elst[ERR_NOHOME] = CSAVS(1, 78, "No $home variable set");
295219820Sjeff    elst[ERR_HISTUS] = CSAVS(1, 79,
296219820Sjeff	"Usage: history [-%s] [# number of events]");
297219820Sjeff    elst[ERR_SPDOLLT] = CSAVS(1, 80, "$, ! or < not allowed with $# or $?");
298219820Sjeff    elst[ERR_NEWLINE] = CSAVS(1, 81, "Newline in variable name");
299219820Sjeff    elst[ERR_SPSTAR] = CSAVS(1, 82, "* not allowed with $# or $?");
300219820Sjeff    elst[ERR_DIGIT] = CSAVS(1, 83, "$?<digit> or $#<digit> not allowed");
301219820Sjeff    elst[ERR_VARILL] = CSAVS(1, 84, "Illegal variable name");
302219820Sjeff    elst[ERR_NLINDEX] = CSAVS(1, 85, "Newline in variable index");
303219820Sjeff    elst[ERR_EXPOVFL] = CSAVS(1, 86, "Expansion buffer overflow");
304219820Sjeff    elst[ERR_VARSYN] = CSAVS(1, 87, "Variable syntax");
305219820Sjeff    elst[ERR_BADBANG] = CSAVS(1, 88, "Bad ! form");
306219820Sjeff    elst[ERR_NOSUBST] = CSAVS(1, 89, "No previous substitute");
307219820Sjeff    elst[ERR_BADSUBST] = CSAVS(1, 90, "Bad substitute");
308219820Sjeff    elst[ERR_LHS] = CSAVS(1, 91, "No previous left hand side");
309219820Sjeff    elst[ERR_RHSLONG] = CSAVS(1, 92, "Right hand side too long");
310219820Sjeff    elst[ERR_BADBANGMOD] = CSAVS(1, 93, "Bad ! modifier: %c");
311219820Sjeff    elst[ERR_MODFAIL] = CSAVS(1, 94, "Modifier failed");
312219820Sjeff    elst[ERR_SUBOVFL] = CSAVS(1, 95, "Substitution buffer overflow");
313219820Sjeff    elst[ERR_BADBANGARG] = CSAVS(1, 96, "Bad ! arg selector");
314219820Sjeff    elst[ERR_NOSEARCH] = CSAVS(1, 97, "No prev search");
315219820Sjeff    elst[ERR_NOEVENT] = CSAVS(1, 98, "%s: Event not found");
316219820Sjeff    elst[ERR_TOOMANYRP] = CSAVS(1, 99, "Too many )'s");
317219820Sjeff    elst[ERR_TOOMANYLP] = CSAVS(1, 100, "Too many ('s");
318219820Sjeff    elst[ERR_BADPLP] = CSAVS(1, 101, "Badly placed (");
319219820Sjeff    elst[ERR_MISRED] = CSAVS(1, 102, "Missing name for redirect");
320219820Sjeff    elst[ERR_OUTRED] = CSAVS(1, 103, "Ambiguous output redirect");
321219820Sjeff    elst[ERR_REDPAR] = CSAVS(1, 104, "Can't << within ()'s");
322219820Sjeff    elst[ERR_INRED] = CSAVS(1, 105, "Ambiguous input redirect");
323219820Sjeff    elst[ERR_BADPLPS] = CSAVS(1, 106, "Badly placed ()'s");
324219820Sjeff    elst[ERR_ALIASLOOP] = CSAVS(1, 107, "Alias loop");
325219820Sjeff    elst[ERR_NOWATCH] = CSAVS(1, 108, "No $watch variable set");
326219820Sjeff    elst[ERR_NOSCHED] = CSAVS(1, 109, "No scheduled events");
327219820Sjeff    elst[ERR_SCHEDUSAGE] = CSAVS(1, 110,
328219820Sjeff	"Usage: sched -<item#>.\nUsage: sched [+]hh:mm <command>");
329219820Sjeff    elst[ERR_SCHEDEV] = CSAVS(1, 111, "Not that many scheduled events");
330219820Sjeff    elst[ERR_SCHEDCOM] = CSAVS(1, 112, "No command to run");
331219820Sjeff    elst[ERR_SCHEDTIME] = CSAVS(1, 113, "Invalid time for event");
332219820Sjeff    elst[ERR_SCHEDREL] = CSAVS(1, 114, "Relative time inconsistent with am/pm");
333219820Sjeff    elst[ERR_TCNOSTR] = CSAVS(1, 115, "Out of termcap string space");
334219820Sjeff    elst[ERR_SETTCUS] = CSAVS(1, 116, "Usage: settc %s [yes|no]");
335219820Sjeff    elst[ERR_TCCAP] = CSAVS(1, 117, "Unknown capability `%s'");
336219820Sjeff    elst[ERR_TCPARM] = CSAVS(1, 118, "Unknown termcap parameter `%%%c'");
337219820Sjeff    elst[ERR_TCARGS] = CSAVS(1, 119, "Too many arguments for `%s' (%d)");
338219820Sjeff    elst[ERR_TCNARGS] = CSAVS(1, 120, "`%s' requires %d arguments");
339219820Sjeff    elst[ERR_TCUSAGE] = CSAVS(1, 121,
340219820Sjeff	"Usage: echotc [-v|-s] [<capability> [<args>]]");
341219820Sjeff    elst[ERR_ARCH] = CSAVS(1, 122, "%s: %s. Binary file not executable");
342219820Sjeff    elst[ERR_HISTLOOP] = CSAVS(1, 123, "!# History loop");
343219820Sjeff    elst[ERR_FILEINQ] = CSAVS(1, 124, "Malformed file inquiry");
344219820Sjeff    elst[ERR_SELOVFL] = CSAVS(1, 125, "Selector overflow");
345219820Sjeff#ifdef apollo
346219820Sjeff    elst[ERR_TCSHUSAGE] = CSAVS(1, 126,
347219820Sjeff"Unknown option: `-%s'\nUsage: %s [ -bcdefilmnqstvVxX -Dname[=value] ] [ argument ... ]");
348219820Sjeff#else /* !apollo */
349219820Sjeff# ifdef convex
350219820Sjeff    elst[ERR_TCSHUSAGE] = CSAVS(1, 127,
351219820Sjeff"Unknown option: `-%s'\nUsage: %s [ -bcdefFilmnqstvVxX ] [ argument ... ]");
352219820Sjeff# else /* rest */
353219820Sjeff    elst[ERR_TCSHUSAGE] = CSAVS(1, 128,
354219820Sjeff"Unknown option: `-%s'\nUsage: %s [ -bcdefilmnqstvVxX ] [ argument ... ]");
355219820Sjeff# endif /* convex */
356219820Sjeff#endif /* apollo */
357219820Sjeff    elst[ERR_COMPCOM] = CSAVS(1, 129, "\nInvalid completion: \"%s\"");
358219820Sjeff    elst[ERR_COMPINV] = CSAVS(1, 130, "\nInvalid %s: '%c'");
359219820Sjeff    elst[ERR_COMPMIS] = CSAVS(1, 131,
360219820Sjeff	"\nMissing separator '%c' after %s \"%s\"");
361219820Sjeff    elst[ERR_COMPINC] = CSAVS(1, 132, "\nIncomplete %s: \"%s\"");
362219820Sjeff    elst[ERR_MFLAG] = CSAVS(1, 133, "No operand for -m flag");
363219820Sjeff    elst[ERR_ULIMUS] = CSAVS(1, 134, "Usage: unlimit [-fh] [limits]");
364219820Sjeff    elst[ERR_READONLY] = CSAVS(1, 135, "$%S is read-only");
365219820Sjeff    elst[ERR_BADJOB] = CSAVS(1, 136, "No such job (badjob)");
366219820Sjeff    elst[ERR_BADCOLORVAR] = CSAVS(1, 137, "Unknown colorls variable `%c%c'");
367219820Sjeff}
368219820Sjeff
369219820Sjeff/* Cleanup data. */
370219820Sjeffstruct cleanup_entry
371219820Sjeff{
372219820Sjeff    void *var;
373219820Sjeff    void (*fn) (void *);
374219820Sjeff#ifdef CLEANUP_DEBUG
375219820Sjeff    const char *file;
376219820Sjeff    size_t line;
377219820Sjeff#endif
378219820Sjeff};
379219820Sjeff
380219820Sjeffstatic struct cleanup_entry *cleanup_stack; /* = NULL; */
381219820Sjeffstatic size_t cleanup_sp; /* = 0; Next free entry */
382219820Sjeffstatic size_t cleanup_mark; /* = 0; Last entry to handle before unwinding */
383219820Sjeffstatic size_t cleanup_stack_size; /* = 0 */
384219820Sjeff
385219820Sjeff/* fn() will be run with all signals blocked, so it should not do anything
386219820Sjeff   risky. */
387219820Sjeffvoid
388219820Sjeffcleanup_push_internal(void *var, void (*fn) (void *)
389219820Sjeff#ifdef CLEANUP_DEBUG
390219820Sjeff    , const char *file, size_t line
391219820Sjeff#endif
392219820Sjeff)
393219820Sjeff{
394219820Sjeff    struct cleanup_entry *ce;
395219820Sjeff
396219820Sjeff    if (cleanup_sp == cleanup_stack_size) {
397219820Sjeff	if (cleanup_stack_size == 0)
398219820Sjeff	    cleanup_stack_size = 64; /* Arbitrary */
399219820Sjeff	else
400219820Sjeff	    cleanup_stack_size *= 2;
401219820Sjeff	cleanup_stack = xrealloc(cleanup_stack,
402219820Sjeff				 cleanup_stack_size * sizeof (*cleanup_stack));
403219820Sjeff    }
404219820Sjeff    ce = cleanup_stack + cleanup_sp;
405219820Sjeff    ce->var = var;
406219820Sjeff    ce->fn = fn;
407219820Sjeff#ifdef CLEANUP_DEBUG
408219820Sjeff    ce->file = file;
409219820Sjeff    ce->line = line;
410219820Sjeff#endif
411219820Sjeff    cleanup_sp++;
412219820Sjeff}
413219820Sjeff
414219820Sjeffstatic void
415219820Sjeffcleanup_ignore_fn(void *dummy)
416219820Sjeff{
417219820Sjeff    USE(dummy);
418219820Sjeff}
419219820Sjeff
420219820Sjeffvoid
421219820Sjeffcleanup_ignore(void *var)
422219820Sjeff{
423219820Sjeff    struct cleanup_entry *ce;
424219820Sjeff
425219820Sjeff    ce = cleanup_stack + cleanup_sp;
426219820Sjeff    while (ce != cleanup_stack) {
427219820Sjeff        ce--;
428219820Sjeff	if (ce->var == var) {
429219820Sjeff	    ce->fn = cleanup_ignore_fn;
430219820Sjeff	    return;
431219820Sjeff	}
432219820Sjeff    }
433219820Sjeff    abort();
434219820Sjeff}
435219820Sjeff
436219820Sjeffvoid
437219820Sjeffcleanup_until(void *last_var)
438219820Sjeff{
439219820Sjeff    while (cleanup_sp != 0) {
440219820Sjeff	struct cleanup_entry ce;
441219820Sjeff
442219820Sjeff	cleanup_sp--;
443219820Sjeff	ce = cleanup_stack[cleanup_sp];
444219820Sjeff	ce.fn(ce.var);
445219820Sjeff	if (ce.var == last_var)
446219820Sjeff	    return;
447219820Sjeff    }
448219820Sjeff    abort();
449219820Sjeff}
450219820Sjeff
451219820Sjeffvoid
452219820Sjeffcleanup_until_mark(void)
453219820Sjeff{
454219820Sjeff    while (cleanup_sp > cleanup_mark) {
455219820Sjeff	struct cleanup_entry ce;
456219820Sjeff
457219820Sjeff	cleanup_sp--;
458219820Sjeff	ce = cleanup_stack[cleanup_sp];
459219820Sjeff	ce.fn(ce.var);
460219820Sjeff    }
461219820Sjeff}
462219820Sjeff
463219820Sjeffsize_t
464219820Sjeffcleanup_push_mark(void)
465219820Sjeff{
466219820Sjeff    size_t old_mark;
467219820Sjeff
468219820Sjeff    old_mark = cleanup_mark;
469219820Sjeff    cleanup_mark = cleanup_sp;
470219820Sjeff    return old_mark;
471219820Sjeff}
472219820Sjeff
473219820Sjeffvoid
474219820Sjeffcleanup_pop_mark(size_t mark)
475219820Sjeff{
476219820Sjeff    assert (mark <= cleanup_sp);
477219820Sjeff    cleanup_mark = mark;
478219820Sjeff}
479219820Sjeff
480219820Sjeffvoid
481219820Sjeffsigint_cleanup(void *xsa)
482219820Sjeff{
483219820Sjeff    const struct sigaction *sa;
484219820Sjeff
485219820Sjeff    sa = xsa;
486219820Sjeff    sigaction(SIGINT, sa, NULL);
487219820Sjeff}
488219820Sjeff
489219820Sjeffvoid
490219820Sjeffsigprocmask_cleanup(void *xmask)
491219820Sjeff{
492219820Sjeff    sigset_t *mask;
493219820Sjeff
494219820Sjeff    mask = xmask;
495219820Sjeff    sigprocmask(SIG_SETMASK, mask, NULL);
496219820Sjeff}
497219820Sjeff
498219820Sjeffvoid
499219820Sjeffopen_cleanup(void *xptr)
500219820Sjeff{
501219820Sjeff    int *ptr;
502219820Sjeff
503219820Sjeff    ptr = xptr;
504219820Sjeff    xclose(*ptr);
505219820Sjeff}
506219820Sjeff
507219820Sjeffvoid
508219820Sjeffopendir_cleanup(void *xdir)
509219820Sjeff{
510219820Sjeff    DIR *dir;
511219820Sjeff
512219820Sjeff    dir = xdir;
513219820Sjeff    xclosedir(dir);
514219820Sjeff}
515219820Sjeff
516219820Sjeffvoid
517219820Sjeffxfree_indirect(void *xptr)
518219820Sjeff{
519219820Sjeff    void **ptr; /* This is actually type punning :( */
520219820Sjeff
521219820Sjeff    ptr = xptr;
522219820Sjeff    xfree(*ptr);
523219820Sjeff}
524219820Sjeff
525219820Sjeffvoid
526219820Sjeffreset(void)
527219820Sjeff{
528219820Sjeff    cleanup_until_mark();
529219820Sjeff    _reset();
530219820Sjeff}
531219820Sjeff
532219820Sjeff/*
533219820Sjeff * The parser and scanner set up errors for later by calling seterr,
534219820Sjeff * which sets the variable err as a side effect; later to be tested,
535219820Sjeff * e.g. in process.
536219820Sjeff */
537219820Sjeffvoid
538219820Sjeff/*VARARGS1*/
539219820Sjeffseterror(unsigned int id, ...)
540219820Sjeff{
541219820Sjeff    if (seterr == 0) {
542219820Sjeff	va_list va;
543219820Sjeff
544219820Sjeff	va_start(va, id);
545219820Sjeff	if (id >= sizeof(elst) / sizeof(elst[0]))
546219820Sjeff	    id = ERR_INVALID;
547219820Sjeff	seterr = xvasprintf(elst[id], va);
548219820Sjeff	va_end(va);
549219820Sjeff    }
550219820Sjeff}
551219820Sjeff
552219820Sjeff/*
553219820Sjeff * Print the error with the given id.
554219820Sjeff *
555219820Sjeff * Special ids:
556219820Sjeff *	ERR_SILENT: Print nothing.
557219820Sjeff *	ERR_OLD: Print the previously set error if one was there.
558219820Sjeff *	         otherwise return.
559219820Sjeff *	ERR_NAME: If this bit is set, print the name of the function
560219820Sjeff *		  in bname
561219820Sjeff *
562219820Sjeff * This routine always resets or exits.  The flag haderr
563219820Sjeff * is set so the routine who catches the unwind can propogate
564219820Sjeff * it if they want.
565219820Sjeff *
566219820Sjeff * Note that any open files at the point of error will eventually
567219820Sjeff * be closed in the routine process in sh.c which is the only
568219820Sjeff * place error unwinds are ever caught.
569219820Sjeff */
570219820Sjeffvoid
571219820Sjeff/*VARARGS*/
572219820Sjeffstderror(unsigned int id, ...)
573219820Sjeff{
574219820Sjeff    va_list va;
575219820Sjeff    int flags;
576219820Sjeff    int vareturn;
577219820Sjeff
578219820Sjeff    va_start(va, id);
579219820Sjeff
580219820Sjeff    /*
581219820Sjeff     * Reset don't free flag for buggy os's
582219820Sjeff     */
583219820Sjeff    dont_free = 0;
584219820Sjeff
585219820Sjeff    flags = (int) id & ERR_FLAGS;
586219820Sjeff    id &= ~ERR_FLAGS;
587219820Sjeff
588219820Sjeff    /* Pyramid's OS/x has a subtle bug in <varargs.h> which prevents calling
589219820Sjeff     * va_end more than once in the same function. -- sterling@netcom.com
590219820Sjeff     */
591219820Sjeff    if (!((flags & ERR_OLD) && seterr == NULL)) {
592219820Sjeff	vareturn = 0;	/* Don't return immediately after va_end */
593219820Sjeff	if (id >= sizeof(elst) / sizeof(elst[0]))
594219820Sjeff	    id = ERR_INVALID;
595219820Sjeff
596219820Sjeff	/*
597219820Sjeff	 * Must flush before we print as we wish output before the error to go
598219820Sjeff	 * on (some form of) standard output, while output after goes on (some
599219820Sjeff	 * form of) diagnostic output. If didfds then output will go to 1/2
600219820Sjeff	 * else to FSHOUT/FSHDIAG. See flush in sh.print.c.
601219820Sjeff	 */
602219820Sjeff	flush();/*FIXRESET*/
603219820Sjeff	haderr = 1;			/* Now to diagnostic output */
604219820Sjeff
605219820Sjeff	if (!(flags & ERR_SILENT)) {
606219820Sjeff	    if (flags & ERR_NAME)
607219820Sjeff		xprintf("%s: ", bname);/*FIXRESET*/
608219820Sjeff	    if ((flags & ERR_OLD)) {
609219820Sjeff		/* Old error. */
610219820Sjeff		xprintf("%s.\n", seterr);/*FIXRESET*/
611219820Sjeff	    } else {
612219820Sjeff		xvprintf(elst[id], va);/*FIXRESET*/
613219820Sjeff		xprintf(".\n");/*FIXRESET*/
614219820Sjeff	    }
615219820Sjeff	}
616219820Sjeff    } else {
617219820Sjeff	vareturn = 1;	/* Return immediately after va_end */
618219820Sjeff    }
619219820Sjeff    va_end(va);
620219820Sjeff    if (vareturn)
621219820Sjeff	return;
622219820Sjeff
623219820Sjeff    if (seterr) {
624219820Sjeff	xfree(seterr);
625219820Sjeff	seterr = NULL;
626219820Sjeff    }
627219820Sjeff
628219820Sjeff    didfds = 0;			/* Forget about 0,1,2 */
629219820Sjeff    /*
630219820Sjeff     * Go away if -e or we are a child shell
631219820Sjeff     */
632219820Sjeff    if (!exitset || exiterr || child)
633219820Sjeff	xexit(1);
634219820Sjeff
635219820Sjeff    /*
636219820Sjeff     * Reset the state of the input. This buffered seek to end of file will
637219820Sjeff     * also clear the while/foreach stack.
638219820Sjeff     */
639219820Sjeff    btoeof();
640219820Sjeff
641219820Sjeff    setcopy(STRstatus, STR1, VAR_READWRITE);/*FIXRESET*/
642219820Sjeff#ifdef BSDJOBS
643219820Sjeff    if (tpgrp > 0)
644219820Sjeff	(void) tcsetpgrp(FSHTTY, tpgrp);
645219820Sjeff#endif
646219820Sjeff    reset();			/* Unwind */
647219820Sjeff}
648219820Sjeff