diff --git a/src/runtime/c/utils/pgf-service.c b/src/runtime/c/utils/pgf-service.c deleted file mode 100644 index f63b17f9f..000000000 --- a/src/runtime/c/utils/pgf-service.c +++ /dev/null @@ -1,291 +0,0 @@ -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define NO_FCGI_DEFINES -#include -#include -#include - -#define ISXDIGIT(c) ( \ - (c >= 48 && c <= 57) || \ - ((c & ~0x20) >= 65 && (c & ~0x20) <= 70) \ -) - -void -url_escape(char *str) -{ - char *pr = str, *pw = str; - size_t len = strlen(str); - - for (;;) { - if (((size_t) (pr - str)) >= len) - break; - - if (*pr == '%' && - (((size_t) (pr - str))+2) < len && - ISXDIGIT(*(pr+1)) && - ISXDIGIT(*(pr+2))) - { - pr++; - - char hexstr[3]; - hexstr[0] = *pr++; - hexstr[1] = *pr++; - hexstr[2] = 0; - - char *ptr; - int ch = strtoul(hexstr, &ptr, 16); - *pw++ = (char) (ch & 0x7f); - } - else if(*pr == '+') { - *pw++ = ' '; - } - else { - *pw++ = *pr++; - } - } - - *pw++ = 0; -} - -static int -render(PgfPGF* pgf, PgfExpr expr, GuPool* pool) -{ - int pid; - int pc[2]; /* Parent to child pipe */ - int cp[2]; /* Child to parent pipe */ - char ch; - - /* Make pipes */ - if (pipe(pc) < 0) - return 0; - if (pipe(cp) < 0) - return 0; - - /* Create a child to run command. */ - switch (pid = fork()) - { - case -1: - return 0; - case 0: - /* Child. */ - dup2(cp[1], 1); /* Make stdout go to write - end of pipe. */ - dup2(pc[0], 0); /* Make stdin come from read - end of pipe. */ - close(pc[1]); - close(cp[0]); - - char *args[] = {"dot", "-Tsvg", NULL}; - execvp(args[0], args); - - exit(1); - default: { - /* Parent. */ - FILE* fstream = fdopen(pc[1], "w"); - GuOut* out = gu_file_out(fstream, pool); - GuExn* err = gu_new_exn(NULL, gu_kind(type), pool); - - pgf_graphviz_abstract_tree(pgf, expr, out, err); - fclose(fstream); - - close(cp[1]); - while (read(cp[0], &ch, 1) == 1) - { - FCGI_putchar(ch); - } - return 1; - } - } -} - -static void -put_gu_string(GuString s) { - GuWord w = s.w_; - uint8_t buf[sizeof(GuWord)]; - - char* src; - size_t len; - if (w & 1) { - len = (w & 0xff) >> 1; - gu_assert(len <= sizeof(GuWord)); - size_t i = len; - while (i > 0) { - w >>= 8; - buf[--i] = w & 0xff; - } - src = (char*) buf; - } else { - uint8_t* p = (void*) w; - len = (p[0] == 0) ? ((size_t*) p)[-1] : p[0]; - src = (char*) &p[1]; - } - - for (size_t i = 0; i < len; i++) { - FCGI_putchar(src[i]); - } -} - -static void -linearize(PgfConcr* concr, PgfExpr expr, GuPool* pool) -{ - GuStringBuf* sbuf = gu_string_buf(pool); - GuOut* out = gu_string_buf_out(sbuf); - - GuExn* err = gu_new_exn(NULL, gu_kind(type), pool); - - pgf_linearize(concr, expr, out, err); - - GuString s = gu_string_buf_freeze(sbuf, pool); - put_gu_string(s); -} - -static void -print_lang(GuMapItor* fn, const void* key, void* value, GuExn* err) -{ - PgfCId lang = *((PgfCId*) key); - put_gu_string(lang); - FCGI_putchar(' '); -} - -int main () -{ - // Create the pool that is used to allocate everything - GuPool* pool = gu_new_pool(); - int status = EXIT_SUCCESS; - - // Create an exception frame that catches all errors. - GuExn* err = gu_new_exn(NULL, gu_kind(type), pool); - - char* grammar_path = getenv("GRAMMAR_PATH"); - if (grammar_path == NULL) { - fprintf(stderr, "Please set the GRAMMAR_PATH variable\n"); - status = EXIT_FAILURE; - goto fail; - } - - // Read the PGF grammar. - char* grammar_name = "/ParseEngAbs.pgf"; - char* grammar_file = malloc(strlen(grammar_path)+strlen(grammar_name)+1); - strcpy(grammar_file,grammar_path); - strcat(grammar_file,grammar_name); - PgfPGF* pgf = pgf_read(grammar_file, pool, err); - free(grammar_file); - - // If an error occured, it shows in the exception frame - if (!gu_ok(err)) { - fprintf(stderr, "Reading PGF failed\n"); - status = EXIT_FAILURE; - goto fail; - } - - // Read the extra probs. - char* probs_name = "/ParseEngAbs3.probs"; - char* probs_file = malloc(strlen(grammar_path)+strlen(probs_name)+1); - strcpy(probs_file,grammar_path); - strcat(probs_file,probs_name); - pgf_load_meta_child_probs(pgf, probs_file, pool, err); - free(probs_file); - - if (!gu_ok(err)) { - fprintf(stderr, "Loading meta child probs failed\n"); - status = EXIT_FAILURE; - goto fail; - } - - GuString cat = "Phr"; - GuString from_lang = "ParseEng"; - PgfConcr* from_concr = - pgf_get_language(pgf, from_lang); - if (!from_concr) { - status = EXIT_FAILURE; - goto fail; - } - - // Register a callback for the literal category Symbol - pgf_parser_add_literal(from_concr, "Symb", - &pgf_nerc_literal_callback); - - while (FCGI_Accept() >= 0) { - char* query = getenv("QUERY_STRING"); - - char sentence[202]; - char to_lang_buf[51] = ""; - if (query == NULL || - sscanf(query, "sentence=%200[^&]&to=%50[^&]", sentence, to_lang_buf) < 1) { - FCGI_printf("Status: 200 OK\r\n"); - FCGI_printf("Content-type: text/plain; charset=utf-8\r\n\r\n"); - - GuMapItor clo = { print_lang }; - pgf_iter_languages(pgf, &clo, NULL); - FCGI_putchar('\n'); - } else { - // We create a temporary pool for translating a single - // sentence, so our memory usage doesn't increase over time. - GuPool* ppool = gu_new_pool(); - - PgfConcr* to_concr = NULL; - if (strlen(to_lang_buf) > 0) { - GuString to_lang = to_lang_buf; - to_concr = - pgf_get_language(pgf, to_lang); - if (!to_concr) { - status = EXIT_FAILURE; - goto fail; - } - } - - url_escape(sentence); - int len = strlen(sentence); - sentence[len] = '\n'; - sentence[len+1] = '\0'; - - GuReader *rdr = - gu_string_reader(sentence, ppool); - PgfLexer *lexer = - pgf_new_simple_lexer(rdr, ppool); - - GuEnum* result = - pgf_parse(from_concr, cat, lexer, ppool, ppool); - if (result == NULL) { - FCGI_printf("Status: 500 Internal Server Error\r\n"); - FCGI_printf("Content-type: text/plain\r\n" - "\r\n" - "Parsing failed"); - goto done; - } - - PgfExprProb* ep = gu_next(result, PgfExprProb*, ppool); - if (ep == NULL) { - FCGI_printf("Status: 500 Internal Server Error\r\n"); - FCGI_printf("Content-type: text/plain\r\n" - "\r\n" - "The sentence was parsed but there was no tree constructed"); - goto done; - } - - FCGI_printf("Status: 200 OK\r\n"); - if (to_concr == NULL) { - FCGI_printf("Content-type: image/svg+xml\r\n\r\n"); - render(pgf, ep->expr, ppool); - } else { - FCGI_printf("Content-type: text/plain; charset=utf-8\r\n\r\n"); - linearize(to_concr, ep->expr, ppool); - } - -done: - gu_pool_free(ppool); - } - } - -fail: - gu_pool_free(pool); - return status; -}