| @@ -0,0 +1,1230 @@ |
| | 1 | #include <stdio.h> |
| | 2 | #include <stdlib.h> |
| | 3 | #include <string.h> |
| | 4 | #ifndef WORGLITE |
| | 5 | #include <sqlite3.h> |
| | 6 | #endif |
| | 7 | #include "parg.h" |
| | 8 | #include "worgle.h" |
| | 9 | #include "worgle_private.h" |
| | 10 | #ifndef WORGLITE |
| | 11 | #include "db.h" |
| | 12 | #endif |
| | 13 | |
| | 14 | static int use_debug = 0; |
| | 15 | static int use_warnings = 0; |
| | 16 | static int map_source_code = 0; |
| | 17 | static char *map_filename = NULL; |
| | 18 | #ifndef WORGLITE |
| | 19 | static int generate_db = 0; |
| | 20 | static char *db_filename = NULL; |
| | 21 | #endif |
| | 22 | static int tangle_code = 1; |
| | 23 | enum { |
| | 24 | MODE_ORG, |
| | 25 | MODE_BEGINCODE, |
| | 26 | MODE_CODE |
| | 27 | }; |
| | 28 | enum { |
| | 29 | ORGLET_HEADER, |
| | 30 | ORGLET_CONTENT, |
| | 31 | ORGLET_BLKREF, |
| | 32 | ORGLET_UNKNOWN |
| | 33 | }; |
| | 34 | static int loadfile(worgle_d *worg, int file); |
| | 35 | static int parse_name(char *line, size_t len, worgle_string *str); |
| | 36 | #ifndef WORGLITE |
| | 37 | static int parse_header(worgle_d *worg, |
| | 38 | char *line, |
| | 39 | size_t len); |
| | 40 | #endif |
| | 41 | static int parse_begin(char *line, size_t len, worgle_string *str); |
| | 42 | static int check_for_reference(char *line , size_t size, worgle_string *str); |
| | 43 | static int worgle_getline(char *fullbuf, |
| | 44 | char **line, |
| | 45 | size_t *pos, |
| | 46 | size_t *line_size, |
| | 47 | size_t buf_size); |
| | 48 | static void append_filename(worgle_d *worg, char *filename); |
| | 49 | #ifndef WORGLITE |
| | 50 | static void tangle_to_db(worgle_d *worg); |
| | 51 | #endif |
| | 52 | static int loadfile(worgle_d *worg, int file) |
| | 53 | { |
| | 54 | FILE *fp; |
| | 55 | char *filename; |
| | 56 | worgle_textbuf *txt; |
| | 57 | size_t size; |
| | 58 | char *buf; |
| | 59 | txt = &worg->buffers[file]; |
| | 60 | filename = txt->filename.str; |
| | 61 | fp = fopen(filename, "r"); |
| | 62 | |
| | 63 | if(fp == NULL) { |
| | 64 | fprintf(stderr, "Could not find file %s\n", filename); |
| | 65 | return 1; |
| | 66 | } |
| | 67 | fseek(fp, 0, SEEK_END); |
| | 68 | size = ftell(fp); |
| | 69 | buf = calloc(1, size); |
| | 70 | worgle_textbuf_init(&worg->buffers[file], buf, size); |
| | 71 | fseek(fp, 0, SEEK_SET); |
| | 72 | fread(buf, size, 1, fp); |
| | 73 | fclose(fp); |
| | 74 | return 1; |
| | 75 | } |
| | 76 | int parse_file(worgle_d *worg, int file) |
| | 77 | { |
| | 78 | char *buf; |
| | 79 | size_t size; |
| | 80 | worgle_textbuf *curbuf; |
| | 81 | worgle_string str; |
| | 82 | char *line; |
| | 83 | size_t pos; |
| | 84 | size_t read; |
| | 85 | int mode; |
| | 86 | int rc; |
| | 87 | int status; |
| | 88 | |
| | 89 | curbuf = &worg->buffers[file]; |
| | 90 | buf = curbuf->buf; |
| | 91 | size = curbuf->size; |
| | 92 | worg->curbuf = curbuf; |
| | 93 | #ifndef WORGLITE |
| | 94 | worg->curorg = &worg->orgs[file]; |
| | 95 | if (file > 0) { |
| | 96 | worg->curorg->prev = &worg->orgs[file - 1]; |
| | 97 | } else { |
| | 98 | worg->curorg->prev = NULL; |
| | 99 | } |
| | 100 | #endif |
| | 101 | worgle_string_init(&str); |
| | 102 | line = NULL; |
| | 103 | pos = 0; |
| | 104 | mode = MODE_ORG; |
| | 105 | rc = 0; |
| | 106 | status = 0; |
| | 107 | worg->linum = 0; |
| | 108 | while (1) { |
| | 109 | worg->linum++; |
| | 110 | status = worgle_getline(buf, &line, &pos, &read, size); |
| | 111 | if(!status) break; |
| | 112 | if(mode == MODE_ORG) { |
| | 113 | #ifndef WORGLITE |
| | 114 | if (generate_db) { |
| | 115 | if (read >= 2) { |
| | 116 | if (parse_header(worg, line, read)) { |
| | 117 | continue; |
| | 118 | } |
| | 119 | } |
| | 120 | } |
| | 121 | #endif |
| | 122 | if(read >= 7) { |
| | 123 | if(!strncmp(line, "#+NAME", 6)) { |
| | 124 | #ifndef WORGLITE |
| | 125 | if (generate_db) { |
| | 126 | worgle_orgfile_append_content(worg, &worg->segblock); |
| | 127 | worgle_string_reset(&worg->segblock); |
| | 128 | } |
| | 129 | #endif |
| | 130 | if(line[6] != ':') { |
| | 131 | fprintf(stderr, |
| | 132 | "line %lu: expected ':'\n", |
| | 133 | worg->linum); |
| | 134 | rc = 1; |
| | 135 | break; |
| | 136 | } |
| | 137 | mode = MODE_BEGINCODE; |
| | 138 | parse_name(line, read, &str); |
| | 139 | worgle_begin_block(worg, &str); |
| | 140 | #ifndef WORGLITE |
| | 141 | continue; |
| | 142 | #endif |
| | 143 | } |
| | 144 | } |
| | 145 | #ifndef WORGLITE |
| | 146 | if (generate_db) { |
| | 147 | #ifndef WORGLITE |
| | 148 | if (worg->new_content) { |
| | 149 | worg->new_content = 0; |
| | 150 | worgle_string_reset(&worg->segblock); |
| | 151 | worg->segblock.str = line; |
| | 152 | } |
| | 153 | worg->segblock.size += read; |
| | 154 | #endif |
| | 155 | } |
| | 156 | #endif |
| | 157 | } else if(mode == MODE_CODE) { |
| | 158 | if(read >= 9) { |
| | 159 | if(!strncmp(line, "#+END_SRC", 9)) { |
| | 160 | mode = MODE_ORG; |
| | 161 | worg->block_started = 0; |
| | 162 | worgle_append_string(worg); |
| | 163 | #ifndef WORGLITE |
| | 164 | worg->new_content = 1; |
| | 165 | #endif |
| | 166 | continue; |
| | 167 | } |
| | 168 | } |
| | 169 | |
| | 170 | if(check_for_reference(line, read, &str)) { |
| | 171 | worgle_append_string(worg); |
| | 172 | worgle_append_reference(worg, &str); |
| | 173 | worg->block_started = 1; |
| | 174 | worgle_string_reset(&worg->block); |
| | 175 | continue; |
| | 176 | } |
| | 177 | |
| | 178 | worg->block.size += read; |
| | 179 | |
| | 180 | if(worg->block_started) { |
| | 181 | worg->block.str = line; |
| | 182 | worg->block_started = 0; |
| | 183 | worg->curline = worg->linum; |
| | 184 | } |
| | 185 | } else if(mode == MODE_BEGINCODE) { |
| | 186 | if (read >= 11) { |
| | 187 | if(!strncmp (line, "#+BEGIN_SRC",11)) { |
| | 188 | mode = MODE_CODE; |
| | 189 | worg->block_started = 1; |
| | 190 | worgle_string_reset(&worg->block); |
| | 191 | if (parse_begin(line, read, &str) == 2) { |
| | 192 | worgle_append_file(worg, &str); |
| | 193 | } |
| | 194 | continue; |
| | 195 | } else { |
| | 196 | fwrite(line, read, 1, stderr); |
| | 197 | fprintf(stderr, |
| | 198 | "line %lu: Expected #+BEGIN_SRC\n", |
| | 199 | worg->linum); |
| | 200 | rc = 1; |
| | 201 | break; |
| | 202 | } |
| | 203 | } |
| | 204 | fprintf(stderr, |
| | 205 | "line %lu: Expected #+BEGIN_SRC\n", |
| | 206 | worg->linum); |
| | 207 | rc = 1; |
| | 208 | } |
| | 209 | } |
| | 210 | return rc; |
| | 211 | } |
| | 212 | static int parse_name(char *line, size_t len, worgle_string *str) |
| | 213 | { |
| | 214 | size_t n; |
| | 215 | size_t pos; |
| | 216 | int mode; |
| | 217 | |
| | 218 | line+=7; |
| | 219 | len-=7; |
| | 220 | /* *namelen = 0; */ |
| | 221 | str->size = 0; |
| | 222 | str->str = NULL; |
| | 223 | if(len <= 0) return 1; |
| | 224 | pos = 0; |
| | 225 | mode = 0; |
| | 226 | for(n = 0; n < len; n++) { |
| | 227 | if(mode == 2) break; |
| | 228 | switch(mode) { |
| | 229 | case 0: |
| | 230 | if(line[n] == ' ') { |
| | 231 | |
| | 232 | } else { |
| | 233 | str->str = &line[n]; |
| | 234 | str->size++; |
| | 235 | pos++; |
| | 236 | mode = 1; |
| | 237 | } |
| | 238 | break; |
| | 239 | case 1: |
| | 240 | if(line[n] == 0xa) { |
| | 241 | mode = 2; |
| | 242 | break; |
| | 243 | } |
| | 244 | pos++; |
| | 245 | str->size++; |
| | 246 | break; |
| | 247 | default: |
| | 248 | break; |
| | 249 | } |
| | 250 | } |
| | 251 | /* *namelen = pos; */ |
| | 252 | return 1; |
| | 253 | } |
| | 254 | void worgle_begin_block(worgle_d *worg, worgle_string *name) |
| | 255 | { |
| | 256 | worg->curblock = worgle_hashmap_get(&worg->dict, name); |
| | 257 | if (worgle_block_id_get(worg->curblock) == 0) { |
| | 258 | worgle_block_id_set(worg->curblock, worgle_uuid_new(worg)); |
| | 259 | } |
| | 260 | worg->curblock->nblocks++; |
| | 261 | #ifndef WORGLITE |
| | 262 | worgle_orgfile_append_reference(worg, worg->curblock); |
| | 263 | #endif |
| | 264 | } |
| | 265 | #ifndef WORGLITE |
| | 266 | static int parse_header(worgle_d *worg, |
| | 267 | char *line, |
| | 268 | size_t len) |
| | 269 | { |
| | 270 | int mode; |
| | 271 | int rc; |
| | 272 | size_t s; |
| | 273 | char *header; |
| | 274 | worgle_string str; |
| | 275 | int lvl; |
| | 276 | mode = 0; |
| | 277 | |
| | 278 | if(line[0] != '*') return 0; |
| | 279 | |
| | 280 | rc = 0; |
| | 281 | worgle_string_init(&str); |
| | 282 | lvl = 1; |
| | 283 | for (s = 1; s < len; s++) { |
| | 284 | if (mode == 2) break; |
| | 285 | switch (mode) { |
| | 286 | case 0: |
| | 287 | if (line[s] == '*') { |
| | 288 | lvl++; |
| | 289 | } else if (line[s] == ' '){ |
| | 290 | mode = 1; |
| | 291 | } else { |
| | 292 | mode = 2; |
| | 293 | rc = 0; |
| | 294 | } |
| | 295 | break; |
| | 296 | case 1: |
| | 297 | rc = 1; |
| | 298 | mode = 2; |
| | 299 | header = &line[s]; |
| | 300 | str.str = header; |
| | 301 | str.size = len - s; |
| | 302 | str.size -= line[len - 1] == '\n'; |
| | 303 | worgle_orgfile_append_content(worg, &worg->segblock); |
| | 304 | worgle_string_reset(&worg->segblock); |
| | 305 | worgle_orgfile_append_header(worg, |
| | 306 | &str, |
| | 307 | lvl); |
| | 308 | worg->new_content = 1; |
| | 309 | break; |
| | 310 | } |
| | 311 | } |
| | 312 | return rc; |
| | 313 | } |
| | 314 | #endif |
| | 315 | static int parse_begin(char *line, size_t len, worgle_string *str) |
| | 316 | { |
| | 317 | size_t n; |
| | 318 | int mode; |
| | 319 | int rc; |
| | 320 | |
| | 321 | line += 11; |
| | 322 | len -= 11; |
| | 323 | |
| | 324 | if(len <= 0) return 0; |
| | 325 | |
| | 326 | |
| | 327 | mode = 0; |
| | 328 | n = 0; |
| | 329 | rc = 1; |
| | 330 | str->str = NULL; |
| | 331 | str->size = 0; |
| | 332 | while(n < len) { |
| | 333 | switch(mode) { |
| | 334 | case 0: /* initial spaces after BEGIN_SRC */ |
| | 335 | if(line[n] == ' ') { |
| | 336 | n++; |
| | 337 | } else { |
| | 338 | mode = 1; |
| | 339 | } |
| | 340 | break; |
| | 341 | case 1: /* look for :tangle */ |
| | 342 | if(line[n] == ' ') { |
| | 343 | mode = 0; |
| | 344 | n++; |
| | 345 | } else { |
| | 346 | if(line[n] == ':') { |
| | 347 | if(!strncmp(line + n + 1, "tangle", 6)) { |
| | 348 | n+=7; |
| | 349 | mode = 2; |
| | 350 | rc = 2; |
| | 351 | } |
| | 352 | } |
| | 353 | n++; |
| | 354 | } |
| | 355 | break; |
| | 356 | case 2: /* save file name, spaces after tangle */ |
| | 357 | if(line[n] != ' ') { |
| | 358 | str->str = &line[n]; |
| | 359 | str->size++; |
| | 360 | mode = 3; |
| | 361 | } |
| | 362 | n++; |
| | 363 | break; |
| | 364 | case 3: /* read up to next space or line break */ |
| | 365 | if(line[n] == ' ' || line[n] == '\n') { |
| | 366 | mode = 4; |
| | 367 | } else { |
| | 368 | str->size++; |
| | 369 | } |
| | 370 | n++; |
| | 371 | break; |
| | 372 | case 4: /* countdown til end */ |
| | 373 | n++; |
| | 374 | break; |
| | 375 | } |
| | 376 | } |
| | 377 | |
| | 378 | return rc; |
| | 379 | } |
| | 380 | void worgle_append_file(worgle_d *worg, worgle_string *filename) |
| | 381 | { |
| | 382 | worgle_file *f; |
| | 383 | f = worgle_filelist_append(&worg->flist, filename, worg->curblock); |
| | 384 | worgle_file_id_set(f, worgle_uuid_new(worg)); |
| | 385 | } |
| | 386 | void worgle_append_string(worgle_d *worg) |
| | 387 | { |
| | 388 | worgle_segment *seg; |
| | 389 | if(worg->curblock == NULL) return; |
| | 390 | if(worg->curline < 0) return; |
| | 391 | seg = worgle_block_append_string(worg->curblock, |
| | 392 | &worg->block, |
| | 393 | worg->curline, |
| | 394 | &worg->curbuf->filename); |
| | 395 | worgle_segment_id_set(seg, worgle_uuid_new(worg)); |
| | 396 | worg->curblock->last_seg = seg->id; |
| | 397 | } |
| | 398 | void worgle_append_reference(worgle_d *worg, worgle_string *ref) |
| | 399 | { |
| | 400 | worgle_segment *seg; |
| | 401 | if(worg->curblock == NULL) return; |
| | 402 | seg = worgle_block_append_reference(worg->curblock, |
| | 403 | ref, |
| | 404 | worg->linum, |
| | 405 | &worg->curbuf->filename); |
| | 406 | worgle_segment_id_set(seg, worgle_uuid_new(worg)); |
| | 407 | worg->curblock->last_seg = seg->id; |
| | 408 | } |
| | 409 | static int check_for_reference(char *line , size_t size, worgle_string *str) |
| | 410 | { |
| | 411 | int mode; |
| | 412 | size_t n; |
| | 413 | mode = 0; |
| | 414 | |
| | 415 | str->size = 0; |
| | 416 | str->str = NULL; |
| | 417 | for(n = 0; n < size; n++) { |
| | 418 | if(mode < 0) break; |
| | 419 | switch(mode) { |
| | 420 | case 0: /* spaces */ |
| | 421 | if(line[n] == ' ') continue; |
| | 422 | else if(line[n] == '<') mode = 1; |
| | 423 | else mode = -1; |
| | 424 | break; |
| | 425 | case 1: /* second < */ |
| | 426 | if(line[n] == '<') mode = 2; |
| | 427 | else mode = -1; |
| | 428 | break; |
| | 429 | case 2: /* word setup */ |
| | 430 | str->str = &line[n]; |
| | 431 | str->size++; |
| | 432 | mode = 3; |
| | 433 | break; |
| | 434 | case 3: /* the word */ |
| | 435 | if(line[n] == '>') { |
| | 436 | mode = 4; |
| | 437 | break; |
| | 438 | } |
| | 439 | str->size++; |
| | 440 | break; |
| | 441 | case 4: /* last > */ |
| | 442 | if(line[n] == '>') mode = 5; |
| | 443 | else mode = -1; |
| | 444 | break; |
| | 445 | } |
| | 446 | } |
| | 447 | |
| | 448 | return (mode == 5); |
| | 449 | } |
| | 450 | static int worgle_getline(char *fullbuf, |
| | 451 | char **line, |
| | 452 | size_t *pos, |
| | 453 | size_t *line_size, |
| | 454 | size_t buf_size) |
| | 455 | { |
| | 456 | size_t p; |
| | 457 | size_t s; |
| | 458 | *line_size = 0; |
| | 459 | p = *pos; |
| | 460 | *line = &fullbuf[p]; |
| | 461 | s = 0; |
| | 462 | while(1) { |
| | 463 | s++; |
| | 464 | if(p >= buf_size) return 0; |
| | 465 | if(fullbuf[p] == '\n') { |
| | 466 | *pos = p + 1; |
| | 467 | *line_size = s; |
| | 468 | return 1; |
| | 469 | } |
| | 470 | p++; |
| | 471 | } |
| | 472 | } |
| | 473 | int worgle_generate(worgle_d *worg) |
| | 474 | { |
| | 475 | return worgle_filelist_write(&worg->flist, &worg->dict); |
| | 476 | } |
| | 477 | void worgle_init(worgle_d *worg) |
| | 478 | { |
| | 479 | worgle_string_init(&worg->block); |
| | 480 | #ifndef WORGLITE |
| | 481 | worgle_string_init(&worg->segblock); |
| | 482 | #endif |
| | 483 | worg->curline = -1; |
| | 484 | worg->block_started = 0; |
| | 485 | #ifndef WORGLITE |
| | 486 | worg->new_content = 1; |
| | 487 | #endif |
| | 488 | worgle_hashmap_init(&worg->dict); |
| | 489 | worgle_filelist_init(&worg->flist); |
| | 490 | worg->curbuf = NULL; |
| | 491 | worg->buffers = NULL; |
| | 492 | worg->nbuffers = 0; |
| | 493 | worg->curblock = NULL; |
| | 494 | worg->linum = 0; |
| | 495 | worg->orgs = NULL; |
| | 496 | worg->curorg = NULL; |
| | 497 | worg->prog = 0; |
| | 498 | worg->UUID_count = 1; |
| | 499 | } |
| | 500 | void worgle_free(worgle_d *worg) |
| | 501 | { |
| | 502 | int i; |
| | 503 | worgle_hashmap_free(&worg->dict); |
| | 504 | worgle_filelist_free(&worg->flist); |
| | 505 | for(i = 0; i < worg->nbuffers; i++) { |
| | 506 | worgle_textbuf_free(&worg->buffers[i]); |
| | 507 | } |
| | 508 | if(worg->nbuffers > 0) free(worg->buffers); |
| | 509 | if(worg->orgs != NULL && worg->nbuffers > 0) { |
| | 510 | for(i = 0; i < worg->nbuffers; i++) { |
| | 511 | worgle_orgfile_free(&worg->orgs[i]); |
| | 512 | } |
| | 513 | free(worg->orgs); |
| | 514 | } |
| | 515 | } |
| | 516 | void worgle_string_reset(worgle_string *str) |
| | 517 | { |
| | 518 | str->str = NULL; |
| | 519 | str->size = 0; |
| | 520 | } |
| | 521 | void worgle_string_init(worgle_string *str) |
| | 522 | { |
| | 523 | worgle_string_reset(str); |
| | 524 | } |
| | 525 | int worgle_string_write(FILE *fp, worgle_string *str) |
| | 526 | { |
| | 527 | return fwrite(str->str, 1, str->size, fp); |
| | 528 | } |
| | 529 | void worgle_segment_init(worgle_segment *s, |
| | 530 | int type, |
| | 531 | worgle_string *str, |
| | 532 | worgle_string *filename, |
| | 533 | size_t linum) |
| | 534 | { |
| | 535 | s->type = type; |
| | 536 | s->str = *str; |
| | 537 | s->filename = filename; |
| | 538 | s->linum = linum; |
| | 539 | s->nxt = NULL; |
| | 540 | s->id = 0; |
| | 541 | } |
| | 542 | int worgle_segment_write(worgle_segment *s, worgle_hashmap *h, FILE *fp) |
| | 543 | { |
| | 544 | worgle_block *b; |
| | 545 | if(s->type == SEGTYPE_TEXT) { |
| | 546 | if(use_debug) { |
| | 547 | fprintf(fp, "#line %lu \"", s->linum); |
| | 548 | worgle_string_write(fp, s->filename); |
| | 549 | fprintf(fp, "\"\n"); |
| | 550 | } |
| | 551 | worgle_string_write(fp, &s->str); |
| | 552 | } else { |
| | 553 | if(!worgle_hashmap_find(h, &s->str, &b)) { |
| | 554 | fprintf(stderr, "Warning: could not find reference segment '"); |
| | 555 | worgle_string_write(stderr, &s->str); |
| | 556 | fprintf(stderr, "'\n"); |
| | 557 | if(use_warnings == 2) { |
| | 558 | return 0; |
| | 559 | } else { |
| | 560 | return 1; |
| | 561 | } |
| | 562 | } |
| | 563 | return worgle_block_write(b, h, fp); |
| | 564 | } |
| | 565 | |
| | 566 | return 1; |
| | 567 | } |
| | 568 | int worgle_segment_is_text(worgle_segment *s) |
| | 569 | { |
| | 570 | return s->type == SEGTYPE_TEXT; |
| | 571 | } |
| | 572 | |
| | 573 | int worgle_segment_is_reference(worgle_segment *s) |
| | 574 | { |
| | 575 | return s->type == SEGTYPE_REFERENCE; |
| | 576 | } |
| | 577 | void worgle_block_init(worgle_block *b) |
| | 578 | { |
| | 579 | b->nsegs = 0; |
| | 580 | b->head = NULL; |
| | 581 | b->tail = NULL; |
| | 582 | b->nxt = NULL; |
| | 583 | b->am_i_used = 0; |
| | 584 | worgle_string_init(&b->name); |
| | 585 | b->nblocks = 0; |
| | 586 | b->last_seg = -1; |
| | 587 | b->id = 0; |
| | 588 | } |
| | 589 | void worgle_block_free(worgle_block *lst) |
| | 590 | { |
| | 591 | worgle_segment *s; |
| | 592 | worgle_segment *nxt; |
| | 593 | int n; |
| | 594 | s = lst->head; |
| | 595 | for(n = 0; n < lst->nsegs; n++) { |
| | 596 | nxt = s->nxt; |
| | 597 | free(s); |
| | 598 | s = nxt; |
| | 599 | } |
| | 600 | } |
| | 601 | worgle_segment* worgle_block_append_segment(worgle_block *b, |
| | 602 | worgle_string *str, |
| | 603 | int type, |
| | 604 | size_t linum, |
| | 605 | worgle_string *filename) |
| | 606 | { |
| | 607 | worgle_segment *s; |
| | 608 | s = malloc(sizeof(worgle_segment)); |
| | 609 | if(b->nsegs == 0) { |
| | 610 | b->head = s; |
| | 611 | b->tail = s; |
| | 612 | } |
| | 613 | worgle_segment_init(s, type, str, filename, linum); |
| | 614 | b->tail->nxt = s; |
| | 615 | b->tail = s; |
| | 616 | b->nsegs++; |
| | 617 | /* TODO: remove this */ |
| | 618 | /* b->last_seg = s->id; */ |
| | 619 | return s; |
| | 620 | } |
| | 621 | worgle_segment* worgle_block_append_string(worgle_block *b, |
| | 622 | worgle_string *str, |
| | 623 | size_t linum, |
| | 624 | worgle_string *filename) |
| | 625 | { |
| | 626 | return worgle_block_append_segment(b, str, SEGTYPE_TEXT, linum, filename); |
| | 627 | } |
| | 628 | worgle_segment* worgle_block_append_reference(worgle_block *b, |
| | 629 | worgle_string *str, |
| | 630 | size_t linum, |
| | 631 | worgle_string *filename) |
| | 632 | { |
| | 633 | return worgle_block_append_segment(b, str, SEGTYPE_REFERENCE, |
| | 634 | linum, filename); |
| | 635 | } |
| | 636 | int worgle_block_write(worgle_block *b, worgle_hashmap *h, FILE *fp) |
| | 637 | { |
| | 638 | worgle_segment *s; |
| | 639 | int n; |
| | 640 | s = b->head; |
| | 641 | b->am_i_used = 1; |
| | 642 | for(n = 0; n < b->nsegs; n++) { |
| | 643 | if(!worgle_segment_write(s, h, fp)) return 0; |
| | 644 | s = s->nxt; |
| | 645 | } |
| | 646 | |
| | 647 | return 1; |
| | 648 | } |
| | 649 | void worgle_blocklist_init(worgle_blocklist *lst) |
| | 650 | { |
| | 651 | lst->head = NULL; |
| | 652 | lst->tail = NULL; |
| | 653 | lst->nblocks = 0; |
| | 654 | } |
| | 655 | void worgle_blocklist_free(worgle_blocklist *lst) |
| | 656 | { |
| | 657 | worgle_block *b; |
| | 658 | worgle_block *nxt; |
| | 659 | int n; |
| | 660 | b = lst->head; |
| | 661 | for(n = 0; n < lst->nblocks; n++) { |
| | 662 | nxt = b->nxt; |
| | 663 | worgle_block_free(b); |
| | 664 | free(b); |
| | 665 | b = nxt; |
| | 666 | } |
| | 667 | } |
| | 668 | void worgle_blocklist_append(worgle_blocklist *lst, worgle_block *b) |
| | 669 | { |
| | 670 | if(lst->nblocks == 0) { |
| | 671 | lst->head = b; |
| | 672 | lst->tail = b; |
| | 673 | } |
| | 674 | lst->tail->nxt = b; |
| | 675 | lst->tail = b; |
| | 676 | lst->nblocks++; |
| | 677 | } |
| | 678 | void worgle_hashmap_init(worgle_hashmap *h) |
| | 679 | { |
| | 680 | int n; |
| | 681 | h->nwords = 0; |
| | 682 | for(n = 0; n < HASH_SIZE; n++) { |
| | 683 | worgle_blocklist_init(&h->blk[n]); |
| | 684 | } |
| | 685 | } |
| | 686 | void worgle_hashmap_free(worgle_hashmap *h) |
| | 687 | { |
| | 688 | int n; |
| | 689 | for(n = 0; n < HASH_SIZE; n++) { |
| | 690 | worgle_blocklist_free(&h->blk[n]); |
| | 691 | } |
| | 692 | } |
| | 693 | static int hash(const char *str, size_t size) |
| | 694 | { |
| | 695 | unsigned int h = 5381; |
| | 696 | size_t i = 0; |
| | 697 | |
| | 698 | for(i = 0; i < size; i++) { |
| | 699 | h = ((h << 5) + h) ^ str[i]; |
| | 700 | h %= 0x7FFFFFFF; |
| | 701 | } |
| | 702 | |
| | 703 | return h % HASH_SIZE; |
| | 704 | } |
| | 705 | int worgle_hashmap_find(worgle_hashmap *h, worgle_string *name, worgle_block **b) |
| | 706 | { |
| | 707 | int pos; |
| | 708 | worgle_blocklist *lst; |
| | 709 | int n; |
| | 710 | worgle_block *blk; |
| | 711 | pos = hash(name->str, name->size); |
| | 712 | lst = &h->blk[pos]; |
| | 713 | |
| | 714 | blk = lst->head; |
| | 715 | for(n = 0; n < lst->nblocks; n++) { |
| | 716 | if(name->size == blk->name.size) { |
| | 717 | if(!strncmp(name->str, blk->name.str, name->size)) { |
| | 718 | *b = blk; |
| | 719 | return 1; |
| | 720 | } |
| | 721 | } |
| | 722 | blk = blk->nxt; |
| | 723 | } |
| | 724 | return 0; |
| | 725 | } |
| | 726 | worgle_block * worgle_hashmap_get(worgle_hashmap *h, worgle_string *name) |
| | 727 | { |
| | 728 | worgle_block *b; |
| | 729 | worgle_blocklist *lst; |
| | 730 | int pos; |
| | 731 | |
| | 732 | if(worgle_hashmap_find(h, name, &b)) return b; |
| | 733 | pos = hash(name->str, name->size); |
| | 734 | b = NULL; |
| | 735 | b = malloc(sizeof(worgle_block)); |
| | 736 | worgle_block_init(b); |
| | 737 | b->name = *name; |
| | 738 | lst = &h->blk[pos]; |
| | 739 | worgle_blocklist_append(lst, b); |
| | 740 | return b; |
| | 741 | } |
| | 742 | int worgle_file_write(worgle_file *f, worgle_hashmap *h) |
| | 743 | { |
| | 744 | FILE *fp; |
| | 745 | char tmp[128]; |
| | 746 | size_t n; |
| | 747 | size_t size; |
| | 748 | int rc; |
| | 749 | |
| | 750 | if(f->filename.size > 128) size = 127; |
| | 751 | else size = f->filename.size; |
| | 752 | for(n = 0; n < size; n++) tmp[n] = f->filename.str[n]; |
| | 753 | tmp[size] = 0; |
| | 754 | |
| | 755 | fp = fopen(tmp, "w"); |
| | 756 | |
| | 757 | rc = worgle_block_write(f->top, h, fp); |
| | 758 | |
| | 759 | fclose(fp); |
| | 760 | return rc; |
| | 761 | } |
| | 762 | void worgle_filelist_init(worgle_filelist *flist) |
| | 763 | { |
| | 764 | flist->head = NULL; |
| | 765 | flist->tail = NULL; |
| | 766 | flist->nfiles = 0; |
| | 767 | } |
| | 768 | void worgle_filelist_free(worgle_filelist *flist) |
| | 769 | { |
| | 770 | worgle_file *f; |
| | 771 | worgle_file *nxt; |
| | 772 | int n; |
| | 773 | f = flist->head; |
| | 774 | for(n = 0; n < flist->nfiles; n++) { |
| | 775 | nxt = f->nxt; |
| | 776 | free(f); |
| | 777 | f = nxt; |
| | 778 | } |
| | 779 | } |
| | 780 | worgle_file* worgle_filelist_append(worgle_filelist *flist, |
| | 781 | worgle_string *name, |
| | 782 | worgle_block *top) |
| | 783 | { |
| | 784 | worgle_file *f; |
| | 785 | f = malloc(sizeof(worgle_file)); |
| | 786 | f->filename = *name; |
| | 787 | f->top = top; |
| | 788 | f->nxt = NULL; |
| | 789 | f->id = 0; |
| | 790 | |
| | 791 | if(flist->nfiles == 0) { |
| | 792 | flist->head = f; |
| | 793 | flist->tail = f; |
| | 794 | } |
| | 795 | flist->tail->nxt = f; |
| | 796 | flist->tail = f; |
| | 797 | flist->nfiles++; |
| | 798 | return f; |
| | 799 | } |
| | 800 | int worgle_filelist_write(worgle_filelist *flist, worgle_hashmap *h) |
| | 801 | { |
| | 802 | worgle_file *f; |
| | 803 | int n; |
| | 804 | |
| | 805 | f = flist->head; |
| | 806 | for(n = 0; n < flist->nfiles; n++) { |
| | 807 | if(!worgle_file_write(f, h)) return 0; |
| | 808 | f = f->nxt; |
| | 809 | } |
| | 810 | |
| | 811 | return 1; |
| | 812 | } |
| | 813 | void worgle_textbuf_zero(worgle_textbuf *txt) |
| | 814 | { |
| | 815 | txt->buf = NULL; |
| | 816 | worgle_string_init(&txt->filename); |
| | 817 | txt->size = 0; |
| | 818 | } |
| | 819 | void worgle_textbuf_init(worgle_textbuf *txt, |
| | 820 | char *buf, |
| | 821 | size_t bufsize) |
| | 822 | { |
| | 823 | txt->buf = buf; |
| | 824 | txt->size = bufsize; |
| | 825 | } |
| | 826 | void worgle_textbuf_free(worgle_textbuf *txt) |
| | 827 | { |
| | 828 | if(txt->buf != NULL) free(txt->buf); |
| | 829 | worgle_textbuf_zero(txt); |
| | 830 | } |
| | 831 | worgle_long worgle_uuid_new(worgle_d *worg) |
| | 832 | { |
| | 833 | return worg->UUID_count++; |
| | 834 | } |
| | 835 | worgle_long worgle_segment_id_get(worgle_segment *s) |
| | 836 | { |
| | 837 | return s->id; |
| | 838 | } |
| | 839 | |
| | 840 | void worgle_segment_id_set(worgle_segment *s, worgle_long id) |
| | 841 | { |
| | 842 | s->id = id; |
| | 843 | } |
| | 844 | worgle_long worgle_block_id_get(worgle_block *b) |
| | 845 | { |
| | 846 | return b->id; |
| | 847 | } |
| | 848 | |
| | 849 | void worgle_block_id_set(worgle_block *b, worgle_long id) |
| | 850 | { |
| | 851 | b->id = id; |
| | 852 | } |
| | 853 | void worgle_file_id_set(worgle_file *f, worgle_long id) |
| | 854 | { |
| | 855 | f->id = id; |
| | 856 | } |
| | 857 | void worgle_orglet_id_set(worgle_orglet *orglet, |
| | 858 | worgle_long id) |
| | 859 | { |
| | 860 | orglet->id = id; |
| | 861 | } |
| | 862 | void worgle_orgfile_init(worgle_orgfile *org) |
| | 863 | { |
| | 864 | org->head = NULL; |
| | 865 | org->tail = NULL; |
| | 866 | org->size = 0; |
| | 867 | org->prev = NULL; |
| | 868 | } |
| | 869 | void worgle_orgfile_free(worgle_orgfile *org) |
| | 870 | { |
| | 871 | worgle_orglet *ent; |
| | 872 | worgle_orglet *nxt; |
| | 873 | int n; |
| | 874 | if (org->size > 0) { |
| | 875 | ent = org->head; |
| | 876 | for (n = 0; n < org->size; n++) { |
| | 877 | nxt = ent->next; |
| | 878 | worgle_orglet_free(ent); |
| | 879 | ent = nxt; |
| | 880 | } |
| | 881 | } |
| | 882 | } |
| | 883 | void worgle_orgfile_append(worgle_d *worg, |
| | 884 | worgle_orgfile *file, |
| | 885 | worgle_orglet *orglet) |
| | 886 | { |
| | 887 | if (file->size <= 0) { |
| | 888 | file->head = orglet; |
| | 889 | if (file->prev != NULL) { |
| | 890 | file->prev->tail->next = file->head; |
| | 891 | } |
| | 892 | file->tail = orglet; |
| | 893 | } |
| | 894 | |
| | 895 | file->tail->next = orglet; |
| | 896 | file->tail = orglet; |
| | 897 | file->size++; |
| | 898 | worgle_orglet_id_set(orglet, worgle_uuid_new(worg)); |
| | 899 | } |
| | 900 | void worgle_orgfile_append_header(worgle_d *worg, |
| | 901 | worgle_string *header, |
| | 902 | int lvl) |
| | 903 | { |
| | 904 | worgle_orglet *orglet; |
| | 905 | worgle_orglet_header *h; |
| | 906 | worgle_orgfile *f; |
| | 907 | size_t linum; |
| | 908 | |
| | 909 | f = worg->curorg; |
| | 910 | linum = worg->linum; |
| | 911 | |
| | 912 | orglet = calloc(1, sizeof(worgle_orglet)); |
| | 913 | h = calloc(1, sizeof(worgle_orglet_header)); |
| | 914 | |
| | 915 | h->str = *header; |
| | 916 | h->lvl = lvl; |
| | 917 | worgle_orglet_init(orglet); |
| | 918 | |
| | 919 | orglet->type = ORGLET_HEADER; |
| | 920 | orglet->ud = h; |
| | 921 | orglet->linum = linum; |
| | 922 | worgle_orgfile_append(worg, f, orglet); |
| | 923 | } |
| | 924 | void worgle_orgfile_append_content(worgle_d *worg, |
| | 925 | worgle_string *text) |
| | 926 | { |
| | 927 | worgle_orglet *orglet; |
| | 928 | worgle_orglet_content *c; |
| | 929 | worgle_orgfile *f; |
| | 930 | size_t linum; |
| | 931 | |
| | 932 | if (text->size == 0) return; |
| | 933 | if (text->size == 1) return; |
| | 934 | |
| | 935 | f = worg->curorg; |
| | 936 | linum = worg->linum; |
| | 937 | |
| | 938 | orglet = calloc(1, sizeof(worgle_orglet)); |
| | 939 | c = calloc(1, sizeof(worgle_orglet_content)); |
| | 940 | |
| | 941 | c->text = *text; |
| | 942 | |
| | 943 | /* printf("CONTENT(%d): '", c->text.size); */ |
| | 944 | /* fwrite(c->text.str, 1, c->text.size, stdout); */ |
| | 945 | /* printf("'\n"); */ |
| | 946 | |
| | 947 | worgle_orglet_init(orglet); |
| | 948 | |
| | 949 | orglet->type = ORGLET_CONTENT; |
| | 950 | orglet->ud = c; |
| | 951 | orglet->linum = linum; |
| | 952 | worgle_orgfile_append(worg, f, orglet); |
| | 953 | } |
| | 954 | void worgle_orgfile_append_reference(worgle_d *worg, |
| | 955 | worgle_block *blk) |
| | 956 | { |
| | 957 | worgle_orglet *orglet; |
| | 958 | worgle_orglet_blkref *br; |
| | 959 | worgle_orgfile *f; |
| | 960 | size_t linum; |
| | 961 | |
| | 962 | f = worg->curorg; |
| | 963 | linum = worg->linum; |
| | 964 | |
| | 965 | orglet = calloc(1, sizeof(worgle_orglet)); |
| | 966 | br = calloc(1, sizeof(worgle_orglet_blkref)); |
| | 967 | |
| | 968 | br->blk = blk; |
| | 969 | br->pos = blk->nblocks; |
| | 970 | br->prev_lastseg = blk->last_seg; |
| | 971 | br->segoff = blk->nsegs; |
| | 972 | worgle_orglet_init(orglet); |
| | 973 | |
| | 974 | orglet->type = ORGLET_BLKREF; |
| | 975 | orglet->ud = br; |
| | 976 | orglet->linum = linum; |
| | 977 | worgle_orgfile_append(worg, f, orglet); |
| | 978 | } |
| | 979 | void worgle_orglet_init(worgle_orglet *orglet) |
| | 980 | { |
| | 981 | orglet->type = ORGLET_UNKNOWN; |
| | 982 | orglet->ud = NULL; |
| | 983 | orglet->next = NULL; |
| | 984 | orglet->linum = 0; |
| | 985 | orglet->id = 0; |
| | 986 | } |
| | 987 | void worgle_orglet_free(worgle_orglet *orglet) |
| | 988 | { |
| | 989 | free(orglet->ud); |
| | 990 | free(orglet); |
| | 991 | } |
| | 992 | int worgle_warn_unused(worgle_d *worg) |
| | 993 | { |
| | 994 | worgle_hashmap *dict; |
| | 995 | worgle_block *blk; |
| | 996 | worgle_blocklist *lst; |
| | 997 | int n; |
| | 998 | int b; |
| | 999 | int rc; |
| | 1000 | |
| | 1001 | dict = &worg->dict; |
| | 1002 | rc = 0; |
| | 1003 | |
| | 1004 | for(n = 0; n < HASH_SIZE; n++) { |
| | 1005 | lst = &dict->blk[n]; |
| | 1006 | blk = lst->head; |
| | 1007 | for(b = 0; b < lst->nblocks; b++) { |
| | 1008 | if(blk->am_i_used == 0) { |
| | 1009 | fprintf(stderr, "Warning: block '"); |
| | 1010 | worgle_string_write(stderr, &blk->name); |
| | 1011 | fprintf(stderr, "' unused.\n"); |
| | 1012 | fprintf(stderr, "First declared in "); |
| | 1013 | worgle_string_write(stderr, |
| | 1014 | blk->head->filename); |
| | 1015 | fprintf(stderr, ", line %lu\n", |
| | 1016 | blk->head->linum); |
| | 1017 | if(use_warnings == 2) rc = 1; |
| | 1018 | } |
| | 1019 | blk = blk->nxt; |
| | 1020 | } |
| | 1021 | } |
| | 1022 | return rc; |
| | 1023 | } |
| | 1024 | static void append_filename(worgle_d *worg, char *filename) |
| | 1025 | { |
| | 1026 | worgle_string *str; |
| | 1027 | int pos; |
| | 1028 | pos = worg->nbuffers; |
| | 1029 | worg->nbuffers++; |
| | 1030 | if(worg->nbuffers == 1) { |
| | 1031 | worg->buffers = calloc(1, sizeof(worgle_textbuf)); |
| | 1032 | } else { |
| | 1033 | worg->buffers = realloc(worg->buffers, |
| | 1034 | sizeof(worgle_textbuf) * |
| | 1035 | worg->nbuffers); |
| | 1036 | } |
| | 1037 | str = &worg->buffers[pos].filename; |
| | 1038 | str->str = filename; |
| | 1039 | str->size = strlen(filename); |
| | 1040 | #ifndef WORGLITE |
| | 1041 | if(worg->nbuffers == 1) { |
| | 1042 | worg->orgs = calloc(1, sizeof(worgle_orgfile)); |
| | 1043 | } else { |
| | 1044 | worg->orgs = realloc(worg->orgs, |
| | 1045 | sizeof(worgle_orgfile) * |
| | 1046 | worg->nbuffers); |
| | 1047 | } |
| | 1048 | if(worg->nbuffers > 0) { |
| | 1049 | worgle_orgfile_init(&worg->orgs[worg->nbuffers - 1]); |
| | 1050 | } |
| | 1051 | #endif |
| | 1052 | } |
| | 1053 | #ifndef WORGLITE |
| | 1054 | static void tangle_to_db(worgle_d *worg) |
| | 1055 | { |
| | 1056 | sqlite3 *db; |
| | 1057 | int rc; |
| | 1058 | |
| | 1059 | if(db_filename == NULL) return; |
| | 1060 | |
| | 1061 | rc = sqlite3_open(db_filename, &db); |
| | 1062 | if(rc) { |
| | 1063 | fprintf(stderr, |
| | 1064 | "Could not open database: %s", |
| | 1065 | sqlite3_errmsg(db)); |
| | 1066 | sqlite3_close(db); |
| | 1067 | return; |
| | 1068 | } |
| | 1069 | worgle_db_clear(db, worg->prog); |
| | 1070 | worgle_db_schemas(worg, db); |
| | 1071 | worgle_db_generate(worg, db); |
| | 1072 | sqlite3_close(db); |
| | 1073 | } |
| | 1074 | #endif |
| | 1075 | void worgle_map(worgle_d *worg, worgle_block *b, int lvl, FILE *out) |
| | 1076 | { |
| | 1077 | int i; |
| | 1078 | worgle_segment *s; |
| | 1079 | worgle_block *newblk; |
| | 1080 | worgle_hashmap *h; |
| | 1081 | |
| | 1082 | h = &worg->dict; |
| | 1083 | if(lvl != 0) { |
| | 1084 | for(i = 0; i <= lvl; i++) { |
| | 1085 | fputc('*', out); |
| | 1086 | } |
| | 1087 | fputc(' ', out); |
| | 1088 | worgle_string_write(out, &b->name); |
| | 1089 | fputc('\n', out); |
| | 1090 | } |
| | 1091 | |
| | 1092 | s = b->head; |
| | 1093 | |
| | 1094 | newblk = NULL; |
| | 1095 | |
| | 1096 | for(i = 0; i < b->nsegs; i++) { |
| | 1097 | if(s->type == SEGTYPE_TEXT) { |
| | 1098 | if(s->str.size > 0) { |
| | 1099 | worgle_string_write(out, s->filename); |
| | 1100 | fprintf(out, ":%lu\n", s->linum); |
| | 1101 | fprintf(out, "#+NAME: "); |
| | 1102 | worgle_string_write(out, &b->name); |
| | 1103 | fprintf(out, "_%d\n", i); |
| | 1104 | fprintf(out, "#+BEGIN_SRC\n"); |
| | 1105 | worgle_string_write(out, &s->str); |
| | 1106 | fprintf(out, "#+END_SRC"); |
| | 1107 | } |
| | 1108 | fprintf(out, "\n"); |
| | 1109 | } else if(worgle_hashmap_find(h, &s->str, &newblk)) { |
| | 1110 | worgle_map(worg, newblk, lvl + 1, out); |
| | 1111 | } |
| | 1112 | s = s->nxt; |
| | 1113 | } |
| | 1114 | } |
| | 1115 | void worgle_map_files(worgle_d *worg, char *filename) |
| | 1116 | { |
| | 1117 | int n; |
| | 1118 | worgle_file *f; |
| | 1119 | FILE *fp; |
| | 1120 | |
| | 1121 | fp = fopen(filename, "w"); |
| | 1122 | if(fp == NULL) return; |
| | 1123 | |
| | 1124 | f = worg->flist.head; |
| | 1125 | |
| | 1126 | fprintf(fp, "#+TITLE: Code Map\n"); |
| | 1127 | for(n = 0; n < worg->flist.nfiles; n++) { |
| | 1128 | worgle_map_a_file(worg, f, fp); |
| | 1129 | f = f->nxt; |
| | 1130 | } |
| | 1131 | |
| | 1132 | fclose(fp); |
| | 1133 | } |
| | 1134 | |
| | 1135 | void worgle_map_a_file(worgle_d *worg, worgle_file *file, FILE *out) |
| | 1136 | { |
| | 1137 | fprintf(out, "* "); |
| | 1138 | worgle_string_write(out, &file->filename); |
| | 1139 | fprintf(out, "\n"); |
| | 1140 | worgle_map(worg, file->top, 0, out); |
| | 1141 | } |
| | 1142 | |
| | 1143 | int main(int argc, char *argv[]) |
| | 1144 | { |
| | 1145 | worgle_d worg; |
| | 1146 | char *filename; |
| | 1147 | int rc; |
| | 1148 | int i; |
| | 1149 | struct parg_state ps; |
| | 1150 | int c; |
| | 1151 | worgle_init(&worg); |
| | 1152 | filename = NULL; |
| | 1153 | if(argc < 2) { |
| | 1154 | fprintf(stderr, "Usage: %s filename.org\n", argv[0]); |
| | 1155 | return 1; |
| | 1156 | } |
| | 1157 | parg_init(&ps); |
| | 1158 | while ((c = parg_getopt(&ps, argc, argv, "gW:m:d:p:n")) != -1) { |
| | 1159 | switch(c) { |
| | 1160 | case 1: |
| | 1161 | filename = (char *)ps.optarg; |
| | 1162 | append_filename(&worg, (char *)ps.optarg); |
| | 1163 | break; |
| | 1164 | case 'g': |
| | 1165 | use_debug = 1; |
| | 1166 | break; |
| | 1167 | case 'W': |
| | 1168 | if(!strncmp(ps.optarg, "soft", 4)) { |
| | 1169 | use_warnings = 1; |
| | 1170 | } else if(!strncmp(ps.optarg, "error", 5)) { |
| | 1171 | use_warnings = 2; |
| | 1172 | } else { |
| | 1173 | fprintf(stderr, "Unidentified warning mode '%s'\n", ps.optarg); |
| | 1174 | return 1; |
| | 1175 | } |
| | 1176 | break; |
| | 1177 | case 'm': |
| | 1178 | map_source_code = 1; |
| | 1179 | map_filename = (char *)ps.optarg; |
| | 1180 | break; |
| | 1181 | case 'd': |
| | 1182 | #ifndef WORGLITE |
| | 1183 | generate_db = 1; |
| | 1184 | db_filename = (char *)ps.optarg; |
| | 1185 | #else |
| | 1186 | fprintf(stderr, "Database flag (-d) is not enabled\n"); |
| | 1187 | return 1; |
| | 1188 | #endif |
| | 1189 | break; |
| | 1190 | case 'p': |
| | 1191 | worg.prog = atoi(ps.optarg); |
| | 1192 | break; |
| | 1193 | case 'n': |
| | 1194 | tangle_code = 0; |
| | 1195 | break; |
| | 1196 | default: |
| | 1197 | fprintf(stderr, "Unknown option -%c\n", c); |
| | 1198 | return 1; |
| | 1199 | } |
| | 1200 | } |
| | 1201 | if(filename == NULL) { |
| | 1202 | fprintf(stderr, "No filename specified\n"); |
| | 1203 | return 1; |
| | 1204 | } |
| | 1205 | rc = 0; |
| | 1206 | for(i = 0; i < worg.nbuffers; i++) { |
| | 1207 | rc = loadfile(&worg, i); |
| | 1208 | if(!rc) goto cleanup; |
| | 1209 | } |
| | 1210 | for (i = 0; i < worg.nbuffers; i++) { |
| | 1211 | rc = parse_file(&worg, i); |
| | 1212 | if (rc) goto cleanup; |
| | 1213 | } |
| | 1214 | #ifndef WORGLITE |
| | 1215 | if (generate_db) { |
| | 1216 | worgle_orgfile_append_content(&worg, &worg.segblock); |
| | 1217 | } |
| | 1218 | #endif |
| | 1219 | if(!rc && tangle_code) if(!worgle_generate(&worg)) rc = 1; |
| | 1220 | if(!rc && use_warnings) rc = worgle_warn_unused(&worg); |
| | 1221 | if(map_source_code && map_filename != NULL) { |
| | 1222 | worgle_map_files(&worg, map_filename); |
| | 1223 | } |
| | 1224 | #ifndef WORGLITE |
| | 1225 | if(generate_db) tangle_to_db(&worg); |
| | 1226 | #endif |
| | 1227 | cleanup: |
| | 1228 | worgle_free(&worg); |
| | 1229 | return rc; |
| | 1230 | } |