xref: /illumos-gate/usr/src/cmd/make/lib/mksh/misc.cc (revision e7afc443)
110d63b7dSRichard Lowe /*
210d63b7dSRichard Lowe  * CDDL HEADER START
310d63b7dSRichard Lowe  *
410d63b7dSRichard Lowe  * The contents of this file are subject to the terms of the
510d63b7dSRichard Lowe  * Common Development and Distribution License (the "License").
610d63b7dSRichard Lowe  * You may not use this file except in compliance with the License.
710d63b7dSRichard Lowe  *
810d63b7dSRichard Lowe  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
910d63b7dSRichard Lowe  * or http://www.opensolaris.org/os/licensing.
1010d63b7dSRichard Lowe  * See the License for the specific language governing permissions
1110d63b7dSRichard Lowe  * and limitations under the License.
1210d63b7dSRichard Lowe  *
1310d63b7dSRichard Lowe  * When distributing Covered Code, include this CDDL HEADER in each
1410d63b7dSRichard Lowe  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1510d63b7dSRichard Lowe  * If applicable, add the following below this CDDL HEADER, with the
1610d63b7dSRichard Lowe  * fields enclosed by brackets "[]" replaced with your own identifying
1710d63b7dSRichard Lowe  * information: Portions Copyright [yyyy] [name of copyright owner]
1810d63b7dSRichard Lowe  *
1910d63b7dSRichard Lowe  * CDDL HEADER END
2010d63b7dSRichard Lowe  */
2110d63b7dSRichard Lowe /*
2210d63b7dSRichard Lowe  * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
2310d63b7dSRichard Lowe  * Use is subject to license terms.
2410d63b7dSRichard Lowe  */
2510d63b7dSRichard Lowe 
2610d63b7dSRichard Lowe 
2710d63b7dSRichard Lowe /*
2810d63b7dSRichard Lowe  *	misc.cc
2910d63b7dSRichard Lowe  *
3010d63b7dSRichard Lowe  *	This file contains various unclassified routines. Some main groups:
3110d63b7dSRichard Lowe  *		getname
3210d63b7dSRichard Lowe  *		Memory allocation
3310d63b7dSRichard Lowe  *		String handling
3410d63b7dSRichard Lowe  *		Property handling
3510d63b7dSRichard Lowe  *		Error message handling
3610d63b7dSRichard Lowe  *		Make internal state dumping
3710d63b7dSRichard Lowe  *		main routine support
3810d63b7dSRichard Lowe  */
3910d63b7dSRichard Lowe 
4010d63b7dSRichard Lowe /*
4110d63b7dSRichard Lowe  * Included files
4210d63b7dSRichard Lowe  */
4310d63b7dSRichard Lowe #include <bsd/bsd.h>		/* bsd_signal() */
4410d63b7dSRichard Lowe #include <mksh/i18n.h>		/* get_char_semantics_value() */
4510d63b7dSRichard Lowe #include <mksh/misc.h>
4610d63b7dSRichard Lowe #include <stdarg.h>		/* va_list, va_start(), va_end() */
4710d63b7dSRichard Lowe #include <stdlib.h>		/* mbstowcs() */
4810d63b7dSRichard Lowe #include <sys/signal.h>		/* SIG_DFL */
4910d63b7dSRichard Lowe #include <sys/wait.h>		/* wait() */
5010d63b7dSRichard Lowe 
5110d63b7dSRichard Lowe #include <string.h>		/* strerror() */
5210d63b7dSRichard Lowe #include <libintl.h>
5310d63b7dSRichard Lowe 
5410d63b7dSRichard Lowe 
5510d63b7dSRichard Lowe /*
5610d63b7dSRichard Lowe  * Defined macros
5710d63b7dSRichard Lowe  */
5810d63b7dSRichard Lowe 
5910d63b7dSRichard Lowe /*
6010d63b7dSRichard Lowe  * typedefs & structs
6110d63b7dSRichard Lowe  */
6210d63b7dSRichard Lowe 
6310d63b7dSRichard Lowe /*
6410d63b7dSRichard Lowe  * Static variables
6510d63b7dSRichard Lowe  */
6610d63b7dSRichard Lowe extern "C" {
6710d63b7dSRichard Lowe 	void		(*sigivalue)(int) = SIG_DFL;
6810d63b7dSRichard Lowe 	void		(*sigqvalue)(int) = SIG_DFL;
6910d63b7dSRichard Lowe 	void		(*sigtvalue)(int) = SIG_DFL;
7010d63b7dSRichard Lowe 	void		(*sighvalue)(int) = SIG_DFL;
7110d63b7dSRichard Lowe }
7210d63b7dSRichard Lowe 
7310d63b7dSRichard Lowe long	getname_bytes_count = 0;
7410d63b7dSRichard Lowe long	getname_names_count = 0;
7510d63b7dSRichard Lowe long	getname_struct_count = 0;
7610d63b7dSRichard Lowe 
7710d63b7dSRichard Lowe long	freename_bytes_count = 0;
7810d63b7dSRichard Lowe long	freename_names_count = 0;
7910d63b7dSRichard Lowe long	freename_struct_count = 0;
8010d63b7dSRichard Lowe 
8110d63b7dSRichard Lowe long	expandstring_count = 0;
8210d63b7dSRichard Lowe long	getwstring_count = 0;
8310d63b7dSRichard Lowe 
8410d63b7dSRichard Lowe /*
8510d63b7dSRichard Lowe  * File table of contents
8610d63b7dSRichard Lowe  */
87*e7afc443SToomas Soome static void	expand_string(String string, int length);
8810d63b7dSRichard Lowe 
8910d63b7dSRichard Lowe #define	FATAL_ERROR_MSG_SIZE 200
9010d63b7dSRichard Lowe 
9110d63b7dSRichard Lowe /*
9210d63b7dSRichard Lowe  *	getmem(size)
9310d63b7dSRichard Lowe  *
9410d63b7dSRichard Lowe  *	malloc() version that checks the returned value.
9510d63b7dSRichard Lowe  *
9610d63b7dSRichard Lowe  *	Return value:
9710d63b7dSRichard Lowe  *				The memory chunk we allocated
9810d63b7dSRichard Lowe  *
9910d63b7dSRichard Lowe  *	Parameters:
10010d63b7dSRichard Lowe  *		size		The size of the chunk we need
10110d63b7dSRichard Lowe  *
10210d63b7dSRichard Lowe  *	Global variables used:
10310d63b7dSRichard Lowe  */
10410d63b7dSRichard Lowe char *
getmem(size_t size)105356ba08cSToomas Soome getmem(size_t size)
10610d63b7dSRichard Lowe {
107356ba08cSToomas Soome 	char *result = (char *)malloc(size);
10810d63b7dSRichard Lowe 	if (result == NULL) {
109356ba08cSToomas Soome 		(void) fprintf(stderr, "*** Error: malloc(%d) failed: %s\n%s",
110356ba08cSToomas Soome 		    size, strerror(errno),
111356ba08cSToomas Soome 		    gettext("mksh: Fatal error: Out of memory\n"));
11210d63b7dSRichard Lowe 		exit(1);
11310d63b7dSRichard Lowe 	}
114356ba08cSToomas Soome 	return (result);
11510d63b7dSRichard Lowe }
11610d63b7dSRichard Lowe 
11710d63b7dSRichard Lowe /*
11810d63b7dSRichard Lowe  *	retmem(p)
11910d63b7dSRichard Lowe  *
12010d63b7dSRichard Lowe  *	Cover funtion for free() to make it possible to insert advises.
12110d63b7dSRichard Lowe  *
12210d63b7dSRichard Lowe  *	Parameters:
12310d63b7dSRichard Lowe  *		p		The memory block to free
12410d63b7dSRichard Lowe  *
12510d63b7dSRichard Lowe  *	Global variables used:
12610d63b7dSRichard Lowe  */
12710d63b7dSRichard Lowe void
retmem(wchar_t * p)12810d63b7dSRichard Lowe retmem(wchar_t *p)
12910d63b7dSRichard Lowe {
13010d63b7dSRichard Lowe 	(void) free((char *) p);
13110d63b7dSRichard Lowe }
13210d63b7dSRichard Lowe 
13310d63b7dSRichard Lowe void
retmem_mb(caddr_t p)13410d63b7dSRichard Lowe retmem_mb(caddr_t p)
13510d63b7dSRichard Lowe {
13610d63b7dSRichard Lowe 	(void) free(p);
13710d63b7dSRichard Lowe }
13810d63b7dSRichard Lowe 
13910d63b7dSRichard Lowe /*
14010d63b7dSRichard Lowe  *	getname_fn(name, len, dont_enter)
14110d63b7dSRichard Lowe  *
14210d63b7dSRichard Lowe  *	Hash a name string to the corresponding nameblock.
14310d63b7dSRichard Lowe  *
14410d63b7dSRichard Lowe  *	Return value:
14510d63b7dSRichard Lowe  *				The Name block for the string
14610d63b7dSRichard Lowe  *
14710d63b7dSRichard Lowe  *	Parameters:
14810d63b7dSRichard Lowe  *		name		The string we want to internalize
14910d63b7dSRichard Lowe  *		len		The length of that string
15010d63b7dSRichard Lowe  *		dont_enter	Don't enter the name if it does not exist
15110d63b7dSRichard Lowe  *
15210d63b7dSRichard Lowe  *	Global variables used:
15310d63b7dSRichard Lowe  *		funny		The vector of semantic tags for characters
15410d63b7dSRichard Lowe  *		hashtab		The hashtable used for the nametable
15510d63b7dSRichard Lowe  */
15610d63b7dSRichard Lowe Name
getname_fn(wchar_t * name,int len,Boolean dont_enter,Boolean * foundp)157*e7afc443SToomas Soome getname_fn(wchar_t *name, int len, Boolean dont_enter, Boolean * foundp)
15810d63b7dSRichard Lowe {
159*e7afc443SToomas Soome 	int		length;
160*e7afc443SToomas Soome 	wchar_t	*cap = name;
161*e7afc443SToomas Soome 	Name		np;
16210d63b7dSRichard Lowe 	static Name_rec		empty_Name;
16310d63b7dSRichard Lowe 	char			*tmp_mbs_buffer = NULL;
16410d63b7dSRichard Lowe 	char			*mbs_name = mbs_buffer;
16510d63b7dSRichard Lowe 
16610d63b7dSRichard Lowe 	/*
16710d63b7dSRichard Lowe 	 * First figure out how long the string is.
16810d63b7dSRichard Lowe 	 * If the len argument is -1 we count the chars here.
16910d63b7dSRichard Lowe 	 */
17010d63b7dSRichard Lowe 	if (len == FIND_LENGTH) {
17110d63b7dSRichard Lowe 		length = wcslen(name);
17210d63b7dSRichard Lowe 	} else {
17310d63b7dSRichard Lowe 		length = len;
17410d63b7dSRichard Lowe 	}
17510d63b7dSRichard Lowe 
17610d63b7dSRichard Lowe 	Wstring ws;
17710d63b7dSRichard Lowe 	ws.init(name, length);
17810d63b7dSRichard Lowe 	if (length >= MAXPATHLEN) {
17910d63b7dSRichard Lowe 		mbs_name = tmp_mbs_buffer = getmem((length * MB_LEN_MAX) + 1);
18010d63b7dSRichard Lowe 	}
18110d63b7dSRichard Lowe 	(void) wcstombs(mbs_name, ws.get_string(), (length * MB_LEN_MAX) + 1);
18210d63b7dSRichard Lowe 
18310d63b7dSRichard Lowe 	/* Look for the string */
18410d63b7dSRichard Lowe 	if (dont_enter || (foundp != 0)) {
18510d63b7dSRichard Lowe 		np = hashtab.lookup(mbs_name);
18610d63b7dSRichard Lowe 		if (foundp != 0) {
18710d63b7dSRichard Lowe 			*foundp = (np != 0) ? true : false;
18810d63b7dSRichard Lowe 		}
18910d63b7dSRichard Lowe 		if ((np != 0) || dont_enter) {
19010d63b7dSRichard Lowe 			if(tmp_mbs_buffer != NULL) {
19110d63b7dSRichard Lowe 				retmem_mb(tmp_mbs_buffer);
19210d63b7dSRichard Lowe 			}
19310d63b7dSRichard Lowe 			return np;
19410d63b7dSRichard Lowe 		} else {
19510d63b7dSRichard Lowe 			np = ALLOC(Name);
19610d63b7dSRichard Lowe 		}
19710d63b7dSRichard Lowe 	} else {
19810d63b7dSRichard Lowe 		Boolean found;
19910d63b7dSRichard Lowe 		np = hashtab.insert(mbs_name, found);
20010d63b7dSRichard Lowe 		if (found) {
20110d63b7dSRichard Lowe 			if(tmp_mbs_buffer != NULL) {
20210d63b7dSRichard Lowe 				retmem_mb(tmp_mbs_buffer);
20310d63b7dSRichard Lowe 			}
20410d63b7dSRichard Lowe 			return np;
20510d63b7dSRichard Lowe 		}
20610d63b7dSRichard Lowe 	}
20710d63b7dSRichard Lowe 	getname_struct_count += sizeof(struct _Name);
20810d63b7dSRichard Lowe 	*np = empty_Name;
20910d63b7dSRichard Lowe 
21010d63b7dSRichard Lowe 	np->string_mb = strdup(mbs_name);
21110d63b7dSRichard Lowe 	if(tmp_mbs_buffer != NULL) {
21210d63b7dSRichard Lowe 		retmem_mb(tmp_mbs_buffer);
21310d63b7dSRichard Lowe 		mbs_name = tmp_mbs_buffer = NULL;
21410d63b7dSRichard Lowe 	}
21510d63b7dSRichard Lowe 	getname_bytes_count += strlen(np->string_mb) + 1;
21610d63b7dSRichard Lowe 	/* Fill in the new Name */
21710d63b7dSRichard Lowe 	np->stat.time = file_no_time;
21810d63b7dSRichard Lowe 	np->hash.length = length;
21910d63b7dSRichard Lowe 	/* Scan the namestring to classify it */
22010d63b7dSRichard Lowe 	for (cap = name, len = 0; --length >= 0;) {
22110d63b7dSRichard Lowe 		len |= get_char_semantics_value(*cap++);
22210d63b7dSRichard Lowe 	}
22310d63b7dSRichard Lowe 	np->dollar = BOOLEAN((len & (int) dollar_sem) != 0);
22410d63b7dSRichard Lowe 	np->meta = BOOLEAN((len & (int) meta_sem) != 0);
22510d63b7dSRichard Lowe 	np->percent = BOOLEAN((len & (int) percent_sem) != 0);
22610d63b7dSRichard Lowe 	np->wildcard = BOOLEAN((len & (int) wildcard_sem) != 0);
22710d63b7dSRichard Lowe 	np->colon = BOOLEAN((len & (int) colon_sem) != 0);
22810d63b7dSRichard Lowe 	np->parenleft = BOOLEAN((len & (int) parenleft_sem) != 0);
22910d63b7dSRichard Lowe 	getname_names_count++;
23010d63b7dSRichard Lowe 	return np;
23110d63b7dSRichard Lowe }
23210d63b7dSRichard Lowe 
23310d63b7dSRichard Lowe void
store_name(Name name)23410d63b7dSRichard Lowe store_name(Name name)
23510d63b7dSRichard Lowe {
23610d63b7dSRichard Lowe 	hashtab.insert(name);
23710d63b7dSRichard Lowe }
23810d63b7dSRichard Lowe 
23910d63b7dSRichard Lowe void
free_name(Name name)24010d63b7dSRichard Lowe free_name(Name name)
24110d63b7dSRichard Lowe {
24210d63b7dSRichard Lowe 	freename_names_count++;
24310d63b7dSRichard Lowe 	freename_struct_count += sizeof(struct _Name);
24410d63b7dSRichard Lowe 	freename_bytes_count += strlen(name->string_mb) + 1;
24510d63b7dSRichard Lowe 	retmem_mb(name->string_mb);
24610d63b7dSRichard Lowe 	for (Property next, p = name->prop; p != NULL; p = next) {
24710d63b7dSRichard Lowe 		next = p->next;
24810d63b7dSRichard Lowe 		free(p);
24910d63b7dSRichard Lowe 	}
25010d63b7dSRichard Lowe 	free(name);
25110d63b7dSRichard Lowe }
25210d63b7dSRichard Lowe 
25310d63b7dSRichard Lowe /*
25410d63b7dSRichard Lowe  *	enable_interrupt(handler)
25510d63b7dSRichard Lowe  *
25610d63b7dSRichard Lowe  *	This routine sets a new interrupt handler for the signals make
25710d63b7dSRichard Lowe  *	wants to deal with.
25810d63b7dSRichard Lowe  *
25910d63b7dSRichard Lowe  *	Parameters:
26010d63b7dSRichard Lowe  *		handler		The function installed as interrupt handler
26110d63b7dSRichard Lowe  *
26210d63b7dSRichard Lowe  *	Static variables used:
26310d63b7dSRichard Lowe  *		sigivalue	The original signal handler
26410d63b7dSRichard Lowe  *		sigqvalue	The original signal handler
26510d63b7dSRichard Lowe  *		sigtvalue	The original signal handler
26610d63b7dSRichard Lowe  *		sighvalue	The original signal handler
26710d63b7dSRichard Lowe  */
26810d63b7dSRichard Lowe void
enable_interrupt(void (* handler)(int))269*e7afc443SToomas Soome enable_interrupt(void (*handler) (int))
27010d63b7dSRichard Lowe {
27110d63b7dSRichard Lowe 	if (sigivalue != SIG_IGN) {
27210d63b7dSRichard Lowe 		(void) bsd_signal(SIGINT, (SIG_PF) handler);
27310d63b7dSRichard Lowe 	}
27410d63b7dSRichard Lowe 	if (sigqvalue != SIG_IGN) {
27510d63b7dSRichard Lowe 		(void) bsd_signal(SIGQUIT, (SIG_PF) handler);
27610d63b7dSRichard Lowe 	}
27710d63b7dSRichard Lowe 	if (sigtvalue != SIG_IGN) {
27810d63b7dSRichard Lowe 		(void) bsd_signal(SIGTERM, (SIG_PF) handler);
27910d63b7dSRichard Lowe 	}
28010d63b7dSRichard Lowe 	if (sighvalue != SIG_IGN) {
28110d63b7dSRichard Lowe 		(void) bsd_signal(SIGHUP, (SIG_PF) handler);
28210d63b7dSRichard Lowe 	}
28310d63b7dSRichard Lowe }
28410d63b7dSRichard Lowe 
28510d63b7dSRichard Lowe /*
28610d63b7dSRichard Lowe  *	setup_char_semantics()
28710d63b7dSRichard Lowe  *
28810d63b7dSRichard Lowe  *	Load the vector char_semantics[] with lexical markers
28910d63b7dSRichard Lowe  *
29010d63b7dSRichard Lowe  *	Parameters:
29110d63b7dSRichard Lowe  *
29210d63b7dSRichard Lowe  *	Global variables used:
29310d63b7dSRichard Lowe  *		char_semantics	The vector of character semantics that we set
29410d63b7dSRichard Lowe  */
29510d63b7dSRichard Lowe void
setup_char_semantics(void)29610d63b7dSRichard Lowe setup_char_semantics(void)
29710d63b7dSRichard Lowe {
29810d63b7dSRichard Lowe 	const char	*s;
29910d63b7dSRichard Lowe 	wchar_t		wc_buffer[1];
30010d63b7dSRichard Lowe 	int		entry;
30110d63b7dSRichard Lowe 
30210d63b7dSRichard Lowe 	if (svr4) {
30310d63b7dSRichard Lowe 		s = "@-";
30410d63b7dSRichard Lowe 	} else {
30510d63b7dSRichard Lowe 		s = "=@-?!+";
30610d63b7dSRichard Lowe 	}
30710d63b7dSRichard Lowe 	for (s; MBTOWC(wc_buffer, s); s++) {
30810d63b7dSRichard Lowe 		entry = get_char_semantics_entry(*wc_buffer);
30910d63b7dSRichard Lowe 		char_semantics[entry] |= (int) command_prefix_sem;
31010d63b7dSRichard Lowe 	}
31110d63b7dSRichard Lowe 	char_semantics[dollar_char_entry] |= (int) dollar_sem;
31210d63b7dSRichard Lowe 	for (s = "#|=^();&<>*?[]:$`'\"\\\n"; MBTOWC(wc_buffer, s); s++) {
31310d63b7dSRichard Lowe 		entry = get_char_semantics_entry(*wc_buffer);
31410d63b7dSRichard Lowe 		char_semantics[entry] |= (int) meta_sem;
31510d63b7dSRichard Lowe 	}
31610d63b7dSRichard Lowe 	char_semantics[percent_char_entry] |= (int) percent_sem;
31710d63b7dSRichard Lowe 	for (s = "@*<%?^"; MBTOWC(wc_buffer, s); s++) {
31810d63b7dSRichard Lowe 		entry = get_char_semantics_entry(*wc_buffer);
31910d63b7dSRichard Lowe 		char_semantics[entry] |= (int) special_macro_sem;
32010d63b7dSRichard Lowe 	}
32110d63b7dSRichard Lowe 	for (s = "?[*"; MBTOWC(wc_buffer, s); s++) {
32210d63b7dSRichard Lowe 		entry = get_char_semantics_entry(*wc_buffer);
32310d63b7dSRichard Lowe 		char_semantics[entry] |= (int) wildcard_sem;
32410d63b7dSRichard Lowe 	}
32510d63b7dSRichard Lowe 	char_semantics[colon_char_entry] |= (int) colon_sem;
32610d63b7dSRichard Lowe 	char_semantics[parenleft_char_entry] |= (int) parenleft_sem;
32710d63b7dSRichard Lowe }
32810d63b7dSRichard Lowe 
32910d63b7dSRichard Lowe /*
33010d63b7dSRichard Lowe  *	errmsg(errnum)
33110d63b7dSRichard Lowe  *
33210d63b7dSRichard Lowe  *	Return the error message for a system call error
33310d63b7dSRichard Lowe  *
33410d63b7dSRichard Lowe  *	Return value:
33510d63b7dSRichard Lowe  *				An error message string
33610d63b7dSRichard Lowe  *
33710d63b7dSRichard Lowe  *	Parameters:
33810d63b7dSRichard Lowe  *		errnum		The number of the error we want to describe
33910d63b7dSRichard Lowe  */
34010d63b7dSRichard Lowe char *
errmsg(int errnum)34110d63b7dSRichard Lowe errmsg(int errnum)
34210d63b7dSRichard Lowe {
343356ba08cSToomas Soome 	char *msg;
344356ba08cSToomas Soome 	char *errbuf;
345356ba08cSToomas Soome 
346356ba08cSToomas Soome 	errno = 0;
347356ba08cSToomas Soome 	msg = strerror(errnum);
348356ba08cSToomas Soome 	if (errno == EINVAL) {
349356ba08cSToomas Soome 		size_t size = 6 + 1 + 11 + 1;
350356ba08cSToomas Soome 		errbuf = getmem(size);
351356ba08cSToomas Soome 		(void) snprintf(errbuf, size, gettext("Error %d"), errnum);
352356ba08cSToomas Soome 		return (errbuf);
35310d63b7dSRichard Lowe 	}
354356ba08cSToomas Soome 	return (msg);
35510d63b7dSRichard Lowe }
35610d63b7dSRichard Lowe 
35710d63b7dSRichard Lowe static char static_buf[MAXPATHLEN*3];
35810d63b7dSRichard Lowe 
35910d63b7dSRichard Lowe /*
36010d63b7dSRichard Lowe  *	fatal_mksh(format, args...)
36110d63b7dSRichard Lowe  *
36210d63b7dSRichard Lowe  *	Print a message and die
36310d63b7dSRichard Lowe  *
36410d63b7dSRichard Lowe  *	Parameters:
36510d63b7dSRichard Lowe  *		format		printf type format string
36610d63b7dSRichard Lowe  *		args		Arguments to match the format
36710d63b7dSRichard Lowe  */
36810d63b7dSRichard Lowe /*VARARGS*/
36910d63b7dSRichard Lowe void
fatal_mksh(const char * message,...)37010d63b7dSRichard Lowe fatal_mksh(const char *message, ...)
37110d63b7dSRichard Lowe {
37210d63b7dSRichard Lowe 	va_list args;
37310d63b7dSRichard Lowe 	char    *buf = static_buf;
37410d63b7dSRichard Lowe 	char	*mksh_fat_err = gettext("mksh: Fatal error: ");
37510d63b7dSRichard Lowe 	char	*cur_wrk_dir = gettext("Current working directory: ");
37610d63b7dSRichard Lowe 	int	mksh_fat_err_len = strlen(mksh_fat_err);
37710d63b7dSRichard Lowe 
37810d63b7dSRichard Lowe 	va_start(args, message);
37910d63b7dSRichard Lowe 	(void) fflush(stdout);
38010d63b7dSRichard Lowe 	(void) strcpy(buf, mksh_fat_err);
38110d63b7dSRichard Lowe 	size_t buf_len = vsnprintf(static_buf + mksh_fat_err_len,
38210d63b7dSRichard Lowe 				   sizeof(static_buf) - mksh_fat_err_len,
38310d63b7dSRichard Lowe 				   message, args)
38410d63b7dSRichard Lowe 			+ mksh_fat_err_len
38510d63b7dSRichard Lowe 			+ strlen(cur_wrk_dir)
38610d63b7dSRichard Lowe 			+ strlen(get_current_path_mksh())
38710d63b7dSRichard Lowe 			+ 3; // "\n\n"
38810d63b7dSRichard Lowe 	va_end(args);
38910d63b7dSRichard Lowe 	if (buf_len >= sizeof(static_buf)) {
39010d63b7dSRichard Lowe 		buf = getmem(buf_len);
39110d63b7dSRichard Lowe 		(void) strcpy(buf, mksh_fat_err);
39210d63b7dSRichard Lowe 		va_start(args, message);
39310d63b7dSRichard Lowe 		(void) vsprintf(buf + mksh_fat_err_len, message, args);
39410d63b7dSRichard Lowe 		va_end(args);
39510d63b7dSRichard Lowe 	}
39610d63b7dSRichard Lowe 	(void) strcat(buf, "\n");
39710d63b7dSRichard Lowe /*
39810d63b7dSRichard Lowe 	if (report_pwd) {
39910d63b7dSRichard Lowe  */
40010d63b7dSRichard Lowe 	if (1) {
40110d63b7dSRichard Lowe 		(void) strcat(buf, cur_wrk_dir);
40210d63b7dSRichard Lowe 		(void) strcat(buf, get_current_path_mksh());
40310d63b7dSRichard Lowe 		(void) strcat(buf, "\n");
40410d63b7dSRichard Lowe 	}
40510d63b7dSRichard Lowe 	(void) fputs(buf, stderr);
40610d63b7dSRichard Lowe 	(void) fflush(stderr);
40710d63b7dSRichard Lowe 	if (buf != static_buf) {
40810d63b7dSRichard Lowe 		retmem_mb(buf);
40910d63b7dSRichard Lowe 	}
41010d63b7dSRichard Lowe 	exit_status = 1;
41110d63b7dSRichard Lowe 	exit(1);
41210d63b7dSRichard Lowe }
41310d63b7dSRichard Lowe 
41410d63b7dSRichard Lowe /*
41510d63b7dSRichard Lowe  *	fatal_reader_mksh(format, args...)
41610d63b7dSRichard Lowe  *
41710d63b7dSRichard Lowe  *	Parameters:
41810d63b7dSRichard Lowe  *		format		printf style format string
41910d63b7dSRichard Lowe  *		args		arguments to match the format
42010d63b7dSRichard Lowe  */
42110d63b7dSRichard Lowe /*VARARGS*/
42210d63b7dSRichard Lowe void
fatal_reader_mksh(const char * pattern,...)42310d63b7dSRichard Lowe fatal_reader_mksh(const char * pattern, ...)
42410d63b7dSRichard Lowe {
42510d63b7dSRichard Lowe 	va_list args;
42610d63b7dSRichard Lowe 	char	message[1000];
42710d63b7dSRichard Lowe 
42810d63b7dSRichard Lowe 	va_start(args, pattern);
42910d63b7dSRichard Lowe /*
43010d63b7dSRichard Lowe 	if (file_being_read != NULL) {
43110d63b7dSRichard Lowe 		WCSTOMBS(mbs_buffer, file_being_read);
43210d63b7dSRichard Lowe 		if (line_number != 0) {
43310d63b7dSRichard Lowe 			(void) sprintf(message,
43410d63b7dSRichard Lowe 				       gettext("%s, line %d: %s"),
43510d63b7dSRichard Lowe 				       mbs_buffer,
43610d63b7dSRichard Lowe 				       line_number,
43710d63b7dSRichard Lowe 				       pattern);
43810d63b7dSRichard Lowe 		} else {
43910d63b7dSRichard Lowe 			(void) sprintf(message,
44010d63b7dSRichard Lowe 				       "%s: %s",
44110d63b7dSRichard Lowe 				       mbs_buffer,
44210d63b7dSRichard Lowe 				       pattern);
44310d63b7dSRichard Lowe 		}
44410d63b7dSRichard Lowe 		pattern = message;
44510d63b7dSRichard Lowe 	}
44610d63b7dSRichard Lowe  */
44710d63b7dSRichard Lowe 
44810d63b7dSRichard Lowe 	(void) fflush(stdout);
44910d63b7dSRichard Lowe 	(void) fprintf(stderr, gettext("mksh: Fatal error in reader: "));
45010d63b7dSRichard Lowe 	(void) vfprintf(stderr, pattern, args);
45110d63b7dSRichard Lowe 	(void) fprintf(stderr, "\n");
45210d63b7dSRichard Lowe 	va_end(args);
45310d63b7dSRichard Lowe 
45410d63b7dSRichard Lowe /*
45510d63b7dSRichard Lowe 	if (temp_file_name != NULL) {
45610d63b7dSRichard Lowe 		(void) fprintf(stderr,
45710d63b7dSRichard Lowe 			       gettext("mksh: Temp-file %s not removed\n"),
45810d63b7dSRichard Lowe 			       temp_file_name->string_mb);
45910d63b7dSRichard Lowe 		temp_file_name = NULL;
46010d63b7dSRichard Lowe 	}
46110d63b7dSRichard Lowe  */
46210d63b7dSRichard Lowe 
46310d63b7dSRichard Lowe /*
46410d63b7dSRichard Lowe 	if (report_pwd) {
46510d63b7dSRichard Lowe  */
46610d63b7dSRichard Lowe 	if (1) {
46710d63b7dSRichard Lowe 		(void) fprintf(stderr,
46810d63b7dSRichard Lowe 			       gettext("Current working directory %s\n"),
46910d63b7dSRichard Lowe 			       get_current_path_mksh());
47010d63b7dSRichard Lowe 	}
47110d63b7dSRichard Lowe 	(void) fflush(stderr);
47210d63b7dSRichard Lowe 	exit_status = 1;
47310d63b7dSRichard Lowe 	exit(1);
47410d63b7dSRichard Lowe }
47510d63b7dSRichard Lowe 
47610d63b7dSRichard Lowe /*
47710d63b7dSRichard Lowe  *	warning_mksh(format, args...)
47810d63b7dSRichard Lowe  *
47910d63b7dSRichard Lowe  *	Print a message and continue.
48010d63b7dSRichard Lowe  *
48110d63b7dSRichard Lowe  *	Parameters:
48210d63b7dSRichard Lowe  *		format		printf type format string
48310d63b7dSRichard Lowe  *		args		Arguments to match the format
48410d63b7dSRichard Lowe  */
48510d63b7dSRichard Lowe /*VARARGS*/
48610d63b7dSRichard Lowe void
warning_mksh(char * message,...)48710d63b7dSRichard Lowe warning_mksh(char * message, ...)
48810d63b7dSRichard Lowe {
48910d63b7dSRichard Lowe 	va_list args;
49010d63b7dSRichard Lowe 
49110d63b7dSRichard Lowe 	va_start(args, message);
49210d63b7dSRichard Lowe 	(void) fflush(stdout);
49310d63b7dSRichard Lowe 	(void) fprintf(stderr, gettext("mksh: Warning: "));
49410d63b7dSRichard Lowe 	(void) vfprintf(stderr, message, args);
49510d63b7dSRichard Lowe 	(void) fprintf(stderr, "\n");
49610d63b7dSRichard Lowe 	va_end(args);
49710d63b7dSRichard Lowe /*
49810d63b7dSRichard Lowe 	if (report_pwd) {
49910d63b7dSRichard Lowe  */
50010d63b7dSRichard Lowe 	if (1) {
50110d63b7dSRichard Lowe 		(void) fprintf(stderr,
50210d63b7dSRichard Lowe 			       gettext("Current working directory %s\n"),
50310d63b7dSRichard Lowe 			       get_current_path_mksh());
50410d63b7dSRichard Lowe 	}
50510d63b7dSRichard Lowe 	(void) fflush(stderr);
50610d63b7dSRichard Lowe }
50710d63b7dSRichard Lowe 
50810d63b7dSRichard Lowe /*
50910d63b7dSRichard Lowe  *	get_current_path_mksh()
51010d63b7dSRichard Lowe  *
51110d63b7dSRichard Lowe  *	Stuff current_path with the current path if it isnt there already.
51210d63b7dSRichard Lowe  *
51310d63b7dSRichard Lowe  *	Parameters:
51410d63b7dSRichard Lowe  *
51510d63b7dSRichard Lowe  *	Global variables used:
51610d63b7dSRichard Lowe  */
51710d63b7dSRichard Lowe char *
get_current_path_mksh(void)51810d63b7dSRichard Lowe get_current_path_mksh(void)
51910d63b7dSRichard Lowe {
52010d63b7dSRichard Lowe 	char			pwd[(MAXPATHLEN * MB_LEN_MAX)];
52110d63b7dSRichard Lowe 	static char		*current_path;
52210d63b7dSRichard Lowe 
52310d63b7dSRichard Lowe 	if (current_path == NULL) {
52410d63b7dSRichard Lowe 		getcwd(pwd, sizeof(pwd));
52510d63b7dSRichard Lowe 		if (pwd[0] == (int) nul_char) {
52610d63b7dSRichard Lowe 			pwd[0] = (int) slash_char;
52710d63b7dSRichard Lowe 			pwd[1] = (int) nul_char;
52810d63b7dSRichard Lowe 		}
52910d63b7dSRichard Lowe 		current_path = strdup(pwd);
53010d63b7dSRichard Lowe 	}
53110d63b7dSRichard Lowe 	return current_path;
53210d63b7dSRichard Lowe }
53310d63b7dSRichard Lowe 
53410d63b7dSRichard Lowe /*
53510d63b7dSRichard Lowe  *	append_prop(target, type)
53610d63b7dSRichard Lowe  *
53710d63b7dSRichard Lowe  *	Create a new property and append it to the property list of a Name.
53810d63b7dSRichard Lowe  *
53910d63b7dSRichard Lowe  *	Return value:
54010d63b7dSRichard Lowe  *				A new property block for the target
54110d63b7dSRichard Lowe  *
54210d63b7dSRichard Lowe  *	Parameters:
54310d63b7dSRichard Lowe  *		target		The target that wants a new property
54410d63b7dSRichard Lowe  *		type		The type of property being requested
54510d63b7dSRichard Lowe  *
54610d63b7dSRichard Lowe  *	Global variables used:
54710d63b7dSRichard Lowe  */
54810d63b7dSRichard Lowe Property
append_prop(Name target,Property_id type)549*e7afc443SToomas Soome append_prop(Name target, Property_id type)
55010d63b7dSRichard Lowe {
551*e7afc443SToomas Soome 	Property	*insert = &target->prop;
552*e7afc443SToomas Soome 	Property	prop = *insert;
553*e7afc443SToomas Soome 	int		size;
55410d63b7dSRichard Lowe 
55510d63b7dSRichard Lowe 	switch (type) {
55610d63b7dSRichard Lowe 	case conditional_prop:
55710d63b7dSRichard Lowe 		size = sizeof (struct Conditional);
55810d63b7dSRichard Lowe 		break;
55910d63b7dSRichard Lowe 	case line_prop:
56010d63b7dSRichard Lowe 		size = sizeof (struct Line);
56110d63b7dSRichard Lowe 		break;
56210d63b7dSRichard Lowe 	case macro_prop:
56310d63b7dSRichard Lowe 		size = sizeof (struct _Macro);
56410d63b7dSRichard Lowe 		break;
56510d63b7dSRichard Lowe 	case makefile_prop:
56610d63b7dSRichard Lowe 		size = sizeof (struct Makefile);
56710d63b7dSRichard Lowe 		break;
56810d63b7dSRichard Lowe 	case member_prop:
56910d63b7dSRichard Lowe 		size = sizeof (struct Member);
57010d63b7dSRichard Lowe 		break;
57110d63b7dSRichard Lowe 	case recursive_prop:
57210d63b7dSRichard Lowe 		size = sizeof (struct Recursive);
57310d63b7dSRichard Lowe 		break;
57410d63b7dSRichard Lowe 	case sccs_prop:
57510d63b7dSRichard Lowe 		size = sizeof (struct Sccs);
57610d63b7dSRichard Lowe 		break;
57710d63b7dSRichard Lowe 	case suffix_prop:
57810d63b7dSRichard Lowe 		size = sizeof (struct Suffix);
57910d63b7dSRichard Lowe 		break;
58010d63b7dSRichard Lowe 	case target_prop:
58110d63b7dSRichard Lowe 		size = sizeof (struct Target);
58210d63b7dSRichard Lowe 		break;
58310d63b7dSRichard Lowe 	case time_prop:
58410d63b7dSRichard Lowe 		size = sizeof (struct STime);
58510d63b7dSRichard Lowe 		break;
58610d63b7dSRichard Lowe 	case vpath_alias_prop:
58710d63b7dSRichard Lowe 		size = sizeof (struct Vpath_alias);
58810d63b7dSRichard Lowe 		break;
58910d63b7dSRichard Lowe 	case long_member_name_prop:
59010d63b7dSRichard Lowe 		size = sizeof (struct Long_member_name);
59110d63b7dSRichard Lowe 		break;
59210d63b7dSRichard Lowe 	case macro_append_prop:
59310d63b7dSRichard Lowe 		size = sizeof (struct _Macro_appendix);
59410d63b7dSRichard Lowe 		break;
59510d63b7dSRichard Lowe 	case env_mem_prop:
59610d63b7dSRichard Lowe 		size = sizeof (struct _Env_mem);
59710d63b7dSRichard Lowe 		break;
59810d63b7dSRichard Lowe 	default:
59910d63b7dSRichard Lowe 		fatal_mksh(gettext("Internal error. Unknown prop type %d"), type);
60010d63b7dSRichard Lowe 	}
60110d63b7dSRichard Lowe 	for (; prop != NULL; insert = &prop->next, prop = *insert);
60210d63b7dSRichard Lowe 	size += PROPERTY_HEAD_SIZE;
60310d63b7dSRichard Lowe 	*insert = prop = (Property) getmem(size);
60410d63b7dSRichard Lowe 	memset((char *) prop, 0, size);
60510d63b7dSRichard Lowe 	prop->type = type;
60610d63b7dSRichard Lowe 	prop->next = NULL;
60710d63b7dSRichard Lowe 	return prop;
60810d63b7dSRichard Lowe }
60910d63b7dSRichard Lowe 
61010d63b7dSRichard Lowe /*
61110d63b7dSRichard Lowe  *	maybe_append_prop(target, type)
61210d63b7dSRichard Lowe  *
61310d63b7dSRichard Lowe  *	Append a property to the Name if none of this type exists
61410d63b7dSRichard Lowe  *	else return the one already there
61510d63b7dSRichard Lowe  *
61610d63b7dSRichard Lowe  *	Return value:
61710d63b7dSRichard Lowe  *				A property of the requested type for the target
61810d63b7dSRichard Lowe  *
61910d63b7dSRichard Lowe  *	Parameters:
62010d63b7dSRichard Lowe  *		target		The target that wants a new property
62110d63b7dSRichard Lowe  *		type		The type of property being requested
62210d63b7dSRichard Lowe  *
62310d63b7dSRichard Lowe  *	Global variables used:
62410d63b7dSRichard Lowe  */
62510d63b7dSRichard Lowe Property
maybe_append_prop(Name target,Property_id type)626*e7afc443SToomas Soome maybe_append_prop(Name target, Property_id type)
62710d63b7dSRichard Lowe {
628*e7afc443SToomas Soome 	Property	prop;
62910d63b7dSRichard Lowe 
63010d63b7dSRichard Lowe 	if ((prop = get_prop(target->prop, type)) != NULL) {
63110d63b7dSRichard Lowe 		return prop;
63210d63b7dSRichard Lowe 	}
63310d63b7dSRichard Lowe 	return append_prop(target, type);
63410d63b7dSRichard Lowe }
63510d63b7dSRichard Lowe 
63610d63b7dSRichard Lowe /*
63710d63b7dSRichard Lowe  *	get_prop(start, type)
63810d63b7dSRichard Lowe  *
63910d63b7dSRichard Lowe  *	Scan the property list of a Name to find the next property
64010d63b7dSRichard Lowe  *	of a given type.
64110d63b7dSRichard Lowe  *
64210d63b7dSRichard Lowe  *	Return value:
64310d63b7dSRichard Lowe  *				The first property of the type, if any left
64410d63b7dSRichard Lowe  *
64510d63b7dSRichard Lowe  *	Parameters:
64610d63b7dSRichard Lowe  *		start		The first property block to check for type
64710d63b7dSRichard Lowe  *		type		The type of property block we need
64810d63b7dSRichard Lowe  *
64910d63b7dSRichard Lowe  *	Global variables used:
65010d63b7dSRichard Lowe  */
65110d63b7dSRichard Lowe Property
get_prop(Property start,Property_id type)652*e7afc443SToomas Soome get_prop(Property start, Property_id type)
65310d63b7dSRichard Lowe {
65410d63b7dSRichard Lowe 	for (; start != NULL; start = start->next) {
65510d63b7dSRichard Lowe 		if (start->type == type) {
65610d63b7dSRichard Lowe 			return start;
65710d63b7dSRichard Lowe 		}
65810d63b7dSRichard Lowe 	}
65910d63b7dSRichard Lowe 	return NULL;
66010d63b7dSRichard Lowe }
66110d63b7dSRichard Lowe 
66210d63b7dSRichard Lowe /*
66310d63b7dSRichard Lowe  *	append_string(from, to, length)
66410d63b7dSRichard Lowe  *
66510d63b7dSRichard Lowe  *	Append a C string to a make string expanding it if nessecary
66610d63b7dSRichard Lowe  *
66710d63b7dSRichard Lowe  *	Parameters:
66810d63b7dSRichard Lowe  *		from		The source (C style) string
66910d63b7dSRichard Lowe  *		to		The destination (make style) string
67010d63b7dSRichard Lowe  *		length		The length of the from string
67110d63b7dSRichard Lowe  *
67210d63b7dSRichard Lowe  *	Global variables used:
67310d63b7dSRichard Lowe  */
67410d63b7dSRichard Lowe void
append_string(wchar_t * from,String to,int length)675*e7afc443SToomas Soome append_string(wchar_t *from, String to, int length)
67610d63b7dSRichard Lowe {
67710d63b7dSRichard Lowe 	if (length == FIND_LENGTH) {
67810d63b7dSRichard Lowe 		length = wcslen(from);
67910d63b7dSRichard Lowe 	}
68010d63b7dSRichard Lowe 	if (to->buffer.start == NULL) {
68110d63b7dSRichard Lowe 		expand_string(to, 32 + length);
68210d63b7dSRichard Lowe 	}
68310d63b7dSRichard Lowe 	if (to->buffer.end - to->text.p <= length) {
68410d63b7dSRichard Lowe 		expand_string(to,
68510d63b7dSRichard Lowe 			      (to->buffer.end - to->buffer.start) * 2 +
68610d63b7dSRichard Lowe 			      length);
68710d63b7dSRichard Lowe 	}
68810d63b7dSRichard Lowe 	if (length > 0) {
68910d63b7dSRichard Lowe 		(void) wcsncpy(to->text.p, from, length);
69010d63b7dSRichard Lowe 		to->text.p += length;
69110d63b7dSRichard Lowe 	}
69210d63b7dSRichard Lowe 	*(to->text.p) = (int) nul_char;
69310d63b7dSRichard Lowe }
69410d63b7dSRichard Lowe 
get_wstring(char * from)69510d63b7dSRichard Lowe wchar_t * get_wstring(char *from) {
69610d63b7dSRichard Lowe 	if(from == NULL) {
69710d63b7dSRichard Lowe 		return NULL;
69810d63b7dSRichard Lowe 	}
69910d63b7dSRichard Lowe 	getwstring_count++;
70010d63b7dSRichard Lowe 	wchar_t * wcbuf = ALLOC_WC(strlen(from) + 1);
701