From b744fc85f549534bcbc36dedcc1659c02e16c617 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Mon, 6 May 2019 11:34:47 +0000 Subject: [libcpp] struct deps renaming https://gcc.gnu.org/ml/gcc-patches/2019-05/msg00199.html libcpp/ * include/mkdeps.h: Rename struct deps to struct mkdeps. * mkdeps.c: Likewise. * include/cpplib.h (cpp_get_deps): Rename return type.. * directives.c (cpp_get_deps): Likewise. * internal.h (struct cpp_reader): Rename deps field type. gcc/c-family/ * c-opts.c (handle_defered_opts): Rename struct deps to struc mkdeps. From-SVN: r270905 --- libcpp/ChangeLog | 8 ++++++++ libcpp/directives.c | 2 +- libcpp/include/cpplib.h | 2 +- libcpp/include/mkdeps.h | 22 +++++++++++----------- libcpp/internal.h | 2 +- libcpp/mkdeps.c | 26 +++++++++++++------------- 6 files changed, 35 insertions(+), 27 deletions(-) (limited to 'libcpp') diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog index 7fe5b52..0e3fc56 100644 --- a/libcpp/ChangeLog +++ b/libcpp/ChangeLog @@ -1,3 +1,11 @@ +2019-05-06 Nathan Sidwell + + * include/mkdeps.h: Rename struct deps to struct mkdeps. + * mkdeps.c: Likewise. + * include/cpplib.h (cpp_get_deps): Rename return type.. + * directives.c (cpp_get_deps): Likewise. + * internal.h (struct cpp_reader): Rename deps field type. + 2019-04-03 Jonathan Wakely * files.c (search_path_exhausted): Fix typo in comment. diff --git a/libcpp/directives.c b/libcpp/directives.c index 1ada834..3ee8bc4 100644 --- a/libcpp/directives.c +++ b/libcpp/directives.c @@ -2539,7 +2539,7 @@ cpp_set_callbacks (cpp_reader *pfile, cpp_callbacks *cb) } /* The dependencies structure. (Creates one if it hasn't already been.) */ -struct deps * +struct mkdeps * cpp_get_deps (cpp_reader *pfile) { if (!pfile->deps) diff --git a/libcpp/include/cpplib.h b/libcpp/include/cpplib.h index 87cc6a3..3edb93d 100644 --- a/libcpp/include/cpplib.h +++ b/libcpp/include/cpplib.h @@ -953,7 +953,7 @@ extern void cpp_set_include_chains (cpp_reader *, cpp_dir *, cpp_dir *, int); extern cpp_options *cpp_get_options (cpp_reader *); extern cpp_callbacks *cpp_get_callbacks (cpp_reader *); extern void cpp_set_callbacks (cpp_reader *, cpp_callbacks *); -extern struct deps *cpp_get_deps (cpp_reader *); +extern struct mkdeps *cpp_get_deps (cpp_reader *); /* This function reads the file, but does not start preprocessing. It returns the name of the original file; this is the same as the diff --git a/libcpp/include/mkdeps.h b/libcpp/include/mkdeps.h index 161291a..b0e3472 100644 --- a/libcpp/include/mkdeps.h +++ b/libcpp/include/mkdeps.h @@ -26,54 +26,54 @@ along with this program; see the file COPYING3. If not see /* This is the data structure used by all the functions in mkdeps.c. It's quite straightforward, but should be treated as opaque. */ -struct deps; +struct mkdeps; /* Create a deps buffer. */ -extern struct deps *deps_init (void); +extern struct mkdeps *deps_init (void); /* Destroy a deps buffer. */ -extern void deps_free (struct deps *); +extern void deps_free (struct mkdeps *); /* Add a set of "vpath" directories. The second argument is a colon- separated list of pathnames, like you would set Make's VPATH variable to. If a dependency or target name begins with any of these pathnames (and the next path element is not "..") that pathname is stripped off. */ -extern void deps_add_vpath (struct deps *, const char *); +extern void deps_add_vpath (struct mkdeps *, const char *); /* Add a target (appears on left side of the colon) to the deps list. Takes a boolean indicating whether to quote the target for MAKE. */ -extern void deps_add_target (struct deps *, const char *, int); +extern void deps_add_target (struct mkdeps *, const char *, int); /* Sets the default target if none has been given already. An empty string as the default target is interpreted as stdin. */ -extern void deps_add_default_target (struct deps *, const char *); +extern void deps_add_default_target (struct mkdeps *, const char *); /* Add a dependency (appears on the right side of the colon) to the deps list. Dependencies will be printed in the order that they were entered with this function. By convention, the first dependency entered should be the primary source file. */ -extern void deps_add_dep (struct deps *, const char *); +extern void deps_add_dep (struct mkdeps *, const char *); /* Write out a deps buffer to a specified file. The third argument is the number of columns to word-wrap at (0 means don't wrap). */ -extern void deps_write (const struct deps *, FILE *, unsigned int); +extern void deps_write (const struct mkdeps *, FILE *, unsigned int); /* Write out a deps buffer to a file, in a form that can be read back with deps_restore. Returns nonzero on error, in which case the error number will be in errno. */ -extern int deps_save (struct deps *, FILE *); +extern int deps_save (struct mkdeps *, FILE *); /* Read back dependency information written with deps_save into the deps buffer. The third argument may be NULL, in which case the dependency information is just skipped, or it may be a filename, in which case that filename is skipped. */ -extern int deps_restore (struct deps *, FILE *, const char *); +extern int deps_restore (struct mkdeps *, FILE *, const char *); /* For each dependency *except the first*, emit a dummy rule for that file, causing it to depend on nothing. This is used to work around the intermediate-file deletion misfeature in Make, in some automatic dependency schemes. */ -extern void deps_phony_targets (const struct deps *, FILE *); +extern void deps_phony_targets (const struct mkdeps *, FILE *); #endif /* ! LIBCPP_MKDEPS_H */ diff --git a/libcpp/internal.h b/libcpp/internal.h index 77a2a3b..5b9c389 100644 --- a/libcpp/internal.h +++ b/libcpp/internal.h @@ -512,7 +512,7 @@ struct cpp_reader cpp_token eof; /* Opaque handle to the dependencies of mkdeps.c. */ - struct deps *deps; + struct mkdeps *deps; /* Obstack holding all macro hash nodes. This never shrinks. See identifiers.c */ diff --git a/libcpp/mkdeps.c b/libcpp/mkdeps.c index e506200..3cbd756 100644 --- a/libcpp/mkdeps.c +++ b/libcpp/mkdeps.c @@ -26,7 +26,7 @@ along with this program; see the file COPYING3. If not see /* Keep this structure local to this file, so clients don't find it easy to start making assumptions. */ -struct deps +struct mkdeps { const char **targetv; unsigned int ntargets; /* number of slots actually occupied */ @@ -122,7 +122,7 @@ munge (const char *filename) /* If T begins with any of the partial pathnames listed in d->vpathv, then advance T to point beyond that pathname. */ static const char * -apply_vpath (struct deps *d, const char *t) +apply_vpath (struct mkdeps *d, const char *t) { if (d->vpathv) { @@ -163,14 +163,14 @@ apply_vpath (struct deps *d, const char *t) /* Public routines. */ -struct deps * +struct mkdeps * deps_init (void) { - return XCNEW (struct deps); + return XCNEW (struct mkdeps); } void -deps_free (struct deps *d) +deps_free (struct mkdeps *d) { unsigned int i; @@ -202,7 +202,7 @@ deps_free (struct deps *d) /* Adds a target T. We make a copy, so it need not be a permanent string. QUOTE is true if the string should be quoted. */ void -deps_add_target (struct deps *d, const char *t, int quote) +deps_add_target (struct mkdeps *d, const char *t, int quote) { if (d->ntargets == d->targets_size) { @@ -223,7 +223,7 @@ deps_add_target (struct deps *d, const char *t, int quote) string as the default target in interpreted as stdin. The string is quoted for MAKE. */ void -deps_add_default_target (struct deps *d, const char *tgt) +deps_add_default_target (struct mkdeps *d, const char *tgt) { /* Only if we have no targets. */ if (d->ntargets) @@ -253,7 +253,7 @@ deps_add_default_target (struct deps *d, const char *tgt) } void -deps_add_dep (struct deps *d, const char *t) +deps_add_dep (struct mkdeps *d, const char *t) { t = munge (apply_vpath (d, t)); /* Also makes permanent copy. */ @@ -266,7 +266,7 @@ deps_add_dep (struct deps *d, const char *t) } void -deps_add_vpath (struct deps *d, const char *vpath) +deps_add_vpath (struct mkdeps *d, const char *vpath) { const char *elem, *p; char *copy; @@ -295,7 +295,7 @@ deps_add_vpath (struct deps *d, const char *vpath) } void -deps_write (const struct deps *d, FILE *fp, unsigned int colmax) +deps_write (const struct mkdeps *d, FILE *fp, unsigned int colmax) { unsigned int size, i, column; @@ -346,7 +346,7 @@ deps_write (const struct deps *d, FILE *fp, unsigned int colmax) } void -deps_phony_targets (const struct deps *d, FILE *fp) +deps_phony_targets (const struct mkdeps *d, FILE *fp) { unsigned int i; @@ -364,7 +364,7 @@ deps_phony_targets (const struct deps *d, FILE *fp) error number will be in errno. */ int -deps_save (struct deps *deps, FILE *f) +deps_save (struct mkdeps *deps, FILE *f) { unsigned int i; @@ -393,7 +393,7 @@ deps_save (struct deps *deps, FILE *f) in which case that filename is skipped. */ int -deps_restore (struct deps *deps, FILE *fd, const char *self) +deps_restore (struct mkdeps *deps, FILE *fd, const char *self) { unsigned int i, count; size_t num_to_read; -- cgit v1.1 From d7b6aee8cd346328b6f22fc415ffc28b9cf8a285 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Tue, 7 May 2019 12:39:59 +0000 Subject: [libcpp] Reimplement mkdeps data structures https://gcc.gnu.org/ml/gcc-patches/2019-05/msg00293.html * include/mkdeps.h (deps_write): Add PHONY arg. (deps_phony_targets): Delete. * init.c (cpp_finish): Just call deps_write. * mkdeps.c (struct mkdeps): Add local vector class. Reimplement vector handling. (munge): Munge to static buffer. (apply_vpath): Adjust vector handling. (deps_init, deps_free): Use new, delete. (deps_add_target): Do not munge here. Record quoting low water mark. (deps_add_dep): Do not munge here. (deps_add_vpath): Adjust vector handling. (make_write_name): New. Munge on demand here. (make_write_vec): New. (deps_phony_targets): Delete. (make_write): New. (deps_write): Forward to deps_Write. (deps_save, deps_restore): Adjust vector handling. From-SVN: r270943 --- libcpp/ChangeLog | 20 ++ libcpp/include/mkdeps.h | 8 +- libcpp/init.c | 11 +- libcpp/mkdeps.c | 494 +++++++++++++++++++++++++----------------------- 4 files changed, 281 insertions(+), 252 deletions(-) (limited to 'libcpp') diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog index 0e3fc56..df8da71 100644 --- a/libcpp/ChangeLog +++ b/libcpp/ChangeLog @@ -1,3 +1,23 @@ +2019-05-07 Nathan Sidwell + + * include/mkdeps.h (deps_write): Add PHONY arg. + (deps_phony_targets): Delete. + * init.c (cpp_finish): Just call deps_write. + * mkdeps.c (struct mkdeps): Add local vector class. Reimplement + vector handling. + (munge): Munge to static buffer. + (apply_vpath): Adjust vector handling. + (deps_init, deps_free): Use new, delete. + (deps_add_target): Do not munge here. Record quoting low water mark. + (deps_add_dep): Do not munge here. + (deps_add_vpath): Adjust vector handling. + (make_write_name): New. Munge on demand here. + (make_write_vec): New. + (deps_phony_targets): Delete. + (make_write): New. + (deps_write): Forward to deps_Write. + (deps_save, deps_restore): Adjust vector handling. + 2019-05-06 Nathan Sidwell * include/mkdeps.h: Rename struct deps to struct mkdeps. diff --git a/libcpp/include/mkdeps.h b/libcpp/include/mkdeps.h index b0e3472..e0ac21f 100644 --- a/libcpp/include/mkdeps.h +++ b/libcpp/include/mkdeps.h @@ -57,7 +57,7 @@ extern void deps_add_dep (struct mkdeps *, const char *); /* Write out a deps buffer to a specified file. The third argument is the number of columns to word-wrap at (0 means don't wrap). */ -extern void deps_write (const struct mkdeps *, FILE *, unsigned int); +extern void deps_write (const struct mkdeps *, FILE *, bool, unsigned int); /* Write out a deps buffer to a file, in a form that can be read back with deps_restore. Returns nonzero on error, in which case the @@ -70,10 +70,4 @@ extern int deps_save (struct mkdeps *, FILE *); in which case that filename is skipped. */ extern int deps_restore (struct mkdeps *, FILE *, const char *); -/* For each dependency *except the first*, emit a dummy rule for that - file, causing it to depend on nothing. This is used to work around - the intermediate-file deletion misfeature in Make, in some - automatic dependency schemes. */ -extern void deps_phony_targets (const struct mkdeps *, FILE *); - #endif /* ! LIBCPP_MKDEPS_H */ diff --git a/libcpp/init.c b/libcpp/init.c index 60d2588..c0c9020 100644 --- a/libcpp/init.c +++ b/libcpp/init.c @@ -764,14 +764,9 @@ cpp_finish (cpp_reader *pfile, FILE *deps_stream) while (pfile->buffer) _cpp_pop_buffer (pfile); - if (CPP_OPTION (pfile, deps.style) != DEPS_NONE - && deps_stream) - { - deps_write (pfile->deps, deps_stream, 72); - - if (CPP_OPTION (pfile, deps.phony_targets)) - deps_phony_targets (pfile->deps, deps_stream); - } + if (CPP_OPTION (pfile, deps.style) != DEPS_NONE && deps_stream) + deps_write (pfile->deps, deps_stream, + CPP_OPTION (pfile, deps.phony_targets), 72); /* Report on headers that could use multiple include guards. */ if (CPP_OPTION (pfile, print_include_names)) diff --git a/libcpp/mkdeps.c b/libcpp/mkdeps.c index 3cbd756..a9a050c 100644 --- a/libcpp/mkdeps.c +++ b/libcpp/mkdeps.c @@ -24,129 +24,184 @@ along with this program; see the file COPYING3. If not see #include "system.h" #include "mkdeps.h" +/* Not set up to just include std::vector et al, here's a simple + implementation. */ + /* Keep this structure local to this file, so clients don't find it easy to start making assumptions. */ struct mkdeps { - const char **targetv; - unsigned int ntargets; /* number of slots actually occupied */ - unsigned int targets_size; /* amt of allocated space - in words */ - - const char **depv; - unsigned int ndeps; - unsigned int deps_size; - - const char **vpathv; - size_t *vpathlv; - unsigned int nvpaths; - unsigned int vpaths_size; -}; - -static const char *munge (const char *); - -/* Given a filename, quote characters in that filename which are - significant to Make. Note that it's not possible to quote all such - characters - e.g. \n, %, *, ?, [, \ (in some contexts), and ~ are - not properly handled. It isn't possible to get this right in any - current version of Make. (??? Still true? Old comment referred to - 3.76.1.) */ - -static const char * -munge (const char *filename) -{ - int len; - const char *p, *q; - char *dst, *buffer; - - for (p = filename, len = 0; *p; p++, len++) +public: + /* T has trivial cctor & dtor. */ + template + class vec + { + private: + T *ary; + unsigned num; + unsigned alloc; + + public: + vec () + : ary (NULL), num (0), alloc (0) + {} + ~vec () + { + XDELETEVEC (ary); + } + + public: + unsigned size () const { - switch (*p) - { - case ' ': - case '\t': - /* GNU make uses a weird quoting scheme for white space. - A space or tab preceded by 2N+1 backslashes represents - N backslashes followed by space; a space or tab - preceded by 2N backslashes represents N backslashes at - the end of a file name; and backslashes in other - contexts should not be doubled. */ - for (q = p - 1; filename <= q && *q == '\\'; q--) - len++; - len++; - break; - - case '$': - /* '$' is quoted by doubling it. */ - len++; - break; - - case '#': - /* '#' is quoted with a backslash. */ - len++; - break; - } + return num; } - - /* Now we know how big to make the buffer. */ - buffer = XNEWVEC (char, len + 1); - - for (p = filename, dst = buffer; *p; p++, dst++) + const T &operator[] (unsigned ix) const { - switch (*p) + return ary[ix]; + } + void push (const T &elt) + { + if (num == alloc) { - case ' ': - case '\t': - for (q = p - 1; filename <= q && *q == '\\'; q--) - *dst++ = '\\'; - *dst++ = '\\'; - break; - - case '$': - *dst++ = '$'; - break; - - case '#': - *dst++ = '\\'; - break; - - default: - /* nothing */; + alloc = alloc ? alloc * 2 : 16; + ary = XRESIZEVEC (T, ary, alloc); } - *dst = *p; + ary[num++] = elt; } + }; + struct velt + { + const char *str; + size_t len; + }; + + mkdeps () + : quote_lwm (0) + { + } + ~mkdeps () + { + unsigned int i; + + for (i = targets.size (); i--;) + free (const_cast (targets[i])); + for (i = deps.size (); i--;) + free (const_cast (deps[i])); + for (i = vpath.size (); i--;) + XDELETEVEC (vpath[i].str); + } + +public: + vec targets; + vec deps; + vec vpath; + +public: + unsigned short quote_lwm; +}; - *dst = '\0'; - return buffer; -} +/* Apply Make quoting to STR, TRAIL etc. Note that it's not possible + to quote all such characters - e.g. \n, %, *, ?, [, \ (in some + contexts), and ~ are not properly handled. It isn't possible to + get this right in any current version of Make. (??? Still true? + Old comment referred to 3.76.1.) */ -/* If T begins with any of the partial pathnames listed in d->vpathv, - then advance T to point beyond that pathname. */ static const char * -apply_vpath (struct mkdeps *d, const char *t) +munge (const char *str, const char *trail = NULL, ...) { - if (d->vpathv) + static unsigned alloc; + static char *buf; + unsigned dst = 0; + va_list args; + if (trail) + va_start (args, trail); + + for (bool first = true; str; first = false) { - unsigned int i; - for (i = 0; i < d->nvpaths; i++) + unsigned slashes = 0; + char c; + for (const char *probe = str; (c = *probe++);) { - if (!filename_ncmp (d->vpathv[i], t, d->vpathlv[i])) + if (alloc < dst + 4 + slashes) { - const char *p = t + d->vpathlv[i]; - if (!IS_DIR_SEPARATOR (*p)) - goto not_this_one; + alloc = alloc * 2 + 32; + buf = XRESIZEVEC (char, buf, alloc); + } - /* Do not simplify $(vpath)/../whatever. ??? Might not - be necessary. */ - if (p[1] == '.' && p[2] == '.' && IS_DIR_SEPARATOR (p[3])) - goto not_this_one; + switch (c) + { + case '\\': + slashes++; + break; - /* found a match */ - t = t + d->vpathlv[i] + 1; + case '$': + buf[dst++] = '$'; + goto def; + + case ' ': + case '\t': + /* GNU make uses a weird quoting scheme for white space. + A space or tab preceded by 2N+1 backslashes + represents N backslashes followed by space; a space + or tab preceded by 2N backslashes represents N + backslashes at the end of a file name; and + backslashes in other contexts should not be + doubled. */ + while (slashes--) + buf[dst++] = '\\'; + /* FALLTHROUGH */ + + case '#': + case ':': + buf[dst++] = '\\'; + /* FALLTHROUGH */ + + default: + def: + slashes = 0; break; } - not_this_one:; + + buf[dst++] = c; } + + if (first) + str = trail; + else + str = va_arg (args, const char *); } + if (trail) + va_end (args); + + buf[dst] = 0; + return buf; +} + +/* If T begins with any of the partial pathnames listed in d->vpathv, + then advance T to point beyond that pathname. */ +static const char * +apply_vpath (struct mkdeps *d, const char *t) +{ + if (unsigned len = d->vpath.size ()) + for (unsigned i = len; i--;) + { + if (!filename_ncmp (d->vpath[i].str, t, d->vpath[i].len)) + { + const char *p = t + d->vpath[i].len; + if (!IS_DIR_SEPARATOR (*p)) + goto not_this_one; + + /* Do not simplify $(vpath)/../whatever. ??? Might not + be necessary. */ + if (p[1] == '.' && p[2] == '.' && IS_DIR_SEPARATOR (p[3])) + goto not_this_one; + + /* found a match */ + t = t + d->vpath[i].len + 1; + break; + } + not_this_one:; + } /* Remove leading ./ in any case. */ while (t[0] == '.' && IS_DIR_SEPARATOR (t[1])) @@ -166,37 +221,13 @@ apply_vpath (struct mkdeps *d, const char *t) struct mkdeps * deps_init (void) { - return XCNEW (struct mkdeps); + return new mkdeps (); } void deps_free (struct mkdeps *d) { - unsigned int i; - - if (d->targetv) - { - for (i = 0; i < d->ntargets; i++) - free ((void *) d->targetv[i]); - free (d->targetv); - } - - if (d->depv) - { - for (i = 0; i < d->ndeps; i++) - free ((void *) d->depv[i]); - free (d->depv); - } - - if (d->vpathv) - { - for (i = 0; i < d->nvpaths; i++) - free ((void *) d->vpathv[i]); - free (d->vpathv); - free (d->vpathlv); - } - - free (d); + delete d; } /* Adds a target T. We make a copy, so it need not be a permanent @@ -204,19 +235,14 @@ deps_free (struct mkdeps *d) void deps_add_target (struct mkdeps *d, const char *t, int quote) { - if (d->ntargets == d->targets_size) + t = apply_vpath (d, t); + if (!quote) { - d->targets_size = d->targets_size * 2 + 4; - d->targetv = XRESIZEVEC (const char *, d->targetv, d->targets_size); + gcc_assert (d->quote_lwm == d->targets.size ()); + d->quote_lwm++; } - t = apply_vpath (d, t); - if (quote) - t = munge (t); /* Also makes permanent copy. */ - else - t = xstrdup (t); - - d->targetv[d->ntargets++] = t; + d->targets.push (xstrdup (t)); } /* Sets the default target if none has been given already. An empty @@ -226,7 +252,7 @@ void deps_add_default_target (struct mkdeps *d, const char *tgt) { /* Only if we have no targets. */ - if (d->ntargets) + if (d->targets.size ()) return; if (tgt[0] == '\0') @@ -255,110 +281,106 @@ deps_add_default_target (struct mkdeps *d, const char *tgt) void deps_add_dep (struct mkdeps *d, const char *t) { - t = munge (apply_vpath (d, t)); /* Also makes permanent copy. */ + t = apply_vpath (d, t); - if (d->ndeps == d->deps_size) - { - d->deps_size = d->deps_size * 2 + 8; - d->depv = XRESIZEVEC (const char *, d->depv, d->deps_size); - } - d->depv[d->ndeps++] = t; + d->deps.push (xstrdup (t)); } void deps_add_vpath (struct mkdeps *d, const char *vpath) { const char *elem, *p; - char *copy; - size_t len; for (elem = vpath; *elem; elem = p) { - for (p = elem; *p && *p != ':'; p++); - len = p - elem; - copy = XNEWVEC (char, len + 1); - memcpy (copy, elem, len); - copy[len] = '\0'; + for (p = elem; *p && *p != ':'; p++) + continue; + mkdeps::velt elt; + elt.len = p - elem; + char *str = XNEWVEC (char, elt.len + 1); + elt.str = str; + memcpy (str, elem, elt.len); + str[elt.len] = '\0'; if (*p == ':') p++; - if (d->nvpaths == d->vpaths_size) - { - d->vpaths_size = d->vpaths_size * 2 + 8; - d->vpathv = XRESIZEVEC (const char *, d->vpathv, d->vpaths_size); - d->vpathlv = XRESIZEVEC (size_t, d->vpathlv, d->vpaths_size); - } - d->vpathv[d->nvpaths] = copy; - d->vpathlv[d->nvpaths] = len; - d->nvpaths++; + d->vpath.push (elt); } } -void -deps_write (const struct mkdeps *d, FILE *fp, unsigned int colmax) -{ - unsigned int size, i, column; +/* Write NAME, with a leading space to FP, a Makefile. Advance COL as + appropriate, wrap at COLMAX, returning new column number. Iff + QUOTE apply quoting. Append TRAIL. */ - column = 0; - if (colmax && colmax < 34) - colmax = 34; +static unsigned +make_write_name (const char *name, FILE *fp, unsigned col, unsigned colmax, + bool quote = true, const char *trail = NULL) +{ + if (quote) + name = munge (name, trail, NULL); + unsigned size = strlen (name); - for (i = 0; i < d->ntargets; i++) + if (col) { - size = strlen (d->targetv[i]); - column += size; - if (i) + if (colmax && col + size> colmax) { - if (colmax && column > colmax) - { - fputs (" \\\n ", fp); - column = 1 + size; - } - else - { - putc (' ', fp); - column++; - } + fputs (" \\\n", fp); + col = 0; } - fputs (d->targetv[i], fp); + col++; + fputs (" ", fp); } - putc (':', fp); - column++; + col += size; + fputs (name, fp); - for (i = 0; i < d->ndeps; i++) - { - size = strlen (d->depv[i]); - column += size; - if (colmax && column > colmax) - { - fputs (" \\\n ", fp); - column = 1 + size; - } - else - { - putc (' ', fp); - column++; - } - fputs (d->depv[i], fp); - } - putc ('\n', fp); + return col; } -void -deps_phony_targets (const struct mkdeps *d, FILE *fp) +/* Write all the names in VEC via make_write_name. */ + +static unsigned +make_write_vec (const mkdeps::vec &vec, FILE *fp, + unsigned col, unsigned colmax, unsigned quote_lwm = 0, + const char *trail = NULL) { - unsigned int i; + for (unsigned ix = 0; ix != vec.size (); ix++) + col = make_write_name (vec[ix], fp, col, colmax, ix >= quote_lwm, trail); + return col; +} - for (i = 1; i < d->ndeps; i++) +/* Write the dependencies to a Makefile. If PHONY is true, add + .PHONY targets for all the dependencies too. */ + +static void +make_write (const struct mkdeps *d, FILE *fp, bool phony, unsigned int colmax) +{ + unsigned column = 0; + if (colmax && colmax < 34) + colmax = 34; + + if (d->deps.size ()) { - putc ('\n', fp); - fputs (d->depv[i], fp); - putc (':', fp); - putc ('\n', fp); + column = make_write_vec (d->targets, fp, 0, colmax, d->quote_lwm); + fputs (":", fp); + column++; + column = make_write_vec (d->deps, fp, column, colmax); + fputs ("\n", fp); + if (phony) + for (unsigned i = 1; i < d->deps.size (); i++) + fprintf (fp, "%s:\n", munge (d->deps[i])); } } +/* Write out dependencies according to the selected format (which is + only Make at the moment). */ + +void +deps_write (const struct mkdeps *d, FILE *fp, bool phony, unsigned int colmax) +{ + make_write (d, fp, phony, colmax); +} + /* Write out a deps buffer to a file, in a form that can be read back with deps_restore. Returns nonzero on error, in which case the error number will be in errno. */ @@ -367,71 +389,69 @@ int deps_save (struct mkdeps *deps, FILE *f) { unsigned int i; + size_t size; /* The cppreader structure contains makefile dependences. Write out this structure. */ /* The number of dependences. */ - if (fwrite (&deps->ndeps, sizeof (deps->ndeps), 1, f) != 1) - return -1; + size = deps->deps.size (); + if (fwrite (&size, sizeof (size), 1, f) != 1) + return -1; + /* The length of each dependence followed by the string. */ - for (i = 0; i < deps->ndeps; i++) + for (i = 0; i < deps->deps.size (); i++) { - size_t num_to_write = strlen (deps->depv[i]); - if (fwrite (&num_to_write, sizeof (size_t), 1, f) != 1) - return -1; - if (fwrite (deps->depv[i], num_to_write, 1, f) != 1) - return -1; + size = strlen (deps->deps[i]); + if (fwrite (&size, sizeof (size), 1, f) != 1) + return -1; + if (fwrite (deps->deps[i], size, 1, f) != 1) + return -1; } return 0; } /* Read back dependency information written with deps_save into - the deps buffer. The third argument may be NULL, in which case + the deps sizefer. The third argument may be NULL, in which case the dependency information is just skipped, or it may be a filename, in which case that filename is skipped. */ int deps_restore (struct mkdeps *deps, FILE *fd, const char *self) { - unsigned int i, count; - size_t num_to_read; - size_t buf_size = 512; - char *buf; + size_t size; + char *buf = NULL; + size_t buf_size = 0; /* Number of dependences. */ - if (fread (&count, 1, sizeof (count), fd) != sizeof (count)) + if (fread (&size, sizeof (size), 1, fd) != 1) return -1; - buf = XNEWVEC (char, buf_size); - /* The length of each dependence string, followed by the string. */ - for (i = 0; i < count; i++) + for (unsigned i = size; i--;) { /* Read in # bytes in string. */ - if (fread (&num_to_read, 1, sizeof (size_t), fd) != sizeof (size_t)) - { - free (buf); - return -1; - } - if (buf_size < num_to_read + 1) + if (fread (&size, sizeof (size), 1, fd) != 1) + return -1; + + if (size >= buf_size) { - buf_size = num_to_read + 1 + 127; + buf_size = size + 512; buf = XRESIZEVEC (char, buf, buf_size); } - if (fread (buf, 1, num_to_read, fd) != num_to_read) + if (fread (buf, 1, size, fd) != size) { - free (buf); + XDELETEVEC (buf); return -1; } - buf[num_to_read] = '\0'; + buf[size] = 0; /* Generate makefile dependencies from .pch if -nopch-deps. */ if (self != NULL && filename_cmp (buf, self) != 0) deps_add_dep (deps, buf); } - free (buf); + XDELETEVEC (buf); return 0; } -- cgit v1.1 From 61145d937ba07e368d8251fd0ffe0b987b50a7b5 Mon Sep 17 00:00:00 2001 From: Nathan Sidwell Date: Tue, 7 May 2019 18:13:57 +0000 Subject: [libcpp] Reimplement mkdeps data structures https://gcc.gnu.org/ml/gcc-patches/2019-05/msg00323.html * files.c (_cpp_stack_file): Empty filenames aren't dependencies. * mkdeps.c (deps_add_dep): Assert not empty. From-SVN: r270978 --- libcpp/ChangeLog | 3 +++ libcpp/files.c | 10 +++++----- libcpp/mkdeps.c | 2 ++ 3 files changed, 10 insertions(+), 5 deletions(-) (limited to 'libcpp') diff --git a/libcpp/ChangeLog b/libcpp/ChangeLog index df8da71..1c314ea 100644 --- a/libcpp/ChangeLog +++ b/libcpp/ChangeLog @@ -1,5 +1,8 @@ 2019-05-07 Nathan Sidwell + * files.c (_cpp_stack_file): Empty filenames aren't dependencies. + * mkdeps.c (deps_add_dep): Assert not empty. + * include/mkdeps.h (deps_write): Add PHONY arg. (deps_phony_targets): Delete. * init.c (cpp_finish): Just call deps_write. diff --git a/libcpp/files.c b/libcpp/files.c index b0ac22b..3255cbf 100644 --- a/libcpp/files.c +++ b/libcpp/files.c @@ -906,11 +906,11 @@ _cpp_stack_file (cpp_reader *pfile, _cpp_file *file, bool import, sysp = MAX (pfile->buffer->sysp, file->dir->sysp); /* Add the file to the dependencies on its first inclusion. */ - if (CPP_OPTION (pfile, deps.style) > !!sysp && !file->stack_count) - { - if (!file->main_file || !CPP_OPTION (pfile, deps.ignore_main_file)) - deps_add_dep (pfile->deps, file->path); - } + if (!file->stack_count + && CPP_OPTION (pfile, deps.style) > !!sysp + && file->path[0] + && (!file->main_file || !CPP_OPTION (pfile, deps.ignore_main_file))) + deps_add_dep (pfile->deps, file->path); /* Clear buffer_valid since _cpp_clean_line messes it up. */ file->buffer_valid = false; diff --git a/libcpp/mkdeps.c b/libcpp/mkdeps.c index a9a050c..96cc49b 100644 --- a/libcpp/mkdeps.c +++ b/libcpp/mkdeps.c @@ -281,6 +281,8 @@ deps_add_default_target (struct mkdeps *d, const char *tgt) void deps_add_dep (struct mkdeps *d, const char *t) { + gcc_assert (*t); + t = apply_vpath (d, t); d->deps.push (xstrdup (t)); -- cgit v1.1