merge from gcc
[binutils.git] / gas / depend.c
blob3c6049d4c37fee412d421f8299025ed48f26ce99
1 /* depend.c - Handle dependency tracking.
2 Copyright 1997, 1998, 2000, 2001 Free Software Foundation, Inc.
4 This file is part of GAS, the GNU Assembler.
6 GAS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GAS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GAS; see the file COPYING. If not, write to the Free
18 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
19 02111-1307, USA. */
21 #include "as.h"
23 /* The file to write to, or NULL if no dependencies being kept. */
24 static char * dep_file = NULL;
26 struct dependency
28 char * file;
29 struct dependency * next;
32 /* All the files we depend on. */
33 static struct dependency * dep_chain = NULL;
35 /* Current column in output file. */
36 static int column = 0;
38 static int quote_string_for_make PARAMS ((FILE *, char *));
39 static void wrap_output PARAMS ((FILE *, char *, int));
41 /* Number of columns allowable. */
42 #define MAX_COLUMNS 72
44 /* Start saving dependencies, to be written to FILENAME. If this is
45 never called, then dependency tracking is simply skipped. */
47 void
48 start_dependencies (filename)
49 char *filename;
51 dep_file = filename;
54 /* Noticed a new filename, so try to register it. */
56 void
57 register_dependency (filename)
58 char *filename;
60 struct dependency *dep;
62 if (dep_file == NULL)
63 return;
65 for (dep = dep_chain; dep != NULL; dep = dep->next)
67 if (!strcmp (filename, dep->file))
68 return;
71 dep = (struct dependency *) xmalloc (sizeof (struct dependency));
72 dep->file = xstrdup (filename);
73 dep->next = dep_chain;
74 dep_chain = dep;
77 /* Quote a file name the way `make' wants it, and print it to FILE.
78 If FILE is NULL, do no printing, but return the length of the
79 quoted string.
81 This code is taken from gcc with only minor changes. */
83 static int
84 quote_string_for_make (file, src)
85 FILE *file;
86 char *src;
88 char *p = src;
89 int i = 0;
91 for (;;)
93 char c = *p++;
95 switch (c)
97 case '\0':
98 case ' ':
99 case '\t':
101 /* GNU make uses a weird quoting scheme for white space.
102 A space or tab preceded by 2N+1 backslashes represents
103 N backslashes followed by space; a space or tab
104 preceded by 2N backslashes represents N backslashes at
105 the end of a file name; and backslashes in other
106 contexts should not be doubled. */
107 char *q;
109 for (q = p - 1; src < q && q[-1] == '\\'; q--)
111 if (file)
112 putc ('\\', file);
113 i++;
116 if (!c)
117 return i;
118 if (file)
119 putc ('\\', file);
120 i++;
121 goto ordinary_char;
123 case '$':
124 if (file)
125 putc (c, file);
126 i++;
127 /* Fall through. This can mishandle things like "$(" but
128 there's no easy fix. */
129 default:
130 ordinary_char:
131 /* This can mishandle characters in the string "\0\n%*?[\\~";
132 exactly which chars are mishandled depends on the `make' version.
133 We know of no portable solution for this;
134 even GNU make 3.76.1 doesn't solve the problem entirely.
135 (Also, '\0' is mishandled due to our calling conventions.) */
136 if (file)
137 putc (c, file);
138 i++;
139 break;
144 /* Append some output to the file, keeping track of columns and doing
145 wrapping as necessary. */
147 static void
148 wrap_output (f, string, spacer)
149 FILE *f;
150 char *string;
151 int spacer;
153 int len = quote_string_for_make (NULL, string);
155 if (len == 0)
156 return;
158 if (column
159 && (MAX_COLUMNS
160 - 1 /* spacer */
161 - 2 /* ` \' */
162 < column + len))
164 fprintf (f, " \\\n ");
165 column = 0;
166 if (spacer == ' ')
167 spacer = '\0';
170 if (spacer == ' ')
172 putc (spacer, f);
173 ++column;
176 quote_string_for_make (f, string);
177 column += len;
179 if (spacer == ':')
181 putc (spacer, f);
182 ++column;
186 /* Print dependency file. */
188 void
189 print_dependencies ()
191 FILE *f;
192 struct dependency *dep;
194 if (dep_file == NULL)
195 return;
197 f = fopen (dep_file, FOPEN_WT);
198 if (f == NULL)
200 as_warn (_("can't open `%s' for writing"), dep_file);
201 return;
204 column = 0;
205 wrap_output (f, out_file_name, ':');
206 for (dep = dep_chain; dep != NULL; dep = dep->next)
207 wrap_output (f, dep->file, ' ');
209 putc ('\n', f);
211 if (fclose (f))
212 as_warn (_("can't close `%s'"), dep_file);