Subversion Repositories Kolibri OS

Rev

Rev 5222 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
5222 serge 1
/* depend.c - Handle dependency tracking.
6324 serge 2
   Copyright (C) 1997-2015 Free Software Foundation, Inc.
5222 serge 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 3, 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, 51 Franklin Street - Fifth Floor, Boston, MA
19
   02110-1301, USA.  */
20
 
21
#include "as.h"
22
#include "filenames.h"
23
 
24
/* The file to write to, or NULL if no dependencies being kept.  */
25
static char * dep_file = NULL;
26
 
27
struct dependency
28
  {
29
    char * file;
30
    struct dependency * next;
31
  };
32
 
33
/* All the files we depend on.  */
34
static struct dependency * dep_chain = NULL;
35
 
36
/* Current column in output file.  */
37
static int column = 0;
38
 
39
static int quote_string_for_make (FILE *, char *);
40
static void wrap_output (FILE *, char *, int);
41
 
42
/* Number of columns allowable.  */
43
#define MAX_COLUMNS 72
44
 
45
/* Start saving dependencies, to be written to FILENAME.  If this is
46
   never called, then dependency tracking is simply skipped.  */
47
 
48
void
49
start_dependencies (char *filename)
50
{
51
  dep_file = filename;
52
}
53
 
54
/* Noticed a new filename, so try to register it.  */
55
 
56
void
57
register_dependency (char *filename)
58
{
59
  struct dependency *dep;
60
 
61
  if (dep_file == NULL)
62
    return;
63
 
64
  for (dep = dep_chain; dep != NULL; dep = dep->next)
65
    {
66
      if (!filename_cmp (filename, dep->file))
67
	return;
68
    }
69
 
70
  dep = (struct dependency *) xmalloc (sizeof (struct dependency));
71
  dep->file = xstrdup (filename);
72
  dep->next = dep_chain;
73
  dep_chain = dep;
74
}
75
 
76
/* Quote a file name the way `make' wants it, and print it to FILE.
77
   If FILE is NULL, do no printing, but return the length of the
78
   quoted string.
79
 
80
   This code is taken from gcc with only minor changes.  */
81
 
82
static int
83
quote_string_for_make (FILE *file, char *src)
84
{
85
  char *p = src;
86
  int i = 0;
87
 
88
  for (;;)
89
    {
90
      char c = *p++;
91
 
92
      switch (c)
93
	{
94
	case '\0':
95
	case ' ':
96
	case '\t':
97
	  {
98
	    /* GNU make uses a weird quoting scheme for white space.
99
	       A space or tab preceded by 2N+1 backslashes represents
100
	       N backslashes followed by space; a space or tab
101
	       preceded by 2N backslashes represents N backslashes at
102
	       the end of a file name; and backslashes in other
103
	       contexts should not be doubled.  */
104
	    char *q;
105
 
106
	    for (q = p - 1; src < q && q[-1] == '\\'; q--)
107
	      {
108
		if (file)
109
		  putc ('\\', file);
110
		i++;
111
	      }
112
	  }
113
	  if (!c)
114
	    return i;
115
	  if (file)
116
	    putc ('\\', file);
117
	  i++;
118
	  goto ordinary_char;
119
 
120
	case '$':
121
	  if (file)
122
	    putc (c, file);
123
	  i++;
124
	  /* Fall through.  This can mishandle things like "$(" but
125
	     there's no easy fix.  */
126
	default:
127
	ordinary_char:
128
	  /* This can mishandle characters in the string "\0\n%*?[\\~";
129
	     exactly which chars are mishandled depends on the `make' version.
130
	     We know of no portable solution for this;
131
	     even GNU make 3.76.1 doesn't solve the problem entirely.
132
	     (Also, '\0' is mishandled due to our calling conventions.)  */
133
	  if (file)
134
	    putc (c, file);
135
	  i++;
136
	  break;
137
	}
138
    }
139
}
140
 
141
/* Append some output to the file, keeping track of columns and doing
142
   wrapping as necessary.  */
143
 
144
static void
145
wrap_output (FILE *f, char *string, int spacer)
146
{
147
  int len = quote_string_for_make (NULL, string);
148
 
149
  if (len == 0)
150
    return;
151
 
152
  if (column
153
      && (MAX_COLUMNS
154
	  - 1 /* spacer */
155
	  - 2 /* ` \'   */
156
	  < column + len))
157
    {
158
      fprintf (f, " \\\n ");
159
      column = 0;
160
      if (spacer == ' ')
161
	spacer = '\0';
162
    }
163
 
164
  if (spacer == ' ')
165
    {
166
      putc (spacer, f);
167
      ++column;
168
    }
169
 
170
  quote_string_for_make (f, string);
171
  column += len;
172
 
173
  if (spacer == ':')
174
    {
175
      putc (spacer, f);
176
      ++column;
177
    }
178
}
179
 
180
/* Print dependency file.  */
181
 
182
void
183
print_dependencies (void)
184
{
185
  FILE *f;
186
  struct dependency *dep;
187
 
188
  if (dep_file == NULL)
189
    return;
190
 
191
  f = fopen (dep_file, FOPEN_WT);
192
  if (f == NULL)
193
    {
194
      as_warn (_("can't open `%s' for writing"), dep_file);
195
      return;
196
    }
197
 
198
  column = 0;
199
  wrap_output (f, out_file_name, ':');
200
  for (dep = dep_chain; dep != NULL; dep = dep->next)
201
    wrap_output (f, dep->file, ' ');
202
 
203
  putc ('\n', f);
204
 
205
  if (fclose (f))
206
    as_warn (_("can't close `%s'"), dep_file);
207
}