1169695Skan/* Dependency generator for Makefile fragments. 2169695Skan Copyright (C) 2000, 2001, 2003, 2007 Free Software Foundation, Inc. 3169695Skan Contributed by Zack Weinberg, Mar 2000 4169695Skan 5169695SkanThis program is free software; you can redistribute it and/or modify it 6169695Skanunder the terms of the GNU General Public License as published by the 7169695SkanFree Software Foundation; either version 2, or (at your option) any 8169695Skanlater version. 9169695Skan 10169695SkanThis program is distributed in the hope that it will be useful, 11169695Skanbut WITHOUT ANY WARRANTY; without even the implied warranty of 12169695SkanMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13169695SkanGNU General Public License for more details. 14169695Skan 15169695SkanYou should have received a copy of the GNU General Public License 16169695Skanalong with this program; if not, write to the Free Software 17169695SkanFoundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18169695Skan 19169695Skan In other words, you are welcome to use, share and improve this program. 20169695Skan You are forbidden to forbid anyone else to use, share and improve 21169695Skan what you give them. Help stamp out software-hoarding! */ 22169695Skan 23169695Skan#include "config.h" 24169695Skan#include "system.h" 25169695Skan#include "mkdeps.h" 26169695Skan 27169695Skan/* Keep this structure local to this file, so clients don't find it 28169695Skan easy to start making assumptions. */ 29169695Skanstruct deps 30169695Skan{ 31169695Skan const char **targetv; 32169695Skan unsigned int ntargets; /* number of slots actually occupied */ 33169695Skan unsigned int targets_size; /* amt of allocated space - in words */ 34169695Skan 35169695Skan const char **depv; 36169695Skan unsigned int ndeps; 37169695Skan unsigned int deps_size; 38169695Skan 39169695Skan const char **vpathv; 40169695Skan size_t *vpathlv; 41169695Skan unsigned int nvpaths; 42169695Skan unsigned int vpaths_size; 43169695Skan}; 44169695Skan 45169695Skanstatic const char *munge (const char *); 46169695Skan 47169695Skan/* Given a filename, quote characters in that filename which are 48169695Skan significant to Make. Note that it's not possible to quote all such 49169695Skan characters - e.g. \n, %, *, ?, [, \ (in some contexts), and ~ are 50169695Skan not properly handled. It isn't possible to get this right in any 51169695Skan current version of Make. (??? Still true? Old comment referred to 52169695Skan 3.76.1.) */ 53169695Skan 54169695Skanstatic const char * 55169695Skanmunge (const char *filename) 56169695Skan{ 57169695Skan int len; 58169695Skan const char *p, *q; 59169695Skan char *dst, *buffer; 60169695Skan 61169695Skan for (p = filename, len = 0; *p; p++, len++) 62169695Skan { 63169695Skan switch (*p) 64169695Skan { 65169695Skan case ' ': 66169695Skan case '\t': 67169695Skan /* GNU make uses a weird quoting scheme for white space. 68169695Skan A space or tab preceded by 2N+1 backslashes represents 69169695Skan N backslashes followed by space; a space or tab 70169695Skan preceded by 2N backslashes represents N backslashes at 71169695Skan the end of a file name; and backslashes in other 72169695Skan contexts should not be doubled. */ 73169695Skan for (q = p - 1; filename <= q && *q == '\\'; q--) 74169695Skan len++; 75169695Skan len++; 76169695Skan break; 77169695Skan 78169695Skan case '$': 79169695Skan /* '$' is quoted by doubling it. */ 80169695Skan len++; 81169695Skan break; 82169695Skan } 83169695Skan } 84169695Skan 85169695Skan /* Now we know how big to make the buffer. */ 86169695Skan buffer = XNEWVEC (char, len + 1); 87169695Skan 88169695Skan for (p = filename, dst = buffer; *p; p++, dst++) 89169695Skan { 90169695Skan switch (*p) 91169695Skan { 92169695Skan case ' ': 93169695Skan case '\t': 94169695Skan for (q = p - 1; filename <= q && *q == '\\'; q--) 95169695Skan *dst++ = '\\'; 96169695Skan *dst++ = '\\'; 97169695Skan break; 98169695Skan 99169695Skan case '$': 100169695Skan *dst++ = '$'; 101169695Skan break; 102169695Skan 103169695Skan default: 104169695Skan /* nothing */; 105169695Skan } 106169695Skan *dst = *p; 107169695Skan } 108169695Skan 109169695Skan *dst = '\0'; 110169695Skan return buffer; 111169695Skan} 112169695Skan 113169695Skan/* If T begins with any of the partial pathnames listed in d->vpathv, 114169695Skan then advance T to point beyond that pathname. */ 115169695Skanstatic const char * 116169695Skanapply_vpath (struct deps *d, const char *t) 117169695Skan{ 118169695Skan if (d->vpathv) 119169695Skan { 120169695Skan unsigned int i; 121169695Skan for (i = 0; i < d->nvpaths; i++) 122169695Skan { 123169695Skan if (!strncmp (d->vpathv[i], t, d->vpathlv[i])) 124169695Skan { 125169695Skan const char *p = t + d->vpathlv[i]; 126169695Skan if (!IS_DIR_SEPARATOR (*p)) 127169695Skan goto not_this_one; 128169695Skan 129169695Skan /* Do not simplify $(vpath)/../whatever. ??? Might not 130169695Skan be necessary. */ 131169695Skan if (p[1] == '.' && p[2] == '.' && IS_DIR_SEPARATOR (p[3])) 132169695Skan goto not_this_one; 133169695Skan 134169695Skan /* found a match */ 135169695Skan t = t + d->vpathlv[i] + 1; 136169695Skan break; 137169695Skan } 138169695Skan not_this_one:; 139169695Skan } 140169695Skan } 141169695Skan 142169695Skan /* Remove leading ./ in any case. */ 143169695Skan while (t[0] == '.' && IS_DIR_SEPARATOR (t[1])) 144169695Skan { 145169695Skan t += 2; 146169695Skan /* If we removed a leading ./, then also remove any /s after the 147169695Skan first. */ 148169695Skan while (IS_DIR_SEPARATOR (t[0])) 149169695Skan ++t; 150169695Skan } 151169695Skan 152169695Skan return t; 153169695Skan} 154169695Skan 155169695Skan/* Public routines. */ 156169695Skan 157169695Skanstruct deps * 158169695Skandeps_init (void) 159169695Skan{ 160169695Skan return XCNEW (struct deps); 161169695Skan} 162169695Skan 163169695Skanvoid 164169695Skandeps_free (struct deps *d) 165169695Skan{ 166169695Skan unsigned int i; 167169695Skan 168169695Skan if (d->targetv) 169169695Skan { 170169695Skan for (i = 0; i < d->ntargets; i++) 171169695Skan free ((void *) d->targetv[i]); 172169695Skan free (d->targetv); 173169695Skan } 174169695Skan 175169695Skan if (d->depv) 176169695Skan { 177169695Skan for (i = 0; i < d->ndeps; i++) 178169695Skan free ((void *) d->depv[i]); 179169695Skan free (d->depv); 180169695Skan } 181169695Skan 182169695Skan if (d->vpathv) 183169695Skan { 184169695Skan for (i = 0; i < d->nvpaths; i++) 185169695Skan free ((void *) d->vpathv[i]); 186169695Skan free (d->vpathv); 187169695Skan free (d->vpathlv); 188169695Skan } 189169695Skan 190169695Skan free (d); 191169695Skan} 192169695Skan 193169695Skan/* Adds a target T. We make a copy, so it need not be a permanent 194169695Skan string. QUOTE is true if the string should be quoted. */ 195169695Skanvoid 196169695Skandeps_add_target (struct deps *d, const char *t, int quote) 197169695Skan{ 198169695Skan if (d->ntargets == d->targets_size) 199169695Skan { 200169695Skan d->targets_size = d->targets_size * 2 + 4; 201169695Skan d->targetv = XRESIZEVEC (const char *, d->targetv, d->targets_size); 202169695Skan } 203169695Skan 204169695Skan t = apply_vpath (d, t); 205169695Skan if (quote) 206169695Skan t = munge (t); /* Also makes permanent copy. */ 207169695Skan else 208169695Skan t = xstrdup (t); 209169695Skan 210169695Skan d->targetv[d->ntargets++] = t; 211169695Skan} 212169695Skan 213169695Skan/* Sets the default target if none has been given already. An empty 214169695Skan string as the default target in interpreted as stdin. The string 215169695Skan is quoted for MAKE. */ 216169695Skanvoid 217169695Skandeps_add_default_target (struct deps *d, const char *tgt) 218169695Skan{ 219169695Skan /* Only if we have no targets. */ 220169695Skan if (d->ntargets) 221169695Skan return; 222169695Skan 223169695Skan if (tgt[0] == '\0') 224169695Skan deps_add_target (d, "-", 1); 225169695Skan else 226169695Skan { 227169695Skan#ifndef TARGET_OBJECT_SUFFIX 228169695Skan# define TARGET_OBJECT_SUFFIX ".o" 229169695Skan#endif 230169695Skan const char *start = lbasename (tgt); 231169695Skan char *o = (char *) alloca (strlen (start) 232169695Skan + strlen (TARGET_OBJECT_SUFFIX) + 1); 233169695Skan char *suffix; 234169695Skan 235169695Skan strcpy (o, start); 236169695Skan 237169695Skan suffix = strrchr (o, '.'); 238169695Skan if (!suffix) 239169695Skan suffix = o + strlen (o); 240169695Skan strcpy (suffix, TARGET_OBJECT_SUFFIX); 241169695Skan 242169695Skan deps_add_target (d, o, 1); 243169695Skan } 244169695Skan} 245169695Skan 246169695Skanvoid 247169695Skandeps_add_dep (struct deps *d, const char *t) 248169695Skan{ 249169695Skan t = munge (apply_vpath (d, t)); /* Also makes permanent copy. */ 250169695Skan 251169695Skan if (d->ndeps == d->deps_size) 252169695Skan { 253169695Skan d->deps_size = d->deps_size * 2 + 8; 254169695Skan d->depv = XRESIZEVEC (const char *, d->depv, d->deps_size); 255169695Skan } 256169695Skan d->depv[d->ndeps++] = t; 257169695Skan} 258169695Skan 259169695Skanvoid 260169695Skandeps_add_vpath (struct deps *d, const char *vpath) 261169695Skan{ 262169695Skan const char *elem, *p; 263169695Skan char *copy; 264169695Skan size_t len; 265169695Skan 266169695Skan for (elem = vpath; *elem; elem = p) 267169695Skan { 268169695Skan for (p = elem; *p && *p != ':'; p++); 269169695Skan len = p - elem; 270169695Skan copy = XNEWVEC (char, len + 1); 271169695Skan memcpy (copy, elem, len); 272169695Skan copy[len] = '\0'; 273169695Skan if (*p == ':') 274169695Skan p++; 275169695Skan 276169695Skan if (d->nvpaths == d->vpaths_size) 277169695Skan { 278169695Skan d->vpaths_size = d->vpaths_size * 2 + 8; 279169695Skan d->vpathv = XRESIZEVEC (const char *, d->vpathv, d->vpaths_size); 280169695Skan d->vpathlv = XRESIZEVEC (size_t, d->vpathlv, d->vpaths_size); 281169695Skan } 282169695Skan d->vpathv[d->nvpaths] = copy; 283169695Skan d->vpathlv[d->nvpaths] = len; 284169695Skan d->nvpaths++; 285169695Skan } 286169695Skan} 287169695Skan 288169695Skanvoid 289169695Skandeps_write (const struct deps *d, FILE *fp, unsigned int colmax) 290169695Skan{ 291169695Skan unsigned int size, i, column; 292169695Skan 293169695Skan column = 0; 294169695Skan if (colmax && colmax < 34) 295169695Skan colmax = 34; 296169695Skan 297169695Skan for (i = 0; i < d->ntargets; i++) 298169695Skan { 299169695Skan size = strlen (d->targetv[i]); 300169695Skan column += size; 301169695Skan if (colmax && column > colmax) 302169695Skan { 303169695Skan fputs (" \\\n ", fp); 304169695Skan column = 1 + size; 305169695Skan } 306169695Skan if (i) 307169695Skan { 308169695Skan putc (' ', fp); 309169695Skan column++; 310169695Skan } 311169695Skan fputs (d->targetv[i], fp); 312169695Skan } 313169695Skan 314169695Skan putc (':', fp); 315169695Skan putc (' ', fp); 316169695Skan column += 2; 317169695Skan 318169695Skan for (i = 0; i < d->ndeps; i++) 319169695Skan { 320169695Skan size = strlen (d->depv[i]); 321169695Skan column += size; 322169695Skan if (colmax && column > colmax) 323169695Skan { 324169695Skan fputs (" \\\n ", fp); 325169695Skan column = 1 + size; 326169695Skan } 327169695Skan if (i) 328169695Skan { 329169695Skan putc (' ', fp); 330169695Skan column++; 331169695Skan } 332169695Skan fputs (d->depv[i], fp); 333169695Skan } 334169695Skan putc ('\n', fp); 335169695Skan} 336169695Skan 337169695Skanvoid 338169695Skandeps_phony_targets (const struct deps *d, FILE *fp) 339169695Skan{ 340169695Skan unsigned int i; 341169695Skan 342169695Skan for (i = 1; i < d->ndeps; i++) 343169695Skan { 344169695Skan putc ('\n', fp); 345169695Skan fputs (d->depv[i], fp); 346169695Skan putc (':', fp); 347169695Skan putc ('\n', fp); 348169695Skan } 349169695Skan} 350169695Skan 351169695Skan/* Write out a deps buffer to a file, in a form that can be read back 352169695Skan with deps_restore. Returns nonzero on error, in which case the 353169695Skan error number will be in errno. */ 354169695Skan 355169695Skanint 356169695Skandeps_save (struct deps *deps, FILE *f) 357169695Skan{ 358169695Skan unsigned int i; 359169695Skan 360169695Skan /* The cppreader structure contains makefile dependences. Write out this 361169695Skan structure. */ 362169695Skan 363169695Skan /* The number of dependences. */ 364169695Skan if (fwrite (&deps->ndeps, sizeof (deps->ndeps), 1, f) != 1) 365169695Skan return -1; 366169695Skan /* The length of each dependence followed by the string. */ 367169695Skan for (i = 0; i < deps->ndeps; i++) 368169695Skan { 369169695Skan size_t num_to_write = strlen (deps->depv[i]); 370169695Skan if (fwrite (&num_to_write, sizeof (size_t), 1, f) != 1) 371169695Skan return -1; 372169695Skan if (fwrite (deps->depv[i], num_to_write, 1, f) != 1) 373169695Skan return -1; 374169695Skan } 375169695Skan 376169695Skan return 0; 377169695Skan} 378169695Skan 379169695Skan/* Read back dependency information written with deps_save into 380169695Skan the deps buffer. The third argument may be NULL, in which case 381169695Skan the dependency information is just skipped, or it may be a filename, 382169695Skan in which case that filename is skipped. */ 383169695Skan 384169695Skanint 385169695Skandeps_restore (struct deps *deps, FILE *fd, const char *self) 386169695Skan{ 387169695Skan unsigned int i, count; 388169695Skan size_t num_to_read; 389169695Skan size_t buf_size = 512; 390169695Skan char *buf = XNEWVEC (char, buf_size); 391169695Skan 392169695Skan /* Number of dependences. */ 393169695Skan if (fread (&count, 1, sizeof (count), fd) != sizeof (count)) 394169695Skan return -1; 395169695Skan 396169695Skan /* The length of each dependence string, followed by the string. */ 397169695Skan for (i = 0; i < count; i++) 398169695Skan { 399169695Skan /* Read in # bytes in string. */ 400169695Skan if (fread (&num_to_read, 1, sizeof (size_t), fd) != sizeof (size_t)) 401169695Skan return -1; 402169695Skan if (buf_size < num_to_read + 1) 403169695Skan { 404169695Skan buf_size = num_to_read + 1 + 127; 405169695Skan buf = XRESIZEVEC (char, buf, buf_size); 406169695Skan } 407169695Skan if (fread (buf, 1, num_to_read, fd) != num_to_read) 408169695Skan return -1; 409169695Skan buf[num_to_read] = '\0'; 410169695Skan 411169695Skan /* Generate makefile dependencies from .pch if -nopch-deps. */ 412169695Skan if (self != NULL && strcmp (buf, self) != 0) 413169695Skan deps_add_dep (deps, buf); 414169695Skan } 415169695Skan 416169695Skan free (buf); 417169695Skan return 0; 418169695Skan} 419