1 1.1 mrg /* Dependency generator for Makefile fragments. 2 1.1 mrg Copyright (C) 2000-2022 Free Software Foundation, Inc. 3 1.1 mrg Contributed by Zack Weinberg, Mar 2000 4 1.1 mrg 5 1.1 mrg This program is free software; you can redistribute it and/or modify it 6 1.1 mrg under the terms of the GNU General Public License as published by the 7 1.1 mrg Free Software Foundation; either version 3, or (at your option) any 8 1.1 mrg later version. 9 1.1 mrg 10 1.1 mrg This program is distributed in the hope that it will be useful, 11 1.1 mrg but WITHOUT ANY WARRANTY; without even the implied warranty of 12 1.1 mrg MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 1.1 mrg GNU General Public License for more details. 14 1.1 mrg 15 1.1 mrg You should have received a copy of the GNU General Public License 16 1.1 mrg along with this program; see the file COPYING3. If not see 17 1.1 mrg <http://www.gnu.org/licenses/>. 18 1.1 mrg 19 1.1 mrg In other words, you are welcome to use, share and improve this program. 20 1.1 mrg You are forbidden to forbid anyone else to use, share and improve 21 1.1 mrg what you give them. Help stamp out software-hoarding! */ 22 1.1 mrg 23 1.1 mrg #include "config.h" 24 1.1 mrg #include "system.h" 25 1.1 mrg #include "mkdeps.h" 26 1.1 mrg #include "internal.h" 27 1.1 mrg 28 1.1 mrg /* Not set up to just include std::vector et al, here's a simple 29 1.1 mrg implementation. */ 30 1.1 mrg 31 1.1 mrg /* Keep this structure local to this file, so clients don't find it 32 1.1 mrg easy to start making assumptions. */ 33 1.1 mrg class mkdeps 34 1.1 mrg { 35 1.1 mrg public: 36 1.1 mrg /* T has trivial cctor & dtor. */ 37 1.1 mrg template <typename T> 38 1.1 mrg class vec 39 1.1 mrg { 40 1.1 mrg private: 41 1.1 mrg T *ary; 42 1.1 mrg unsigned num; 43 1.1 mrg unsigned alloc; 44 1.1 mrg 45 1.1 mrg public: 46 1.1 mrg vec () 47 1.1 mrg : ary (NULL), num (0), alloc (0) 48 1.1 mrg {} 49 1.1 mrg ~vec () 50 1.1 mrg { 51 1.1 mrg XDELETEVEC (ary); 52 1.1 mrg } 53 1.1 mrg 54 1.1 mrg public: 55 1.1 mrg unsigned size () const 56 1.1 mrg { 57 1.1 mrg return num; 58 1.1 mrg } 59 1.1 mrg const T &operator[] (unsigned ix) const 60 1.1 mrg { 61 1.1 mrg return ary[ix]; 62 1.1 mrg } 63 1.1 mrg T &operator[] (unsigned ix) 64 1.1 mrg { 65 1.1 mrg return ary[ix]; 66 1.1 mrg } 67 1.1 mrg void push (const T &elt) 68 1.1 mrg { 69 1.1 mrg if (num == alloc) 70 1.1 mrg { 71 1.1 mrg alloc = alloc ? alloc * 2 : 16; 72 1.1 mrg ary = XRESIZEVEC (T, ary, alloc); 73 1.1 mrg } 74 1.1 mrg ary[num++] = elt; 75 1.1 mrg } 76 1.1 mrg }; 77 1.1 mrg struct velt 78 1.1 mrg { 79 1.1 mrg const char *str; 80 1.1 mrg size_t len; 81 1.1 mrg }; 82 1.1 mrg 83 1.1 mrg mkdeps () 84 1.1 mrg : module_name (NULL), cmi_name (NULL), is_header_unit (false), quote_lwm (0) 85 1.1 mrg { 86 1.1 mrg } 87 1.1 mrg ~mkdeps () 88 1.1 mrg { 89 1.1 mrg unsigned int i; 90 1.1 mrg 91 1.1 mrg for (i = targets.size (); i--;) 92 1.1 mrg free (const_cast <char *> (targets[i])); 93 1.1 mrg for (i = deps.size (); i--;) 94 1.1 mrg free (const_cast <char *> (deps[i])); 95 1.1 mrg for (i = vpath.size (); i--;) 96 1.1 mrg XDELETEVEC (vpath[i].str); 97 1.1 mrg for (i = modules.size (); i--;) 98 1.1 mrg XDELETEVEC (modules[i]); 99 1.1 mrg XDELETEVEC (module_name); 100 1.1 mrg free (const_cast <char *> (cmi_name)); 101 1.1 mrg } 102 1.1 mrg 103 1.1 mrg public: 104 1.1 mrg vec<const char *> targets; 105 1.1 mrg vec<const char *> deps; 106 1.1 mrg vec<velt> vpath; 107 1.1 mrg vec<const char *> modules; 108 1.1 mrg 109 1.1 mrg public: 110 1.1 mrg const char *module_name; 111 1.1 mrg const char *cmi_name; 112 1.1 mrg bool is_header_unit; 113 1.1 mrg unsigned short quote_lwm; 114 1.1 mrg }; 115 1.1 mrg 116 1.1 mrg /* Apply Make quoting to STR, TRAIL. Note that it's not possible to 117 1.1 mrg quote all such characters - e.g. \n, %, *, ?, [, \ (in some 118 1.1 mrg contexts), and ~ are not properly handled. It isn't possible to 119 1.1 mrg get this right in any current version of Make. (??? Still true? 120 1.1 mrg Old comment referred to 3.76.1.) */ 121 1.1 mrg 122 1.1 mrg static const char * 123 1.1 mrg munge (const char *str, const char *trail = nullptr) 124 1.1 mrg { 125 1.1 mrg static unsigned alloc; 126 1.1 mrg static char *buf; 127 1.1 mrg unsigned dst = 0; 128 1.1 mrg 129 1.1 mrg for (; str; str = trail, trail = nullptr) 130 1.1 mrg { 131 1.1 mrg unsigned slashes = 0; 132 1.1 mrg char c; 133 1.1 mrg for (const char *probe = str; (c = *probe++);) 134 1.1 mrg { 135 1.1 mrg if (alloc < dst + 4 + slashes) 136 1.1 mrg { 137 1.1 mrg alloc = alloc * 2 + 32; 138 1.1 mrg buf = XRESIZEVEC (char, buf, alloc); 139 1.1 mrg } 140 1.1 mrg 141 1.1 mrg switch (c) 142 1.1 mrg { 143 1.1 mrg case '\\': 144 1.1 mrg slashes++; 145 1.1 mrg break; 146 1.1 mrg 147 1.1 mrg case '$': 148 1.1 mrg buf[dst++] = '$'; 149 1.1 mrg goto def; 150 1.1 mrg 151 1.1 mrg case ' ': 152 1.1 mrg case '\t': 153 1.1 mrg /* GNU make uses a weird quoting scheme for white space. 154 1.1 mrg A space or tab preceded by 2N+1 backslashes 155 1.1 mrg represents N backslashes followed by space; a space 156 1.1 mrg or tab preceded by 2N backslashes represents N 157 1.1 mrg backslashes at the end of a file name; and 158 1.1 mrg backslashes in other contexts should not be 159 1.1 mrg doubled. */ 160 1.1 mrg while (slashes--) 161 1.1 mrg buf[dst++] = '\\'; 162 1.1 mrg /* FALLTHROUGH */ 163 1.1 mrg 164 1.1 mrg case '#': 165 1.1 mrg buf[dst++] = '\\'; 166 1.1 mrg /* FALLTHROUGH */ 167 1.1 mrg 168 1.1 mrg default: 169 1.1 mrg def: 170 1.1 mrg slashes = 0; 171 1.1 mrg break; 172 1.1 mrg } 173 1.1 mrg 174 1.1 mrg buf[dst++] = c; 175 1.1 mrg } 176 1.1 mrg } 177 1.1 mrg 178 1.1 mrg buf[dst] = 0; 179 1.1 mrg return buf; 180 1.1 mrg } 181 1.1 mrg 182 1.1 mrg /* If T begins with any of the partial pathnames listed in d->vpathv, 183 1.1 mrg then advance T to point beyond that pathname. */ 184 1.1 mrg static const char * 185 1.1 mrg apply_vpath (class mkdeps *d, const char *t) 186 1.1 mrg { 187 1.1 mrg if (unsigned len = d->vpath.size ()) 188 1.1 mrg for (unsigned i = len; i--;) 189 1.1 mrg { 190 1.1 mrg if (!filename_ncmp (d->vpath[i].str, t, d->vpath[i].len)) 191 1.1 mrg { 192 1.1 mrg const char *p = t + d->vpath[i].len; 193 1.1 mrg if (!IS_DIR_SEPARATOR (*p)) 194 1.1 mrg goto not_this_one; 195 1.1 mrg 196 1.1 mrg /* Do not simplify $(vpath)/../whatever. ??? Might not 197 1.1 mrg be necessary. */ 198 1.1 mrg if (p[1] == '.' && p[2] == '.' && IS_DIR_SEPARATOR (p[3])) 199 1.1 mrg goto not_this_one; 200 1.1 mrg 201 1.1 mrg /* found a match */ 202 1.1 mrg t = t + d->vpath[i].len + 1; 203 1.1 mrg break; 204 1.1 mrg } 205 1.1 mrg not_this_one:; 206 1.1 mrg } 207 1.1 mrg 208 1.1 mrg /* Remove leading ./ in any case. */ 209 1.1 mrg while (t[0] == '.' && IS_DIR_SEPARATOR (t[1])) 210 1.1 mrg { 211 1.1 mrg t += 2; 212 1.1 mrg /* If we removed a leading ./, then also remove any /s after the 213 1.1 mrg first. */ 214 1.1 mrg while (IS_DIR_SEPARATOR (t[0])) 215 1.1 mrg ++t; 216 1.1 mrg } 217 1.1 mrg 218 1.1 mrg return t; 219 1.1 mrg } 220 1.1 mrg 221 1.1 mrg /* Public routines. */ 222 1.1 mrg 223 1.1 mrg class mkdeps * 224 1.1 mrg deps_init (void) 225 1.1 mrg { 226 1.1 mrg return new mkdeps (); 227 1.1 mrg } 228 1.1 mrg 229 1.1 mrg void 230 1.1 mrg deps_free (class mkdeps *d) 231 1.1 mrg { 232 1.1 mrg delete d; 233 1.1 mrg } 234 1.1 mrg 235 1.1 mrg /* Adds a target T. We make a copy, so it need not be a permanent 236 1.1 mrg string. QUOTE is true if the string should be quoted. */ 237 1.1 mrg void 238 1.1 mrg deps_add_target (class mkdeps *d, const char *t, int quote) 239 1.1 mrg { 240 1.1 mrg t = xstrdup (apply_vpath (d, t)); 241 1.1 mrg 242 1.1 mrg if (!quote) 243 1.1 mrg { 244 1.1 mrg /* Sometimes unquoted items are added after quoted ones. 245 1.1 mrg Swap out the lowest quoted. */ 246 1.1 mrg if (d->quote_lwm != d->targets.size ()) 247 1.1 mrg { 248 1.1 mrg const char *lowest = d->targets[d->quote_lwm]; 249 1.1 mrg d->targets[d->quote_lwm] = t; 250 1.1 mrg t = lowest; 251 1.1 mrg } 252 1.1 mrg d->quote_lwm++; 253 1.1 mrg } 254 1.1 mrg 255 1.1 mrg d->targets.push (t); 256 1.1 mrg } 257 1.1 mrg 258 1.1 mrg /* Sets the default target if none has been given already. An empty 259 1.1 mrg string as the default target in interpreted as stdin. The string 260 1.1 mrg is quoted for MAKE. */ 261 1.1 mrg void 262 1.1 mrg deps_add_default_target (class mkdeps *d, const char *tgt) 263 1.1 mrg { 264 1.1 mrg /* Only if we have no targets. */ 265 1.1 mrg if (d->targets.size ()) 266 1.1 mrg return; 267 1.1 mrg 268 1.1 mrg if (tgt[0] == '\0') 269 1.1 mrg d->targets.push (xstrdup ("-")); 270 1.1 mrg else 271 1.1 mrg { 272 1.1 mrg #ifndef TARGET_OBJECT_SUFFIX 273 1.1 mrg # define TARGET_OBJECT_SUFFIX ".o" 274 1.1 mrg #endif 275 1.1 mrg const char *start = lbasename (tgt); 276 1.1 mrg char *o = (char *) alloca (strlen (start) 277 1.1 mrg + strlen (TARGET_OBJECT_SUFFIX) + 1); 278 1.1 mrg char *suffix; 279 1.1 mrg 280 1.1 mrg strcpy (o, start); 281 1.1 mrg 282 1.1 mrg suffix = strrchr (o, '.'); 283 1.1 mrg if (!suffix) 284 1.1 mrg suffix = o + strlen (o); 285 1.1 mrg strcpy (suffix, TARGET_OBJECT_SUFFIX); 286 1.1 mrg 287 1.1 mrg deps_add_target (d, o, 1); 288 1.1 mrg } 289 1.1 mrg } 290 1.1 mrg 291 1.1 mrg void 292 1.1 mrg deps_add_dep (class mkdeps *d, const char *t) 293 1.1 mrg { 294 1.1 mrg gcc_assert (*t); 295 1.1 mrg 296 1.1 mrg t = apply_vpath (d, t); 297 1.1 mrg 298 1.1 mrg d->deps.push (xstrdup (t)); 299 1.1 mrg } 300 1.1 mrg 301 1.1 mrg void 302 1.1 mrg deps_add_vpath (class mkdeps *d, const char *vpath) 303 1.1 mrg { 304 1.1 mrg const char *elem, *p; 305 1.1 mrg 306 1.1 mrg for (elem = vpath; *elem; elem = p) 307 1.1 mrg { 308 1.1 mrg for (p = elem; *p && *p != ':'; p++) 309 1.1 mrg continue; 310 1.1 mrg mkdeps::velt elt; 311 1.1 mrg elt.len = p - elem; 312 1.1 mrg char *str = XNEWVEC (char, elt.len + 1); 313 1.1 mrg elt.str = str; 314 1.1 mrg memcpy (str, elem, elt.len); 315 1.1 mrg str[elt.len] = '\0'; 316 1.1 mrg if (*p == ':') 317 1.1 mrg p++; 318 1.1 mrg 319 1.1 mrg d->vpath.push (elt); 320 1.1 mrg } 321 1.1 mrg } 322 1.1 mrg 323 1.1 mrg /* Add a new module target (there can only be one). M is the module 324 1.1 mrg name. */ 325 1.1 mrg 326 1.1 mrg void 327 1.1 mrg deps_add_module_target (struct mkdeps *d, const char *m, 328 1.1 mrg const char *cmi, bool is_header_unit) 329 1.1 mrg { 330 1.1 mrg gcc_assert (!d->module_name); 331 1.1 mrg 332 1.1 mrg d->module_name = xstrdup (m); 333 1.1 mrg d->is_header_unit = is_header_unit; 334 1.1 mrg d->cmi_name = xstrdup (cmi); 335 1.1 mrg } 336 1.1 mrg 337 1.1 mrg /* Add a new module dependency. M is the module name. */ 338 1.1 mrg 339 1.1 mrg void 340 1.1 mrg deps_add_module_dep (struct mkdeps *d, const char *m) 341 1.1 mrg { 342 1.1 mrg d->modules.push (xstrdup (m)); 343 1.1 mrg } 344 1.1 mrg 345 1.1 mrg /* Write NAME, with a leading space to FP, a Makefile. Advance COL as 346 1.1 mrg appropriate, wrap at COLMAX, returning new column number. Iff 347 1.1 mrg QUOTE apply quoting. Append TRAIL. */ 348 1.1 mrg 349 1.1 mrg static unsigned 350 1.1 mrg make_write_name (const char *name, FILE *fp, unsigned col, unsigned colmax, 351 1.1 mrg bool quote = true, const char *trail = NULL) 352 1.1 mrg { 353 1.1 mrg if (quote) 354 1.1 mrg name = munge (name, trail); 355 1.1 mrg unsigned size = strlen (name); 356 1.1 mrg 357 1.1 mrg if (col) 358 1.1 mrg { 359 1.1 mrg if (colmax && col + size> colmax) 360 1.1 mrg { 361 1.1 mrg fputs (" \\\n", fp); 362 1.1 mrg col = 0; 363 1.1 mrg } 364 1.1 mrg col++; 365 1.1 mrg fputs (" ", fp); 366 1.1 mrg } 367 1.1 mrg 368 1.1 mrg col += size; 369 1.1 mrg fputs (name, fp); 370 1.1 mrg 371 1.1 mrg return col; 372 1.1 mrg } 373 1.1 mrg 374 1.1 mrg /* Write all the names in VEC via make_write_name. */ 375 1.1 mrg 376 1.1 mrg static unsigned 377 1.1 mrg make_write_vec (const mkdeps::vec<const char *> &vec, FILE *fp, 378 1.1 mrg unsigned col, unsigned colmax, unsigned quote_lwm = 0, 379 1.1 mrg const char *trail = NULL) 380 1.1 mrg { 381 1.1 mrg for (unsigned ix = 0; ix != vec.size (); ix++) 382 1.1 mrg col = make_write_name (vec[ix], fp, col, colmax, ix >= quote_lwm, trail); 383 1.1 mrg return col; 384 1.1 mrg } 385 1.1 mrg 386 1.1 mrg /* Write the dependencies to a Makefile. If PHONY is true, add 387 1.1 mrg .PHONY targets for all the dependencies too. */ 388 1.1 mrg 389 1.1 mrg static void 390 1.1 mrg make_write (const cpp_reader *pfile, FILE *fp, unsigned int colmax) 391 1.1 mrg { 392 1.1 mrg const mkdeps *d = pfile->deps; 393 1.1 mrg 394 1.1 mrg unsigned column = 0; 395 1.1 mrg if (colmax && colmax < 34) 396 1.1 mrg colmax = 34; 397 1.1 mrg 398 1.1 mrg if (d->deps.size ()) 399 1.1 mrg { 400 1.1 mrg column = make_write_vec (d->targets, fp, 0, colmax, d->quote_lwm); 401 1.1 mrg if (CPP_OPTION (pfile, deps.modules) && d->cmi_name) 402 1.1 mrg column = make_write_name (d->cmi_name, fp, column, colmax); 403 1.1 mrg fputs (":", fp); 404 1.1 mrg column++; 405 1.1 mrg make_write_vec (d->deps, fp, column, colmax); 406 1.1 mrg fputs ("\n", fp); 407 1.1 mrg if (CPP_OPTION (pfile, deps.phony_targets)) 408 1.1 mrg for (unsigned i = 1; i < d->deps.size (); i++) 409 1.1 mrg fprintf (fp, "%s:\n", munge (d->deps[i])); 410 1.1 mrg } 411 1.1 mrg 412 1.1 mrg if (!CPP_OPTION (pfile, deps.modules)) 413 1.1 mrg return; 414 1.1 mrg 415 1.1 mrg if (d->modules.size ()) 416 1.1 mrg { 417 1.1 mrg column = make_write_vec (d->targets, fp, 0, colmax, d->quote_lwm); 418 1.1 mrg if (d->cmi_name) 419 1.1 mrg column = make_write_name (d->cmi_name, fp, column, colmax); 420 1.1 mrg fputs (":", fp); 421 1.1 mrg column++; 422 1.1 mrg column = make_write_vec (d->modules, fp, column, colmax, 0, ".c++m"); 423 1.1 mrg fputs ("\n", fp); 424 1.1 mrg } 425 1.1 mrg 426 1.1 mrg if (d->module_name) 427 1.1 mrg { 428 1.1 mrg if (d->cmi_name) 429 1.1 mrg { 430 1.1 mrg /* module-name : cmi-name */ 431 1.1 mrg column = make_write_name (d->module_name, fp, 0, colmax, 432 1.1 mrg true, ".c++m"); 433 1.1 mrg fputs (":", fp); 434 1.1 mrg column++; 435 1.1 mrg column = make_write_name (d->cmi_name, fp, column, colmax); 436 1.1 mrg fputs ("\n", fp); 437 1.1 mrg 438 1.1 mrg column = fprintf (fp, ".PHONY:"); 439 1.1 mrg column = make_write_name (d->module_name, fp, column, colmax, 440 1.1 mrg true, ".c++m"); 441 1.1 mrg fputs ("\n", fp); 442 1.1 mrg } 443 1.1 mrg 444 1.1 mrg if (d->cmi_name && !d->is_header_unit) 445 1.1 mrg { 446 1.1 mrg /* An order-only dependency. 447 1.1 mrg cmi-name :| first-target 448 1.1 mrg We can probably drop this this in favour of Make-4.3's grouped 449 1.1 mrg targets '&:' */ 450 1.1 mrg column = make_write_name (d->cmi_name, fp, 0, colmax); 451 1.1 mrg fputs (":|", fp); 452 1.1 mrg column++; 453 1.1 mrg column = make_write_name (d->targets[0], fp, column, colmax); 454 1.1 mrg fputs ("\n", fp); 455 1.1 mrg } 456 1.1 mrg } 457 1.1 mrg 458 1.1 mrg if (d->modules.size ()) 459 1.1 mrg { 460 1.1 mrg column = fprintf (fp, "CXX_IMPORTS +="); 461 1.1 mrg make_write_vec (d->modules, fp, column, colmax, 0, ".c++m"); 462 1.1 mrg fputs ("\n", fp); 463 1.1 mrg } 464 1.1 mrg } 465 1.1 mrg 466 1.1 mrg /* Write out dependencies according to the selected format (which is 467 1.1 mrg only Make at the moment). */ 468 1.1 mrg /* Really we should be opening fp here. */ 469 1.1 mrg 470 1.1 mrg void 471 1.1 mrg deps_write (const cpp_reader *pfile, FILE *fp, unsigned int colmax) 472 1.1 mrg { 473 1.1 mrg make_write (pfile, fp, colmax); 474 1.1 mrg } 475 1.1 mrg 476 1.1 mrg /* Write out a deps buffer to a file, in a form that can be read back 477 1.1 mrg with deps_restore. Returns nonzero on error, in which case the 478 1.1 mrg error number will be in errno. */ 479 1.1 mrg 480 1.1 mrg int 481 1.1 mrg deps_save (class mkdeps *deps, FILE *f) 482 1.1 mrg { 483 1.1 mrg unsigned int i; 484 1.1 mrg size_t size; 485 1.1 mrg 486 1.1 mrg /* The cppreader structure contains makefile dependences. Write out this 487 1.1 mrg structure. */ 488 1.1 mrg 489 1.1 mrg /* The number of dependences. */ 490 1.1 mrg size = deps->deps.size (); 491 1.1 mrg if (fwrite (&size, sizeof (size), 1, f) != 1) 492 1.1 mrg return -1; 493 1.1 mrg 494 1.1 mrg /* The length of each dependence followed by the string. */ 495 1.1 mrg for (i = 0; i < deps->deps.size (); i++) 496 1.1 mrg { 497 1.1 mrg size = strlen (deps->deps[i]); 498 1.1 mrg if (fwrite (&size, sizeof (size), 1, f) != 1) 499 1.1 mrg return -1; 500 1.1 mrg if (fwrite (deps->deps[i], size, 1, f) != 1) 501 1.1 mrg return -1; 502 1.1 mrg } 503 1.1 mrg 504 1.1 mrg return 0; 505 1.1 mrg } 506 1.1 mrg 507 1.1 mrg /* Read back dependency information written with deps_save into 508 1.1 mrg the deps sizefer. The third argument may be NULL, in which case 509 1.1 mrg the dependency information is just skipped, or it may be a filename, 510 1.1 mrg in which case that filename is skipped. */ 511 1.1 mrg 512 1.1 mrg int 513 1.1 mrg deps_restore (class mkdeps *deps, FILE *fd, const char *self) 514 1.1 mrg { 515 1.1 mrg size_t size; 516 1.1 mrg char *buf = NULL; 517 1.1 mrg size_t buf_size = 0; 518 1.1 mrg 519 1.1 mrg /* Number of dependences. */ 520 1.1 mrg if (fread (&size, sizeof (size), 1, fd) != 1) 521 1.1 mrg return -1; 522 1.1 mrg 523 1.1 mrg /* The length of each dependence string, followed by the string. */ 524 1.1 mrg for (unsigned i = size; i--;) 525 1.1 mrg { 526 1.1 mrg /* Read in # bytes in string. */ 527 1.1 mrg if (fread (&size, sizeof (size), 1, fd) != 1) 528 1.1 mrg return -1; 529 1.1 mrg 530 1.1 mrg if (size >= buf_size) 531 1.1 mrg { 532 1.1 mrg buf_size = size + 512; 533 1.1 mrg buf = XRESIZEVEC (char, buf, buf_size); 534 1.1 mrg } 535 1.1 mrg if (fread (buf, 1, size, fd) != size) 536 1.1 mrg { 537 1.1 mrg XDELETEVEC (buf); 538 1.1 mrg return -1; 539 1.1 mrg } 540 1.1 mrg buf[size] = 0; 541 1.1 mrg 542 1.1 mrg /* Generate makefile dependencies from .pch if -nopch-deps. */ 543 1.1 mrg if (self != NULL && filename_cmp (buf, self) != 0) 544 1.1 mrg deps_add_dep (deps, buf); 545 1.1 mrg } 546 1.1 mrg 547 1.1 mrg XDELETEVEC (buf); 548 1.1 mrg return 0; 549 1.1 mrg } 550