static int collect_ht_nodes (cpp_reader *, cpp_hashnode *, void *);
static int write_defs (cpp_reader *, cpp_hashnode *, void *);
static int save_macros (cpp_reader *, cpp_hashnode *, void *);
+static int _cpp_save_pushed_macros (cpp_reader *, FILE *);
+static int _cpp_restore_pushed_macros (cpp_reader *, FILE *);
/* This structure represents a macro definition on disk. */
struct macrodef_struct
return -1;
}
+ /* Write saved macros. */
+ if (! _cpp_save_pushed_macros (r, f))
+ {
+ cpp_errno (r, CPP_DL_ERROR, "while writing precompiled header");
+ return -1;
+ }
+
return 0;
}
+static int
+_cpp_restore_pushed_macros (cpp_reader *r, FILE *f)
+{
+ size_t count_saved = 0;
+ size_t i;
+ struct def_pragma_macro *p;
+ size_t nlen;
+ cpp_hashnode *h = NULL;
+ cpp_macro *m;
+ uchar *defn;
+ size_t defnlen;
+
+ if (fread (&count_saved, sizeof (count_saved), 1, f) != 1)
+ return 0;
+ if (! count_saved)
+ return 1;
+ for (i = 0; i < count_saved; i++)
+ {
+ if (fread (&nlen, sizeof (nlen), 1, f) != 1)
+ return 0;
+ p = XNEW (struct def_pragma_macro);
+ p->name = XNEWVAR (char, nlen + 1);
+ p->name[nlen] = 0;
+ if (fread (p->name, nlen, 1, f) != 1)
+ return 0;
+ /* Save old state. */
+ m = cpp_push_definition (r, p->name);
+ if (fread (&defnlen, sizeof (defnlen), 1, f) != 1)
+ return 0;
+ defn = XNEWVAR (uchar, defnlen + 2);
+ defn[defnlen] = '\n';
+ defn[defnlen + 1] = 0;
+
+ if (fread (defn, defnlen, 1, f) != 1)
+ return 0;
+ cpp_pop_definition (r, p->name, NULL);
+ {
+ size_t namelen;
+ uchar *dn;
+
+ namelen = ustrcspn (defn, "( \n");
+ h = cpp_lookup (r, defn, namelen);
+ dn = defn + namelen;
+
+ h->type = NT_VOID;
+ h->flags &= ~(NODE_POISONED|NODE_BUILTIN|NODE_DISABLED|NODE_USED);
+ if (cpp_push_buffer (r, dn, ustrchr (dn, '\n') - dn, true)
+ != NULL)
+ {
+ _cpp_clean_line (r);
+ if (!_cpp_create_definition (r, h))
+ abort ();
+ _cpp_pop_buffer (r);
+ }
+ else
+ abort ();
+ }
+ p->value = cpp_push_definition (r, p->name);
+
+ free (defn);
+ p->next = r->pushed_macros;
+ r->pushed_macros = p;
+ /* Restore current state. */
+ cpp_pop_definition (r, p->name, m);
+ }
+ return 1;
+}
+
+static int
+_cpp_save_pushed_macros (cpp_reader *r, FILE *f)
+{
+ size_t count_saved = 0;
+ size_t i;
+ struct def_pragma_macro *p,**pp;
+ cpp_hashnode *node;
+ cpp_macro *m;
+ size_t defnlen;
+ const uchar *defn;
+
+ /* Get count. */
+ p = r->pushed_macros;
+ while (p != NULL)
+ {
+ count_saved++;
+ p = p->next;
+ }
+ if (fwrite (&count_saved, sizeof (count_saved), 1, f) != 1)
+ return 0;
+ if (!count_saved)
+ return 1;
+
+ pp = (struct def_pragma_macro **) alloca (sizeof (struct def_pragma_macro *)
+ * count_saved);
+ /* Store them in reverse order. */
+ p = r->pushed_macros;
+ i = count_saved;
+ while (p != NULL)
+ {
+ --i;
+ pp[i] = p;
+ p = p->next;
+ }
+ for (i = 0; i < count_saved; i++)
+ {
+ /* Save old state. */
+ m = cpp_push_definition (r, pp[i]->name);
+ /* Set temporary macro name to saved state. */
+ cpp_pop_definition (r, pp[i]->name, pp[i]->value);
+ node = _cpp_lex_identifier (r, pp[i]->name);
+ defnlen = strlen (pp[i]->name);
+ if (fwrite (&defnlen, sizeof (size_t), 1, f) != 1
+ || fwrite (pp[i]->name, defnlen, 1, f) != 1)
+ return 0;
+ defn = cpp_macro_definition (r, node);
+ defnlen = ustrlen (defn);
+ if (fwrite (&defnlen, sizeof (size_t), 1, f) != 1
+ || fwrite (defn, defnlen, 1, f) != 1)
+ return 0;
+ /* Restore current state. */
+ cpp_pop_definition (r, pp[i]->name, m);
+ }
+ return 1;
+}
+
/* Data structure to transform hash table nodes into a sorted list */
|| h->flags & NODE_POISONED)
{
if (CPP_OPTION (r, warn_invalid_pch))
- cpp_error (r, CPP_DL_WARNING_SYSHDR,
- "%s: not used because `%.*s' is poisoned",
- name, m.name_length, namebuf);
+ cpp_warning_syshdr (r, CPP_W_INVALID_PCH,
+ "%s: not used because `%.*s' is poisoned",
+ name, m.name_length, namebuf);
goto fail;
}
continue;
if (CPP_OPTION (r, warn_invalid_pch))
- cpp_error (r, CPP_DL_WARNING_SYSHDR,
- "%s: not used because `%.*s' not defined",
- name, m.name_length, namebuf);
+ cpp_warning_syshdr (r, CPP_W_INVALID_PCH,
+ "%s: not used because `%.*s' not defined",
+ name, m.name_length, namebuf);
goto fail;
}
|| memcmp (namebuf, newdefn, m.definition_length) != 0)
{
if (CPP_OPTION (r, warn_invalid_pch))
- cpp_error (r, CPP_DL_WARNING_SYSHDR,
+ cpp_warning_syshdr (r, CPP_W_INVALID_PCH,
"%s: not used because `%.*s' defined as `%s' not `%.*s'",
name, m.name_length, namebuf, newdefn + m.name_length,
m.definition_length - m.name_length,
else
{
if (CPP_OPTION (r, warn_invalid_pch))
- cpp_error (r, CPP_DL_WARNING_SYSHDR,
- "%s: not used because `%s' is defined",
- name, first);
+ cpp_warning_syshdr (r, CPP_W_INVALID_PCH,
+ "%s: not used because `%s' is defined",
+ name, first);
goto fail;
}
}
if (counter && r->counter)
{
if (CPP_OPTION (r, warn_invalid_pch))
- cpp_error (r, CPP_DL_WARNING_SYSHDR,
- "%s: not used because `__COUNTER__' is invalid",
- name);
+ cpp_warning_syshdr (r, CPP_W_INVALID_PCH,
+ "%s: not used because `__COUNTER__' is invalid",
+ name);
goto fail;
}
if (!r->counter)
r->counter = counter;
+ /* Read pushed macros. */
+ if (! _cpp_restore_pushed_macros (r, f))
+ goto error;
return 0;
error: