00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032 #include "proj.h"
00033 #include "where.h"
00034 #include "lex.h"
00035 #include "malloc.h"
00036 #include "ggc.h"
00037
00038
00039
00040 struct _ffewhere_line_ ffewhere_unknown_line_
00041 =
00042 {NULL, NULL, 0, 0, 0, {0}};
00043
00044
00045
00046
00047
00048
00049 typedef struct _ffewhere_ll_ *ffewhereLL_;
00050
00051
00052
00053
00054
00055
00056 struct _ffewhere_ll_
00057 {
00058 ffewhereLL_ next;
00059 ffewhereLL_ previous;
00060 ffewhereFile wf;
00061 ffewhereLineNumber line_no;
00062 ffewhereLineNumber offset;
00063 };
00064
00065 struct _ffewhere_root_ll_
00066 {
00067 ffewhereLL_ first;
00068 ffewhereLL_ last;
00069 };
00070
00071 struct _ffewhere_root_line_
00072 {
00073 ffewhereLine first;
00074 ffewhereLine last;
00075 ffewhereLineNumber none;
00076 };
00077
00078
00079
00080 static struct _ffewhere_root_ll_ ffewhere_root_ll_;
00081 static struct _ffewhere_root_line_ ffewhere_root_line_;
00082
00083
00084
00085 static ffewhereLL_ ffewhere_ll_lookup_ (ffewhereLineNumber ln);
00086
00087
00088
00089
00090
00091
00092 static ffewhereLL_
00093 ffewhere_ll_lookup_ (ffewhereLineNumber ln)
00094 {
00095 ffewhereLL_ ll;
00096
00097 if (ln == 0)
00098 return ffewhere_root_ll_.first;
00099
00100 for (ll = ffewhere_root_ll_.last;
00101 ll != (ffewhereLL_) &ffewhere_root_ll_.first;
00102 ll = ll->previous)
00103 {
00104 if (ll->line_no <= ln)
00105 return ll;
00106 }
00107
00108 assert ("no line num" == NULL);
00109 return NULL;
00110 }
00111
00112
00113
00114 #define NUM_FFEWHERE_HEAD_FILES 31
00115 static struct ffewhere_ggc_tracker
00116 {
00117 struct ffewhere_ggc_tracker *next;
00118 ffewhereFile files[NUM_FFEWHERE_HEAD_FILES];
00119 } *ffewhere_head = NULL;
00120
00121 static void
00122 mark_ffewhere_head (void *arg)
00123 {
00124 struct ffewhere_ggc_tracker *head;
00125 int i;
00126
00127 for (head = * (struct ffewhere_ggc_tracker **) arg;
00128 head != NULL;
00129 head = head->next)
00130 {
00131 ggc_mark (head);
00132 for (i = 0; i < NUM_FFEWHERE_HEAD_FILES; i++)
00133 ggc_mark (head->files[i]);
00134 }
00135 }
00136
00137
00138
00139
00140
00141
00142
00143
00144 void
00145 ffewhere_file_kill (ffewhereFile wf)
00146 {
00147 struct ffewhere_ggc_tracker *head;
00148 int i;
00149
00150 for (head = ffewhere_head; head != NULL; head = head->next)
00151 for (i = 0; i < NUM_FFEWHERE_HEAD_FILES; i++)
00152 if (head->files[i] == wf)
00153 {
00154 head->files[i] = NULL;
00155 return;
00156 }
00157
00158 abort();
00159 }
00160
00161
00162
00163 ffewhereFile
00164 ffewhere_file_new (const char *name, size_t length)
00165 {
00166 ffewhereFile wf;
00167 int filepos;
00168
00169 wf = ggc_alloc (offsetof (struct _ffewhere_file_, text)
00170 + length + 1);
00171 wf->length = length;
00172 memcpy (&wf->text[0], name, length);
00173 wf->text[length] = '\0';
00174
00175 if (ffewhere_head == NULL)
00176 {
00177 ggc_add_root (&ffewhere_head, 1, sizeof ffewhere_head,
00178 mark_ffewhere_head);
00179 filepos = NUM_FFEWHERE_HEAD_FILES;
00180 }
00181 else
00182 {
00183 for (filepos = 0; filepos < NUM_FFEWHERE_HEAD_FILES; filepos++)
00184 if (ffewhere_head->files[filepos] == NULL)
00185 {
00186 ffewhere_head->files[filepos] = wf;
00187 break;
00188 }
00189 }
00190 if (filepos == NUM_FFEWHERE_HEAD_FILES)
00191 {
00192
00193 struct ffewhere_ggc_tracker *old_head = ffewhere_head;
00194 int i;
00195
00196 ffewhere_head = ggc_alloc (sizeof (*ffewhere_head));
00197 ffewhere_head->next = old_head;
00198 ffewhere_head->files[0] = wf;
00199 for (i = 1; i < NUM_FFEWHERE_HEAD_FILES; i++)
00200 ffewhere_head->files[i] = NULL;
00201 }
00202
00203 return wf;
00204 }
00205
00206
00207
00208
00209
00210 void
00211 ffewhere_file_set (ffewhereFile wf, bool have_num, ffewhereLineNumber ln)
00212 {
00213 ffewhereLL_ ll;
00214
00215 ll = malloc_new_kp (ffe_pool_file (), "ffewhereLL_", sizeof (*ll));
00216 ll->next = (ffewhereLL_) &ffewhere_root_ll_.first;
00217 ll->previous = ffewhere_root_ll_.last;
00218 ll->next->previous = ll;
00219 ll->previous->next = ll;
00220 if (wf == NULL)
00221 {
00222 if (ll->previous == ll->next)
00223 ll->wf = NULL;
00224 else
00225 ll->wf = ll->previous->wf;
00226 }
00227 else
00228 ll->wf = wf;
00229 ll->line_no = ffelex_line_number ();
00230 if (have_num)
00231 ll->offset = ln;
00232 else
00233 {
00234 if (ll->previous == ll->next)
00235 ll->offset = 1;
00236 else
00237 ll->offset
00238 = ll->line_no - ll->previous->line_no + ll->previous->offset;
00239 }
00240 }
00241
00242
00243
00244 void
00245 ffewhere_init_1 ()
00246 {
00247 ffewhere_root_line_.first = ffewhere_root_line_.last
00248 = (ffewhereLine) &ffewhere_root_line_.first;
00249 ffewhere_root_line_.none = 0;
00250
00251 ffewhere_root_ll_.first = ffewhere_root_ll_.last
00252 = (ffewhereLL_) &ffewhere_root_ll_.first;
00253 }
00254
00255
00256
00257 char *
00258 ffewhere_line_content (ffewhereLine wl)
00259 {
00260 assert (wl != NULL);
00261 return wl->content;
00262 }
00263
00264
00265
00266 ffewhereFile
00267 ffewhere_line_file (ffewhereLine wl)
00268 {
00269 ffewhereLL_ ll;
00270
00271 assert (wl != NULL);
00272 ll = ffewhere_ll_lookup_ (wl->line_num);
00273 return ll->wf;
00274 }
00275
00276
00277
00278 ffewhereLineNumber
00279 ffewhere_line_filelinenum (ffewhereLine wl)
00280 {
00281 ffewhereLL_ ll;
00282
00283 assert (wl != NULL);
00284 ll = ffewhere_ll_lookup_ (wl->line_num);
00285 return wl->line_num + ll->offset - ll->line_no;
00286 }
00287
00288
00289
00290 void
00291 ffewhere_line_kill (ffewhereLine wl)
00292 {
00293 #if 0
00294 if (!ffewhere_line_is_unknown (wl))
00295 fprintf (dmpout, "; ffewhere_line_kill %" ffewhereLineNumber_f "u, uses=%"
00296 ffewhereUses_f_ "u\n",
00297 wl->line_num, wl->uses);
00298 #endif
00299 assert (ffewhere_line_is_unknown (wl) || (wl->uses != 0));
00300 if (!ffewhere_line_is_unknown (wl) && (--wl->uses == 0))
00301 {
00302 wl->previous->next = wl->next;
00303 wl->next->previous = wl->previous;
00304 malloc_kill_ks (ffe_pool_file (), wl,
00305 offsetof (struct _ffewhere_line_, content)
00306 + wl->length + 1);
00307 }
00308 }
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318 ffewhereLine
00319 ffewhere_line_new (ffewhereLineNumber ln)
00320 {
00321 ffewhereLine wl = ffewhere_root_line_.last;
00322
00323
00324
00325
00326 if (((ln == 0)
00327 || (wl->line_num != ln))
00328 && (ffelex_line_number () == ln))
00329 {
00330 #if 0
00331 fprintf (dmpout,
00332 "; ffewhere_line_new %" ffewhereLineNumber_f "u, lexer\n",
00333 ln);
00334 #endif
00335 wl = malloc_new_ks (ffe_pool_file (), "FFEWHERE line",
00336 offsetof (struct _ffewhere_line_, content)
00337 + (size_t) ffelex_line_length () + 1);
00338 wl->next = (ffewhereLine) &ffewhere_root_line_;
00339 wl->previous = ffewhere_root_line_.last;
00340 wl->previous->next = wl;
00341 wl->next->previous = wl;
00342 wl->line_num = ln;
00343 wl->uses = 1;
00344 wl->length = ffelex_line_length ();
00345 strcpy (wl->content, ffelex_line ());
00346 return wl;
00347 }
00348
00349
00350
00351 while (wl->line_num > ln)
00352 wl = wl->previous;
00353
00354
00355
00356 if (wl->line_num == ln)
00357 {
00358 #if 0
00359 fprintf (dmpout, "; ffewhere_line_new %" ffewhereLineNumber_f "u, uses=%"
00360 ffewhereUses_f_ "u\n", ln,
00361 wl->uses);
00362 #endif
00363 wl->uses++;
00364 return wl;
00365 }
00366
00367
00368
00369
00370 fprintf (stderr,
00371 "(Cannot resurrect line %lu for error reporting purposes.)\n",
00372 ln);
00373
00374 wl = malloc_new_ks (ffe_pool_file (), "FFEWHERE line",
00375 offsetof (struct _ffewhere_line_, content)
00376 + 1);
00377 wl->next = (ffewhereLine) &ffewhere_root_line_;
00378 wl->previous = ffewhere_root_line_.last;
00379 wl->previous->next = wl;
00380 wl->next->previous = wl;
00381 wl->line_num = ln;
00382 wl->uses = 1;
00383 wl->length = 0;
00384 *(wl->content) = '\0';
00385 return wl;
00386 }
00387
00388
00389
00390 ffewhereLine
00391 ffewhere_line_use (ffewhereLine wl)
00392 {
00393 #if 0
00394 fprintf (dmpout, "; ffewhere_line_use %" ffewhereLineNumber_f "u, uses=%" ffewhereUses_f_
00395 "u\n", wl->line_num, wl->uses);
00396 #endif
00397 assert (ffewhere_line_is_unknown (wl) || (wl->uses != 0));
00398 if (!ffewhere_line_is_unknown (wl))
00399 ++wl->uses;
00400 return wl;
00401 }
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411 void
00412 ffewhere_set_from_track (ffewhereLine *wol, ffewhereColumn *woc,
00413 ffewhereLine wrl, ffewhereColumn wrc,
00414 ffewhereTrack wt, ffewhereIndex i)
00415 {
00416 ffewhereLineNumber ln;
00417 ffewhereColumnNumber cn;
00418 ffewhereIndex j;
00419 ffewhereIndex k;
00420
00421 if ((i == 0) || (i >= FFEWHERE_indexMAX))
00422 {
00423 *wol = ffewhere_line_use (wrl);
00424 *woc = ffewhere_column_use (wrc);
00425 }
00426 else
00427 {
00428 ln = ffewhere_line_number (wrl);
00429 cn = ffewhere_column_number (wrc);
00430 for (j = 0, k = 0; j < i; ++j, k += 2)
00431 {
00432 if ((wt[k] == FFEWHERE_indexUNKNOWN)
00433 || (wt[k + 1] == FFEWHERE_indexUNKNOWN))
00434 {
00435 *wol = ffewhere_line_unknown ();
00436 *woc = ffewhere_column_unknown ();
00437 return;
00438 }
00439 if (wt[k] == 0)
00440 cn += wt[k + 1] + 1;
00441 else
00442 {
00443 ln += wt[k];
00444 cn = wt[k + 1] + 1;
00445 }
00446 }
00447 if (ln == ffewhere_line_number (wrl))
00448 {
00449
00450 *wol = ffewhere_line_use (wrl);
00451 }
00452 else
00453 *wol = ffewhere_line_new (ln);
00454 *woc = ffewhere_column_new (cn);
00455 }
00456 }
00457
00458
00459
00460
00461
00462
00463
00464 void
00465 ffewhere_track (ffewhereLine *wl, ffewhereColumn *wc, ffewhereTrack wt,
00466 ffewhereIndex i, ffewhereLineNumber ln,
00467 ffewhereColumnNumber cn)
00468 {
00469 unsigned int lo;
00470 unsigned int co;
00471
00472 if ((ffewhere_line_is_unknown (*wl))
00473 || (ffewhere_column_is_unknown (*wc))
00474 || ((lo = ln - ffewhere_line_number (*wl)) >= FFEWHERE_indexUNKNOWN))
00475 {
00476 wt[i * 2 - 2] = wt[i * 2 - 1] = FFEWHERE_indexUNKNOWN;
00477 ffewhere_line_kill (*wl);
00478 ffewhere_column_kill (*wc);
00479 *wl = FFEWHERE_lineUNKNOWN;
00480 *wc = FFEWHERE_columnUNKNOWN;
00481 }
00482 else if (lo == 0)
00483 {
00484 wt[i * 2 - 2] = 0;
00485 if ((co = cn - ffewhere_column_number (*wc)) > FFEWHERE_indexUNKNOWN)
00486 {
00487 wt[i * 2 - 1] = FFEWHERE_indexUNKNOWN;
00488 ffewhere_line_kill (*wl);
00489 ffewhere_column_kill (*wc);
00490 *wl = FFEWHERE_lineUNKNOWN;
00491 *wc = FFEWHERE_columnUNKNOWN;
00492 }
00493 else
00494 {
00495 wt[i * 2 - 1] = co - 1;
00496 ffewhere_column_kill (*wc);
00497 *wc = ffewhere_column_use (ffewhere_column_new (cn));
00498 }
00499 }
00500 else
00501 {
00502 wt[i * 2 - 2] = lo;
00503 if (cn > FFEWHERE_indexUNKNOWN)
00504 {
00505 wt[i * 2 - 1] = FFEWHERE_indexUNKNOWN;
00506 ffewhere_line_kill (*wl);
00507 ffewhere_column_kill (*wc);
00508 *wl = ffewhere_line_unknown ();
00509 *wc = ffewhere_column_unknown ();
00510 }
00511 else
00512 {
00513 wt[i * 2 - 1] = cn - 1;
00514 ffewhere_line_kill (*wl);
00515 ffewhere_column_kill (*wc);
00516 *wl = ffewhere_line_use (ffewhere_line_new (ln));
00517 *wc = ffewhere_column_use (ffewhere_column_new (cn));
00518 }
00519 }
00520 }
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530 void
00531 ffewhere_track_clear (ffewhereTrack wt, ffewhereIndex length)
00532 {
00533 ffewhereIndex i;
00534
00535 if (length > FFEWHERE_indexMAX)
00536 length = FFEWHERE_indexMAX;
00537
00538 for (i = 1; i < length; ++i)
00539 wt[i * 2 - 2] = wt[i * 2 - 1] = 0;
00540 }
00541
00542
00543
00544
00545
00546
00547
00548
00549 void
00550 ffewhere_track_copy (ffewhereTrack dwt, ffewhereTrack swt, ffewhereIndex start,
00551 ffewhereIndex length)
00552 {
00553 ffewhereIndex i;
00554 ffewhereIndex copy;
00555
00556 if (length > FFEWHERE_indexMAX)
00557 length = FFEWHERE_indexMAX;
00558
00559 if (length + start > FFEWHERE_indexMAX)
00560 copy = FFEWHERE_indexMAX - start;
00561 else
00562 copy = length;
00563
00564 for (i = 1; i < copy; ++i)
00565 {
00566 dwt[i * 2 - 2] = swt[(i + start) * 2 - 2];
00567 dwt[i * 2 - 1] = swt[(i + start) * 2 - 1];
00568 }
00569
00570 for (; i < length; ++i)
00571 {
00572 dwt[i * 2 - 2] = 0;
00573 dwt[i * 2 - 1] = 0;
00574 }
00575 }
00576
00577
00578
00579
00580
00581
00582 void
00583 ffewhere_track_kill (ffewhereLine wrl, ffewhereColumn wrc UNUSED,
00584 ffewhereTrack wt, ffewhereIndex length)
00585 {
00586 ffewhereLineNumber ln;
00587 unsigned int lo;
00588 ffewhereIndex i;
00589
00590 ln = ffewhere_line_number (wrl);
00591
00592 if (length > FFEWHERE_indexMAX)
00593 length = FFEWHERE_indexMAX;
00594
00595 for (i = 0; i < length - 1; ++i)
00596 {
00597 if ((lo = wt[i * 2]) == FFEWHERE_indexUNKNOWN)
00598 break;
00599 else if (lo != 0)
00600 {
00601 ln += lo;
00602 wrl = ffewhere_line_new (ln);
00603 ffewhere_line_kill (wrl);
00604 }
00605 }
00606 }