00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "config.h"
00020 #include "system.h"
00021 #include "cpplib.h"
00022 #include "internal.h"
00023 #include "hashtab.h"
00024 #include "mkdeps.h"
00025
00026 static int write_macdef (cpp_reader *, cpp_hashnode *, void *);
00027 static int save_idents (cpp_reader *, cpp_hashnode *, void *);
00028 static hashval_t hashmem (const void *, size_t);
00029 static hashval_t cpp_string_hash (const void *);
00030 static int cpp_string_eq (const void *, const void *);
00031 static int count_defs (cpp_reader *, cpp_hashnode *, void *);
00032 static int comp_hashnodes (const void *, const void *);
00033 static int collect_ht_nodes (cpp_reader *, cpp_hashnode *, void *);
00034 static int write_defs (cpp_reader *, cpp_hashnode *, void *);
00035 static int save_macros (cpp_reader *, cpp_hashnode *, void *);
00036
00037
00038 struct macrodef_struct
00039 {
00040 unsigned int definition_length;
00041 unsigned short name_length;
00042 unsigned short flags;
00043 };
00044
00045
00046
00047
00048 static int
00049 write_macdef (cpp_reader *pfile, cpp_hashnode *hn, void *file_p)
00050 {
00051 FILE *f = (FILE *) file_p;
00052 switch (hn->type)
00053 {
00054 case NT_VOID:
00055 if (! (hn->flags & NODE_POISONED))
00056 return 1;
00057
00058 case NT_MACRO:
00059 if ((hn->flags & NODE_BUILTIN))
00060 return 1;
00061
00062 {
00063 struct macrodef_struct s;
00064 const unsigned char *defn;
00065
00066 s.name_length = NODE_LEN (hn);
00067 s.flags = hn->flags & NODE_POISONED;
00068
00069 if (hn->type == NT_MACRO)
00070 {
00071 defn = cpp_macro_definition (pfile, hn);
00072 s.definition_length = ustrlen (defn);
00073 }
00074 else
00075 {
00076 defn = NODE_NAME (hn);
00077 s.definition_length = s.name_length;
00078 }
00079
00080 if (fwrite (&s, sizeof (s), 1, f) != 1
00081 || fwrite (defn, 1, s.definition_length, f) != s.definition_length)
00082 {
00083 cpp_errno (pfile, CPP_DL_ERROR,
00084 "while writing precompiled header");
00085 return 0;
00086 }
00087 }
00088 return 1;
00089
00090 case NT_ASSERTION:
00091
00092 return 1;
00093
00094 default:
00095 abort ();
00096 }
00097 }
00098
00099
00100
00101
00102
00103 struct cpp_savedstate
00104 {
00105
00106 htab_t definedhash;
00107
00108
00109 size_t hashsize;
00110
00111 size_t n_defs;
00112
00113 cpp_hashnode **defs;
00114
00115
00116 unsigned char *definedstrs;
00117 };
00118
00119
00120
00121
00122 static int
00123 save_idents (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *hn, void *ss_p)
00124 {
00125 struct cpp_savedstate *const ss = (struct cpp_savedstate *)ss_p;
00126
00127 if (hn->type != NT_VOID)
00128 {
00129 struct cpp_string news;
00130 void **slot;
00131
00132 news.len = NODE_LEN (hn);
00133 news.text= NODE_NAME (hn);
00134 slot = htab_find_slot (ss->definedhash, &news, INSERT);
00135 if (*slot == NULL)
00136 {
00137 struct cpp_string *sp;
00138 unsigned char *text;
00139
00140 sp = xmalloc (sizeof (struct cpp_string));
00141 *slot = sp;
00142
00143 sp->len = NODE_LEN (hn);
00144 sp->text = text = xmalloc (NODE_LEN (hn));
00145 memcpy (text, NODE_NAME (hn), NODE_LEN (hn));
00146 }
00147 }
00148
00149 return 1;
00150 }
00151
00152
00153
00154 static hashval_t
00155 hashmem (const void *p_p, size_t sz)
00156 {
00157 const unsigned char *p = (const unsigned char *)p_p;
00158 size_t i;
00159 hashval_t h;
00160
00161 h = 0;
00162 for (i = 0; i < sz; i++)
00163 h = h * 67 - (*p++ - 113);
00164 return h;
00165 }
00166
00167
00168
00169 static hashval_t
00170 cpp_string_hash (const void *a_p)
00171 {
00172 const struct cpp_string *a = (const struct cpp_string *) a_p;
00173 return hashmem (a->text, a->len);
00174 }
00175
00176
00177
00178 static int
00179 cpp_string_eq (const void *a_p, const void *b_p)
00180 {
00181 const struct cpp_string *a = (const struct cpp_string *) a_p;
00182 const struct cpp_string *b = (const struct cpp_string *) b_p;
00183 return (a->len == b->len
00184 && memcmp (a->text, b->text, a->len) == 0);
00185 }
00186
00187
00188
00189
00190
00191
00192 int
00193 cpp_save_state (cpp_reader *r, FILE *f)
00194 {
00195
00196 r->savedstate = xmalloc (sizeof (struct cpp_savedstate));
00197 r->savedstate->definedhash = htab_create (100, cpp_string_hash,
00198 cpp_string_eq, NULL);
00199 cpp_forall_identifiers (r, save_idents, r->savedstate);
00200
00201
00202 cpp_forall_identifiers (r, write_macdef, f);
00203
00204 return 0;
00205 }
00206
00207
00208
00209 static int
00210 count_defs (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *hn, void *ss_p)
00211 {
00212 struct cpp_savedstate *const ss = (struct cpp_savedstate *)ss_p;
00213
00214 switch (hn->type)
00215 {
00216 case NT_MACRO:
00217 if (hn->flags & NODE_BUILTIN)
00218 return 1;
00219
00220
00221
00222 case NT_VOID:
00223 {
00224 struct cpp_string news;
00225 void **slot;
00226
00227 news.len = NODE_LEN (hn);
00228 news.text = NODE_NAME (hn);
00229 slot = htab_find (ss->definedhash, &news);
00230 if (slot == NULL)
00231 {
00232 ss->hashsize += NODE_LEN (hn) + 1;
00233 ss->n_defs += 1;
00234 }
00235 }
00236 return 1;
00237
00238 case NT_ASSERTION:
00239
00240 return 1;
00241
00242 default:
00243 abort ();
00244 }
00245 }
00246
00247
00248 static int
00249 write_defs (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *hn, void *ss_p)
00250 {
00251 struct cpp_savedstate *const ss = (struct cpp_savedstate *)ss_p;
00252
00253 switch (hn->type)
00254 {
00255 case NT_MACRO:
00256 if (hn->flags & NODE_BUILTIN)
00257 return 1;
00258
00259
00260
00261 case NT_VOID:
00262 {
00263 struct cpp_string news;
00264 void **slot;
00265
00266 news.len = NODE_LEN (hn);
00267 news.text = NODE_NAME (hn);
00268 slot = htab_find (ss->definedhash, &news);
00269 if (slot == NULL)
00270 {
00271 ss->defs[ss->n_defs] = hn;
00272 ss->n_defs += 1;
00273 }
00274 }
00275 return 1;
00276
00277 case NT_ASSERTION:
00278
00279 return 1;
00280
00281 default:
00282 abort ();
00283 }
00284 }
00285
00286
00287
00288 static int
00289 comp_hashnodes (const void *px, const void *py)
00290 {
00291 cpp_hashnode *x = *(cpp_hashnode **) px;
00292 cpp_hashnode *y = *(cpp_hashnode **) py;
00293 return ustrcmp (NODE_NAME (x), NODE_NAME (y));
00294 }
00295
00296
00297
00298
00299 int
00300 cpp_write_pch_deps (cpp_reader *r, FILE *f)
00301 {
00302 struct macrodef_struct z;
00303 struct cpp_savedstate *const ss = r->savedstate;
00304 unsigned char *definedstrs;
00305 size_t i;
00306
00307
00308
00309 ss->hashsize = 0;
00310 ss->n_defs = 0;
00311 cpp_forall_identifiers (r, count_defs, ss);
00312
00313 ss->defs = xmalloc (ss->n_defs * sizeof (cpp_hashnode *));
00314 ss->n_defs = 0;
00315 cpp_forall_identifiers (r, write_defs, ss);
00316
00317
00318 qsort (ss->defs, ss->n_defs, sizeof (cpp_hashnode *), &comp_hashnodes);
00319 definedstrs = ss->definedstrs = xmalloc (ss->hashsize);
00320 for (i = 0; i < ss->n_defs; ++i)
00321 {
00322 size_t len = NODE_LEN (ss->defs[i]);
00323 memcpy (definedstrs, NODE_NAME (ss->defs[i]), len + 1);
00324 definedstrs += len + 1;
00325 }
00326
00327 memset (&z, 0, sizeof (z));
00328 z.definition_length = ss->hashsize;
00329 if (fwrite (&z, sizeof (z), 1, f) != 1
00330 || fwrite (ss->definedstrs, ss->hashsize, 1, f) != 1)
00331 {
00332 cpp_errno (r, CPP_DL_ERROR, "while writing precompiled header");
00333 return -1;
00334 }
00335 free (ss->definedstrs);
00336
00337
00338 free (ss);
00339 r->savedstate = NULL;
00340 return 0;
00341 }
00342
00343
00344
00345
00346 int
00347 cpp_write_pch_state (cpp_reader *r, FILE *f)
00348 {
00349 if (!r->deps)
00350 r->deps = deps_init ();
00351
00352 if (deps_save (r->deps, f) != 0)
00353 {
00354 cpp_errno (r, CPP_DL_ERROR, "while writing precompiled header");
00355 return -1;
00356 }
00357
00358 if (! _cpp_save_file_entries (r, f))
00359 {
00360 cpp_errno (r, CPP_DL_ERROR, "while writing precompiled header");
00361 return -1;
00362 }
00363
00364 return 0;
00365 }
00366
00367
00368
00369
00370 struct ht_node_list
00371 {
00372
00373 cpp_hashnode **defs;
00374
00375 size_t n_defs;
00376
00377 size_t asize;
00378 };
00379
00380
00381
00382 static int
00383 collect_ht_nodes (cpp_reader *pfile ATTRIBUTE_UNUSED, cpp_hashnode *hn,
00384 void *nl_p)
00385 {
00386 struct ht_node_list *const nl = (struct ht_node_list *)nl_p;
00387
00388 if (hn->type != NT_VOID || hn->flags & NODE_POISONED)
00389 {
00390 if (nl->n_defs == nl->asize)
00391 {
00392 nl->asize *= 2;
00393 nl->defs = xrealloc (nl->defs, nl->asize * sizeof (cpp_hashnode *));
00394 }
00395
00396 nl->defs[nl->n_defs] = hn;
00397 ++nl->n_defs;
00398 }
00399 return 1;
00400 }
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416 int
00417 cpp_valid_state (cpp_reader *r, const char *name, int fd)
00418 {
00419 struct macrodef_struct m;
00420 size_t namebufsz = 256;
00421 unsigned char *namebuf = xmalloc (namebufsz);
00422 unsigned char *undeftab = NULL;
00423 struct ht_node_list nl = { 0, 0, 0 };
00424 unsigned char *first, *last;
00425 unsigned int i;
00426
00427
00428
00429 for (;;)
00430 {
00431 cpp_hashnode *h;
00432 const unsigned char *newdefn;
00433
00434 if (read (fd, &m, sizeof (m)) != sizeof (m))
00435 goto error;
00436
00437 if (m.name_length == 0)
00438 break;
00439
00440
00441
00442 if (CPP_OPTION (r, preprocessed))
00443 {
00444 if (lseek (fd, m.definition_length, SEEK_CUR) == -1)
00445 goto error;
00446 continue;
00447 }
00448
00449 if (m.definition_length > namebufsz)
00450 {
00451 free (namebuf);
00452 namebufsz = m.definition_length + 256;
00453 namebuf = xmalloc (namebufsz);
00454 }
00455
00456 if ((size_t)read (fd, namebuf, m.definition_length)
00457 != m.definition_length)
00458 goto error;
00459
00460 h = cpp_lookup (r, namebuf, m.name_length);
00461 if (m.flags & NODE_POISONED
00462 || h->type != NT_MACRO
00463 || h->flags & NODE_POISONED)
00464 {
00465 if (CPP_OPTION (r, warn_invalid_pch))
00466 cpp_error (r, CPP_DL_WARNING_SYSHDR,
00467 "%s: not used because `%.*s' not defined",
00468 name, m.name_length, namebuf);
00469 goto fail;
00470 }
00471
00472 newdefn = cpp_macro_definition (r, h);
00473
00474 if (m.definition_length != ustrlen (newdefn)
00475 || memcmp (namebuf, newdefn, m.definition_length) != 0)
00476 {
00477 if (CPP_OPTION (r, warn_invalid_pch))
00478 cpp_error (r, CPP_DL_WARNING_SYSHDR,
00479 "%s: not used because `%.*s' defined as `%s' not `%.*s'",
00480 name, m.name_length, namebuf, newdefn + m.name_length,
00481 m.definition_length - m.name_length,
00482 namebuf + m.name_length);
00483 goto fail;
00484 }
00485 }
00486 free (namebuf);
00487 namebuf = NULL;
00488
00489
00490
00491 undeftab = xmalloc (m.definition_length);
00492 if ((size_t) read (fd, undeftab, m.definition_length) != m.definition_length)
00493 goto error;
00494
00495
00496 nl.n_defs = 0;
00497 nl.asize = 10;
00498 nl.defs = xmalloc (nl.asize * sizeof (cpp_hashnode *));
00499 cpp_forall_identifiers (r, &collect_ht_nodes, &nl);
00500 qsort (nl.defs, nl.n_defs, sizeof (cpp_hashnode *), &comp_hashnodes);
00501
00502
00503
00504 first = undeftab;
00505 last = undeftab + m.definition_length;
00506 i = 0;
00507
00508 while (first < last && i < nl.n_defs)
00509 {
00510 int cmp = ustrcmp (first, NODE_NAME (nl.defs[i]));
00511
00512 if (cmp < 0)
00513 first += ustrlen (first) + 1;
00514 else if (cmp > 0)
00515 ++i;
00516 else
00517 {
00518 if (CPP_OPTION (r, warn_invalid_pch))
00519 cpp_error (r, CPP_DL_WARNING_SYSHDR,
00520 "%s: not used because `%s' is defined",
00521 name, first);
00522 goto fail;
00523 }
00524 }
00525
00526 free(nl.defs);
00527 free (undeftab);
00528
00529
00530 return 0;
00531
00532 error:
00533 cpp_errno (r, CPP_DL_ERROR, "while reading precompiled header");
00534 return -1;
00535
00536 fail:
00537 if (namebuf != NULL)
00538 free (namebuf);
00539 if (undeftab != NULL)
00540 free (undeftab);
00541 if (nl.defs != NULL)
00542 free (nl.defs);
00543 return 1;
00544 }
00545
00546
00547
00548 struct save_macro_data
00549 {
00550 uchar **defns;
00551 size_t count;
00552 size_t array_size;
00553 char **saved_pragmas;
00554 };
00555
00556
00557
00558
00559
00560
00561
00562
00563
00564
00565
00566
00567
00568
00569
00570 static int
00571 save_macros (cpp_reader *r, cpp_hashnode *h, void *data_p)
00572 {
00573 struct save_macro_data *data = (struct save_macro_data *)data_p;
00574 if (h->type != NT_VOID
00575 && (h->flags & NODE_BUILTIN) == 0)
00576 {
00577 if (data->count == data->array_size)
00578 {
00579 data->array_size *= 2;
00580 data->defns = xrealloc (data->defns, (data->array_size
00581 * sizeof (uchar *)));
00582 }
00583
00584 switch (h->type)
00585 {
00586 case NT_ASSERTION:
00587
00588 return 1;
00589
00590 case NT_MACRO:
00591 {
00592 const uchar * defn = cpp_macro_definition (r, h);
00593 size_t defnlen = ustrlen (defn);
00594
00595 data->defns[data->count] = xmemdup (defn, defnlen, defnlen + 2);
00596 data->defns[data->count][defnlen] = '\n';
00597 }
00598 break;
00599
00600 default:
00601 abort ();
00602 }
00603 data->count++;
00604 }
00605 return 1;
00606 }
00607
00608
00609
00610
00611 void
00612 cpp_prepare_state (cpp_reader *r, struct save_macro_data **data)
00613 {
00614 struct save_macro_data *d = xmalloc (sizeof (struct save_macro_data));
00615
00616 d->array_size = 512;
00617 d->defns = xmalloc (d->array_size * sizeof (d->defns[0]));
00618 d->count = 0;
00619 cpp_forall_identifiers (r, save_macros, d);
00620 d->saved_pragmas = _cpp_save_pragma_names (r);
00621 *data = d;
00622 }
00623
00624
00625
00626
00627
00628 int
00629 cpp_read_state (cpp_reader *r, const char *name, FILE *f,
00630 struct save_macro_data *data)
00631 {
00632 size_t i;
00633 struct lexer_state old_state;
00634
00635
00636
00637 {
00638 struct spec_nodes *s = &r->spec_nodes;
00639 s->n_defined = cpp_lookup (r, DSC("defined"));
00640 s->n_true = cpp_lookup (r, DSC("true"));
00641 s->n_false = cpp_lookup (r, DSC("false"));
00642 s->n__VA_ARGS__ = cpp_lookup (r, DSC("__VA_ARGS__"));
00643 }
00644
00645 old_state = r->state;
00646 r->state.in_directive = 1;
00647 r->state.prevent_expansion = 1;
00648 r->state.angled_headers = 0;
00649
00650
00651 for (i = 0; i < data->count; i++)
00652 {
00653 cpp_hashnode *h;
00654 size_t namelen;
00655 uchar *defn;
00656
00657 namelen = ustrcspn (data->defns[i], "( \n");
00658 h = cpp_lookup (r, data->defns[i], namelen);
00659 defn = data->defns[i] + namelen;
00660
00661
00662
00663
00664 if (h->type == NT_VOID)
00665 {
00666 if (cpp_push_buffer (r, defn, ustrchr (defn, '\n') - defn, true)
00667 != NULL)
00668 {
00669 _cpp_clean_line (r);
00670 if (!_cpp_create_definition (r, h))
00671 abort ();
00672 _cpp_pop_buffer (r);
00673 }
00674 else
00675 abort ();
00676 }
00677
00678 free (data->defns[i]);
00679 }
00680 r->state = old_state;
00681
00682 _cpp_restore_pragma_names (r, data->saved_pragmas);
00683
00684 free (data);
00685
00686 if (deps_restore (r->deps, f, CPP_OPTION (r, restore_pch_deps) ? name : NULL)
00687 != 0)
00688 goto error;
00689
00690 if (! _cpp_read_file_entries (r, f))
00691 goto error;
00692
00693 return 0;
00694
00695 error:
00696 cpp_errno (r, CPP_DL_ERROR, "while reading precompiled header");
00697 return -1;
00698 }