00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "config.h"
00024 #include "system.h"
00025 #include "mkdeps.h"
00026
00027
00028
00029 struct deps
00030 {
00031 const char **targetv;
00032 unsigned int ntargets;
00033 unsigned int targets_size;
00034
00035 const char **depv;
00036 unsigned int ndeps;
00037 unsigned int deps_size;
00038
00039 const char **vpathv;
00040 size_t *vpathlv;
00041 unsigned int nvpaths;
00042 unsigned int vpaths_size;
00043 };
00044
00045 static const char *munge (const char *);
00046
00047
00048
00049
00050
00051
00052
00053
00054 static const char *
00055 munge (const char *filename)
00056 {
00057 int len;
00058 const char *p, *q;
00059 char *dst, *buffer;
00060
00061 for (p = filename, len = 0; *p; p++, len++)
00062 {
00063 switch (*p)
00064 {
00065 case ' ':
00066 case '\t':
00067
00068
00069
00070
00071
00072
00073 for (q = p - 1; filename <= q && *q == '\\'; q--)
00074 len++;
00075 len++;
00076 break;
00077
00078 case '$':
00079
00080 len++;
00081 break;
00082 }
00083 }
00084
00085
00086 buffer = xmalloc (len + 1);
00087
00088 for (p = filename, dst = buffer; *p; p++, dst++)
00089 {
00090 switch (*p)
00091 {
00092 case ' ':
00093 case '\t':
00094 for (q = p - 1; filename <= q && *q == '\\'; q--)
00095 *dst++ = '\\';
00096 *dst++ = '\\';
00097 break;
00098
00099 case '$':
00100 *dst++ = '$';
00101 break;
00102
00103 default:
00104 ;
00105 }
00106 *dst = *p;
00107 }
00108
00109 *dst = '\0';
00110 return buffer;
00111 }
00112
00113
00114
00115 static const char *
00116 apply_vpath (struct deps *d, const char *t)
00117 {
00118 if (d->vpathv)
00119 {
00120 unsigned int i;
00121 for (i = 0; i < d->nvpaths; i++)
00122 {
00123 if (!strncmp (d->vpathv[i], t, d->vpathlv[i]))
00124 {
00125 const char *p = t + d->vpathlv[i];
00126 if (!IS_DIR_SEPARATOR (*p))
00127 goto not_this_one;
00128
00129
00130
00131 if (p[1] == '.' && p[2] == '.' && IS_DIR_SEPARATOR (p[3]))
00132 goto not_this_one;
00133
00134
00135 t = t + d->vpathlv[i] + 1;
00136 break;
00137 }
00138 not_this_one:;
00139 }
00140 }
00141
00142
00143 while (t[0] == '.' && IS_DIR_SEPARATOR (t[1]))
00144 t += 2;
00145
00146 return t;
00147 }
00148
00149
00150
00151 struct deps *
00152 deps_init (void)
00153 {
00154 return xcalloc (sizeof (struct deps), 1);
00155 }
00156
00157 void
00158 deps_free (struct deps *d)
00159 {
00160 unsigned int i;
00161
00162 if (d->targetv)
00163 {
00164 for (i = 0; i < d->ntargets; i++)
00165 free ((void *) d->targetv[i]);
00166 free (d->targetv);
00167 }
00168
00169 if (d->depv)
00170 {
00171 for (i = 0; i < d->ndeps; i++)
00172 free ((void *) d->depv[i]);
00173 free (d->depv);
00174 }
00175
00176 if (d->vpathv)
00177 {
00178 for (i = 0; i < d->nvpaths; i++)
00179 free ((void *) d->vpathv[i]);
00180 free (d->vpathv);
00181 free (d->vpathlv);
00182 }
00183
00184 free (d);
00185 }
00186
00187
00188
00189 void
00190 deps_add_target (struct deps *d, const char *t, int quote)
00191 {
00192 if (d->ntargets == d->targets_size)
00193 {
00194 d->targets_size = d->targets_size * 2 + 4;
00195 d->targetv = xrealloc (d->targetv,
00196 d->targets_size * sizeof (const char *));
00197 }
00198
00199 t = apply_vpath (d, t);
00200 if (quote)
00201 t = munge (t);
00202 else
00203 t = xstrdup (t);
00204
00205 d->targetv[d->ntargets++] = t;
00206 }
00207
00208
00209
00210
00211 void
00212 deps_add_default_target (struct deps *d, const char *tgt)
00213 {
00214
00215 if (d->ntargets)
00216 return;
00217
00218 if (tgt[0] == '\0')
00219 deps_add_target (d, "-", 1);
00220 else
00221 {
00222 #ifndef TARGET_OBJECT_SUFFIX
00223 # define TARGET_OBJECT_SUFFIX ".o"
00224 #endif
00225 const char *start = lbasename (tgt);
00226 char *o = alloca (strlen (start) + strlen (TARGET_OBJECT_SUFFIX) + 1);
00227 char *suffix;
00228
00229 strcpy (o, start);
00230
00231 suffix = strrchr (o, '.');
00232 if (!suffix)
00233 suffix = o + strlen (o);
00234 strcpy (suffix, TARGET_OBJECT_SUFFIX);
00235
00236 deps_add_target (d, o, 1);
00237 }
00238 }
00239
00240 void
00241 deps_add_dep (struct deps *d, const char *t)
00242 {
00243 t = munge (apply_vpath (d, t));
00244
00245 if (d->ndeps == d->deps_size)
00246 {
00247 d->deps_size = d->deps_size * 2 + 8;
00248 d->depv = xrealloc (d->depv, d->deps_size * sizeof (const char *));
00249 }
00250 d->depv[d->ndeps++] = t;
00251 }
00252
00253 void
00254 deps_add_vpath (struct deps *d, const char *vpath)
00255 {
00256 const char *elem, *p;
00257 char *copy;
00258 size_t len;
00259
00260 for (elem = vpath; *elem; elem = p)
00261 {
00262 for (p = elem; *p && *p != ':'; p++);
00263 len = p - elem;
00264 copy = xmalloc (len + 1);
00265 memcpy (copy, elem, len);
00266 copy[len] = '\0';
00267 if (*p == ':')
00268 p++;
00269
00270 if (d->nvpaths == d->vpaths_size)
00271 {
00272 d->vpaths_size = d->vpaths_size * 2 + 8;
00273 d->vpathv = xrealloc (d->vpathv,
00274 d->vpaths_size * sizeof (const char *));
00275 d->vpathlv = xrealloc (d->vpathlv, d->vpaths_size * sizeof (size_t));
00276 }
00277 d->vpathv[d->nvpaths] = copy;
00278 d->vpathlv[d->nvpaths] = len;
00279 d->nvpaths++;
00280 }
00281 }
00282
00283 void
00284 deps_write (const struct deps *d, FILE *fp, unsigned int colmax)
00285 {
00286 unsigned int size, i, column;
00287
00288 column = 0;
00289 if (colmax && colmax < 34)
00290 colmax = 34;
00291
00292 for (i = 0; i < d->ntargets; i++)
00293 {
00294 size = strlen (d->targetv[i]);
00295 column += size;
00296 if (colmax && column > colmax)
00297 {
00298 fputs (" \\\n ", fp);
00299 column = 1 + size;
00300 }
00301 if (i)
00302 {
00303 putc (' ', fp);
00304 column++;
00305 }
00306 fputs (d->targetv[i], fp);
00307 }
00308
00309 putc (':', fp);
00310 putc (' ', fp);
00311 column += 2;
00312
00313 for (i = 0; i < d->ndeps; i++)
00314 {
00315 size = strlen (d->depv[i]);
00316 column += size;
00317 if (colmax && column > colmax)
00318 {
00319 fputs (" \\\n ", fp);
00320 column = 1 + size;
00321 }
00322 if (i)
00323 {
00324 putc (' ', fp);
00325 column++;
00326 }
00327 fputs (d->depv[i], fp);
00328 }
00329 putc ('\n', fp);
00330 }
00331
00332 void
00333 deps_phony_targets (const struct deps *d, FILE *fp)
00334 {
00335 unsigned int i;
00336
00337 for (i = 1; i < d->ndeps; i++)
00338 {
00339 putc ('\n', fp);
00340 fputs (d->depv[i], fp);
00341 putc (':', fp);
00342 putc ('\n', fp);
00343 }
00344 }
00345
00346
00347
00348
00349
00350 int
00351 deps_save (struct deps *deps, FILE *f)
00352 {
00353 unsigned int i;
00354
00355
00356
00357
00358
00359 if (fwrite (&deps->ndeps, sizeof (deps->ndeps), 1, f) != 1)
00360 return -1;
00361
00362 for (i = 0; i < deps->ndeps; i++)
00363 {
00364 size_t num_to_write = strlen (deps->depv[i]);
00365 if (fwrite (&num_to_write, sizeof (size_t), 1, f) != 1)
00366 return -1;
00367 if (fwrite (deps->depv[i], num_to_write, 1, f) != 1)
00368 return -1;
00369 }
00370
00371 return 0;
00372 }
00373
00374
00375
00376
00377
00378
00379 int
00380 deps_restore (struct deps *deps, FILE *fd, const char *self)
00381 {
00382 unsigned int i, count;
00383 size_t num_to_read;
00384 size_t buf_size = 512;
00385 char *buf = xmalloc (buf_size);
00386
00387
00388 if (fread (&count, 1, sizeof (count), fd) != sizeof (count))
00389 return -1;
00390
00391
00392 for (i = 0; i < count; i++)
00393 {
00394
00395 if (fread (&num_to_read, 1, sizeof (size_t), fd) != sizeof (size_t))
00396 return -1;
00397 if (buf_size < num_to_read + 1)
00398 {
00399 buf_size = num_to_read + 1 + 127;
00400 buf = xrealloc (buf, buf_size);
00401 }
00402 if (fread (buf, 1, num_to_read, fd) != num_to_read)
00403 return -1;
00404 buf[num_to_read] = '\0';
00405
00406
00407 if (self != NULL && strcmp (buf, self) != 0)
00408 deps_add_dep (deps, buf);
00409 }
00410
00411 free (buf);
00412 return 0;
00413 }