00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "klone_conf.h"
00012 #include <stdio.h>
00013 #include <stdlib.h>
00014 #include <ctype.h>
00015 #include <fcntl.h>
00016 #include <unistd.h>
00017 #include <limits.h>
00018 #include <u/libu.h>
00019 #include <klone/os.h>
00020 #include <klone/translat.h>
00021 #include <klone/parser.h>
00022 #include <klone/utils.h>
00023 #include <klone/os.h>
00024 #include <klone/io.h>
00025 #include <klone/codec.h>
00026 #include <klone/codecs.h>
00027
00028 #define tr_err(...) \
00029 do { con_p_ctx(p); con_err(__VA_ARGS__); } while(0)
00030 #define tr_err_if(expr) \
00031 do { if( (expr) ) { con_p_ctx(p); u_con("%s", #expr); goto err; } } while(0)
00032 #define tr_err_ifm(expr, ...) \
00033 do { if( (expr) ) { con_p_ctx(p); u_con(__VA_ARGS__); goto err; } } while(0)
00034
00035
00036 typedef struct kblock_s
00037 {
00038 char *name;
00039 u_buf_t *ubuf;
00040 struct kblock_s *parent;
00041 struct kblock_s *ancestor;
00042 u_list_t *children;
00043 } kblock_t;
00044
00045 typedef struct ppctx_s
00046 {
00047 kblock_t *cur;
00048 kblock_t *top;
00049 kblock_t *dead;
00050 int lev;
00051 int extending;
00052 u_list_t *depend;
00053 } ppctx_t;
00054
00055 static int preprocess(io_t *in, io_t *out, ppctx_t*);
00056
00057 static int kblock_free(kblock_t *block)
00058 {
00059 kblock_t *child;
00060 int i;
00061
00062 dbg_err_if(block == NULL);
00063
00064
00065 for(i = 0; (child = u_list_get_n(block->children, i)) != NULL; ++i)
00066 kblock_free(child);
00067
00068 if(block->ancestor)
00069 kblock_free(block->ancestor);
00070
00071 if(block->name)
00072 u_free(block->name);
00073
00074 if(block->ubuf)
00075 u_buf_free(block->ubuf);
00076
00077 u_free(block);
00078
00079 return 0;
00080 err:
00081 return ~0;
00082 }
00083
00084 static int kblock_push_child(kblock_t *parent, kblock_t *child)
00085 {
00086 dbg_err_if(u_list_add(parent->children, child));
00087
00088 child->parent = parent;
00089
00090 return 0;
00091 err:
00092 return ~0;
00093 }
00094
00095 static int kblock_create(const char *name, const char *buf, size_t size,
00096 kblock_t **pblock)
00097 {
00098 kblock_t *b = NULL;
00099
00100 b = u_zalloc(sizeof(kblock_t));
00101 dbg_err_if(b == NULL);
00102
00103 dbg_err_if(u_buf_create(&b->ubuf));
00104
00105 dbg_err_if(u_list_create(&b->children));
00106
00107 if(name)
00108 {
00109 b->name = u_strdup(name);
00110 dbg_err_if(b->name == NULL);
00111 }
00112
00113 if(buf && size)
00114 dbg_err_if(u_buf_append(b->ubuf, buf, size));
00115
00116 *pblock = b;
00117
00118 return 0;
00119 err:
00120 if(b)
00121 kblock_free(b);
00122 return ~0;
00123 }
00124
00125 static int ppctx_print_kblock(kblock_t *block, io_t *out)
00126 {
00127 kblock_t *b;
00128 size_t i;
00129
00130 if(block->name == NULL)
00131 {
00132 if(u_buf_len(block->ubuf))
00133 dbg_err_if(io_write(out, u_buf_ptr(block->ubuf),
00134 u_buf_len(block->ubuf)) < 0);
00135 } else {
00136
00137 for(i = 0; (b = u_list_get_n(block->children, i)) != NULL; ++i)
00138 dbg_err_if(ppctx_print_kblock(b, out));
00139 }
00140
00141 return 0;
00142 err:
00143 return ~0;
00144 }
00145
00146
00147 static int ppctx_depend_push(ppctx_t *ppc, const char *filepath)
00148 {
00149 const char *s;
00150
00151 dbg_err_if((s = u_strdup(filepath)) == NULL);
00152
00153 dbg_err_if(u_list_add(ppc->depend, (void*)s));
00154
00155 return 0;
00156 err:
00157 return ~0;
00158 }
00159
00160 static int ppctx_print_depend(ppctx_t *ppc, io_t *in, io_t *out, io_t *depend)
00161 {
00162 char infile[U_FILENAME_MAX], outfile[U_FILENAME_MAX];
00163 char fullpath[U_FILENAME_MAX];
00164 const char *dfile;
00165 size_t i;
00166
00167 dbg_err_if(ppc == NULL);
00168 dbg_err_if(in == NULL);
00169 dbg_err_if(out == NULL);
00170 dbg_err_if(depend == NULL);
00171
00172
00173
00174
00175 dbg_err_if(io_name_get(in, infile, U_FILENAME_MAX));
00176 dbg_err_if(io_name_get(out, outfile, U_FILENAME_MAX));
00177
00178
00179 dbg_err_if(translate_makefile_filepath(infile, "$(srcdir)", fullpath,
00180 sizeof(fullpath)));
00181
00182 io_printf(depend, "%s %s.kld: %s ", outfile, outfile, fullpath);
00183
00184 for(i = 0; (dfile = u_list_get_n(ppc->depend, i)) != NULL; ++i)
00185 {
00186 dbg_err_if(translate_makefile_filepath(dfile, "$(srcdir)", fullpath,
00187 sizeof(fullpath)));
00188 io_printf(depend, "%s ", fullpath);
00189 }
00190 io_printf(depend, "\n");
00191
00192 return 0;
00193 err:
00194 return ~0;
00195
00196 }
00197
00198 static int ppctx_print(ppctx_t *ppc, io_t *out)
00199 {
00200 kblock_t *b;
00201 size_t i;
00202
00203 dbg_err_if(ppc == NULL);
00204 dbg_err_if(out == NULL);
00205
00206 for(i = 0; (b = u_list_get_n(ppc->top->children, i)) != NULL; ++i)
00207 dbg_err_if(ppctx_print_kblock(b, out));
00208
00209 return 0;
00210 err:
00211 return ~0;
00212
00213 }
00214
00215 static int ppctx_free(ppctx_t *ppc)
00216 {
00217 char *str;
00218 size_t i;
00219
00220 if(ppc->top)
00221 kblock_free(ppc->top);
00222
00223 if(ppc->dead)
00224 kblock_free(ppc->dead);
00225
00226 if(ppc->depend)
00227 {
00228 for(i = 0; (str = u_list_get_n(ppc->depend, i)) != NULL; ++i)
00229 u_free(str);
00230
00231 u_list_free(ppc->depend);
00232 }
00233
00234 u_free(ppc);
00235
00236 return 0;
00237 }
00238
00239 static int ppctx_create(ppctx_t **pppc)
00240 {
00241 ppctx_t *ppc = NULL;
00242
00243 ppc = u_zalloc(sizeof(ppctx_t));
00244 dbg_err_if(ppc == NULL);
00245
00246 dbg_err_if(kblock_create(NULL, NULL, 0, &ppc->top));
00247 dbg_err_if(kblock_create(NULL, NULL, 0, &ppc->dead));
00248
00249 dbg_err_if(u_list_create(&ppc->depend));
00250
00251 ppc->cur = ppc->top;
00252 ppc->dead->parent = ppc->top;
00253
00254 *pppc = ppc;
00255
00256 return 0;
00257 err:
00258 if(ppc)
00259 ppctx_free(ppc);
00260 return ~0;
00261 }
00262
00263
00264 static void con_p_ctx(parser_t *p)
00265 {
00266 char fn[U_FILENAME_MAX];
00267
00268 dbg_err_if(io_name_get(p->in, fn, U_FILENAME_MAX));
00269
00270
00271 fprintf(stderr, "[%s:%d]: error: ", fn, p->code_line);
00272
00273 err:
00274 return;
00275 }
00276
00277 int translate_makefile_filepath(const char *filepath, const char *prefix,
00278 char *buf, size_t size)
00279 {
00280 char file_in[U_FILENAME_MAX];
00281
00282
00283 if(filepath[0] == '/' || filepath[0] == '\\')
00284 {
00285 dbg_err_if(u_snprintf(file_in, U_FILENAME_MAX, "%s", filepath));
00286 } else if(isalpha(filepath[0]) && filepath[1] == ':') {
00287
00288 dbg_err_if(u_snprintf(file_in, U_FILENAME_MAX, "%s", filepath));
00289 } else {
00290
00291 dbg_err_if(u_snprintf(file_in, U_FILENAME_MAX, "%s/%s", prefix,
00292 filepath ));
00293 }
00294
00295 dbg_err_if(u_strlcpy(buf, file_in, size));
00296
00297 return 0;
00298 err:
00299 return ~0;
00300 }
00301
00302 int translate_is_a_script(const char *filename)
00303 {
00304 static const char *script_ext[] = {
00305 ".klone", ".kl1", ".klc",
00306 ".klx",
00307 NULL
00308 };
00309 const char **ext;
00310
00311 dbg_return_if(filename == NULL, 0);
00312
00313
00314 for(ext = script_ext; *ext; ++ext)
00315 {
00316
00317 if(u_match_ext(filename, *ext))
00318 return 1;
00319 }
00320 return 0;
00321 }
00322
00323 static int include_file_full_path(parser_t *p, char *inc_file, char *obuf,
00324 size_t size)
00325 {
00326 char buf[U_FILENAME_MAX], *pc;
00327
00328
00329
00330 dbg_err_if(io_name_get(p->in, buf, U_FILENAME_MAX));
00331
00332
00333 dbg_err_if((pc = strrchr(buf, '/')) == NULL);
00334 ++pc; *pc = 0;
00335
00336 dbg_err_if(u_strlcat(buf, inc_file, U_FILENAME_MAX));
00337
00338 dbg_err_if(u_strlcpy(obuf, buf, size));
00339
00340 return 0;
00341 err:
00342 return ~0;
00343 }
00344
00345 static int process_directive_include(parser_t *p, char *inc_file)
00346 {
00347 ppctx_t *ppc;
00348 char fullpath[U_FILENAME_MAX], file[U_FILENAME_MAX];
00349 io_t *io = NULL;
00350
00351 dbg_return_if (p == NULL, ~0);
00352 dbg_return_if (inc_file == NULL, ~0);
00353
00354 dbg_err_if(io_name_get(p->in, file, U_FILENAME_MAX));
00355
00356 dbg_err_if(include_file_full_path(p, inc_file, fullpath, U_FILENAME_MAX));
00357
00358
00359 tr_err_ifm(u_file_open(fullpath, O_RDONLY, &io),
00360 "unable to open included file %s", fullpath);
00361
00362 dbg_err_if(io_printf(p->out, "<%% #line 1 \"%s\" \n %%>", fullpath));
00363
00364
00365 ppc = parser_get_cb_arg(p);
00366 dbg_err_if(preprocess(io, p->out, ppc));
00367
00368 dbg_err_if(io_printf(p->out, "<%% #line %d \"%s\" \n %%>",
00369 p->code_line, file));
00370
00371 io_free(io);
00372
00373 return 0;
00374 err:
00375 if(io)
00376 io_free(io);
00377 return ~0;
00378 }
00379
00380 static int kblock_get_by_name(kblock_t *parent, const char *name,
00381 kblock_t **pfound, size_t *pidx)
00382 {
00383 kblock_t *b;
00384 size_t i;
00385
00386 dbg_err_if(parent == NULL);
00387
00388 for(i = 0; (b = u_list_get_n(parent->children, i)) != NULL; ++i)
00389 {
00390 if(b->name && strcasecmp(b->name, name) == 0)
00391 {
00392 *pfound = b;
00393 *pidx = i;
00394 return 0;
00395 }
00396 if(kblock_get_by_name(b, name, pfound, pidx) == 0)
00397 return 0;
00398 }
00399
00400 err:
00401 return ~0;
00402 }
00403
00404 static int process_directive_block(parser_t *p, const char *name)
00405 {
00406 kblock_t *block = NULL, *old;
00407 ppctx_t *ppc;
00408 char file[U_FILENAME_MAX];
00409 size_t idx;
00410
00411 dbg_err_if((ppc = parser_get_cb_arg(p)) == NULL);
00412
00413
00414 dbg_err_if(kblock_create(name, NULL, 0, &block));
00415
00416 dbg_err_if(io_name_get(p->in, file, U_FILENAME_MAX));
00417
00418 ppc->lev++;
00419
00420 if(!ppc->extending)
00421 {
00422 con_err_ifm(!kblock_get_by_name(ppc->top, name, &old, &idx),
00423 "[%s:%d] error: block named %s already exists", file, p->code_line,
00424 name);
00425
00426
00427 dbg_err_if(kblock_push_child(ppc->cur, block));
00428
00429 ppc->cur = block;
00430
00431 return 0;
00432 }
00433
00434 ppc->extending++;
00435
00436
00437
00438 if(kblock_get_by_name(ppc->top, name, &old, &idx))
00439 {
00440 if(ppc->cur == ppc->top)
00441 {
00442
00443 u_con("[%s:%d] warning: extending a block (%s) that does not exist "
00444 "in the base templates, ignoring", file, p->code_line, name);
00445
00446
00447 dbg_err_if(kblock_push_child(ppc->dead, block));
00448
00449 } else {
00450
00451 if(ppc->lev)
00452 {
00453
00454 dbg_err_if(kblock_push_child(ppc->cur, block));
00455 }
00456 }
00457
00458 } else {
00459
00460
00461
00462
00463
00464
00465
00466
00467 block->ancestor = old;
00468 block->parent = old->parent;
00469
00470
00471 dbg_err_if(u_list_insert(old->parent->children, block, idx));
00472
00473
00474 dbg_err_if(u_list_del(old->parent->children, old));
00475 }
00476
00477 ppc->cur = block;
00478
00479 return 0;
00480 err:
00481 if(block)
00482 kblock_free(block);
00483 return ~0;
00484 }
00485
00486 static int process_directive_endblock(parser_t *p, const char *name)
00487 {
00488 ppctx_t *ppc;
00489
00490 dbg_err_if((ppc = parser_get_cb_arg(p)) == NULL);
00491
00492 dbg_err_if(ppc->cur == NULL);
00493
00494 tr_err_ifm(--ppc->lev < 0, "unbalanced endblock directive");
00495
00496
00497 if(name)
00498 tr_err_ifm(ppc->cur->name == NULL || strcasecmp(name, ppc->cur->name),
00499 "endblock name is not correct (\"%s\" used when closing to "
00500 "\"%s\" block)", name, ppc->cur->name);
00501
00502 ppc->cur = ppc->cur->parent;
00503
00504 if(ppc->extending)
00505 {
00506
00507 if(--ppc->extending == 1)
00508 ppc->cur = ppc->top;
00509 }
00510
00511 return 0;
00512 err:
00513 return ~0;
00514 }
00515
00516 static int process_directive_inherit(parser_t *p)
00517 {
00518 ppctx_t *ppc;
00519 kblock_t *anc, *b;
00520 int i;
00521
00522 dbg_err_if((ppc = parser_get_cb_arg(p)) == NULL);
00523
00524 dbg_err_if(ppc->cur == NULL);
00525
00526 anc = ppc->cur->ancestor;
00527 tr_err_ifm(anc == NULL, "inherit directive used in a block "
00528 "(\"%s\") that is not extending another block", ppc->cur->name);
00529
00530
00531
00532 for(i = 0; (b = u_list_get_n(anc->children, i)) != NULL; ++i)
00533 dbg_err_if(kblock_push_child(ppc->cur, b));
00534
00535
00536 while(u_list_count(anc->children))
00537 dbg_err_if(u_list_del_n(anc->children, 0, NULL));
00538
00539 return 0;
00540 err:
00541 return ~0;
00542 }
00543
00544 static int process_directive(parser_t *p, char *buf)
00545 {
00546 ppctx_t *ppc;
00547 char *tok, *pp;
00548 char fullpath[U_FILENAME_MAX];
00549
00550 dbg_return_if (p == NULL, ~0);
00551 dbg_return_if (buf == NULL, ~0);
00552
00553
00554 dbg_err_if((ppc = parser_get_cb_arg(p)) == NULL);
00555
00556
00557 tr_err_ifm((tok = strtok_r(buf, " \t", &pp)) == NULL,
00558 "bad or missing preprocessor command");
00559
00560 if(strcasecmp(tok, "include") == 0)
00561 {
00562
00563 tr_err_ifm((tok = strtok_r(NULL, " \t\"", &pp)) == NULL,
00564 "bad or missing include filename");
00565
00566
00567 dbg_err_if(include_file_full_path(p, tok, fullpath, U_FILENAME_MAX));
00568
00569 dbg_err_if(ppctx_depend_push(ppc, fullpath));
00570
00571 dbg_err_if(process_directive_include(p, tok));
00572
00573 } else if(strcasecmp(tok, "extends") == 0) {
00574
00575
00576 tr_err_ifm((tok = strtok_r(NULL, " \t\"", &pp)) == NULL,
00577 "bad or missing 'extends' filename");
00578
00579 tr_err_ifm(p->code_line > 1, "child templates must start with the "
00580 "'<%@ extends \"FILE\" %>' directive (first line) %d");
00581
00582
00583 dbg_err_if(include_file_full_path(p, tok, fullpath, U_FILENAME_MAX));
00584
00585 dbg_err_if(ppctx_depend_push(ppc, fullpath));
00586
00587
00588 dbg_err_if(process_directive_include(p, tok));
00589
00590 con_err_ifm(ppc->lev, "[%s] error: unclosed block \"%s\"", tok,
00591 ppc->cur->name);
00592
00593 ppc->extending++;
00594
00595 } else if(strcasecmp(tok, "block") == 0) {
00596
00597
00598 tr_err_ifm((tok = strtok_r(NULL, " \t\"", &pp)) == NULL,
00599 "bad or missing 'block' name");
00600
00601 dbg_err_if(process_directive_block(p, tok));
00602
00603 } else if(strcasecmp(tok, "endblock") == 0) {
00604
00605
00606 tok = strtok_r(NULL, " \t\"", &pp);
00607
00608 dbg_err_if(process_directive_endblock(p, tok));
00609
00610 } else if(strcasecmp(tok, "inherit") == 0) {
00611
00612 dbg_err_if(process_directive_inherit(p));
00613
00614 } else {
00615 tr_err("unknown preprocessor directive: %s", tok);
00616 }
00617
00618 return 0;
00619 err:
00620 return ~0;
00621 }
00622
00623 static int parse_directive(parser_t *p, void *arg, const char *buf, size_t sz)
00624 {
00625 enum { LINE_BUFSZ = 1024 };
00626 char line[LINE_BUFSZ];
00627 io_t *io = NULL;
00628
00629 u_unused_args(arg);
00630
00631 dbg_return_if (p == NULL, ~0);
00632 dbg_return_if (buf == NULL, ~0);
00633
00634 dbg_err_if(io_mem_create((char*)buf, sz, 0, &io));
00635
00636 while(io_gets(io, line, LINE_BUFSZ) > 0)
00637 dbg_err_if(process_directive(p, line));
00638
00639 io_free(io);
00640
00641 return 0;
00642 err:
00643 if(io)
00644 io_free(io);
00645 return ~0;
00646 }
00647
00648 static int cb_pre_html_block(parser_t *p, void *arg, const char *buf, size_t sz)
00649 {
00650 ppctx_t *ppc = (ppctx_t*)arg;
00651 kblock_t *block = NULL;
00652 char file[U_FILENAME_MAX];
00653 int ln;
00654 size_t i;
00655
00656 u_unused_args(arg);
00657
00658 dbg_err_if (p == NULL);
00659 dbg_err_if (ppc == NULL);
00660
00661
00662 dbg_err_if(kblock_create(NULL, buf, sz, &block));
00663
00664 if(ppc->cur == ppc->top && ppc->extending)
00665 {
00666 for(ln = p->code_line, i = 0; i < sz; ++i)
00667 {
00668 if(buf[i] == '\n')
00669 ln++;
00670 if(!isspace(buf[i]))
00671 {
00672 dbg_err_if(io_name_get(p->in, file, U_FILENAME_MAX));
00673 u_con("[%s:%d] warning: text out of blocks is not allowed in "
00674 "child templates, ignoring", file, ln);
00675 break;
00676 }
00677 }
00678
00679
00680 dbg_err_if(kblock_push_child(ppc->dead, block));
00681 } else {
00682
00683
00684 dbg_err_if(kblock_push_child(ppc->cur, block));
00685 }
00686
00687 return 0;
00688 err:
00689 return ~0;
00690 }
00691
00692 static int cb_pre_code_block(parser_t *p, int cmd, void *arg, const char *buf,
00693 size_t sz)
00694 {
00695 u_string_t *ustr = NULL;
00696 kblock_t *block = NULL;
00697 ppctx_t *ppc;
00698 char file[U_FILENAME_MAX];
00699
00700 dbg_err_if (p == NULL);
00701 dbg_err_if((ppc = parser_get_cb_arg(p)) == NULL);
00702
00703 if(cmd == '@')
00704 {
00705 dbg_err_if(parse_directive(p, arg, buf, sz));
00706 } else {
00707
00708 dbg_err_if(u_string_create(NULL, 0, &ustr));
00709
00710 dbg_err_if(io_name_get(p->in, file, U_FILENAME_MAX));
00711
00712
00713 if(cmd == 0 || cmd == '=')
00714 {
00715 dbg_err_if(u_string_aprintf(ustr, "<%% #line %d \"%s\" \n%%><%%",
00716 p->code_line, file));
00717 if(cmd == '=')
00718 dbg_err_if(u_string_aprintf(ustr, "="));
00719 } else {
00720 dbg_err_if(u_string_aprintf(ustr,
00721 "<%%%c #line %d \"%s\" \n%%><%%%c",
00722 cmd, p->code_line, file, cmd));
00723 }
00724 dbg_err_if(u_string_aprintf(ustr, "%.*s", sz, buf));
00725 dbg_err_if(u_string_aprintf(ustr, "%%>"));
00726
00727
00728 dbg_err_if(u_string_aprintf(ustr, "<%%%c #line 0 __PG_FILE_C__ \n%%>",
00729 (cmd == '!' && cmd != 0 ? cmd : ' ')));
00730
00731 dbg_err_if(kblock_create(NULL, u_string_c(ustr), u_string_len(ustr),
00732 &block));
00733
00734 if(ppc->cur == ppc->top && ppc->extending)
00735 {
00736 dbg_err_if(io_name_get(p->in, file, U_FILENAME_MAX));
00737 u_con("[%s:%d] warning: code out of blocks is not allowed in child "
00738 "templates, ignoring", file, p->code_line);
00739
00740
00741 dbg_err_if(kblock_push_child(ppc->dead, block));
00742 } else {
00743
00744 dbg_err_if(kblock_push_child(ppc->cur, block));
00745 }
00746
00747 dbg_err_if(u_string_free(ustr));
00748 ustr = NULL;
00749 }
00750
00751 return 0;
00752 err:
00753 if(ustr)
00754 u_string_free(ustr);
00755 if(block)
00756 kblock_free(block);
00757 return ~0;
00758 }
00759
00760 static int preprocess(io_t *in, io_t *out, ppctx_t *ppc)
00761 {
00762 parser_t *p = NULL;
00763 char file[U_FILENAME_MAX];
00764
00765 dbg_err_if(in == NULL);
00766 dbg_err_if(out == NULL);
00767 dbg_err_if(ppc == NULL);
00768
00769
00770 dbg_err_if(parser_create(&p));
00771
00772 parser_set_cb_arg(p, ppc);
00773
00774
00775 dbg_err_if(io_name_get(in, file, U_FILENAME_MAX));
00776
00777 parser_set_io(p, in, out);
00778
00779 parser_set_cb_code(p, cb_pre_code_block);
00780 parser_set_cb_html(p, cb_pre_html_block);
00781
00782 dbg_err_if(parser_run(p));
00783
00784 con_err_ifm(ppc->lev, "[%s] error: unclosed block \"%s\"", file,
00785 ppc->cur->name);
00786
00787 parser_free(p);
00788
00789 return 0;
00790 err:
00791 if(p)
00792 parser_free(p);
00793 return ~0;
00794 }
00795
00796 static int fix_line_decl(trans_info_t *pti)
00797 {
00798 io_t *in = NULL, *tmp = NULL;
00799 char tname[U_FILENAME_MAX], buf[1024];
00800 int ln = 0;
00801
00802
00803 con_err_ifm(u_file_open(pti->file_out, O_RDONLY, &in),
00804 "unable to open %s", pti->file_out);
00805
00806
00807 con_err_if(u_tmpfile_open(NULL, &tmp));
00808
00809 while(io_gets(in, buf, sizeof(buf)) > 0)
00810 {
00811 if(strstr(buf, "#line 0 __PG_FILE_C__") == NULL)
00812 {
00813 io_printf(tmp, "%s", buf);
00814 ln++;
00815 } else
00816 io_printf(tmp, "#line %d \"%s\"\n", ln + 2, pti->file_out);
00817 }
00818
00819
00820 dbg_err_if(io_name_get(tmp, tname, U_FILENAME_MAX));
00821
00822 io_free(in), in = NULL;
00823 io_free(tmp), tmp = NULL;
00824
00825
00826 u_remove(pti->file_out);
00827
00828 u_move(tname, pti->file_out);
00829
00830 return 0;
00831 err:
00832 if(in)
00833 io_free(in);
00834 if(tmp)
00835 io_free(tmp);
00836 return ~0;
00837 }
00838
00839 int translate(trans_info_t *pti)
00840 {
00841 io_t *in = NULL, *out = NULL, *tmp = NULL, *depend = NULL;
00842 ppctx_t *ppc = NULL;
00843 codec_t *gzip = NULL, *aes = NULL;
00844 char tname[U_FILENAME_MAX];
00845
00846 dbg_return_if (pti == NULL, ~0);
00847
00848
00849 con_err_ifm(u_file_open(pti->file_in, O_RDONLY, &in),
00850 "unable to open %s", pti->file_in);
00851
00852
00853 con_err_ifm(u_file_open(pti->file_out, O_CREAT | O_TRUNC | O_WRONLY, &out),
00854 "unable to open %s", pti->file_out);
00855
00856
00857 if(pti->depend_out[0])
00858 con_err_ifm(u_file_open(pti->depend_out, O_CREAT | O_TRUNC | O_WRONLY,
00859 &depend), "unable to open %s", pti->depend_out);
00860
00861
00862 if(translate_is_a_script(pti->file_in))
00863 {
00864
00865 con_err_if(u_tmpfile_open(NULL, &tmp));
00866
00867
00868 dbg_err_if(ppctx_create(&ppc));
00869
00870
00871 dbg_err_if(preprocess(in, tmp, ppc));
00872
00873
00874 dbg_err_if(ppctx_print(ppc, tmp));
00875
00876
00877 io_seek(tmp, 0);
00878
00879
00880 dbg_err_if(translate_script_to_c(tmp, out, pti));
00881
00882
00883 dbg_err_if(io_name_get(tmp, tname, U_FILENAME_MAX));
00884
00885
00886 io_free(tmp); tmp = NULL;
00887
00888
00889 u_remove(tname);
00890
00891
00892 if(depend)
00893 dbg_err_if(ppctx_print_depend(ppc, in, out, depend));
00894
00895 dbg_err_if(ppctx_free(ppc)); ppc = NULL;
00896 } else {
00897
00898 #ifdef HAVE_LIBZ
00899 if(pti->comp)
00900 {
00901
00902 dbg_err_if(codec_gzip_create(GZIP_COMPRESS, &gzip));
00903 dbg_err_if(io_codec_add_tail(in, gzip));
00904 gzip = NULL;
00905 }
00906 #endif
00907 #ifdef SSL_ON
00908
00909 if(pti->encrypt)
00910 {
00911
00912 dbg_err_if(codec_cipher_create(CIPHER_ENCRYPT, EVP_aes_256_cbc(),
00913 pti->key, NULL, &aes));
00914 dbg_err_if(io_codec_add_tail(in, aes));
00915 aes = NULL;
00916 }
00917 #endif
00918 dbg_err_if(translate_opaque_to_c(in, out, pti));
00919 }
00920
00921 if(pti->depend_out[0])
00922 io_free(depend), depend = NULL;
00923
00924 io_free(out), out = NULL;
00925 io_free(in), in = NULL;
00926
00927
00928 if(translate_is_a_script(pti->file_in))
00929 dbg_err_if(fix_line_decl(pti));
00930
00931 return 0;
00932 err:
00933 if(pti && strlen(pti->emsg))
00934 u_con("%s", pti->emsg);
00935 if(gzip)
00936 codec_free(gzip);
00937 if(tmp)
00938 io_free(tmp);
00939 if(depend)
00940 io_free(depend);
00941 if(in)
00942 io_free(in);
00943 if(out)
00944 io_free(out);
00945 return ~0;
00946 }