xref: /illumos-gate/usr/src/cmd/make/lib/mksh/read.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  *	read.c
2910d63b7dSRichard Lowe  *
3010d63b7dSRichard Lowe  *	This file contains the makefile reader.
3110d63b7dSRichard Lowe  */
3210d63b7dSRichard Lowe 
3310d63b7dSRichard Lowe /*
3410d63b7dSRichard Lowe  * Included files
3510d63b7dSRichard Lowe  */
3610d63b7dSRichard Lowe #include <mksh/misc.h>		/* retmem() */
3710d63b7dSRichard Lowe #include <mksh/read.h>
3810d63b7dSRichard Lowe #include <sys/uio.h>		/* read() */
3910d63b7dSRichard Lowe #include <unistd.h>		/* close(), unlink(), read() */
4010d63b7dSRichard Lowe #include <libintl.h>
4110d63b7dSRichard Lowe 
4210d63b7dSRichard Lowe #define	STRING_LEN_TO_CONVERT	(8*1024)
4310d63b7dSRichard Lowe 
4410d63b7dSRichard Lowe /*
4510d63b7dSRichard Lowe  *	get_next_block_fn(source)
4610d63b7dSRichard Lowe  *
4710d63b7dSRichard Lowe  *	Will get the next block of text to read either
4810d63b7dSRichard Lowe  *	by popping one source bVSIZEOFlock of the stack of Sources
4910d63b7dSRichard Lowe  *	or by reading some more from the makefile.
5010d63b7dSRichard Lowe  *
5110d63b7dSRichard Lowe  *	Return value:
5210d63b7dSRichard Lowe  *				The new source block to read from
5310d63b7dSRichard Lowe  *
5410d63b7dSRichard Lowe  *	Parameters:
5510d63b7dSRichard Lowe  *		source		The old source block
5610d63b7dSRichard Lowe  *
5710d63b7dSRichard Lowe  *	Global variables used:
5810d63b7dSRichard Lowe  *		file_being_read	The name of the current file, error msg
5910d63b7dSRichard Lowe  */
6010d63b7dSRichard Lowe Boolean		make_state_locked;
6110d63b7dSRichard Lowe Source
get_next_block_fn(Source source)62*e7afc443SToomas Soome get_next_block_fn(Source source)
6310d63b7dSRichard Lowe {
64*e7afc443SToomas Soome 	off_t		to_read;
65*e7afc443SToomas Soome 	int		length;
66*e7afc443SToomas Soome 	size_t		num_wc_chars;
6710d63b7dSRichard Lowe 	char			ch_save;
6810d63b7dSRichard Lowe 	char			*ptr;
6910d63b7dSRichard Lowe 
7010d63b7dSRichard Lowe 	if (source == NULL) {
7110d63b7dSRichard Lowe 		return NULL;
7210d63b7dSRichard Lowe 	}
73*e7afc443SToomas Soome 	if ((source->fd < 0) ||
7410d63b7dSRichard Lowe 		((source->bytes_left_in_file <= 0) &&
7510d63b7dSRichard Lowe 			(source->inp_buf_ptr >= source->inp_buf_end))) {
7610d63b7dSRichard Lowe 		/* We can't read from the makefile, so pop the source block */
7710d63b7dSRichard Lowe 		if (source->fd > 2) {
7810d63b7dSRichard Lowe 			(void) close(source->fd);
7910d63b7dSRichard Lowe 			if (make_state_lockfile != NULL) {
8010d63b7dSRichard Lowe 				(void) unlink(make_state_lockfile);
8110d63b7dSRichard Lowe 				retmem_mb(make_state_lockfile);
8210d63b7dSRichard Lowe 				make_state_lockfile = NULL;
8310d63b7dSRichard Lowe 				make_state_locked = false;
8410d63b7dSRichard Lowe 			}
8510d63b7dSRichard Lowe 		}
8610d63b7dSRichard Lowe 		if (source->string.free_after_use &&
8710d63b7dSRichard Lowe 		    (source->string.buffer.start != NULL)) {
8810d63b7dSRichard Lowe 			retmem(source->string.buffer.start);
8910d63b7dSRichard Lowe 			source->string.buffer.start = NULL;
9010d63b7dSRichard Lowe 		}
9110d63b7dSRichard Lowe 		if (source->inp_buf != NULL) {
9210d63b7dSRichard Lowe 			retmem_mb(source->inp_buf);
9310d63b7dSRichard Lowe 			source->inp_buf = NULL;
9410d63b7dSRichard Lowe 		}
9510d63b7dSRichard Lowe 		source = source->previous;
9610d63b7dSRichard Lowe 		if (source != NULL) {
9710d63b7dSRichard Lowe 			source->error_converting = false;
9810d63b7dSRichard Lowe 		}
9910d63b7dSRichard Lowe 		return source;
10010d63b7dSRichard Lowe 	}
10110d63b7dSRichard Lowe 	if (source->bytes_left_in_file > 0) {
10210d63b7dSRichard Lowe 	/*
10310d63b7dSRichard Lowe 	 * Read the whole makefile.
10410d63b7dSRichard Lowe 	 * Hopefully the kernel managed to prefetch the stuff.
10510d63b7dSRichard Lowe 	 */
10610d63b7dSRichard Lowe 		to_read = source->bytes_left_in_file;
107*e7afc443SToomas Soome 		source->inp_buf_ptr = source->inp_buf = getmem(to_read + 1);
10810d63b7dSRichard Lowe 		source->inp_buf_end = source->inp_buf + to_read;
10910d63b7dSRichard Lowe 		length = read(source->fd, source->inp_buf, (unsigned int) to_read);
11010d63b7dSRichard Lowe 		if (length != to_read) {
11110d63b7dSRichard Lowe 			WCSTOMBS(mbs_buffer, file_being_read);
11210d63b7dSRichard Lowe 			if (length == 0) {
11310d63b7dSRichard Lowe 				fatal_mksh(gettext("Error reading `%s': Premature EOF"),
11410d63b7dSRichard Lowe 				      mbs_buffer);
11510d63b7dSRichard Lowe 			} else {
11610d63b7dSRichard Lowe 				fatal_mksh(gettext("Error reading `%s': %s"),
11710d63b7dSRichard Lowe 				      mbs_buffer,
11810d63b7dSRichard Lowe 				      errmsg(errno));
11910d63b7dSRichard Lowe 			}
12010d63b7dSRichard Lowe 		}
12110d63b7dSRichard Lowe 		*source->inp_buf_end = nul_char;
12210d63b7dSRichard Lowe 		source->bytes_left_in_file = 0;
12310d63b7dSRichard Lowe 	}
12410d63b7dSRichard Lowe 	/*
12510d63b7dSRichard Lowe 	 * Try to convert the next piece.
12610d63b7dSRichard Lowe 	 */
12710d63b7dSRichard Lowe 	ptr = source->inp_buf_ptr + STRING_LEN_TO_CONVERT;
12810d63b7dSRichard Lowe 	if (ptr > source->inp_buf_end) {
12910d63b7dSRichard Lowe 		ptr = source->inp_buf_end;
13010d63b7dSRichard Lowe 	}
13110d63b7dSRichard Lowe 	for (num_wc_chars = 0; ptr > source->inp_buf_ptr; ptr--) {
13210d63b7dSRichard Lowe 		ch_save = *ptr;
13310d63b7dSRichard Lowe 		*ptr = nul_char;
13410d63b7dSRichard Lowe 		num_wc_chars = mbstowcs(source->string.text.end,
13510d63b7dSRichard Lowe 					source->inp_buf_ptr,
13610d63b7dSRichard Lowe 					STRING_LEN_TO_CONVERT);
13710d63b7dSRichard Lowe 		*ptr = ch_save;
13810d63b7dSRichard Lowe 		if (num_wc_chars != (size_t)-1) {
13910d63b7dSRichard Lowe 			break;
14010d63b7dSRichard Lowe 		}
14110d63b7dSRichard Lowe 	}
142*e7afc443SToomas Soome 
14310d63b7dSRichard Lowe 	if ((int) num_wc_chars == (size_t)-1) {
14410d63b7dSRichard Lowe 		source->error_converting = true;
14510d63b7dSRichard Lowe 		return source;
14610d63b7dSRichard Lowe 	}
14710d63b7dSRichard Lowe 
14810d63b7dSRichard Lowe 	source->error_converting = false;
14910d63b7dSRichard Lowe 	source->inp_buf_ptr = ptr;
15010d63b7dSRichard Lowe 	source->string.text.end += num_wc_chars;
15110d63b7dSRichard Lowe 	*source->string.text.end = 0;
15210d63b7dSRichard Lowe 
15310d63b7dSRichard Lowe 	if (source->inp_buf_ptr >= source->inp_buf_end) {
15410d63b7dSRichard Lowe 		if (*(source->string.text.end - 1) != (int) newline_char) {
15510d63b7dSRichard Lowe 			WCSTOMBS(mbs_buffer, file_being_read);
15610d63b7dSRichard Lowe 			warning_mksh(gettext("newline is not last character in file %s"),
15710d63b7dSRichard Lowe 					     mbs_buffer);
15810d63b7dSRichard Lowe 			*source->string.text.end++ = (int) newline_char;
15910d63b7dSRichard Lowe 			*source->string.text.end = (int) nul_char;
16010d63b7dSRichard Lowe 			*source->string.buffer.end++;
16110d63b7dSRichard Lowe 		}
16210d63b7dSRichard Lowe 		if (source->inp_buf != NULL) {
16310d63b7dSRichard Lowe 			retmem_mb(source->inp_buf);
16410d63b7dSRichard Lowe 			source->inp_buf = NULL;
16510d63b7dSRichard Lowe 		}
16610d63b7dSRichard Lowe 	}
16710d63b7dSRichard Lowe 	return source;
16810d63b7dSRichard Lowe }
16910d63b7dSRichard Lowe 
17010d63b7dSRichard Lowe 
171