* app.c: Convert to ISO-C.
[deliverable/binutils-gdb.git] / gas / depend.c
CommitLineData
252b5132 1/* depend.c - Handle dependency tracking.
f740e790 2 Copyright 1997, 1998, 2000, 2001 Free Software Foundation, Inc.
252b5132
RH
3
4 This file is part of GAS, the GNU Assembler.
5
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.
10
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.
15
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. */
20
21#include "as.h"
22
23/* The file to write to, or NULL if no dependencies being kept. */
f740e790 24static char * dep_file = NULL;
252b5132 25
f740e790
NC
26struct dependency
27 {
28 char * file;
29 struct dependency * next;
30 };
252b5132
RH
31
32/* All the files we depend on. */
f740e790 33static struct dependency * dep_chain = NULL;
252b5132
RH
34
35/* Current column in output file. */
36static int column = 0;
37
38static int quote_string_for_make PARAMS ((FILE *, char *));
39static void wrap_output PARAMS ((FILE *, char *, int));
40
41/* Number of columns allowable. */
42#define MAX_COLUMNS 72
252b5132 43\f
252b5132
RH
44/* Start saving dependencies, to be written to FILENAME. If this is
45 never called, then dependency tracking is simply skipped. */
46
47void
48start_dependencies (filename)
49 char *filename;
50{
51 dep_file = filename;
52}
53
54/* Noticed a new filename, so try to register it. */
55
56void
57register_dependency (filename)
58 char *filename;
59{
60 struct dependency *dep;
61
62 if (dep_file == NULL)
63 return;
64
65 for (dep = dep_chain; dep != NULL; dep = dep->next)
66 {
f851444e 67 if (!strcmp (filename, dep->file))
252b5132
RH
68 return;
69 }
70
71 dep = (struct dependency *) xmalloc (sizeof (struct dependency));
72 dep->file = xstrdup (filename);
73 dep->next = dep_chain;
74 dep_chain = dep;
75}
76
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.
80
81 This code is taken from gcc with only minor changes. */
82
83static int
84quote_string_for_make (file, src)
85 FILE *file;
86 char *src;
87{
88 char *p = src;
89 int i = 0;
f740e790 90
252b5132
RH
91 for (;;)
92 {
93 char c = *p++;
f740e790 94
252b5132
RH
95 switch (c)
96 {
97 case '\0':
98 case ' ':
99 case '\t':
100 {
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;
f740e790 108
f851444e 109 for (q = p - 1; src < q && q[-1] == '\\'; q--)
252b5132
RH
110 {
111 if (file)
112 putc ('\\', file);
113 i++;
114 }
115 }
116 if (!c)
117 return i;
118 if (file)
119 putc ('\\', file);
120 i++;
121 goto ordinary_char;
f851444e 122
252b5132
RH
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;
140 }
141 }
142}
143
144/* Append some output to the file, keeping track of columns and doing
145 wrapping as necessary. */
146
147static void
148wrap_output (f, string, spacer)
149 FILE *f;
150 char *string;
151 int spacer;
152{
153 int len = quote_string_for_make (NULL, string);
154
155 if (len == 0)
156 return;
157
f851444e
NC
158 if (column
159 && (MAX_COLUMNS
160 - 1 /* spacer */
161 - 2 /* ` \' */
162 < column + len))
252b5132
RH
163 {
164 fprintf (f, " \\\n ");
165 column = 0;
166 if (spacer == ' ')
167 spacer = '\0';
168 }
169
170 if (spacer == ' ')
171 {
172 putc (spacer, f);
173 ++column;
174 }
175
176 quote_string_for_make (f, string);
177 column += len;
178
179 if (spacer == ':')
180 {
181 putc (spacer, f);
182 ++column;
183 }
184}
185
186/* Print dependency file. */
187
188void
189print_dependencies ()
190{
191 FILE *f;
192 struct dependency *dep;
193
194 if (dep_file == NULL)
195 return;
196
f740e790 197 f = fopen (dep_file, FOPEN_WT);
252b5132
RH
198 if (f == NULL)
199 {
0e389e77 200 as_warn (_("can't open `%s' for writing"), dep_file);
252b5132
RH
201 return;
202 }
203
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, ' ');
208
209 putc ('\n', f);
210
211 if (fclose (f))
0e389e77 212 as_warn (_("can't close `%s'"), dep_file);
252b5132 213}
This page took 0.204473 seconds and 4 git commands to generate.