1*10d63b7dSRichard Lowe /*
2*10d63b7dSRichard Lowe * CDDL HEADER START
3*10d63b7dSRichard Lowe *
4*10d63b7dSRichard Lowe * The contents of this file are subject to the terms of the
5*10d63b7dSRichard Lowe * Common Development and Distribution License (the "License").
6*10d63b7dSRichard Lowe * You may not use this file except in compliance with the License.
7*10d63b7dSRichard Lowe *
8*10d63b7dSRichard Lowe * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*10d63b7dSRichard Lowe * or http://www.opensolaris.org/os/licensing.
10*10d63b7dSRichard Lowe * See the License for the specific language governing permissions
11*10d63b7dSRichard Lowe * and limitations under the License.
12*10d63b7dSRichard Lowe *
13*10d63b7dSRichard Lowe * When distributing Covered Code, include this CDDL HEADER in each
14*10d63b7dSRichard Lowe * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*10d63b7dSRichard Lowe * If applicable, add the following below this CDDL HEADER, with the
16*10d63b7dSRichard Lowe * fields enclosed by brackets "[]" replaced with your own identifying
17*10d63b7dSRichard Lowe * information: Portions Copyright [yyyy] [name of copyright owner]
18*10d63b7dSRichard Lowe *
19*10d63b7dSRichard Lowe * CDDL HEADER END
20*10d63b7dSRichard Lowe */
21*10d63b7dSRichard Lowe /*
22*10d63b7dSRichard Lowe * Copyright 2005 Sun Microsystems, Inc. All rights reserved.
23*10d63b7dSRichard Lowe * Use is subject to license terms.
24*10d63b7dSRichard Lowe */
25*10d63b7dSRichard Lowe
26*10d63b7dSRichard Lowe /*
27*10d63b7dSRichard Lowe * read.c
28*10d63b7dSRichard Lowe *
29*10d63b7dSRichard Lowe * This file contains the makefile reader.
30*10d63b7dSRichard Lowe */
31*10d63b7dSRichard Lowe
32*10d63b7dSRichard Lowe /*
33*10d63b7dSRichard Lowe * Included files
34*10d63b7dSRichard Lowe */
35*10d63b7dSRichard Lowe #include <mk/defs.h>
36*10d63b7dSRichard Lowe #include <mksh/dosys.h> /* sh_command2string() */
37*10d63b7dSRichard Lowe #include <mksh/macro.h> /* expand_value() */
38*10d63b7dSRichard Lowe #include <mksh/misc.h> /* retmem() */
39*10d63b7dSRichard Lowe #include <stdarg.h> /* va_list, va_start(), va_end() */
40*10d63b7dSRichard Lowe #include <libintl.h>
41*10d63b7dSRichard Lowe
42*10d63b7dSRichard Lowe /*
43*10d63b7dSRichard Lowe * Defined macros
44*10d63b7dSRichard Lowe */
45*10d63b7dSRichard Lowe
46*10d63b7dSRichard Lowe /*
47*10d63b7dSRichard Lowe * typedefs & structs
48*10d63b7dSRichard Lowe */
49*10d63b7dSRichard Lowe
50*10d63b7dSRichard Lowe /*
51*10d63b7dSRichard Lowe * Static variables
52*10d63b7dSRichard Lowe */
53*10d63b7dSRichard Lowe static Boolean built_last_make_run_seen;
54*10d63b7dSRichard Lowe
55*10d63b7dSRichard Lowe /*
56*10d63b7dSRichard Lowe * File table of contents
57*10d63b7dSRichard Lowe */
58*10d63b7dSRichard Lowe static Name_vector enter_member_name(register wchar_t *lib_start, register wchar_t *member_start, register wchar_t *string_end, Name_vector current_names, Name_vector *extra_names);
59*10d63b7dSRichard Lowe extern Name normalize_name(register wchar_t *name_string, register int length);
60*10d63b7dSRichard Lowe static void read_suffixes_list(register Name_vector depes);
61*10d63b7dSRichard Lowe static void make_relative(wchar_t *to, wchar_t *result);
62*10d63b7dSRichard Lowe static void print_rule(register Cmd_line command);
63*10d63b7dSRichard Lowe static void sh_transform(Name *name, Name *value);
64*10d63b7dSRichard Lowe
65*10d63b7dSRichard Lowe
66*10d63b7dSRichard Lowe /*
67*10d63b7dSRichard Lowe * enter_name(string, tail_present, string_start, string_end,
68*10d63b7dSRichard Lowe * current_names, extra_names, target_group_seen)
69*10d63b7dSRichard Lowe *
70*10d63b7dSRichard Lowe * Take one string and enter it as a name. The string is passed in
71*10d63b7dSRichard Lowe * two parts. A make string and possibly a C string to append to it.
72*10d63b7dSRichard Lowe * The result is stuffed in the vector current_names.
73*10d63b7dSRichard Lowe * extra_names points to a vector that is used if current_names overflows.
74*10d63b7dSRichard Lowe * This is allocad in the calling routine.
75*10d63b7dSRichard Lowe * Here we handle the "lib.a[members]" notation.
76*10d63b7dSRichard Lowe *
77*10d63b7dSRichard Lowe * Return value:
78*10d63b7dSRichard Lowe * The name vector that was used
79*10d63b7dSRichard Lowe *
80*10d63b7dSRichard Lowe * Parameters:
81*10d63b7dSRichard Lowe * tail_present Indicates if both C and make string was passed
82*10d63b7dSRichard Lowe * string_start C string
83*10d63b7dSRichard Lowe * string_end Pointer to char after last in C string
84*10d63b7dSRichard Lowe * string make style string with head of name
85*10d63b7dSRichard Lowe * current_names Vector to deposit the name in
86*10d63b7dSRichard Lowe * extra_names Where to get next name vector if we run out
87*10d63b7dSRichard Lowe * target_group_seen Pointer to boolean that is set if "+" is seen
88*10d63b7dSRichard Lowe *
89*10d63b7dSRichard Lowe * Global variables used:
90*10d63b7dSRichard Lowe * makefile_type When we read a report file we normalize paths
91*10d63b7dSRichard Lowe * plus Points to the Name "+"
92*10d63b7dSRichard Lowe */
93*10d63b7dSRichard Lowe
94*10d63b7dSRichard Lowe Name_vector
enter_name(String string,Boolean tail_present,register wchar_t * string_start,register wchar_t * string_end,Name_vector current_names,Name_vector * extra_names,Boolean * target_group_seen)95*10d63b7dSRichard Lowe enter_name(String string, Boolean tail_present, register wchar_t *string_start, register wchar_t *string_end, Name_vector current_names, Name_vector *extra_names, Boolean *target_group_seen)
96*10d63b7dSRichard Lowe {
97*10d63b7dSRichard Lowe Name name;
98*10d63b7dSRichard Lowe register wchar_t *cp;
99*10d63b7dSRichard Lowe wchar_t ch;
100*10d63b7dSRichard Lowe
101*10d63b7dSRichard Lowe /* If we were passed a separate tail of the name we append it to the */
102*10d63b7dSRichard Lowe /* make string with the rest of it */
103*10d63b7dSRichard Lowe if (tail_present) {
104*10d63b7dSRichard Lowe append_string(string_start, string, string_end - string_start);
105*10d63b7dSRichard Lowe string_start = string->buffer.start;
106*10d63b7dSRichard Lowe string_end = string->text.p;
107*10d63b7dSRichard Lowe }
108*10d63b7dSRichard Lowe ch = *string_end;
109*10d63b7dSRichard Lowe *string_end = (int) nul_char;
110*10d63b7dSRichard Lowe /*
111*10d63b7dSRichard Lowe * Check if there are any ( or [ that are not prefixed with $.
112*10d63b7dSRichard Lowe * If there are, we have to deal with the lib.a(members) format.
113*10d63b7dSRichard Lowe */
114*10d63b7dSRichard Lowe for (cp = (wchar_t *) wcschr(string_start, (int) parenleft_char);
115*10d63b7dSRichard Lowe cp != NULL;
116*10d63b7dSRichard Lowe cp = (wchar_t *) wcschr(cp + 1, (int) parenleft_char)) {
117*10d63b7dSRichard Lowe if (*(cp - 1) != (int) dollar_char) {
118*10d63b7dSRichard Lowe *string_end = ch;
119*10d63b7dSRichard Lowe return enter_member_name(string_start,
120*10d63b7dSRichard Lowe cp,
121*10d63b7dSRichard Lowe string_end,
122*10d63b7dSRichard Lowe current_names,
123*10d63b7dSRichard Lowe extra_names);
124*10d63b7dSRichard Lowe }
125*10d63b7dSRichard Lowe }
126*10d63b7dSRichard Lowe *string_end = ch;
127*10d63b7dSRichard Lowe
128*10d63b7dSRichard Lowe if (makefile_type == reading_cpp_file) {
129*10d63b7dSRichard Lowe /* Remove extra ../ constructs if we are reading from a report file */
130*10d63b7dSRichard Lowe name = normalize_name(string_start, string_end - string_start);
131*10d63b7dSRichard Lowe } else {
132*10d63b7dSRichard Lowe /*
133*10d63b7dSRichard Lowe * /tolik, fix bug 1197477/
134*10d63b7dSRichard Lowe * Normalize every target name before entering.
135*10d63b7dSRichard Lowe * ..//obj/a.o and ../obj//a.o are not two different targets.
136*10d63b7dSRichard Lowe * There is only one target ../obj/a.o
137*10d63b7dSRichard Lowe */
138*10d63b7dSRichard Lowe /*name = GETNAME(string_start, string_end - string_start);*/
139*10d63b7dSRichard Lowe name = normalize_name(string_start, string_end - string_start);
140*10d63b7dSRichard Lowe }
141*10d63b7dSRichard Lowe
142*10d63b7dSRichard Lowe /* Internalize the name. Detect the name "+" (target group here) */
143*10d63b7dSRichard Lowe if(current_names->used != 0 && current_names->names[current_names->used-1] == plus) {
144*10d63b7dSRichard Lowe if(name == plus) {
145*10d63b7dSRichard Lowe return current_names;
146*10d63b7dSRichard Lowe }
147*10d63b7dSRichard Lowe }
148*10d63b7dSRichard Lowe /* If the current_names vector is full we patch in the one from */
149*10d63b7dSRichard Lowe /* extra_names */
150*10d63b7dSRichard Lowe if (current_names->used == VSIZEOF(current_names->names)) {
151*10d63b7dSRichard Lowe if (current_names->next != NULL) {
152*10d63b7dSRichard Lowe current_names = current_names->next;
153*10d63b7dSRichard Lowe } else {
154*10d63b7dSRichard Lowe current_names->next = *extra_names;
155*10d63b7dSRichard Lowe *extra_names = NULL;
156*10d63b7dSRichard Lowe current_names = current_names->next;
157*10d63b7dSRichard Lowe current_names->used = 0;
158*10d63b7dSRichard Lowe current_names->next = NULL;
159*10d63b7dSRichard Lowe }
160*10d63b7dSRichard Lowe }
161*10d63b7dSRichard Lowe current_names->target_group[current_names->used] = NULL;
162*10d63b7dSRichard Lowe current_names->names[current_names->used++] = name;
163*10d63b7dSRichard Lowe if (name == plus) {
164*10d63b7dSRichard Lowe *target_group_seen = true;
165*10d63b7dSRichard Lowe }
166*10d63b7dSRichard Lowe if (tail_present && string->free_after_use) {
167*10d63b7dSRichard Lowe retmem(string->buffer.start);
168*10d63b7dSRichard Lowe }
169*10d63b7dSRichard Lowe return current_names;
170*10d63b7dSRichard Lowe }
171*10d63b7dSRichard Lowe
172*10d63b7dSRichard Lowe /*
173*10d63b7dSRichard Lowe * enter_member_name(lib_start, member_start, string_end,
174*10d63b7dSRichard Lowe * current_names, extra_names)
175*10d63b7dSRichard Lowe *
176*10d63b7dSRichard Lowe * A string has been found to contain member names.
177*10d63b7dSRichard Lowe * (The "lib.a[members]" and "lib.a(members)" notation)
178*10d63b7dSRichard Lowe * Handle it pretty much as enter_name() does for simple names.
179*10d63b7dSRichard Lowe *
180*10d63b7dSRichard Lowe * Return value:
181*10d63b7dSRichard Lowe * The name vector that was used
182*10d63b7dSRichard Lowe *
183*10d63b7dSRichard Lowe * Parameters:
184*10d63b7dSRichard Lowe * lib_start Points to the of start of "lib.a(member.o)"
185*10d63b7dSRichard Lowe * member_start Points to "member.o" from above string.
186*10d63b7dSRichard Lowe * string_end Points to char after last of above string.
187*10d63b7dSRichard Lowe * current_names Vector to deposit the name in
188*10d63b7dSRichard Lowe * extra_names Where to get next name vector if we run out
189*10d63b7dSRichard Lowe *
190*10d63b7dSRichard Lowe * Global variables used:
191*10d63b7dSRichard Lowe */
192*10d63b7dSRichard Lowe static Name_vector
enter_member_name(register wchar_t * lib_start,register wchar_t * member_start,register wchar_t * string_end,Name_vector current_names,Name_vector * extra_names)193*10d63b7dSRichard Lowe enter_member_name(register wchar_t *lib_start, register wchar_t *member_start, register wchar_t *string_end, Name_vector current_names, Name_vector *extra_names)
194*10d63b7dSRichard Lowe {
195*10d63b7dSRichard Lowe register Boolean entry = false;
196*10d63b7dSRichard Lowe wchar_t buffer[STRING_BUFFER_LENGTH];
197*10d63b7dSRichard Lowe Name lib;
198*10d63b7dSRichard Lowe Name member;
199*10d63b7dSRichard Lowe Name name;
200*10d63b7dSRichard Lowe Property prop;
201*10d63b7dSRichard Lowe wchar_t *memberp;
202*10d63b7dSRichard Lowe wchar_t *q;
203*10d63b7dSRichard Lowe register int paren_count;
204*10d63b7dSRichard Lowe register Boolean has_dollar;
205*10d63b7dSRichard Lowe register wchar_t *cq;
206*10d63b7dSRichard Lowe Name long_member_name = NULL;
207*10d63b7dSRichard Lowe
208*10d63b7dSRichard Lowe /* Internalize the name of the library */
209*10d63b7dSRichard Lowe lib = GETNAME(lib_start, member_start - lib_start);
210*10d63b7dSRichard Lowe lib->is_member = true;
211*10d63b7dSRichard Lowe member_start++;
212*10d63b7dSRichard Lowe if (*member_start == (int) parenleft_char) {
213*10d63b7dSRichard Lowe /* This is really the "lib.a((entries))" format */
214*10d63b7dSRichard Lowe entry = true;
215*10d63b7dSRichard Lowe member_start++;
216*10d63b7dSRichard Lowe }
217*10d63b7dSRichard Lowe /* Move the library name to the buffer where we intend to build the */
218*10d63b7dSRichard Lowe /* "lib.a(member)" for each member */
219*10d63b7dSRichard Lowe (void) wcsncpy(buffer, lib_start, member_start - lib_start);
220*10d63b7dSRichard Lowe memberp = buffer + (member_start-lib_start);
221*10d63b7dSRichard Lowe while (1) {
222*10d63b7dSRichard Lowe long_member_name = NULL;
223*10d63b7dSRichard Lowe /* Skip leading spaces */
224*10d63b7dSRichard Lowe for (;
225*10d63b7dSRichard Lowe (member_start < string_end) && iswspace(*member_start);
226*10d63b7dSRichard Lowe member_start++);
227*10d63b7dSRichard Lowe /* Find the end of the member name. Allow nested (). Detect $*/
228*10d63b7dSRichard Lowe for (cq = memberp, has_dollar = false, paren_count = 0;
229*10d63b7dSRichard Lowe (member_start < string_end) &&
230*10d63b7dSRichard Lowe ((*member_start != (int) parenright_char) ||
231*10d63b7dSRichard Lowe (paren_count > 0)) &&
232*10d63b7dSRichard Lowe !iswspace(*member_start);
233*10d63b7dSRichard Lowe *cq++ = *member_start++) {
234*10d63b7dSRichard Lowe switch (*member_start) {
235*10d63b7dSRichard Lowe case parenleft_char:
236*10d63b7dSRichard Lowe paren_count++;
237*10d63b7dSRichard Lowe break;
238*10d63b7dSRichard Lowe case parenright_char:
239*10d63b7dSRichard Lowe paren_count--;
240*10d63b7dSRichard Lowe break;
241*10d63b7dSRichard Lowe case dollar_char:
242*10d63b7dSRichard Lowe has_dollar = true;
243*10d63b7dSRichard Lowe }
244*10d63b7dSRichard Lowe }
245*10d63b7dSRichard Lowe /* Internalize the member name */
246*10d63b7dSRichard Lowe member = GETNAME(memberp, cq - memberp);
247*10d63b7dSRichard Lowe *cq = 0;
248*10d63b7dSRichard Lowe if ((q = (wchar_t *) wcsrchr(memberp, (int) slash_char)) == NULL) {
249*10d63b7dSRichard Lowe q = memberp;
250*10d63b7dSRichard Lowe }
251*10d63b7dSRichard Lowe if ((cq - q > (int) ar_member_name_len) &&
252*10d63b7dSRichard Lowe !has_dollar) {
253*10d63b7dSRichard Lowe *cq++ = (int) parenright_char;
254*10d63b7dSRichard Lowe if (entry) {
255*10d63b7dSRichard Lowe *cq++ = (int) parenright_char;
256*10d63b7dSRichard Lowe }
257*10d63b7dSRichard Lowe long_member_name = GETNAME(buffer, cq - buffer);
258*10d63b7dSRichard Lowe cq = q + (int) ar_member_name_len;
259*10d63b7dSRichard Lowe }
260*10d63b7dSRichard Lowe *cq++ = (int) parenright_char;
261*10d63b7dSRichard Lowe if (entry) {
262*10d63b7dSRichard Lowe *cq++ = (int) parenright_char;
263*10d63b7dSRichard Lowe }
264*10d63b7dSRichard Lowe /* Internalize the "lib.a(member)" notation for this member */
265*10d63b7dSRichard Lowe name = GETNAME(buffer, cq - buffer);
266*10d63b7dSRichard Lowe name->is_member = lib->is_member;
267*10d63b7dSRichard Lowe if (long_member_name != NULL) {
268*10d63b7dSRichard Lowe prop = append_prop(name, long_member_name_prop);
269*10d63b7dSRichard Lowe name->has_long_member_name = true;
270*10d63b7dSRichard Lowe prop->body.long_member_name.member_name =
271*10d63b7dSRichard Lowe long_member_name;
272*10d63b7dSRichard Lowe }
273*10d63b7dSRichard Lowe /* And add the member prop */
274*10d63b7dSRichard Lowe prop = append_prop(name, member_prop);
275*10d63b7dSRichard Lowe prop->body.member.library = lib;
276*10d63b7dSRichard Lowe if (entry) {
277*10d63b7dSRichard Lowe /* "lib.a((entry))" notation */
278*10d63b7dSRichard Lowe prop->body.member.entry = member;
279*10d63b7dSRichard Lowe prop->body.member.member = NULL;
280*10d63b7dSRichard Lowe } else {
281*10d63b7dSRichard Lowe /* "lib.a(member)" Notation */
282*10d63b7dSRichard Lowe prop->body.member.entry = NULL;
283*10d63b7dSRichard Lowe prop->body.member.member = member;
284*10d63b7dSRichard Lowe }
285*10d63b7dSRichard Lowe /* Handle overflow of current_names */
286*10d63b7dSRichard Lowe if (current_names->used == VSIZEOF(current_names->names)) {
287*10d63b7dSRichard Lowe if (current_names->next != NULL) {
288*10d63b7dSRichard Lowe current_names = current_names->next;
289*10d63b7dSRichard Lowe } else {
290*10d63b7dSRichard Lowe if (*extra_names == NULL) {
291*10d63b7dSRichard Lowe current_names =
292*10d63b7dSRichard Lowe current_names->next =
293*10d63b7dSRichard Lowe ALLOC(Name_vector);
294*10d63b7dSRichard Lowe } else {
295*10d63b7dSRichard Lowe current_names =
296*10d63b7dSRichard Lowe current_names->next =
297*10d63b7dSRichard Lowe *extra_names;
298*10d63b7dSRichard Lowe *extra_names = NULL;
299*10d63b7dSRichard Lowe }
300*10d63b7dSRichard Lowe current_names->used = 0;
301*10d63b7dSRichard Lowe current_names->next = NULL;
302*10d63b7dSRichard Lowe }
303*10d63b7dSRichard Lowe }
304*10d63b7dSRichard Lowe current_names->target_group[current_names->used] = NULL;
305*10d63b7dSRichard Lowe current_names->names[current_names->used++] = name;
306*10d63b7dSRichard Lowe while (iswspace(*member_start)) {
307*10d63b7dSRichard Lowe member_start++;
308*10d63b7dSRichard Lowe }
309*10d63b7dSRichard Lowe /* Check if there are more members */
310*10d63b7dSRichard Lowe if ((*member_start == (int) parenright_char) ||
311*10d63b7dSRichard Lowe (member_start >= string_end)) {
312*10d63b7dSRichard Lowe return current_names;
313*10d63b7dSRichard Lowe }
314*10d63b7dSRichard Lowe }
315*10d63b7dSRichard Lowe /* NOTREACHED */
316*10d63b7dSRichard Lowe }
317*10d63b7dSRichard Lowe
318*10d63b7dSRichard Lowe /*
319*10d63b7dSRichard Lowe * normalize_name(name_string, length)
320*10d63b7dSRichard Lowe *
321*10d63b7dSRichard Lowe * Take a namestring and remove redundant ../, // and ./ constructs
322*10d63b7dSRichard Lowe *
323*10d63b7dSRichard Lowe * Return value:
324*10d63b7dSRichard Lowe * The normalized name
325*10d63b7dSRichard Lowe *
326*10d63b7dSRichard Lowe * Parameters:
327*10d63b7dSRichard Lowe * name_string Path string to normalize
328*10d63b7dSRichard Lowe * length Length of that string
329*10d63b7dSRichard Lowe *
330*10d63b7dSRichard Lowe * Global variables used:
331*10d63b7dSRichard Lowe * dot The Name ".", compared against
332*10d63b7dSRichard Lowe * dotdot The Name "..", compared against
333*10d63b7dSRichard Lowe */
334*10d63b7dSRichard Lowe Name
normalize_name(register wchar_t * name_string,register int length)335*10d63b7dSRichard Lowe normalize_name(register wchar_t *name_string, register int length)
336*10d63b7dSRichard Lowe {
337*10d63b7dSRichard Lowe static Name dotdot;
338*10d63b7dSRichard Lowe register wchar_t *string = ALLOC_WC(length + 1);
339*10d63b7dSRichard Lowe register wchar_t *string2;
340*10d63b7dSRichard Lowe register wchar_t *cdp;
341*10d63b7dSRichard Lowe wchar_t *current_component;
342*10d63b7dSRichard Lowe Name name;
343*10d63b7dSRichard Lowe register int count;
344*10d63b7dSRichard Lowe
345*10d63b7dSRichard Lowe if (dotdot == NULL) {
346*10d63b7dSRichard Lowe MBSTOWCS(wcs_buffer, "..");
347*10d63b7dSRichard Lowe dotdot = GETNAME(wcs_buffer, FIND_LENGTH);
348*10d63b7dSRichard Lowe }
349*10d63b7dSRichard Lowe
350*10d63b7dSRichard Lowe /*
351*10d63b7dSRichard Lowe * Copy string removing ./ and //.
352*10d63b7dSRichard Lowe * First strip leading ./
353*10d63b7dSRichard Lowe */
354*10d63b7dSRichard Lowe while ((length > 1) &&
355*10d63b7dSRichard Lowe (name_string[0] == (int) period_char) &&
356*10d63b7dSRichard Lowe (name_string[1] == (int) slash_char)) {
357*10d63b7dSRichard Lowe name_string += 2;
358*10d63b7dSRichard Lowe length -= 2;
359*10d63b7dSRichard Lowe while ((length > 0) && (name_string[0] == (int) slash_char)) {
360*10d63b7dSRichard Lowe name_string++;
361*10d63b7dSRichard Lowe length--;
362*10d63b7dSRichard Lowe }
363*10d63b7dSRichard Lowe }
364*10d63b7dSRichard Lowe /* Then copy the rest of the string removing /./ & // */
365*10d63b7dSRichard Lowe cdp = string;
366*10d63b7dSRichard Lowe while (length > 0) {
367*10d63b7dSRichard Lowe if (((length > 2) &&
368*10d63b7dSRichard Lowe (name_string[0] == (int) slash_char) &&
369*10d63b7dSRichard Lowe (name_string[1] == (int) period_char) &&
370*10d63b7dSRichard Lowe (name_string[2] == (int) slash_char)) ||
371*10d63b7dSRichard Lowe ((length == 2) &&
372*10d63b7dSRichard Lowe (name_string[0] == (int) slash_char) &&
373*10d63b7dSRichard Lowe (name_string[1] == (int) period_char))) {
374*10d63b7dSRichard Lowe name_string += 2;
375*10d63b7dSRichard Lowe length -= 2;
376*10d63b7dSRichard Lowe continue;
377*10d63b7dSRichard Lowe }
378*10d63b7dSRichard Lowe if ((length > 1) &&
379*10d63b7dSRichard Lowe (name_string[0] == (int) slash_char) &&
380*10d63b7dSRichard Lowe (name_string[1] == (int) slash_char)) {
381*10d63b7dSRichard Lowe name_string++;
382*10d63b7dSRichard Lowe length--;
383*10d63b7dSRichard Lowe continue;
384*10d63b7dSRichard Lowe }
385*10d63b7dSRichard Lowe *cdp++ = *name_string++;
386*10d63b7dSRichard Lowe length--;
387*10d63b7dSRichard Lowe }
388*10d63b7dSRichard Lowe *cdp = (int) nul_char;
389*10d63b7dSRichard Lowe /*
390*10d63b7dSRichard Lowe * Now scan for <name>/../ and remove such combinations iff <name>
391*10d63b7dSRichard Lowe * is not another ..
392*10d63b7dSRichard Lowe * Each time something is removed, the whole process is restarted.
393*10d63b7dSRichard Lowe */
394*10d63b7dSRichard Lowe removed_one:
395*10d63b7dSRichard Lowe name_string = string;
396*10d63b7dSRichard Lowe string2 = name_string; /*save for free*/
397*10d63b7dSRichard Lowe current_component =
398*10d63b7dSRichard Lowe cdp =
399*10d63b7dSRichard Lowe string =
400*10d63b7dSRichard Lowe ALLOC_WC((length = wcslen(name_string)) + 1);
401*10d63b7dSRichard Lowe while (length > 0) {
402*10d63b7dSRichard Lowe if (((length > 3) &&
403*10d63b7dSRichard Lowe (name_string[0] == (int) slash_char) &&
404*10d63b7dSRichard Lowe (name_string[1] == (int) period_char) &&
405*10d63b7dSRichard Lowe (name_string[2] == (int) period_char) &&
406*10d63b7dSRichard Lowe (name_string[3] == (int) slash_char)) ||
407*10d63b7dSRichard Lowe ((length == 3) &&
408*10d63b7dSRichard Lowe (name_string[0] == (int) slash_char) &&
409*10d63b7dSRichard Lowe (name_string[1] == (int) period_char) &&
410*10d63b7dSRichard Lowe (name_string[2] == (int) period_char))) {
411*10d63b7dSRichard Lowe /* Positioned on the / that starts a /.. sequence */
412*10d63b7dSRichard Lowe if (((count = cdp - current_component) != 0) &&
413*10d63b7dSRichard Lowe (exists(name = GETNAME(string, cdp - string)) > file_doesnt_exist) &&
414*10d63b7dSRichard Lowe (!name->stat.is_sym_link)) {
415*10d63b7dSRichard Lowe name = GETNAME(current_component, count);
416*10d63b7dSRichard Lowe if(name != dotdot) {
417*10d63b7dSRichard Lowe cdp = current_component;
418*10d63b7dSRichard Lowe name_string += 3;
419*10d63b7dSRichard Lowe length -= 3;
420*10d63b7dSRichard Lowe if (length > 0) {
421*10d63b7dSRichard Lowe name_string++; /* skip slash */
422*10d63b7dSRichard Lowe length--;
423*10d63b7dSRichard Lowe while (length > 0) {
424*10d63b7dSRichard Lowe *cdp++ = *name_string++;
425*10d63b7dSRichard Lowe length--;
426*10d63b7dSRichard Lowe }
427*10d63b7dSRichard Lowe }
428*10d63b7dSRichard Lowe *cdp = (int) nul_char;
429*10d63b7dSRichard Lowe retmem(string2);
430*10d63b7dSRichard Lowe goto removed_one;
431*10d63b7dSRichard Lowe }
432*10d63b7dSRichard Lowe }
433*10d63b7dSRichard Lowe }
434*10d63b7dSRichard Lowe if ((*cdp++ = *name_string++) == (int) slash_char) {
435*10d63b7dSRichard Lowe current_component = cdp;
436*10d63b7dSRichard Lowe }
437*10d63b7dSRichard Lowe length--;
438*10d63b7dSRichard Lowe }
439*10d63b7dSRichard Lowe *cdp = (int) nul_char;
440*10d63b7dSRichard Lowe if (string[0] == (int) nul_char) {
441*10d63b7dSRichard Lowe name = dot;
442*10d63b7dSRichard Lowe } else {
443*10d63b7dSRichard Lowe name = GETNAME(string, FIND_LENGTH);
444*10d63b7dSRichard Lowe }
445*10d63b7dSRichard Lowe retmem(string);
446*10d63b7dSRichard Lowe retmem(string2);
447*10d63b7dSRichard Lowe return name;
448*10d63b7dSRichard Lowe }
449*10d63b7dSRichard Lowe
450*10d63b7dSRichard Lowe /*
451*10d63b7dSRichard Lowe * find_target_groups(target_list)
452*10d63b7dSRichard Lowe *
453*10d63b7dSRichard Lowe * If a "+" was seen when the target list was scanned we need to extract
454*10d63b7dSRichard Lowe * the groups. Each target in the name vector that is a member of a
455*10d63b7dSRichard Lowe * group gets a pointer to a chain of all the members stuffed in its
456*10d63b7dSRichard Lowe * target_group vector slot
457*10d63b7dSRichard Lowe *
458*10d63b7dSRichard Lowe * Parameters:
459*10d63b7dSRichard Lowe * target_list The list of targets that contains "+"
460*10d63b7dSRichard Lowe *
461*10d63b7dSRichard Lowe * Global variables used:
462*10d63b7dSRichard Lowe * plus The Name "+", compared against
463*10d63b7dSRichard Lowe */
464*10d63b7dSRichard Lowe Chain
find_target_groups(register Name_vector target_list,register int i,Boolean reset)465*10d63b7dSRichard Lowe find_target_groups(register Name_vector target_list, register int i, Boolean reset)
466*10d63b7dSRichard Lowe {
467*10d63b7dSRichard Lowe static Chain target_group = NULL;
468*10d63b7dSRichard Lowe static Chain tail_target_group = NULL;
469*10d63b7dSRichard Lowe static Name *next;
470*10d63b7dSRichard Lowe static Boolean clear_target_group = false;
471*10d63b7dSRichard Lowe
472*10d63b7dSRichard Lowe if (reset) {
473*10d63b7dSRichard Lowe target_group = NULL;
474*10d63b7dSRichard Lowe tail_target_group = NULL;
475*10d63b7dSRichard Lowe clear_target_group = false;
476*10d63b7dSRichard Lowe }
477*10d63b7dSRichard Lowe
478*10d63b7dSRichard Lowe /* Scan the list of targets */
479*10d63b7dSRichard Lowe /* If the previous target terminated a group */
480*10d63b7dSRichard Lowe /* we flush the pointer to that member chain */
481*10d63b7dSRichard Lowe if (clear_target_group) {
482*10d63b7dSRichard Lowe clear_target_group = false;
483*10d63b7dSRichard Lowe target_group = NULL;
484*10d63b7dSRichard Lowe }
485*10d63b7dSRichard Lowe /* Pick up a pointer to the cell with */
486*10d63b7dSRichard Lowe /* the next target */
487*10d63b7dSRichard Lowe if (i + 1 != target_list->used) {
488*10d63b7dSRichard Lowe next = &target_list->names[i + 1];
489*10d63b7dSRichard Lowe } else {
490*10d63b7dSRichard Lowe next = (target_list->next != NULL) ?
491*10d63b7dSRichard Lowe &target_list->next->names[0] : NULL;
492*10d63b7dSRichard Lowe }
493*10d63b7dSRichard Lowe /* We have four states here :
494*10d63b7dSRichard Lowe * 0: No target group started and next element is not "+"
495*10d63b7dSRichard Lowe * This is not interesting.
496*10d63b7dSRichard Lowe * 1: A target group is being built and the next element
497*10d63b7dSRichard Lowe * is not "+". This terminates the group.
498*10d63b7dSRichard Lowe * 2: No target group started and the next member is "+"
499*10d63b7dSRichard Lowe * This is the first target in a group.
500*10d63b7dSRichard Lowe * 3: A target group started and the next member is a "+"
501*10d63b7dSRichard Lowe * The group continues.
502*10d63b7dSRichard Lowe */
503*10d63b7dSRichard Lowe switch ((target_group ? 1 : 0) +
504*10d63b7dSRichard Lowe (next && (*next == plus) ?
505*10d63b7dSRichard Lowe 2 : 0)) {
506*10d63b7dSRichard Lowe case 0: /* Not target_group */
507*10d63b7dSRichard Lowe break;
508*10d63b7dSRichard Lowe case 1: /* Last group member */
509*10d63b7dSRichard Lowe /* We need to keep this pointer so */
510*10d63b7dSRichard Lowe /* we can stuff it for last member */
511*10d63b7dSRichard Lowe clear_target_group = true;
512*10d63b7dSRichard Lowe /* fall into */
513*10d63b7dSRichard Lowe case 3: /* Middle group member */
514*10d63b7dSRichard Lowe /* Add this target to the */
515*10d63b7dSRichard Lowe /* current chain */
516*10d63b7dSRichard Lowe tail_target_group->next = ALLOC(Chain);
517*10d63b7dSRichard Lowe tail_target_group = tail_target_group->next;
518*10d63b7dSRichard Lowe tail_target_group->next = NULL;
519*10d63b7dSRichard Lowe tail_target_group->name = target_list->names[i];
520*10d63b7dSRichard Lowe break;
521*10d63b7dSRichard Lowe case 2: /* First group member */
522*10d63b7dSRichard Lowe /* Start a new chain */
523*10d63b7dSRichard Lowe target_group = tail_target_group = ALLOC(Chain);
524*10d63b7dSRichard Lowe target_group->next = NULL;
525*10d63b7dSRichard Lowe target_group->name = target_list->names[i];
526*10d63b7dSRichard Lowe break;
527*10d63b7dSRichard Lowe }
528*10d63b7dSRichard Lowe /* Stuff the current chain, if any, in the */
529*10d63b7dSRichard Lowe /* targets group slot */
530*10d63b7dSRichard Lowe target_list->target_group[i] = target_group;
531*10d63b7dSRichard Lowe if ((next != NULL) &&
532*10d63b7dSRichard Lowe (*next == plus)) {
533*10d63b7dSRichard Lowe *next = NULL;
534*10d63b7dSRichard Lowe }
535*10d63b7dSRichard Lowe return (tail_target_group);
536*10d63b7dSRichard Lowe }
537*10d63b7dSRichard Lowe
538*10d63b7dSRichard Lowe /*
539*10d63b7dSRichard Lowe * enter_dependencies(target, target_group, depes, command, separator)
540*10d63b7dSRichard Lowe *
541*10d63b7dSRichard Lowe * Take one target and a list of dependencies and process the whole thing.
542*10d63b7dSRichard Lowe * The target might be special in some sense in which case that is handled
543*10d63b7dSRichard Lowe *
544*10d63b7dSRichard Lowe * Parameters:
545*10d63b7dSRichard Lowe * target The target we want to enter
546*10d63b7dSRichard Lowe * target_group Non-NULL if target is part of a group this time
547*10d63b7dSRichard Lowe * depes A list of dependencies for the target
548*10d63b7dSRichard Lowe * command The command the target should be entered with
549*10d63b7dSRichard Lowe * separator Indicates if this is a ":" or a "::" rule
550*10d63b7dSRichard Lowe *
551*10d63b7dSRichard Lowe * Static variables used:
552*10d63b7dSRichard Lowe * built_last_make_run_seen If the previous target was
553*10d63b7dSRichard Lowe * .BUILT_LAST_MAKE_RUN we say to rewrite
554*10d63b7dSRichard Lowe * the state file later on
555*10d63b7dSRichard Lowe *
556*10d63b7dSRichard Lowe * Global variables used:
557*10d63b7dSRichard Lowe * command_changed Set to indicate if .make.state needs rewriting
558*10d63b7dSRichard Lowe * default_target_to_build Set to the target if reading makefile
559*10d63b7dSRichard Lowe * and this is the first regular target
560*10d63b7dSRichard Lowe * force The Name " FORCE", used with "::" targets
561*10d63b7dSRichard Lowe * makefile_type We do different things for makefile vs. report
562*10d63b7dSRichard Lowe * not_auto The Name ".NOT_AUTO", compared against
563*10d63b7dSRichard Lowe * recursive_name The Name ".RECURSIVE", compared against
564*10d63b7dSRichard Lowe * temp_file_number Used to figure out when to clear stale
565*10d63b7dSRichard Lowe * automatic dependencies
566*10d63b7dSRichard Lowe * trace_reader Indicates that we should echo stuff we read
567*10d63b7dSRichard Lowe */
568*10d63b7dSRichard Lowe void
enter_dependencies(register Name target,Chain target_group,register Name_vector depes,register Cmd_line command,register Separator separator)569*10d63b7dSRichard Lowe enter_dependencies(register Name target, Chain target_group, register Name_vector depes, register Cmd_line command, register Separator separator)
570*10d63b7dSRichard Lowe {
571*10d63b7dSRichard Lowe register int i;
572*10d63b7dSRichard Lowe register Property line;
573*10d63b7dSRichard Lowe Name name;
574*10d63b7dSRichard Lowe Name directory;
575*10d63b7dSRichard Lowe wchar_t *namep;
576*10d63b7dSRichard Lowe char *mb_namep;
577*10d63b7dSRichard Lowe Dependency dp;
578*10d63b7dSRichard Lowe Dependency *dpp;
579*10d63b7dSRichard Lowe Property line2;
580*10d63b7dSRichard Lowe wchar_t relative[MAXPATHLEN];
581*10d63b7dSRichard Lowe register int recursive_state;
582*10d63b7dSRichard Lowe Boolean register_as_auto;
583*10d63b7dSRichard Lowe Boolean not_auto_found;
584*10d63b7dSRichard Lowe char *slash;
585*10d63b7dSRichard Lowe Wstring depstr;
586*10d63b7dSRichard Lowe
587*10d63b7dSRichard Lowe /* Check if this is a .RECURSIVE line */
588*10d63b7dSRichard Lowe if ((depes->used >= 3) &&
589*10d63b7dSRichard Lowe (depes->names[0] == recursive_name)) {
590*10d63b7dSRichard Lowe target->has_recursive_dependency = true;
591*10d63b7dSRichard Lowe depes->names[0] = NULL;
592*10d63b7dSRichard Lowe recursive_state = 0;
593*10d63b7dSRichard Lowe dp = NULL;
594*10d63b7dSRichard Lowe dpp = &dp;
595*10d63b7dSRichard Lowe /* Read the dependencies. They are "<directory> <target-made>*/
596*10d63b7dSRichard Lowe /* <makefile>*" */
597*10d63b7dSRichard Lowe for (; depes != NULL; depes = depes->next) {
598*10d63b7dSRichard Lowe for (i = 0; i < depes->used; i++) {
599*10d63b7dSRichard Lowe if (depes->names[i] != NULL) {
600*10d63b7dSRichard Lowe switch (recursive_state++) {
601*10d63b7dSRichard Lowe case 0: /* Directory */
602*10d63b7dSRichard Lowe {
603*10d63b7dSRichard Lowe depstr.init(depes->names[i]);
604*10d63b7dSRichard Lowe make_relative(depstr.get_string(),
605*10d63b7dSRichard Lowe relative);
606*10d63b7dSRichard Lowe directory =
607*10d63b7dSRichard Lowe GETNAME(relative,
608*10d63b7dSRichard Lowe FIND_LENGTH);
609*10d63b7dSRichard Lowe }
610*10d63b7dSRichard Lowe break;
611*10d63b7dSRichard Lowe case 1: /* Target */
612*10d63b7dSRichard Lowe name = depes->names[i];
613*10d63b7dSRichard Lowe break;
614*10d63b7dSRichard Lowe default: /* Makefiles */
615*10d63b7dSRichard Lowe *dpp = ALLOC(Dependency);
616*10d63b7dSRichard Lowe (*dpp)->next = NULL;
617*10d63b7dSRichard Lowe (*dpp)->name = depes->names[i];
618*10d63b7dSRichard Lowe (*dpp)->automatic = false;
619*10d63b7dSRichard Lowe (*dpp)->stale = false;
620*10d63b7dSRichard Lowe (*dpp)->built = false;
621*10d63b7dSRichard Lowe dpp = &((*dpp)->next);
622*10d63b7dSRichard Lowe break;
623*10d63b7dSRichard Lowe }
624*10d63b7dSRichard Lowe }
625*10d63b7dSRichard Lowe }
626*10d63b7dSRichard Lowe }
627*10d63b7dSRichard Lowe /* Check if this recursion already has been reported else */
628*10d63b7dSRichard Lowe /* enter the recursive prop for the target */
629*10d63b7dSRichard Lowe /* The has_built flag is used to tell if this .RECURSIVE */
630*10d63b7dSRichard Lowe /* was discovered from this run (read from a tmp file) */
631*10d63b7dSRichard Lowe /* or was from discovered from the original .make.state */
632*10d63b7dSRichard Lowe /* file */
633*10d63b7dSRichard Lowe for (line = get_prop(target->prop, recursive_prop);
634*10d63b7dSRichard Lowe line != NULL;
635*10d63b7dSRichard Lowe line = get_prop(line->next, recursive_prop)) {
636*10d63b7dSRichard Lowe if ((line->body.recursive.directory == directory) &&
637*10d63b7dSRichard Lowe (line->body.recursive.target == name)) {
638*10d63b7dSRichard Lowe line->body.recursive.makefiles = dp;
639*10d63b7dSRichard Lowe line->body.recursive.has_built =
640*10d63b7dSRichard Lowe (Boolean)
641*10d63b7dSRichard Lowe (makefile_type == reading_cpp_file);
642*10d63b7dSRichard Lowe return;
643*10d63b7dSRichard Lowe }
644*10d63b7dSRichard Lowe }
645*10d63b7dSRichard Lowe line2 = append_prop(target, recursive_prop);
646*10d63b7dSRichard Lowe line2->body.recursive.directory = directory;
647*10d63b7dSRichard Lowe line2->body.recursive.target = name;
648*10d63b7dSRichard Lowe line2->body.recursive.makefiles = dp;
649*10d63b7dSRichard Lowe line2->body.recursive.has_built =
650*10d63b7dSRichard Lowe (Boolean) (makefile_type == reading_cpp_file);
651*10d63b7dSRichard Lowe line2->body.recursive.in_depinfo = false;
652*10d63b7dSRichard Lowe return;
653*10d63b7dSRichard Lowe }
654*10d63b7dSRichard Lowe /* If this is the first target that doesnt start with a "." in the */
655*10d63b7dSRichard Lowe /* makefile we remember that */
656*10d63b7dSRichard Lowe Wstring tstr(target);
657*10d63b7dSRichard Lowe wchar_t * wcb = tstr.get_string();
658*10d63b7dSRichard Lowe if ((makefile_type == reading_makefile) &&
659*10d63b7dSRichard Lowe (default_target_to_build == NULL) &&
660*10d63b7dSRichard Lowe ((wcb[0] != (int) period_char) ||
661*10d63b7dSRichard Lowe wcschr(wcb, (int) slash_char))) {
662*10d63b7dSRichard Lowe
663*10d63b7dSRichard Lowe /* BID 1181577: $(EMPTY_MACRO) + $(EMPTY_MACRO):
664*10d63b7dSRichard Lowe ** The target with empty name cannot be default_target_to_build
665*10d63b7dSRichard Lowe */
666*10d63b7dSRichard Lowe if (target->hash.length != 0)
667*10d63b7dSRichard Lowe default_target_to_build = target;
668*10d63b7dSRichard Lowe }
669*10d63b7dSRichard Lowe /* Check if the line is ":" or "::" */
670*10d63b7dSRichard Lowe if (makefile_type == reading_makefile) {
671*10d63b7dSRichard Lowe if (target->colons == no_colon) {
672*10d63b7dSRichard Lowe target->colons = separator;
673*10d63b7dSRichard Lowe } else {
674*10d63b7dSRichard Lowe if (target->colons != separator) {
675*10d63b7dSRichard Lowe fatal_reader(gettext(":/:: conflict for target `%s'"),
676*10d63b7dSRichard Lowe target->string_mb);
677*10d63b7dSRichard Lowe }
678*10d63b7dSRichard Lowe }
679*10d63b7dSRichard Lowe if (target->colons == two_colon) {
680*10d63b7dSRichard Lowe if (depes->used == 0) {
681*10d63b7dSRichard Lowe /* If this is a "::" type line with no */
682*10d63b7dSRichard Lowe /* dependencies we add one "FRC" type */
683*10d63b7dSRichard Lowe /* dependency for free */
684*10d63b7dSRichard Lowe depes->used = 1; /* Force :: targets with no
685*10d63b7dSRichard Lowe * depes to always run */
686*10d63b7dSRichard Lowe depes->names[0] = force;
687*10d63b7dSRichard Lowe }
688*10d63b7dSRichard Lowe /* Do not delete "::" type targets when interrupted */
689*10d63b7dSRichard Lowe target->stat.is_precious = true;
690*10d63b7dSRichard Lowe /*
691*10d63b7dSRichard Lowe * Build a synthetic target "<number>%target"
692*10d63b7dSRichard Lowe * for "target".
693*10d63b7dSRichard Lowe */
694*10d63b7dSRichard Lowe mb_namep = getmem((int) (strlen(target->string_mb) + 10));
695*10d63b7dSRichard Lowe namep = ALLOC_WC((int) (target->hash.length + 10));
696*10d63b7dSRichard Lowe slash = strrchr(target->string_mb, (int) slash_char);
697*10d63b7dSRichard Lowe if (slash == NULL) {
698*10d63b7dSRichard Lowe (void) sprintf(mb_namep,
699*10d63b7dSRichard Lowe "%d@%s",
700*10d63b7dSRichard Lowe target->colon_splits++,
701*10d63b7dSRichard Lowe target->string_mb);
702*10d63b7dSRichard Lowe } else {
703*10d63b7dSRichard Lowe *slash = 0;
704*10d63b7dSRichard Lowe (void) sprintf(mb_namep,
705*10d63b7dSRichard Lowe "%s/%d@%s",
706*10d63b7dSRichard Lowe target->string_mb,
707*10d63b7dSRichard Lowe target->colon_splits++,
708*10d63b7dSRichard Lowe slash + 1);
709*10d63b7dSRichard Lowe *slash = (int) slash_char;
710*10d63b7dSRichard Lowe }
711*10d63b7dSRichard Lowe MBSTOWCS(namep, mb_namep);
712*10d63b7dSRichard Lowe retmem_mb(mb_namep);
713*10d63b7dSRichard Lowe name = GETNAME(namep, FIND_LENGTH);
714*10d63b7dSRichard Lowe retmem(namep);
715*10d63b7dSRichard Lowe if (trace_reader) {
716*10d63b7dSRichard Lowe (void) printf("%s:\t", target->string_mb);
717*10d63b7dSRichard Lowe }
718*10d63b7dSRichard Lowe /* Make "target" depend on "<number>%target */
719*10d63b7dSRichard Lowe line2 = maybe_append_prop(target, line_prop);
720*10d63b7dSRichard Lowe enter_dependency(line2, name, true);
721*10d63b7dSRichard Lowe line2->body.line.target = target;
722*10d63b7dSRichard Lowe /* Put a prop on "<number>%target that makes */
723*10d63b7dSRichard Lowe /* appear as "target" */
724*10d63b7dSRichard Lowe /* when it is processed */
725*10d63b7dSRichard Lowe maybe_append_prop(name, target_prop)->
726*10d63b7dSRichard Lowe body.target.target = target;
727*10d63b7dSRichard Lowe target->is_double_colon_parent = true;
728*10d63b7dSRichard Lowe name->is_double_colon = true;
729*10d63b7dSRichard Lowe name->has_target_prop = true;
730*10d63b7dSRichard Lowe if (trace_reader) {
731*10d63b7dSRichard Lowe (void) printf("\n");
732*10d63b7dSRichard Lowe }
733*10d63b7dSRichard Lowe (target = name)->stat.is_file = true;
734*10d63b7dSRichard Lowe }
735*10d63b7dSRichard Lowe }
736*10d63b7dSRichard Lowe /* This really is a regular dependency line. Just enter it */
737*10d63b7dSRichard Lowe line = maybe_append_prop(target, line_prop);
738*10d63b7dSRichard Lowe line->body.line.target = target;
739*10d63b7dSRichard Lowe /* Depending on what kind of makefile we are reading we have to */
740*10d63b7dSRichard Lowe /* treat things differently */
741*10d63b7dSRichard Lowe switch (makefile_type) {
742*10d63b7dSRichard Lowe case reading_makefile:
743*10d63b7dSRichard Lowe /* Reading regular makefile. Just notice whether this */
744*10d63b7dSRichard Lowe /* redefines the rule for the target */
745*10d63b7dSRichard Lowe if (command != NULL) {
746*10d63b7dSRichard Lowe if (line->body.line.command_template != NULL) {
747*10d63b7dSRichard Lowe line->body.line.command_template_redefined =
748*10d63b7dSRichard Lowe true;
749*10d63b7dSRichard Lowe if ((wcb[0] == (int) period_char) &&
750*10d63b7dSRichard Lowe !wcschr(wcb, (int) slash_char)) {
751*10d63b7dSRichard Lowe line->body.line.command_template =
752*10d63b7dSRichard Lowe command;
753*10d63b7dSRichard Lowe }
754*10d63b7dSRichard Lowe } else {
755*10d63b7dSRichard Lowe line->body.line.command_template = command;
756*10d63b7dSRichard Lowe }
757*10d63b7dSRichard Lowe } else {
758*10d63b7dSRichard Lowe if ((wcb[0] == (int) period_char) &&
759*10d63b7dSRichard Lowe !wcschr(wcb, (int) slash_char)) {
760*10d63b7dSRichard Lowe line->body.line.command_template = command;
761*10d63b7dSRichard Lowe }
762*10d63b7dSRichard Lowe }
763*10d63b7dSRichard Lowe break;
764*10d63b7dSRichard Lowe case rereading_statefile:
765*10d63b7dSRichard Lowe /* Rereading the statefile. We only enter thing that changed */
766*10d63b7dSRichard Lowe /* since the previous time we read it */
767*10d63b7dSRichard Lowe if (!built_last_make_run_seen) {
768*10d63b7dSRichard Lowe for (Cmd_line next, cmd = command; cmd != NULL; cmd = next) {
769*10d63b7dSRichard Lowe next = cmd->next;
770*10d63b7dSRichard Lowe free(cmd);
771*10d63b7dSRichard Lowe }
772*10d63b7dSRichard Lowe return;
773*10d63b7dSRichard Lowe }
774*10d63b7dSRichard Lowe built_last_make_run_seen = false;
775*10d63b7dSRichard Lowe command_changed = true;
776*10d63b7dSRichard Lowe target->ran_command = true;
777*10d63b7dSRichard Lowe case reading_statefile:
778*10d63b7dSRichard Lowe /* Reading the statefile for the first time. Enter the rules */
779*10d63b7dSRichard Lowe /* as "Commands used" not "templates to use" */
780*10d63b7dSRichard Lowe if (command != NULL) {
781*10d63b7dSRichard Lowe for (Cmd_line next, cmd = line->body.line.command_used;
782*10d63b7dSRichard Lowe cmd != NULL; cmd = next) {
783*10d63b7dSRichard Lowe next = cmd->next;
784*10d63b7dSRichard Lowe free(cmd);
785*10d63b7dSRichard Lowe }
786*10d63b7dSRichard Lowe line->body.line.command_used = command;
787*10d63b7dSRichard Lowe }
788*10d63b7dSRichard Lowe case reading_cpp_file:
789*10d63b7dSRichard Lowe /* Reading report file from programs that reports */
790*10d63b7dSRichard Lowe /* dependencies. If this is the first time the target is */
791*10d63b7dSRichard Lowe /* read from this reportfile we clear all old */
792*10d63b7dSRichard Lowe /* automatic depes */
793*10d63b7dSRichard Lowe if (target->temp_file_number == temp_file_number) {
794*10d63b7dSRichard Lowe break;
795*10d63b7dSRichard Lowe }
796*10d63b7dSRichard Lowe target->temp_file_number = temp_file_number;
797*10d63b7dSRichard Lowe command_changed = true;
798*10d63b7dSRichard Lowe if (line != NULL) {
799*10d63b7dSRichard Lowe for (dp = line->body.line.dependencies;
800*10d63b7dSRichard Lowe dp != NULL;
801*10d63b7dSRichard Lowe dp = dp->next) {
802*10d63b7dSRichard Lowe if (dp->automatic) {
803*10d63b7dSRichard Lowe dp->stale = true;
804*10d63b7dSRichard Lowe }
805*10d63b7dSRichard Lowe }
806*10d63b7dSRichard Lowe }
807*10d63b7dSRichard Lowe break;
808*10d63b7dSRichard Lowe default:
809*10d63b7dSRichard Lowe fatal_reader(gettext("Internal error. Unknown makefile type %d"),
810*10d63b7dSRichard Lowe makefile_type);
811*10d63b7dSRichard Lowe }
812*10d63b7dSRichard Lowe /* A target may only be involved in one target group */
813*10d63b7dSRichard Lowe if (line->body.line.target_group != NULL) {
814*10d63b7dSRichard Lowe if (target_group != NULL) {
815*10d63b7dSRichard Lowe fatal_reader(gettext("Too many target groups for target `%s'"),
816*10d63b7dSRichard Lowe target->string_mb);
817*10d63b7dSRichard Lowe }
818*10d63b7dSRichard Lowe } else {
819*10d63b7dSRichard Lowe line->body.line.target_group = target_group;
820*10d63b7dSRichard Lowe }
821*10d63b7dSRichard Lowe
822*10d63b7dSRichard Lowe if (trace_reader) {
823*10d63b7dSRichard Lowe (void) printf("%s:\t", target->string_mb);
824*10d63b7dSRichard Lowe }
825*10d63b7dSRichard Lowe /* Enter the dependencies */
826*10d63b7dSRichard Lowe register_as_auto = BOOLEAN(makefile_type != reading_makefile);
827*10d63b7dSRichard Lowe not_auto_found = false;
828*10d63b7dSRichard Lowe for (;
829*10d63b7dSRichard Lowe (depes != NULL) && !not_auto_found;
830*10d63b7dSRichard Lowe depes = depes->next) {
831*10d63b7dSRichard Lowe for (i = 0; i < depes->used; i++) {
832*10d63b7dSRichard Lowe /* the dependency .NOT_AUTO signals beginning of
833*10d63b7dSRichard Lowe * explicit dependancies which were put at end of
834*10d63b7dSRichard Lowe * list in .make.state file - we stop entering
835*10d63b7dSRichard Lowe * dependencies at this point
836*10d63b7dSRichard Lowe */
837*10d63b7dSRichard Lowe if (depes->names[i] == not_auto) {
838*10d63b7dSRichard Lowe not_auto_found = true;
839*10d63b7dSRichard Lowe break;
840*10d63b7dSRichard Lowe }
841*10d63b7dSRichard Lowe enter_dependency(line,
842*10d63b7dSRichard Lowe depes->names[i],
843*10d63b7dSRichard Lowe register_as_auto);
844*10d63b7dSRichard Lowe }
845*10d63b7dSRichard Lowe }
846*10d63b7dSRichard Lowe if (trace_reader) {
847*10d63b7dSRichard Lowe (void) printf("\n");
848*10d63b7dSRichard Lowe print_rule(command);
849*10d63b7dSRichard Lowe }
850*10d63b7dSRichard Lowe }
851*10d63b7dSRichard Lowe
852*10d63b7dSRichard Lowe /*
853*10d63b7dSRichard Lowe * enter_dependency(line, depe, automatic)
854*10d63b7dSRichard Lowe *
855*10d63b7dSRichard Lowe * Enter one dependency. Do not enter duplicates.
856*10d63b7dSRichard Lowe *
857*10d63b7dSRichard Lowe * Parameters:
858*10d63b7dSRichard Lowe * line The line block that the dependeny is
859*10d63b7dSRichard Lowe * entered for
860*10d63b7dSRichard Lowe * depe The dependency to enter
861*10d63b7dSRichard Lowe * automatic Used to set the field "automatic"
862*10d63b7dSRichard Lowe *
863*10d63b7dSRichard Lowe * Global variables used:
864*10d63b7dSRichard Lowe * makefile_type We do different things for makefile vs. report
865*10d63b7dSRichard Lowe * trace_reader Indicates that we should echo stuff we read
866*10d63b7dSRichard Lowe * wait_name The Name ".WAIT", compared against
867*10d63b7dSRichard Lowe */
868*10d63b7dSRichard Lowe void
enter_dependency(Property line,register Name depe,Boolean automatic)869*10d63b7dSRichard Lowe enter_dependency(Property line, register Name depe, Boolean automatic)
870*10d63b7dSRichard Lowe {
871*10d63b7dSRichard Lowe register Dependency dp;
872*10d63b7dSRichard Lowe register Dependency *insert;
873*10d63b7dSRichard Lowe
874*10d63b7dSRichard Lowe if (trace_reader) {
875*10d63b7dSRichard Lowe (void) printf("%s ", depe->string_mb);
876*10d63b7dSRichard Lowe }
877*10d63b7dSRichard Lowe /* Find the end of the list and check for duplicates */
878*10d63b7dSRichard Lowe for (insert = &line->body.line.dependencies, dp = *insert;
879*10d63b7dSRichard Lowe dp != NULL;
880*10d63b7dSRichard Lowe insert = &dp->next, dp = *insert) {
881*10d63b7dSRichard Lowe if ((dp->name == depe) && (depe != wait_name)) {
882*10d63b7dSRichard Lowe if (dp->automatic) {
883*10d63b7dSRichard Lowe dp->automatic = automatic;
884*10d63b7dSRichard Lowe if (automatic) {
885*10d63b7dSRichard Lowe dp->built = false;
886*10d63b7dSRichard Lowe depe->stat.is_file = true;
887*10d63b7dSRichard Lowe }
888*10d63b7dSRichard Lowe }
889*10d63b7dSRichard Lowe dp->stale = false;
890*10d63b7dSRichard Lowe return;
891*10d63b7dSRichard Lowe }
892*10d63b7dSRichard Lowe }
893*10d63b7dSRichard Lowe /* Insert the new dependency since we couldnt find it */
894*10d63b7dSRichard Lowe dp = *insert = ALLOC(Dependency);
895*10d63b7dSRichard Lowe dp->name = depe;
896*10d63b7dSRichard Lowe dp->next = NULL;
897*10d63b7dSRichard Lowe dp->automatic = automatic;
898*10d63b7dSRichard Lowe dp->stale = false;
899*10d63b7dSRichard Lowe dp->built = false;
900*10d63b7dSRichard Lowe depe->stat.is_file = true;
901*10d63b7dSRichard Lowe
902*10d63b7dSRichard Lowe if ((makefile_type == reading_makefile) &&
903*10d63b7dSRichard Lowe (line != NULL) &&
904*10d63b7dSRichard Lowe (line->body.line.target != NULL)) {
905*10d63b7dSRichard Lowe line->body.line.target->has_regular_dependency = true;
906*10d63b7dSRichard Lowe }
907*10d63b7dSRichard Lowe }
908*10d63b7dSRichard Lowe
909*10d63b7dSRichard Lowe /*
910*10d63b7dSRichard Lowe * enter_percent(target, depes, command)
911*10d63b7dSRichard Lowe *
912*10d63b7dSRichard Lowe * Enter "x%y : a%b" type lines
913*10d63b7dSRichard Lowe * % patterns are stored in four parts head and tail for target and source
914*10d63b7dSRichard Lowe *
915*10d63b7dSRichard Lowe * Parameters:
916*10d63b7dSRichard Lowe * target Left hand side of pattern
917*10d63b7dSRichard Lowe * depes The dependency list with the rh pattern
918*10d63b7dSRichard Lowe * command The command for the pattern
919*10d63b7dSRichard Lowe *
920*10d63b7dSRichard Lowe * Global variables used:
921*10d63b7dSRichard Lowe * empty_name The Name "", compared against
922*10d63b7dSRichard Lowe * percent_list The list of all percent rules, added to
923*10d63b7dSRichard Lowe * trace_reader Indicates that we should echo stuff we read
924*10d63b7dSRichard Lowe */
925*10d63b7dSRichard Lowe Percent
enter_percent(register Name target,Chain target_group,register Name_vector depes,Cmd_line command)926*10d63b7dSRichard Lowe enter_percent(register Name target, Chain target_group, register Name_vector depes, Cmd_line command)
927*10d63b7dSRichard Lowe {
928*10d63b7dSRichard Lowe register Percent result = ALLOC(Percent);
929*10d63b7dSRichard Lowe register Percent depe;
930*10d63b7dSRichard Lowe register Percent *depe_tail = &result->dependencies;
931*10d63b7dSRichard Lowe register Percent *insert;
932*10d63b7dSRichard Lowe register wchar_t *cp, *cp1;
933*10d63b7dSRichard Lowe Name_vector nvp;
934*10d63b7dSRichard Lowe int i;
935*10d63b7dSRichard Lowe int pattern;
936*10d63b7dSRichard Lowe
937*10d63b7dSRichard Lowe result->next = NULL;
938*10d63b7dSRichard Lowe result->patterns = NULL;
939*10d63b7dSRichard Lowe result->patterns_total = 0;
940*10d63b7dSRichard Lowe result->command_template = command;
941*10d63b7dSRichard Lowe result->being_expanded = false;
942*10d63b7dSRichard Lowe result->name = target;
943*10d63b7dSRichard Lowe result->dependencies = NULL;
944*10d63b7dSRichard Lowe result->target_group = target_group;
945*10d63b7dSRichard Lowe
946*10d63b7dSRichard Lowe /* get patterns count */
947*10d63b7dSRichard Lowe Wstring wcb(target);
948*10d63b7dSRichard Lowe cp = wcb.get_string();
949*10d63b7dSRichard Lowe while (true) {
950*10d63b7dSRichard Lowe cp = (wchar_t *) wcschr(cp, (int) percent_char);
951*10d63b7dSRichard Lowe if (cp != NULL) {
952*10d63b7dSRichard Lowe result->patterns_total++;
953*10d63b7dSRichard Lowe cp++;
954*10d63b7dSRichard Lowe } else {
955*10d63b7dSRichard Lowe break;
956*10d63b7dSRichard Lowe }
957*10d63b7dSRichard Lowe }
958*10d63b7dSRichard Lowe result->patterns_total++;
959*10d63b7dSRichard Lowe
960*10d63b7dSRichard Lowe /* allocate storage for patterns */
961*10d63b7dSRichard Lowe result->patterns = (Name *) getmem(sizeof(Name) * result->patterns_total);
962*10d63b7dSRichard Lowe
963*10d63b7dSRichard Lowe /* then create patterns */
964*10d63b7dSRichard Lowe cp = wcb.get_string();
965*10d63b7dSRichard Lowe pattern = 0;
966*10d63b7dSRichard Lowe while (true) {
967*10d63b7dSRichard Lowe cp1 = (wchar_t *) wcschr(cp, (int) percent_char);
968*10d63b7dSRichard Lowe if (cp1 != NULL) {
969*10d63b7dSRichard Lowe result->patterns[pattern] = GETNAME(cp, cp1 - cp);
970*10d63b7dSRichard Lowe cp = cp1 + 1;
971*10d63b7dSRichard Lowe pattern++;
972*10d63b7dSRichard Lowe } else {
973*10d63b7dSRichard Lowe result->patterns[pattern] = GETNAME(cp, (int) target->hash.length - (cp - wcb.get_string()));
974*10d63b7dSRichard Lowe break;
975*10d63b7dSRichard Lowe }
976*10d63b7dSRichard Lowe }
977*10d63b7dSRichard Lowe
978*10d63b7dSRichard Lowe Wstring wcb1;
979*10d63b7dSRichard Lowe
980*10d63b7dSRichard Lowe /* build dependencies list */
981*10d63b7dSRichard Lowe for (nvp = depes; nvp != NULL; nvp = nvp->next) {
982*10d63b7dSRichard Lowe for (i = 0; i < nvp->used; i++) {
983*10d63b7dSRichard Lowe depe = ALLOC(Percent);
984*10d63b7dSRichard Lowe depe->next = NULL;
985*10d63b7dSRichard Lowe depe->patterns = NULL;
986*10d63b7dSRichard Lowe depe->patterns_total = 0;
987*10d63b7dSRichard Lowe depe->name = nvp->names[i];
988*10d63b7dSRichard Lowe depe->dependencies = NULL;
989*10d63b7dSRichard Lowe depe->command_template = NULL;
990*10d63b7dSRichard Lowe depe->being_expanded = false;
991*10d63b7dSRichard Lowe depe->target_group = NULL;
992*10d63b7dSRichard Lowe
993*10d63b7dSRichard Lowe *depe_tail = depe;
994*10d63b7dSRichard Lowe depe_tail = &depe->next;
995*10d63b7dSRichard Lowe
996*10d63b7dSRichard Lowe if (depe->name->percent) {
997*10d63b7dSRichard Lowe /* get patterns count */
998*10d63b7dSRichard Lowe wcb1.init(depe->name);
999*10d63b7dSRichard Lowe cp = wcb1.get_string();
1000*10d63b7dSRichard Lowe while (true) {
1001*10d63b7dSRichard Lowe cp = (wchar_t *) wcschr(cp, (int) percent_char);
1002*10d63b7dSRichard Lowe if (cp != NULL) {
1003*10d63b7dSRichard Lowe depe->patterns_total++;
1004*10d63b7dSRichard Lowe cp++;
1005*10d63b7dSRichard Lowe } else {
1006*10d63b7dSRichard Lowe break;
1007*10d63b7dSRichard Lowe }
1008*10d63b7dSRichard Lowe }
1009*10d63b7dSRichard Lowe depe->patterns_total++;
1010*10d63b7dSRichard Lowe
1011*10d63b7dSRichard Lowe /* allocate storage for patterns */
1012*10d63b7dSRichard Lowe depe->patterns = (Name *) getmem(sizeof(Name) * depe->patterns_total);
1013*10d63b7dSRichard Lowe
1014*10d63b7dSRichard Lowe /* then create patterns */
1015*10d63b7dSRichard Lowe cp = wcb1.get_string();
1016*10d63b7dSRichard Lowe pattern = 0;
1017*10d63b7dSRichard Lowe while (true) {
1018*10d63b7dSRichard Lowe cp1 = (wchar_t *) wcschr(cp, (int) percent_char);
1019*10d63b7dSRichard Lowe if (cp1 != NULL) {
1020*10d63b7dSRichard Lowe depe->patterns[pattern] = GETNAME(cp, cp1 - cp);
1021*10d63b7dSRichard Lowe cp = cp1 + 1;
1022*10d63b7dSRichard Lowe pattern++;
1023*10d63b7dSRichard Lowe } else {
1024*10d63b7dSRichard Lowe depe->patterns[pattern] = GETNAME(cp, (int) depe->name->hash.length - (cp - wcb1.get_string()));
1025*10d63b7dSRichard Lowe break;
1026*10d63b7dSRichard Lowe }
1027*10d63b7dSRichard Lowe }
1028*10d63b7dSRichard Lowe }
1029*10d63b7dSRichard Lowe }
1030*10d63b7dSRichard Lowe }
1031*10d63b7dSRichard Lowe
1032*10d63b7dSRichard Lowe /* Find the end of the percent list and append the new pattern */
1033*10d63b7dSRichard Lowe for (insert = &percent_list; (*insert) != NULL; insert = &(*insert)->next);
1034*10d63b7dSRichard Lowe *insert = result;
1035*10d63b7dSRichard Lowe
1036*10d63b7dSRichard Lowe if (trace_reader) {
1037*10d63b7dSRichard Lowe (void) printf("%s:", result->name->string_mb);
1038*10d63b7dSRichard Lowe
1039*10d63b7dSRichard Lowe for (depe = result->dependencies; depe != NULL; depe = depe->next) {
1040*10d63b7dSRichard Lowe (void) printf(" %s", depe->name->string_mb);
1041*10d63b7dSRichard Lowe }
1042*10d63b7dSRichard Lowe
1043*10d63b7dSRichard Lowe (void) printf("\n");
1044*10d63b7dSRichard Lowe
1045*10d63b7dSRichard Lowe print_rule(command);
1046*10d63b7dSRichard Lowe }
1047*10d63b7dSRichard Lowe
1048*10d63b7dSRichard Lowe return result;
1049*10d63b7dSRichard Lowe }
1050*10d63b7dSRichard Lowe
1051*10d63b7dSRichard Lowe /*
1052*10d63b7dSRichard Lowe * enter_dyntarget(target)
1053*10d63b7dSRichard Lowe *
1054*10d63b7dSRichard Lowe * Enter "$$(MACRO) : b" type lines
1055*10d63b7dSRichard Lowe *
1056*10d63b7dSRichard Lowe * Parameters:
1057*10d63b7dSRichard Lowe * target Left hand side of pattern
1058*10d63b7dSRichard Lowe *
1059*10d63b7dSRichard Lowe * Global variables used:
1060*10d63b7dSRichard Lowe * dyntarget_list The list of all percent rules, added to
1061*10d63b7dSRichard Lowe * trace_reader Indicates that we should echo stuff we read
1062*10d63b7dSRichard Lowe */
1063*10d63b7dSRichard Lowe Dyntarget
enter_dyntarget(register Name target)1064*10d63b7dSRichard Lowe enter_dyntarget(register Name target)
1065*10d63b7dSRichard Lowe {
1066*10d63b7dSRichard Lowe register Dyntarget result = ALLOC(Dyntarget);
1067*10d63b7dSRichard Lowe Dyntarget p;
1068*10d63b7dSRichard Lowe Dyntarget *insert;
1069*10d63b7dSRichard Lowe int i;
1070*10d63b7dSRichard Lowe
1071*10d63b7dSRichard Lowe result->next = NULL;
1072*10d63b7dSRichard Lowe result->name = target;
1073*10d63b7dSRichard Lowe
1074*10d63b7dSRichard Lowe
1075*10d63b7dSRichard Lowe /* Find the end of the dyntarget list and append the new pattern */
1076*10d63b7dSRichard Lowe for (insert = &dyntarget_list, p = *insert;
1077*10d63b7dSRichard Lowe p != NULL;
1078*10d63b7dSRichard Lowe insert = &p->next, p = *insert);
1079*10d63b7dSRichard Lowe *insert = result;
1080*10d63b7dSRichard Lowe
1081*10d63b7dSRichard Lowe if (trace_reader) {
1082*10d63b7dSRichard Lowe (void) printf("Dynamic target %s:\n", result->name->string_mb);
1083*10d63b7dSRichard Lowe }
1084*10d63b7dSRichard Lowe return( result);
1085*10d63b7dSRichard Lowe }
1086*10d63b7dSRichard Lowe
1087*10d63b7dSRichard Lowe
1088*10d63b7dSRichard Lowe /*
1089*10d63b7dSRichard Lowe * special_reader(target, depes, command)
1090*10d63b7dSRichard Lowe *
1091*10d63b7dSRichard Lowe * Read the pseudo targets make knows about
1092*10d63b7dSRichard Lowe * This handles the special targets that should not be entered as regular
1093*10d63b7dSRichard Lowe * target/dependency sets.
1094*10d63b7dSRichard Lowe *
1095*10d63b7dSRichard Lowe * Parameters:
1096*10d63b7dSRichard Lowe * target The special target
1097*10d63b7dSRichard Lowe * depes The list of dependencies it was entered with
1098*10d63b7dSRichard Lowe * command The command it was entered with
1099*10d63b7dSRichard Lowe *
1100*10d63b7dSRichard Lowe * Static variables used:
1101*10d63b7dSRichard Lowe * built_last_make_run_seen Set to indicate .BUILT_LAST... seen
1102*10d63b7dSRichard Lowe *
1103*10d63b7dSRichard Lowe * Global variables used:
1104*10d63b7dSRichard Lowe * all_parallel Set to indicate that everything runs parallel
1105*10d63b7dSRichard Lowe * svr4 Set when ".SVR4" target is read
1106*10d63b7dSRichard Lowe * svr4_name The Name ".SVR4"
1107*10d63b7dSRichard Lowe * posix Set when ".POSIX" target is read
1108*10d63b7dSRichard Lowe * posix_name The Name ".POSIX"
1109*10d63b7dSRichard Lowe * current_make_version The Name "<current version number>"
1110*10d63b7dSRichard Lowe * default_rule Set when ".DEFAULT" target is read
1111*10d63b7dSRichard Lowe * default_rule_name The Name ".DEFAULT", used for tracing
1112*10d63b7dSRichard Lowe * dot_keep_state The Name ".KEEP_STATE", used for tracing
1113*10d63b7dSRichard Lowe * ignore_errors Set if ".IGNORE" target is read
1114*10d63b7dSRichard Lowe * ignore_name The Name ".IGNORE", used for tracing
1115*10d63b7dSRichard Lowe * keep_state Set if ".KEEP_STATE" target is read
1116*10d63b7dSRichard Lowe * no_parallel_name The Name ".NO_PARALLEL", used for tracing
1117*10d63b7dSRichard Lowe * only_parallel Set to indicate only some targets runs parallel
1118*10d63b7dSRichard Lowe * parallel_name The Name ".PARALLEL", used for tracing
1119*10d63b7dSRichard Lowe * precious The Name ".PRECIOUS", used for tracing
1120*10d63b7dSRichard Lowe * sccs_get_name The Name ".SCCS_GET", used for tracing
1121*10d63b7dSRichard Lowe * sccs_get_posix_name The Name ".SCCS_GET_POSIX", used for tracing
1122*10d63b7dSRichard Lowe * get_name The Name ".GET", used for tracing
1123*10d63b7dSRichard Lowe * sccs_get_rule Set when ".SCCS_GET" target is read
1124*10d63b7dSRichard Lowe * silent Set when ".SILENT" target is read
1125*10d63b7dSRichard Lowe * silent_name The Name ".SILENT", used for tracing
1126*10d63b7dSRichard Lowe * trace_reader Indicates that we should echo stuff we read
1127*10d63b7dSRichard Lowe */
1128*10d63b7dSRichard Lowe void
special_reader(Name target,register Name_vector depes,Cmd_line command)1129*10d63b7dSRichard Lowe special_reader(Name target, register Name_vector depes, Cmd_line command)
1130*10d63b7dSRichard Lowe {
1131*10d63b7dSRichard Lowe register int n;
1132*10d63b7dSRichard Lowe
1133*10d63b7dSRichard Lowe switch (target->special_reader) {
1134*10d63b7dSRichard Lowe
1135*10d63b7dSRichard Lowe case svr4_special:
1136*10d63b7dSRichard Lowe if (depes->used != 0) {
1137*10d63b7dSRichard Lowe fatal_reader(gettext("Illegal dependencies for target `%s'"),
1138*10d63b7dSRichard Lowe target->string_mb);
1139*10d63b7dSRichard Lowe }
1140*10d63b7dSRichard Lowe svr4 = true;
1141*10d63b7dSRichard Lowe posix = false;
1142*10d63b7dSRichard Lowe keep_state = false;
1143*10d63b7dSRichard Lowe all_parallel = false;
1144*10d63b7dSRichard Lowe only_parallel = false;
1145*10d63b7dSRichard Lowe if (trace_reader) {
1146*10d63b7dSRichard Lowe (void) printf("%s:\n", svr4_name->string_mb);
1147*10d63b7dSRichard Lowe }
1148*10d63b7dSRichard Lowe break;
1149*10d63b7dSRichard Lowe
1150*10d63b7dSRichard Lowe case posix_special:
1151*10d63b7dSRichard Lowe if(svr4)
1152*10d63b7dSRichard Lowe break;
1153*10d63b7dSRichard Lowe if (depes->used != 0) {
1154*10d63b7dSRichard Lowe fatal_reader(gettext("Illegal dependencies for target `%s'"),
1155*10d63b7dSRichard Lowe target->string_mb);
1156*10d63b7dSRichard Lowe }
1157*10d63b7dSRichard Lowe posix = true;
1158*10d63b7dSRichard Lowe /* with posix on, use the posix get rule */
1159*10d63b7dSRichard Lowe sccs_get_rule = sccs_get_posix_rule;
1160*10d63b7dSRichard Lowe /* turn keep state off being SunPro make specific */
1161*10d63b7dSRichard Lowe keep_state = false;
1162*10d63b7dSRichard Lowe /* Use /usr/xpg4/bin/sh on Solaris */
1163*10d63b7dSRichard Lowe MBSTOWCS(wcs_buffer, "/usr/xpg4/bin/sh");
1164*10d63b7dSRichard Lowe (void) SETVAR(shell_name, GETNAME(wcs_buffer, FIND_LENGTH), false);
1165*10d63b7dSRichard Lowe if (trace_reader) {
1166*10d63b7dSRichard Lowe (void) printf("%s:\n", posix_name->string_mb);
1167*10d63b7dSRichard Lowe }
1168*10d63b7dSRichard Lowe break;
1169*10d63b7dSRichard Lowe
1170*10d63b7dSRichard Lowe case built_last_make_run_special:
1171*10d63b7dSRichard Lowe built_last_make_run_seen = true;
1172*10d63b7dSRichard Lowe break;
1173*10d63b7dSRichard Lowe
1174*10d63b7dSRichard Lowe case default_special:
1175*10d63b7dSRichard Lowe if (depes->used != 0) {
1176*10d63b7dSRichard Lowe warning(gettext("Illegal dependency list for target `%s'"),
1177*10d63b7dSRichard Lowe target->string_mb);
1178*10d63b7dSRichard Lowe }
1179*10d63b7dSRichard Lowe default_rule = command;
1180*10d63b7dSRichard Lowe if (trace_reader) {
1181*10d63b7dSRichard Lowe (void) printf("%s:\n",
1182*10d63b7dSRichard Lowe default_rule_name->string_mb);
1183*10d63b7dSRichard Lowe print_rule(command);
1184*10d63b7dSRichard Lowe }
1185*10d63b7dSRichard Lowe break;
1186*10d63b7dSRichard Lowe
1187*10d63b7dSRichard Lowe
1188*10d63b7dSRichard Lowe case ignore_special:
1189*10d63b7dSRichard Lowe if ((depes->used != 0) &&(!posix)){
1190*10d63b7dSRichard Lowe fatal_reader(gettext("Illegal dependencies for target `%s'"),
1191*10d63b7dSRichard Lowe target->string_mb);
1192*10d63b7dSRichard Lowe }
1193*10d63b7dSRichard Lowe if (depes->used == 0)
1194*10d63b7dSRichard Lowe {
1195*10d63b7dSRichard Lowe ignore_errors_all = true;
1196*10d63b7dSRichard Lowe }
1197*10d63b7dSRichard Lowe if(svr4) {
1198*10d63b7dSRichard Lowe ignore_errors_all = true;
1199*10d63b7dSRichard Lowe break;
1200*10d63b7dSRichard Lowe }
1201*10d63b7dSRichard Lowe for (; depes != NULL; depes = depes->next) {
1202*10d63b7dSRichard Lowe for (n = 0; n < depes->used; n++) {
1203*10d63b7dSRichard Lowe depes->names[n]->ignore_error_mode = true;
1204*10d63b7dSRichard Lowe }
1205*10d63b7dSRichard Lowe }
1206*10d63b7dSRichard Lowe if (trace_reader) {
1207*10d63b7dSRichard Lowe (void) printf("%s:\n", ignore_name->string_mb);
1208*10d63b7dSRichard Lowe }
1209*10d63b7dSRichard Lowe break;
1210*10d63b7dSRichard Lowe
1211*10d63b7dSRichard Lowe case keep_state_special:
1212*10d63b7dSRichard Lowe if(svr4)
1213*10d63b7dSRichard Lowe break;
1214*10d63b7dSRichard Lowe /* ignore keep state, being SunPro make specific */
1215*10d63b7dSRichard Lowe if(posix)
1216*10d63b7dSRichard Lowe break;
1217*10d63b7dSRichard Lowe if (depes->used != 0) {
1218*10d63b7dSRichard Lowe fatal_reader(gettext("Illegal dependencies for target `%s'"),
1219*10d63b7dSRichard Lowe target->string_mb);
1220*10d63b7dSRichard Lowe }
1221*10d63b7dSRichard Lowe keep_state = true;
1222*10d63b7dSRichard Lowe if (trace_reader) {
1223*10d63b7dSRichard Lowe (void) printf("%s:\n",
1224*10d63b7dSRichard Lowe dot_keep_state->string_mb);
1225*10d63b7dSRichard Lowe }
1226*10d63b7dSRichard Lowe break;
1227*10d63b7dSRichard Lowe
1228*10d63b7dSRichard Lowe case keep_state_file_special:
1229*10d63b7dSRichard Lowe if(svr4)
1230*10d63b7dSRichard Lowe break;
1231*10d63b7dSRichard Lowe if(posix)
1232*10d63b7dSRichard Lowe break;
1233*10d63b7dSRichard Lowe /* it's not necessary to specify KEEP_STATE, if this
1234*10d63b7dSRichard Lowe ** is given, so set the keep_state.
1235*10d63b7dSRichard Lowe */
1236*10d63b7dSRichard Lowe keep_state = true;
1237*10d63b7dSRichard Lowe if (depes->used != 0) {
1238*10d63b7dSRichard Lowe if((!make_state) ||(!strcmp(make_state->string_mb,".make.state"))) {
1239*10d63b7dSRichard Lowe make_state = depes->names[0];
1240*10d63b7dSRichard Lowe }
1241*10d63b7dSRichard Lowe }
1242*10d63b7dSRichard Lowe break;
1243*10d63b7dSRichard Lowe case make_version_special:
1244*10d63b7dSRichard Lowe if(svr4)
1245*10d63b7dSRichard Lowe break;
1246*10d63b7dSRichard Lowe if (depes->used != 1) {
1247*10d63b7dSRichard Lowe fatal_reader(gettext("Illegal dependency list for target `%s'"),
1248*10d63b7dSRichard Lowe target->string_mb);
1249*10d63b7dSRichard Lowe }
1250*10d63b7dSRichard Lowe if (depes->names[0] != current_make_version) {
1251*10d63b7dSRichard Lowe /*
1252*10d63b7dSRichard Lowe * Special case the fact that version 1.0 and 1.1
1253*10d63b7dSRichard Lowe * are identical.
1254*10d63b7dSRichard Lowe */
1255*10d63b7dSRichard Lowe if (!IS_EQUAL(depes->names[0]->string_mb,
1256*10d63b7dSRichard Lowe "VERSION-1.1") ||
1257*10d63b7dSRichard Lowe !IS_EQUAL(current_make_version->string_mb,
1258*10d63b7dSRichard Lowe "VERSION-1.0")) {
1259*10d63b7dSRichard Lowe /*
1260*10d63b7dSRichard Lowe * Version mismatches should cause the
1261*10d63b7dSRichard Lowe * .make.state file to be skipped.
1262*10d63b7dSRichard Lowe * This is currently not true - it is read
1263*10d63b7dSRichard Lowe * anyway.
1264*10d63b7dSRichard Lowe */
1265*10d63b7dSRichard Lowe warning(gettext("Version mismatch between current version `%s' and `%s'"),
1266*10d63b7dSRichard Lowe current_make_version->string_mb,
1267*10d63b7dSRichard Lowe depes->names[0]->string_mb);
1268*10d63b7dSRichard Lowe }
1269*10d63b7dSRichard Lowe }
1270*10d63b7dSRichard Lowe break;
1271*10d63b7dSRichard Lowe
1272*10d63b7dSRichard Lowe case no_parallel_special:
1273*10d63b7dSRichard Lowe if(svr4)
1274*10d63b7dSRichard Lowe break;
1275*10d63b7dSRichard Lowe /* Set the no_parallel bit for all the targets on */
1276*10d63b7dSRichard Lowe /* the dependency list */
1277*10d63b7dSRichard Lowe if (depes->used == 0) {
1278*10d63b7dSRichard Lowe /* only those explicitly made parallel */
1279*10d63b7dSRichard Lowe only_parallel = true;
1280*10d63b7dSRichard Lowe all_parallel = false;
1281*10d63b7dSRichard Lowe }
1282*10d63b7dSRichard Lowe for (; depes != NULL; depes = depes->next) {
1283*10d63b7dSRichard Lowe for (n = 0; n < depes->used; n++) {
1284*10d63b7dSRichard Lowe if (trace_reader) {
1285*10d63b7dSRichard Lowe (void) printf("%s:\t%s\n",
1286*10d63b7dSRichard Lowe no_parallel_name->string_mb,
1287*10d63b7dSRichard Lowe depes->names[n]->string_mb);
1288*10d63b7dSRichard Lowe }
1289*10d63b7dSRichard Lowe depes->names[n]->no_parallel = true;
1290*10d63b7dSRichard Lowe depes->names[n]->parallel = false;
1291*10d63b7dSRichard Lowe }
1292*10d63b7dSRichard Lowe }
1293*10d63b7dSRichard Lowe break;
1294*10d63b7dSRichard Lowe
1295*10d63b7dSRichard Lowe case parallel_special:
1296*10d63b7dSRichard Lowe if(svr4)
1297*10d63b7dSRichard Lowe break;
1298*10d63b7dSRichard Lowe if (depes->used == 0) {
1299*10d63b7dSRichard Lowe /* everything runs in parallel */
1300*10d63b7dSRichard Lowe all_parallel = true;
1301*10d63b7dSRichard Lowe only_parallel = false;
1302*10d63b7dSRichard Lowe }
1303*10d63b7dSRichard Lowe /* Set the parallel bit for all the targets on */
1304*10d63b7dSRichard Lowe /* the dependency list */
1305*10d63b7dSRichard Lowe for (; depes != NULL; depes = depes->next) {
1306*10d63b7dSRichard Lowe for (n = 0; n < depes->used; n++) {
1307*10d63b7dSRichard Lowe if (trace_reader) {
1308*10d63b7dSRichard Lowe (void) printf("%s:\t%s\n",
1309*10d63b7dSRichard Lowe parallel_name->string_mb,
1310*10d63b7dSRichard Lowe depes->names[n]->string_mb);
1311*10d63b7dSRichard Lowe }
1312*10d63b7dSRichard Lowe depes->names[n]->parallel = true;
1313*10d63b7dSRichard Lowe depes->names[n]->no_parallel = false;
1314*10d63b7dSRichard Lowe }
1315*10d63b7dSRichard Lowe }
1316*10d63b7dSRichard Lowe break;
1317*10d63b7dSRichard Lowe
1318*10d63b7dSRichard Lowe case localhost_special:
1319*10d63b7dSRichard Lowe if(svr4)
1320*10d63b7dSRichard Lowe break;
1321*10d63b7dSRichard Lowe /* Set the no_parallel bit for all the targets on */
1322*10d63b7dSRichard Lowe /* the dependency list */
1323*10d63b7dSRichard Lowe if (depes->used == 0) {
1324*10d63b7dSRichard Lowe /* only those explicitly made parallel */
1325*10d63b7dSRichard Lowe only_parallel = true;
1326*10d63b7dSRichard Lowe all_parallel = false;
1327*10d63b7dSRichard Lowe }
1328*10d63b7dSRichard Lowe for (; depes != NULL; depes = depes->next) {
1329*10d63b7dSRichard Lowe for (n = 0; n < depes->used; n++) {
1330*10d63b7dSRichard Lowe if (trace_reader) {
1331*10d63b7dSRichard Lowe (void) printf("%s:\t%s\n",
1332*10d63b7dSRichard Lowe localhost_name->string_mb,
1333*10d63b7dSRichard Lowe depes->names[n]->string_mb);
1334*10d63b7dSRichard Lowe }
1335*10d63b7dSRichard Lowe depes->names[n]->no_parallel = true;
1336*10d63b7dSRichard Lowe depes->names[n]->parallel = false;
1337*10d63b7dSRichard Lowe depes->names[n]->localhost = true;
1338*10d63b7dSRichard Lowe }
1339*10d63b7dSRichard Lowe }
1340*10d63b7dSRichard Lowe break;
1341*10d63b7dSRichard Lowe
1342*10d63b7dSRichard Lowe case precious_special:
1343*10d63b7dSRichard Lowe if (depes->used == 0) {
1344*10d63b7dSRichard Lowe /* everything is precious */
1345*10d63b7dSRichard Lowe all_precious = true;
1346*10d63b7dSRichard Lowe } else {
1347*10d63b7dSRichard Lowe all_precious = false;
1348*10d63b7dSRichard Lowe }
1349*10d63b7dSRichard Lowe if(svr4) {
1350*10d63b7dSRichard Lowe all_precious = true;
1351*10d63b7dSRichard Lowe break;
1352*10d63b7dSRichard Lowe }
1353*10d63b7dSRichard Lowe /* Set the precious bit for all the targets on */
1354*10d63b7dSRichard Lowe /* the dependency list */
1355*10d63b7dSRichard Lowe for (; depes != NULL; depes = depes->next) {
1356*10d63b7dSRichard Lowe for (n = 0; n < depes->used; n++) {
1357*10d63b7dSRichard Lowe if (trace_reader) {
1358*10d63b7dSRichard Lowe (void) printf("%s:\t%s\n",
1359*10d63b7dSRichard Lowe precious->string_mb,
1360*10d63b7dSRichard Lowe depes->names[n]->string_mb);
1361*10d63b7dSRichard Lowe }
1362*10d63b7dSRichard Lowe depes->names[n]->stat.is_precious = true;
1363*10d63b7dSRichard Lowe }
1364*10d63b7dSRichard Lowe }
1365*10d63b7dSRichard Lowe break;
1366*10d63b7dSRichard Lowe
1367*10d63b7dSRichard Lowe case sccs_get_special:
1368*10d63b7dSRichard Lowe if (depes->used != 0) {
1369*10d63b7dSRichard Lowe fatal_reader(gettext("Illegal dependencies for target `%s'"),
1370*10d63b7dSRichard Lowe target->string_mb);
1371*10d63b7dSRichard Lowe }
1372*10d63b7dSRichard Lowe sccs_get_rule = command;
1373*10d63b7dSRichard Lowe sccs_get_org_rule = command;
1374*10d63b7dSRichard Lowe if (trace_reader) {
1375*10d63b7dSRichard Lowe (void) printf("%s:\n", sccs_get_name->string_mb);
1376*10d63b7dSRichard Lowe print_rule(command);
1377*10d63b7dSRichard Lowe }
1378*10d63b7dSRichard Lowe break;
1379*10d63b7dSRichard Lowe
1380*10d63b7dSRichard Lowe case sccs_get_posix_special:
1381*10d63b7dSRichard Lowe if (depes->used != 0) {
1382*10d63b7dSRichard Lowe fatal_reader(gettext("Illegal dependencies for target `%s'"),
1383*10d63b7dSRichard Lowe target->string_mb);
1384*10d63b7dSRichard Lowe }
1385*10d63b7dSRichard Lowe sccs_get_posix_rule = command;
1386*10d63b7dSRichard Lowe if (trace_reader) {
1387*10d63b7dSRichard Lowe (void) printf("%s:\n", sccs_get_posix_name->string_mb);
1388*10d63b7dSRichard Lowe print_rule(command);
1389*10d63b7dSRichard Lowe }
1390*10d63b7dSRichard Lowe break;
1391*10d63b7dSRichard Lowe
1392*10d63b7dSRichard Lowe case get_posix_special:
1393*10d63b7dSRichard Lowe if (depes->used != 0) {
1394*10d63b7dSRichard Lowe fatal_reader(gettext("Illegal dependencies for target `%s'"),
1395*10d63b7dSRichard Lowe target->string_mb);
1396*10d63b7dSRichard Lowe }
1397*10d63b7dSRichard Lowe get_posix_rule = command;
1398*10d63b7dSRichard Lowe if (trace_reader) {
1399*10d63b7dSRichard Lowe (void) printf("%s:\n", get_posix_name->string_mb);
1400*10d63b7dSRichard Lowe print_rule(command);
1401*10d63b7dSRichard Lowe }
1402*10d63b7dSRichard Lowe break;
1403*10d63b7dSRichard Lowe
1404*10d63b7dSRichard Lowe case get_special:
1405*10d63b7dSRichard Lowe if(!svr4) {
1406*10d63b7dSRichard Lowe break;
1407*10d63b7dSRichard Lowe }
1408*10d63b7dSRichard Lowe if (depes->used != 0) {
1409*10d63b7dSRichard Lowe fatal_reader(gettext("Illegal dependencies for target `%s'"),
1410*10d63b7dSRichard Lowe target->string_mb);
1411*10d63b7dSRichard Lowe }
1412*10d63b7dSRichard Lowe get_rule = command;
1413*10d63b7dSRichard Lowe sccs_get_rule = command;
1414*10d63b7dSRichard Lowe if (trace_reader) {
1415*10d63b7dSRichard Lowe (void) printf("%s:\n", get_name->string_mb);
1416*10d63b7dSRichard Lowe print_rule(command);
1417*10d63b7dSRichard Lowe }
1418*10d63b7dSRichard Lowe break;
1419*10d63b7dSRichard Lowe
1420*10d63b7dSRichard Lowe case silent_special:
1421*10d63b7dSRichard Lowe if ((depes->used != 0) && (!posix)){
1422*10d63b7dSRichard Lowe fatal_reader(gettext("Illegal dependencies for target `%s'"),
1423*10d63b7dSRichard Lowe target->string_mb);
1424*10d63b7dSRichard Lowe }
1425*10d63b7dSRichard Lowe if (depes->used == 0)
1426*10d63b7dSRichard Lowe {
1427*10d63b7dSRichard Lowe silent_all = true;
1428*10d63b7dSRichard Lowe }
1429*10d63b7dSRichard Lowe if(svr4) {
1430*10d63b7dSRichard Lowe silent_all = true;
1431*10d63b7dSRichard Lowe break;
1432*10d63b7dSRichard Lowe }
1433*10d63b7dSRichard Lowe for (; depes != NULL; depes = depes->next) {
1434*10d63b7dSRichard Lowe for (n = 0; n < depes->used; n++) {
1435*10d63b7dSRichard Lowe depes->names[n]->silent_mode = true;
1436*10d63b7dSRichard Lowe }
1437*10d63b7dSRichard Lowe }
1438*10d63b7dSRichard Lowe if (trace_reader) {
1439*10d63b7dSRichard Lowe (void) printf("%s:\n", silent_name->string_mb);
1440*10d63b7dSRichard Lowe }
1441*10d63b7dSRichard Lowe break;
1442*10d63b7dSRichard Lowe
1443*10d63b7dSRichard Lowe case suffixes_special:
1444*10d63b7dSRichard Lowe read_suffixes_list(depes);
1445*10d63b7dSRichard Lowe break;
1446*10d63b7dSRichard Lowe
1447*10d63b7dSRichard Lowe default:
1448*10d63b7dSRichard Lowe
1449*10d63b7dSRichard Lowe fatal_reader(gettext("Internal error: Unknown special reader"));
1450*10d63b7dSRichard Lowe }
1451*10d63b7dSRichard Lowe }
1452*10d63b7dSRichard Lowe
1453*10d63b7dSRichard Lowe /*
1454*10d63b7dSRichard Lowe * read_suffixes_list(depes)
1455*10d63b7dSRichard Lowe *
1456*10d63b7dSRichard Lowe * Read the special list .SUFFIXES. If it is empty the old list is
1457*10d63b7dSRichard Lowe * cleared. Else the new one is appended. Suffixes with ~ are extracted
1458*10d63b7dSRichard Lowe * and marked.
1459*10d63b7dSRichard Lowe *
1460*10d63b7dSRichard Lowe * Parameters:
1461*10d63b7dSRichard Lowe * depes The list of suffixes
1462*10d63b7dSRichard Lowe *
1463*10d63b7dSRichard Lowe * Global variables used:
1464*10d63b7dSRichard Lowe * hashtab The central hashtable for Names.
1465*10d63b7dSRichard Lowe * suffixes The list of suffixes, set or appended to
1466*10d63b7dSRichard Lowe * suffixes_name The Name ".SUFFIXES", used for tracing
1467*10d63b7dSRichard Lowe * trace_reader Indicates that we should echo stuff we read
1468*10d63b7dSRichard Lowe */
1469*10d63b7dSRichard Lowe static void
read_suffixes_list(register Name_vector depes)1470*10d63b7dSRichard Lowe read_suffixes_list(register Name_vector depes)
1471*10d63b7dSRichard Lowe {
1472*10d63b7dSRichard Lowe register int n;
1473*10d63b7dSRichard Lowe register Dependency dp;
1474*10d63b7dSRichard Lowe register Dependency *insert_dep;
1475*10d63b7dSRichard Lowe register Name np;
1476*10d63b7dSRichard Lowe Name np2;
1477*10d63b7dSRichard Lowe register Boolean first = true;
1478*10d63b7dSRichard Lowe
1479*10d63b7dSRichard Lowe if (depes->used == 0) {
1480*10d63b7dSRichard Lowe /* .SUFFIXES with no dependency list clears the */
1481*10d63b7dSRichard Lowe /* suffixes list */
1482*10d63b7dSRichard Lowe for (Name_set::iterator np = hashtab.begin(), e = hashtab.end(); np != e; np++) {
1483*10d63b7dSRichard Lowe np->with_squiggle =
1484*10d63b7dSRichard Lowe np->without_squiggle =
1485*10d63b7dSRichard Lowe false;
1486*10d63b7dSRichard Lowe }
1487*10d63b7dSRichard Lowe suffixes = NULL;
1488*10d63b7dSRichard Lowe if (trace_reader) {
1489*10d63b7dSRichard Lowe (void) printf("%s:\n", suffixes_name->string_mb);
1490*10d63b7dSRichard Lowe }
1491*10d63b7dSRichard Lowe return;
1492*10d63b7dSRichard Lowe }
1493*10d63b7dSRichard Lowe Wstring str;
1494*10d63b7dSRichard Lowe /* Otherwise we append to the list */
1495*10d63b7dSRichard Lowe for (; depes != NULL; depes = depes->next) {
1496*10d63b7dSRichard Lowe for (n = 0; n < depes->used; n++) {
1497*10d63b7dSRichard Lowe np = depes->names[n];
1498*10d63b7dSRichard Lowe /* Find the end of the list and check if the */
1499*10d63b7dSRichard Lowe /* suffix already has been entered */
1500*10d63b7dSRichard Lowe for (insert_dep = &suffixes, dp = *insert_dep;
1501*10d63b7dSRichard Lowe dp != NULL;
1502*10d63b7dSRichard Lowe insert_dep = &dp->next, dp = *insert_dep) {
1503*10d63b7dSRichard Lowe if (dp->name == np) {
1504*10d63b7dSRichard Lowe goto duplicate_suffix;
1505*10d63b7dSRichard Lowe }
1506*10d63b7dSRichard Lowe }
1507*10d63b7dSRichard Lowe if (trace_reader) {
1508*10d63b7dSRichard Lowe if (first) {
1509*10d63b7dSRichard Lowe (void) printf("%s:\t",
1510*10d63b7dSRichard Lowe suffixes_name->string_mb);
1511*10d63b7dSRichard Lowe first = false;
1512*10d63b7dSRichard Lowe }
1513*10d63b7dSRichard Lowe (void) printf("%s ", depes->names[n]->string_mb);
1514*10d63b7dSRichard Lowe }
1515*10d63b7dSRichard Lowe if(!(posix|svr4)) {
1516*10d63b7dSRichard Lowe /* If the suffix is suffixed with "~" we */
1517*10d63b7dSRichard Lowe /* strip that and mark the suffix nameblock */
1518*10d63b7dSRichard Lowe str.init(np);
1519*10d63b7dSRichard Lowe wchar_t * wcb = str.get_string();
1520*10d63b7dSRichard Lowe if (wcb[np->hash.length - 1] ==
1521*10d63b7dSRichard Lowe (int) tilde_char) {
1522*10d63b7dSRichard Lowe np2 = GETNAME(wcb,
1523*10d63b7dSRichard Lowe (int)(np->hash.length - 1));
1524*10d63b7dSRichard Lowe np2->with_squiggle = true;
1525*10d63b7dSRichard Lowe if (np2->without_squiggle) {
1526*10d63b7dSRichard Lowe continue;
1527*10d63b7dSRichard Lowe }
1528*10d63b7dSRichard Lowe np = np2;
1529*10d63b7dSRichard Lowe }
1530*10d63b7dSRichard Lowe }
1531*10d63b7dSRichard Lowe np->without_squiggle = true;
1532*10d63b7dSRichard Lowe /* Add the suffix to the list */
1533*10d63b7dSRichard Lowe dp = *insert_dep = ALLOC(Dependency);
1534*10d63b7dSRichard Lowe insert_dep = &dp->next;
1535*10d63b7dSRichard Lowe dp->next = NULL;
1536*10d63b7dSRichard Lowe dp->name = np;
1537*10d63b7dSRichard Lowe dp->built = false;
1538*10d63b7dSRichard Lowe duplicate_suffix:;
1539*10d63b7dSRichard Lowe }
1540*10d63b7dSRichard Lowe }
1541*10d63b7dSRichard Lowe if (trace_reader) {
1542*10d63b7dSRichard Lowe (void) printf("\n");
1543*10d63b7dSRichard Lowe }
1544*10d63b7dSRichard Lowe }
1545*10d63b7dSRichard Lowe
1546*10d63b7dSRichard Lowe /*
1547*10d63b7dSRichard Lowe * make_relative(to, result)
1548*10d63b7dSRichard Lowe *
1549*10d63b7dSRichard Lowe * Given a file name compose a relative path name from it to the
1550*10d63b7dSRichard Lowe * current directory.
1551*10d63b7dSRichard Lowe *
1552*10d63b7dSRichard Lowe * Parameters:
1553*10d63b7dSRichard Lowe * to The path we want to make relative
1554*10d63b7dSRichard Lowe * result Where to put the resulting relative path
1555*10d63b7dSRichard Lowe *
1556*10d63b7dSRichard Lowe * Global variables used:
1557*10d63b7dSRichard Lowe */
1558*10d63b7dSRichard Lowe static void
make_relative(wchar_t * to,wchar_t * result)1559*10d63b7dSRichard Lowe make_relative(wchar_t *to, wchar_t *result)
1560*10d63b7dSRichard Lowe {
1561*10d63b7dSRichard Lowe wchar_t *from;
1562*10d63b7dSRichard Lowe wchar_t *allocated;
1563*10d63b7dSRichard Lowe wchar_t *cp;
1564*10d63b7dSRichard Lowe wchar_t *tocomp;
1565*10d63b7dSRichard Lowe int ncomps;
1566*10d63b7dSRichard Lowe int i;
1567*10d63b7dSRichard Lowe int len;
1568*10d63b7dSRichard Lowe
1569*10d63b7dSRichard Lowe /* Check if the path is already relative. */
1570*10d63b7dSRichard Lowe if (to[0] != (int) slash_char) {
1571*10d63b7dSRichard Lowe (void) wcscpy(result, to);
1572*10d63b7dSRichard Lowe return;
1573*10d63b7dSRichard Lowe }
1574*10d63b7dSRichard Lowe
1575*10d63b7dSRichard Lowe MBSTOWCS(wcs_buffer, get_current_path());
1576*10d63b7dSRichard Lowe from = allocated = (wchar_t *) wcsdup(wcs_buffer);
1577*10d63b7dSRichard Lowe
1578*10d63b7dSRichard Lowe /*
1579*10d63b7dSRichard Lowe * Find the number of components in the from name.
1580*10d63b7dSRichard Lowe * ncomp = number of slashes + 1.
1581*10d63b7dSRichard Lowe */
1582*10d63b7dSRichard Lowe ncomps = 1;
1583*10d63b7dSRichard Lowe for (cp = from; *cp != (int) nul_char; cp++) {
1584*10d63b7dSRichard Lowe if (*cp == (int) slash_char) {
1585*10d63b7dSRichard Lowe ncomps++;
1586*10d63b7dSRichard Lowe }
1587*10d63b7dSRichard Lowe }
1588*10d63b7dSRichard Lowe
1589*10d63b7dSRichard Lowe /*
1590*10d63b7dSRichard Lowe * See how many components match to determine how many "..",
1591*10d63b7dSRichard Lowe * if any, will be needed.
1592*10d63b7dSRichard Lowe */
1593*10d63b7dSRichard Lowe result[0] = (int) nul_char;
1594*10d63b7dSRichard Lowe tocomp = to;
1595*10d63b7dSRichard Lowe while ((*from != (int) nul_char) && (*from == *to)) {
1596*10d63b7dSRichard Lowe if (*from == (int) slash_char) {
1597*10d63b7dSRichard Lowe ncomps--;
1598*10d63b7dSRichard Lowe tocomp = &to[1];
1599*10d63b7dSRichard Lowe }
1600*10d63b7dSRichard Lowe from++;
1601*10d63b7dSRichard Lowe to++;
1602*10d63b7dSRichard Lowe }
1603*10d63b7dSRichard Lowe
1604*10d63b7dSRichard Lowe /*
1605*10d63b7dSRichard Lowe * Now for some special cases. Check for exact matches and
1606*10d63b7dSRichard Lowe * for either name terminating exactly.
1607*10d63b7dSRichard Lowe */
1608*10d63b7dSRichard Lowe if (*from == (int) nul_char) {
1609*10d63b7dSRichard Lowe if (*to == (int) nul_char) {
1610*10d63b7dSRichard Lowe MBSTOWCS(wcs_buffer, ".");
1611*10d63b7dSRichard Lowe (void) wcscpy(result, wcs_buffer);
1612*10d63b7dSRichard Lowe retmem(allocated);
1613*10d63b7dSRichard Lowe return;
1614*10d63b7dSRichard Lowe }
1615*10d63b7dSRichard Lowe if (*to == (int) slash_char) {
1616*10d63b7dSRichard Lowe ncomps--;
1617*10d63b7dSRichard Lowe tocomp = &to[1];
1618*10d63b7dSRichard Lowe }
1619*10d63b7dSRichard Lowe } else if ((*from == (int) slash_char) && (*to == (int) nul_char)) {
1620*10d63b7dSRichard Lowe ncomps--;
1621*10d63b7dSRichard Lowe tocomp = to;
1622*10d63b7dSRichard Lowe }
1623*10d63b7dSRichard Lowe /* Add on the ".."s. */
1624*10d63b7dSRichard Lowe for (i = 0; i < ncomps; i++) {
1625*10d63b7dSRichard Lowe MBSTOWCS(wcs_buffer, "../");
1626*10d63b7dSRichard Lowe (void) wcscat(result, wcs_buffer);
1627*10d63b7dSRichard Lowe }
1628*10d63b7dSRichard Lowe
1629*10d63b7dSRichard Lowe /* Add on the remainder of the to name, if any. */
1630*10d63b7dSRichard Lowe if (*tocomp == (int) nul_char) {
1631*10d63b7dSRichard Lowe len = wcslen(result);
1632*10d63b7dSRichard Lowe result[len - 1] = (int) nul_char;
1633*10d63b7dSRichard Lowe } else {
1634*10d63b7dSRichard Lowe (void) wcscat(result, tocomp);
1635*10d63b7dSRichard Lowe }
1636*10d63b7dSRichard Lowe retmem(allocated);
1637*10d63b7dSRichard Lowe return;
1638*10d63b7dSRichard Lowe }
1639*10d63b7dSRichard Lowe
1640*10d63b7dSRichard Lowe /*
1641*10d63b7dSRichard Lowe * print_rule(command)
1642*10d63b7dSRichard Lowe *
1643*10d63b7dSRichard Lowe * Used when tracing the reading of rules
1644*10d63b7dSRichard Lowe *
1645*10d63b7dSRichard Lowe * Parameters:
1646*10d63b7dSRichard Lowe * command Command to print
1647*10d63b7dSRichard Lowe *
1648*10d63b7dSRichard Lowe * Global variables used:
1649*10d63b7dSRichard Lowe */
1650*10d63b7dSRichard Lowe static void
print_rule(register Cmd_line command)1651*10d63b7dSRichard Lowe print_rule(register Cmd_line command)
1652*10d63b7dSRichard Lowe {
1653*10d63b7dSRichard Lowe for (; command != NULL; command = command->next) {
1654*10d63b7dSRichard Lowe (void) printf("\t%s\n", command->command_line->string_mb);
1655*10d63b7dSRichard Lowe }
1656*10d63b7dSRichard Lowe }
1657*10d63b7dSRichard Lowe
1658*10d63b7dSRichard Lowe /*
1659*10d63b7dSRichard Lowe * enter_conditional(target, name, value, append)
1660*10d63b7dSRichard Lowe *
1661*10d63b7dSRichard Lowe * Enter "target := MACRO= value" constructs
1662*10d63b7dSRichard Lowe *
1663*10d63b7dSRichard Lowe * Parameters:
1664*10d63b7dSRichard Lowe * target The target the macro is for
1665*10d63b7dSRichard Lowe * name The name of the macro
1666*10d63b7dSRichard Lowe * value The value for the macro
1667*10d63b7dSRichard Lowe * append Indicates if the assignment is appending or not
1668*10d63b7dSRichard Lowe *
1669*10d63b7dSRichard Lowe * Global variables used:
1670*10d63b7dSRichard Lowe * conditionals A special Name that stores all conditionals
1671*10d63b7dSRichard Lowe * where the target is a % pattern
1672*10d63b7dSRichard Lowe * trace_reader Indicates that we should echo stuff we read
1673*10d63b7dSRichard Lowe */
1674*10d63b7dSRichard Lowe void
enter_conditional(register Name target,Name name,Name value,register Boolean append)1675*10d63b7dSRichard Lowe enter_conditional(register Name target, Name name, Name value, register Boolean append)
1676*10d63b7dSRichard Lowe {
1677*10d63b7dSRichard Lowe register Property conditional;
1678*10d63b7dSRichard Lowe static int sequence;
1679*10d63b7dSRichard Lowe Name orig_target = target;
1680*10d63b7dSRichard Lowe
1681*10d63b7dSRichard Lowe if (name == target_arch) {
1682*10d63b7dSRichard Lowe enter_conditional(target, virtual_root, virtual_root, false);
1683*10d63b7dSRichard Lowe }
1684*10d63b7dSRichard Lowe
1685*10d63b7dSRichard Lowe if (target->percent) {
1686*10d63b7dSRichard Lowe target = conditionals;
1687*10d63b7dSRichard Lowe }
1688*10d63b7dSRichard Lowe
1689*10d63b7dSRichard Lowe if (name->colon) {
1690*10d63b7dSRichard Lowe sh_transform(&name, &value);
1691*10d63b7dSRichard Lowe }
1692*10d63b7dSRichard Lowe
1693*10d63b7dSRichard Lowe /* Count how many conditionals we must activate before building the */
1694*10d63b7dSRichard Lowe /* target */
1695*10d63b7dSRichard Lowe if (target->percent) {
1696*10d63b7dSRichard Lowe target = conditionals;
1697*10d63b7dSRichard Lowe }
1698*10d63b7dSRichard Lowe
1699*10d63b7dSRichard Lowe target->conditional_cnt++;
1700*10d63b7dSRichard Lowe maybe_append_prop(name, macro_prop)->body.macro.is_conditional = true;
1701*10d63b7dSRichard Lowe /* Add the property for the target */
1702*10d63b7dSRichard Lowe conditional = append_prop(target, conditional_prop);
1703*10d63b7dSRichard Lowe conditional->body.conditional.target = orig_target;
1704*10d63b7dSRichard Lowe conditional->body.conditional.name = name;
1705*10d63b7dSRichard Lowe conditional->body.conditional.value = value;
1706*10d63b7dSRichard Lowe conditional->body.conditional.sequence = sequence++;
1707*10d63b7dSRichard Lowe conditional->body.conditional.append = append;
1708*10d63b7dSRichard Lowe if (trace_reader) {
1709*10d63b7dSRichard Lowe if (value == NULL) {
1710*10d63b7dSRichard Lowe (void) printf("%s := %s %c=\n",
1711*10d63b7dSRichard Lowe target->string_mb,
1712*10d63b7dSRichard Lowe name->string_mb,
1713*10d63b7dSRichard Lowe append ?
1714*10d63b7dSRichard Lowe (int) plus_char : (int) space_char);
1715*10d63b7dSRichard Lowe } else {
1716*10d63b7dSRichard Lowe (void) printf("%s := %s %c= %s\n",
1717*10d63b7dSRichard Lowe target->string_mb,
1718*10d63b7dSRichard Lowe name->string_mb,
1719*10d63b7dSRichard Lowe append ?
1720*10d63b7dSRichard Lowe (int) plus_char : (int) space_char,
1721*10d63b7dSRichard Lowe value->string_mb);
1722*10d63b7dSRichard Lowe }
1723*10d63b7dSRichard Lowe }
1724*10d63b7dSRichard Lowe }
1725*10d63b7dSRichard Lowe
1726*10d63b7dSRichard Lowe /*
1727*10d63b7dSRichard Lowe * enter_equal(name, value, append)
1728*10d63b7dSRichard Lowe *
1729*10d63b7dSRichard Lowe * Enter "MACRO= value" constructs
1730*10d63b7dSRichard Lowe *
1731*10d63b7dSRichard Lowe * Parameters:
1732*10d63b7dSRichard Lowe * name The name of the macro
1733*10d63b7dSRichard Lowe * value The value for the macro
1734*10d63b7dSRichard Lowe * append Indicates if the assignment is appending or not
1735*10d63b7dSRichard Lowe *
1736*10d63b7dSRichard Lowe * Global variables used:
1737*10d63b7dSRichard Lowe * trace_reader Indicates that we should echo stuff we read
1738*10d63b7dSRichard Lowe */
1739*10d63b7dSRichard Lowe void
enter_equal(Name name,Name value,register Boolean append)1740*10d63b7dSRichard Lowe enter_equal(Name name, Name value, register Boolean append)
1741*10d63b7dSRichard Lowe {
1742*10d63b7dSRichard Lowe wchar_t *string;
1743*10d63b7dSRichard Lowe Name temp;
1744*10d63b7dSRichard Lowe
1745*10d63b7dSRichard Lowe if (name->colon) {
1746*10d63b7dSRichard Lowe sh_transform(&name, &value);
1747*10d63b7dSRichard Lowe }
1748*10d63b7dSRichard Lowe (void) SETVAR(name, value, append);
1749*10d63b7dSRichard Lowe
1750*10d63b7dSRichard Lowe /* if we're setting FC, we want to set F77 to the same value. */
1751*10d63b7dSRichard Lowe Wstring nms(name);
1752*10d63b7dSRichard Lowe wchar_t * wcb = nms.get_string();
1753*10d63b7dSRichard Lowe string = wcb;
1754*10d63b7dSRichard Lowe if (string[0]=='F' &&
1755*10d63b7dSRichard Lowe string[1]=='C' &&
1756*10d63b7dSRichard Lowe string[2]=='\0') {
1757*10d63b7dSRichard Lowe MBSTOWCS(wcs_buffer, "F77");
1758*10d63b7dSRichard Lowe temp = GETNAME(wcs_buffer, FIND_LENGTH);
1759*10d63b7dSRichard Lowe (void) SETVAR(temp, value, append);
1760*10d63b7dSRichard Lowe /*
1761*10d63b7dSRichard Lowe fprintf(stderr, gettext("warning: FC is obsolete, use F77 instead\n"));
1762*10d63b7dSRichard Lowe */
1763*10d63b7dSRichard Lowe }
1764*10d63b7dSRichard Lowe
1765*10d63b7dSRichard Lowe if (trace_reader) {
1766*10d63b7dSRichard Lowe if (value == NULL) {
1767*10d63b7dSRichard Lowe (void) printf("%s %c=\n",
1768*10d63b7dSRichard Lowe name->string_mb,
1769*10d63b7dSRichard Lowe append ?
1770*10d63b7dSRichard Lowe (int) plus_char : (int) space_char);
1771*10d63b7dSRichard Lowe } else {
1772*10d63b7dSRichard Lowe (void) printf("%s %c= %s\n",
1773*10d63b7dSRichard Lowe name->string_mb,
1774*10d63b7dSRichard Lowe append ?
1775*10d63b7dSRichard Lowe (int) plus_char : (int) space_char,
1776*10d63b7dSRichard Lowe value->string_mb);
1777*10d63b7dSRichard Lowe }
1778*10d63b7dSRichard Lowe }
1779*10d63b7dSRichard Lowe }
1780*10d63b7dSRichard Lowe
1781*10d63b7dSRichard Lowe /*
1782*10d63b7dSRichard Lowe * sh_transform(name, value)
1783*10d63b7dSRichard Lowe *
1784*10d63b7dSRichard Lowe * Parameters:
1785*10d63b7dSRichard Lowe * name The name of the macro we might transform
1786*10d63b7dSRichard Lowe * value The value to transform
1787*10d63b7dSRichard Lowe *
1788*10d63b7dSRichard Lowe */
1789*10d63b7dSRichard Lowe static void
sh_transform(Name * name,Name * value)1790*10d63b7dSRichard Lowe sh_transform(Name *name, Name *value)
1791*10d63b7dSRichard Lowe {
1792*10d63b7dSRichard Lowe /* Check if we need :sh transform */
1793*10d63b7dSRichard Lowe wchar_t *colon;
1794*10d63b7dSRichard Lowe String_rec command;
1795*10d63b7dSRichard Lowe String_rec destination;
1796*10d63b7dSRichard Lowe wchar_t buffer[1000];
1797*10d63b7dSRichard Lowe wchar_t buffer1[1000];
1798*10d63b7dSRichard Lowe
1799*10d63b7dSRichard Lowe static wchar_t colon_sh[4];
1800*10d63b7dSRichard Lowe static wchar_t colon_shell[7];
1801*10d63b7dSRichard Lowe
1802*10d63b7dSRichard Lowe if (colon_sh[0] == (int) nul_char) {
1803*10d63b7dSRichard Lowe MBSTOWCS(colon_sh, ":sh");
1804*10d63b7dSRichard Lowe MBSTOWCS(colon_shell, ":shell");
1805*10d63b7dSRichard Lowe }
1806*10d63b7dSRichard Lowe Wstring nms((*name));
1807*10d63b7dSRichard Lowe wchar_t * wcb = nms.get_string();
1808*10d63b7dSRichard Lowe
1809*10d63b7dSRichard Lowe colon = (wchar_t *) wcsrchr(wcb, (int) colon_char);
1810*10d63b7dSRichard Lowe if ((colon != NULL) && (IS_WEQUAL(colon, colon_sh) || IS_WEQUAL(colon, colon_shell))) {
1811*10d63b7dSRichard Lowe INIT_STRING_FROM_STACK(destination, buffer);
1812*10d63b7dSRichard Lowe
1813*10d63b7dSRichard Lowe if(*value == NULL) {
1814*10d63b7dSRichard Lowe buffer[0] = 0;
1815*10d63b7dSRichard Lowe } else {
1816*10d63b7dSRichard Lowe Wstring wcb1((*value));
1817*10d63b7dSRichard Lowe if (IS_WEQUAL(colon, colon_shell)) {
1818*10d63b7dSRichard Lowe INIT_STRING_FROM_STACK(command, buffer1);
1819*10d63b7dSRichard Lowe expand_value(*value, &command, false);
1820*10d63b7dSRichard Lowe } else {
1821*10d63b7dSRichard Lowe command.text.p = wcb1.get_string() + (*value)->hash.length;
1822*10d63b7dSRichard Lowe command.text.end = command.text.p;
1823*10d63b7dSRichard Lowe command.buffer.start = wcb1.get_string();
1824*10d63b7dSRichard Lowe command.buffer.end = command.text.p;
1825*10d63b7dSRichard Lowe }
1826*10d63b7dSRichard Lowe sh_command2string(&command, &destination);
1827*10d63b7dSRichard Lowe }
1828*10d63b7dSRichard Lowe
1829*10d63b7dSRichard Lowe (*value) = GETNAME(destination.buffer.start, FIND_LENGTH);
1830*10d63b7dSRichard Lowe *colon = (int) nul_char;
1831*10d63b7dSRichard Lowe (*name) = GETNAME(wcb, FIND_LENGTH);
1832*10d63b7dSRichard Lowe *colon = (int) colon_char;
1833*10d63b7dSRichard Lowe }
1834*10d63b7dSRichard Lowe }
1835*10d63b7dSRichard Lowe
1836*10d63b7dSRichard Lowe /*
1837*10d63b7dSRichard Lowe * fatal_reader(format, args...)
1838*10d63b7dSRichard Lowe *
1839*10d63b7dSRichard Lowe * Parameters:
1840*10d63b7dSRichard Lowe * format printf style format string
1841*10d63b7dSRichard Lowe * args arguments to match the format
1842*10d63b7dSRichard Lowe *
1843*10d63b7dSRichard Lowe * Global variables used:
1844*10d63b7dSRichard Lowe * file_being_read Name of the makefile being read
1845*10d63b7dSRichard Lowe * line_number Line that is being read
1846*10d63b7dSRichard Lowe * report_pwd Indicates whether current path should be shown
1847*10d63b7dSRichard Lowe * temp_file_name When reading tempfile we report that name
1848*10d63b7dSRichard Lowe */
1849*10d63b7dSRichard Lowe /*VARARGS*/
1850*10d63b7dSRichard Lowe void
fatal_reader(char * pattern,...)1851*10d63b7dSRichard Lowe fatal_reader(char * pattern, ...)
1852*10d63b7dSRichard Lowe {
1853*10d63b7dSRichard Lowe va_list args;
1854*10d63b7dSRichard Lowe char message[1000];
1855*10d63b7dSRichard Lowe
1856*10d63b7dSRichard Lowe va_start(args, pattern);
1857*10d63b7dSRichard Lowe if (file_being_read != NULL) {
1858*10d63b7dSRichard Lowe WCSTOMBS(mbs_buffer, file_being_read);
1859*10d63b7dSRichard Lowe if (line_number != 0) {
1860*10d63b7dSRichard Lowe (void) sprintf(message,
1861*10d63b7dSRichard Lowe gettext("%s, line %d: %s"),
1862*10d63b7dSRichard Lowe mbs_buffer,
1863*10d63b7dSRichard Lowe line_number,
1864*10d63b7dSRichard Lowe pattern);
1865*10d63b7dSRichard Lowe } else {
1866*10d63b7dSRichard Lowe (void) sprintf(message,
1867*10d63b7dSRichard Lowe "%s: %s",
1868*10d63b7dSRichard Lowe mbs_buffer,
1869*10d63b7dSRichard Lowe pattern);
1870*10d63b7dSRichard Lowe }
1871*10d63b7dSRichard Lowe pattern = message;
1872*10d63b7dSRichard Lowe }
1873*10d63b7dSRichard Lowe
1874*10d63b7dSRichard Lowe (void) fflush(stdout);
1875*10d63b7dSRichard Lowe (void) fprintf(stderr, gettext("%s: Fatal error in reader: "),
1876*10d63b7dSRichard Lowe getprogname());
1877*10d63b7dSRichard Lowe (void) vfprintf(stderr, pattern, args);
1878*10d63b7dSRichard Lowe (void) fprintf(stderr, "\n");
1879*10d63b7dSRichard Lowe va_end(args);
1880*10d63b7dSRichard Lowe
1881*10d63b7dSRichard Lowe if (temp_file_name != NULL) {
1882*10d63b7dSRichard Lowe (void) fprintf(stderr,
1883*10d63b7dSRichard Lowe gettext("%s: Temp-file %s not removed\n"),
1884*10d63b7dSRichard Lowe getprogname(),
1885*10d63b7dSRichard Lowe temp_file_name->string_mb);
1886*10d63b7dSRichard Lowe temp_file_name = NULL;
1887*10d63b7dSRichard Lowe }
1888*10d63b7dSRichard Lowe
1889*10d63b7dSRichard Lowe if (report_pwd) {
1890*10d63b7dSRichard Lowe (void) fprintf(stderr,
1891*10d63b7dSRichard Lowe gettext("Current working directory %s\n"),
1892*10d63b7dSRichard Lowe get_current_path());
1893*10d63b7dSRichard Lowe }
1894*10d63b7dSRichard Lowe (void) fflush(stderr);
1895*10d63b7dSRichard Lowe exit_status = 1;
1896*10d63b7dSRichard Lowe exit(1);
1897*10d63b7dSRichard Lowe }
1898*10d63b7dSRichard Lowe
1899