4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
30 * This file contains the makefile reader.
36 #include <mksh/misc.h> /* retmem() */
37 #include <mksh/read.h>
38 #include <sys/uio.h> /* read() */
39 #include <unistd.h> /* close(), unlink(), read() */
42 #define STRING_LEN_TO_CONVERT (8*1024)
45 * get_next_block_fn(source)
47 * Will get the next block of text to read either
48 * by popping one source bVSIZEOFlock of the stack of Sources
49 * or by reading some more from the makefile.
52 * The new source block to read from
55 * source The old source block
57 * Global variables used:
58 * file_being_read The name of the current file, error msg
60 Boolean make_state_locked
;
62 get_next_block_fn(register Source source
)
64 register off_t to_read
;
66 register size_t num_wc_chars
;
73 if ((source
->fd
< 0) ||
74 ((source
->bytes_left_in_file
<= 0) &&
75 (source
->inp_buf_ptr
>= source
->inp_buf_end
))) {
76 /* We can't read from the makefile, so pop the source block */
78 (void) close(source
->fd
);
79 if (make_state_lockfile
!= NULL
) {
80 (void) unlink(make_state_lockfile
);
81 retmem_mb(make_state_lockfile
);
82 make_state_lockfile
= NULL
;
83 make_state_locked
= false;
86 if (source
->string
.free_after_use
&&
87 (source
->string
.buffer
.start
!= NULL
)) {
88 retmem(source
->string
.buffer
.start
);
89 source
->string
.buffer
.start
= NULL
;
91 if (source
->inp_buf
!= NULL
) {
92 retmem_mb(source
->inp_buf
);
93 source
->inp_buf
= NULL
;
95 source
= source
->previous
;
97 source
->error_converting
= false;
101 if (source
->bytes_left_in_file
> 0) {
103 * Read the whole makefile.
104 * Hopefully the kernel managed to prefetch the stuff.
106 to_read
= source
->bytes_left_in_file
;
107 source
->inp_buf_ptr
= source
->inp_buf
= getmem(to_read
+ 1);
108 source
->inp_buf_end
= source
->inp_buf
+ to_read
;
109 length
= read(source
->fd
, source
->inp_buf
, (unsigned int) to_read
);
110 if (length
!= to_read
) {
111 WCSTOMBS(mbs_buffer
, file_being_read
);
113 fatal_mksh(gettext("Error reading `%s': Premature EOF"),
116 fatal_mksh(gettext("Error reading `%s': %s"),
121 *source
->inp_buf_end
= nul_char
;
122 source
->bytes_left_in_file
= 0;
125 * Try to convert the next piece.
127 ptr
= source
->inp_buf_ptr
+ STRING_LEN_TO_CONVERT
;
128 if (ptr
> source
->inp_buf_end
) {
129 ptr
= source
->inp_buf_end
;
131 for (num_wc_chars
= 0; ptr
> source
->inp_buf_ptr
; ptr
--) {
134 num_wc_chars
= mbstowcs(source
->string
.text
.end
,
136 STRING_LEN_TO_CONVERT
);
138 if (num_wc_chars
!= (size_t)-1) {
143 if ((int) num_wc_chars
== (size_t)-1) {
144 source
->error_converting
= true;
148 source
->error_converting
= false;
149 source
->inp_buf_ptr
= ptr
;
150 source
->string
.text
.end
+= num_wc_chars
;
151 *source
->string
.text
.end
= 0;
153 if (source
->inp_buf_ptr
>= source
->inp_buf_end
) {
154 if (*(source
->string
.text
.end
- 1) != (int) newline_char
) {
155 WCSTOMBS(mbs_buffer
, file_being_read
);
156 warning_mksh(gettext("newline is not last character in file %s"),
158 *source
->string
.text
.end
++ = (int) newline_char
;
159 *source
->string
.text
.end
= (int) nul_char
;
160 *source
->string
.buffer
.end
++;
162 if (source
->inp_buf
!= NULL
) {
163 retmem_mb(source
->inp_buf
);
164 source
->inp_buf
= NULL
;