diff options
Diffstat (limited to 'utils/split-messages.c')
-rw-r--r-- | utils/split-messages.c | 549 |
1 files changed, 0 insertions, 549 deletions
diff --git a/utils/split-messages.c b/utils/split-messages.c deleted file mode 100644 index 581151485..000000000 --- a/utils/split-messages.c +++ /dev/null @@ -1,549 +0,0 @@ -/** - * \file - * simple tool to split fat messages file without the capabilities of - * the full tool but without the dependancy on perl. - * - */ - -#include <unistd.h> -#include <stdlib.h> -#include <stdio.h> -#include <string.h> -#include <zlib.h> - -#include "errors.h" - -enum out_fmt { - OUTPUTFMT_NONE = 0, - OUTPUTFMT_MESSAGES, -}; - -/** - * parameters that control behaviour of tool - */ -struct param { - /** - * compress output - */ - int compress; - /** - * select language - */ - char *selected; - /** - * fallback language for items unavailable in selecte dlanguage - */ - char *fallback; - int warnings; - char *platform; - enum out_fmt format; - char *infilename; - char *outfilename; -}; - -struct trnsltn_entry { - struct trnsltn_entry *next; - char *lang; - char *key; - char *value; -}; - -static nserror usage(int argc, char **argv) -{ - fprintf(stderr, - "Usage: %s -l lang [-z] [-d lang] [-W warning] [-o <file>] [-i <file>] [-p platform] [-f format] [<file> [<file>]]\n" - "Options:\n" - " -z Gzip output\n" - " -l lang Language to select for\n" - " -d lang Fallback language [default: en]\n" - " -W warning Warnings generated none, all [default: none]\n" - " -p platform Platform to select for any, gtk, ami [default: any]\n" - " -f format Output format [default: messages]\n" - " -i filename Input file\n" - " -o filename Output file\n", - argv[0]); - return NSERROR_OK; -} - -/** - * process command line arguments - * - * - */ -static nserror process_cmdline(int argc, char **argv, struct param *param) -{ - int opt; - - memset(param, 0, sizeof(*param)); - - while ((opt = getopt(argc, argv, "zl:d:W:o:i:p:f:")) != -1) { - switch (opt) { - case 'z': - param->compress = 1; - break; - - case 'l': - param->selected = strdup(optarg); - break; - - case 'd': - param->fallback = strdup(optarg); - break; - - case 'W': - param->warnings = 1; - break; - - case 'o': - param->outfilename = strdup(optarg); - break; - - case 'i': - param->infilename = strdup(optarg); - break; - - case 'p': - param->platform = strdup(optarg); - break; - - case 'f': - if (strcmp(optarg, "messages") == 0) { - param->format = OUTPUTFMT_MESSAGES; - } else { - fprintf(stderr, - "output format %s not supported", - optarg); - usage(argc, argv); - return NSERROR_NOT_IMPLEMENTED; - } - break; - - default: - usage(argc, argv); - return NSERROR_BAD_PARAMETER; - } - } - - /* trailing filename arguments */ - if (optind < argc) { - param->infilename = strdup(argv[optind]); - optind++; - } - - if (optind < argc) { - param->outfilename = strdup(argv[optind]); - optind++; - } - - /* parameter checks */ - if (param->selected == NULL) { - fprintf(stderr, "A language to select must be specified\n"); - usage(argc, argv); - return NSERROR_BAD_PARAMETER; - } - - if (param->infilename == NULL) { - fprintf(stderr, "Input file required\n"); - usage(argc, argv); - return NSERROR_BAD_PARAMETER; - } - - if (param->outfilename == NULL) { - fprintf(stderr, "Output file required\n"); - usage(argc, argv); - return NSERROR_BAD_PARAMETER; - } - - if ((param->platform != NULL) && - (strcmp(param->platform, "any") ==0)) { - free(param->platform); - param->platform = NULL; - } - - /* defaults */ - if (param->fallback == NULL) { - param->fallback = strdup("en"); - } - - if (param->format == OUTPUTFMT_NONE) { - param->format = OUTPUTFMT_MESSAGES; - } - - return NSERROR_OK; -} - - -/** - * extract key/value from a line of input - * - * \retun NSERROR_OK and key_out and value_out updated - * NSERROR_NOT_FOUND if not a key/value input line - * NSERROR_INVALID if the line is and invalid format (missing colon) - */ -static nserror -get_key_value(char *line, ssize_t linelen, char **key_out, char **value_out) -{ - char *key; - char *value; - - /* skip leading whitespace for start of key */ - for (key = line; *key != 0; key++) { - if ((*key != ' ') && (*key != '\t') && (*key != '\n')) { - break; - } - } - - /* empty line or only whitespace */ - if (*key == 0) { - return NSERROR_NOT_FOUND; - } - - /* comment */ - if (*key == '#') { - return NSERROR_NOT_FOUND; - } - - /* get start of value */ - for (value = key; *value != 0; value++) { - if (*value == ':') { - *value = 0; - value++; - break; - } - } - - /* missing colon separator */ - if (*value == 0) { - return NSERROR_INVALID; - } - - /* remove delimiter from value */ - if (line[linelen - 1] == '\n') { - linelen--; - line[linelen] = 0; - } - - *key_out = key; - *value_out = value; - return NSERROR_OK; -} - - -/** - * extract language, platform and token elements from a string - */ -static nserror -get_lang_plat_tok(char *str, char **lang_out, char **plat_out, char **tok_out) -{ - char *plat; - char *tok; - - for (plat = str; *plat != 0; plat++) { - if (*plat == '.') { - *plat = 0; - plat++; - break; - } - } - if (*plat == 0) { - return NSERROR_INVALID; - } - - for (tok = plat; *tok != 0; tok++) { - if (*tok == '.') { - *tok = 0; - tok++; - break; - } - } - if (*tok == 0) { - return NSERROR_INVALID; - } - - *lang_out = str; - *plat_out = plat; - *tok_out = tok; - - return NSERROR_OK; -} - - -/** - * reverse order of entries in a translation list - */ -static nserror -translation_list_reverse(struct trnsltn_entry **tlist) -{ - struct trnsltn_entry *prev; - struct trnsltn_entry *next; - struct trnsltn_entry *curr; - - prev = NULL; - next = NULL; - curr = *tlist; - - while (curr != NULL) { - next = curr->next; - curr->next = prev; - prev = curr; - curr = next; - } - - *tlist = prev; - return NSERROR_OK; -} - - -/** - * find a translation entry from a key - * - * \todo This implementation is imcomplete! it only considers the very - * first entry on the list. this introduces the odd ordering - * requirement for keys in the fatmessages file. This is done to avoid - * an O(n^2) list search for every line of input. - * - * \param tlist translation list head - * \param key The key of the translation to search for - * \param trans_out The sucessful result - * \return NSERROR_OK and trans_out updated on success else NSERROR_NOT_FOUND; - */ -static nserror -translation_from_key(struct trnsltn_entry *tlist, - char *key, - struct trnsltn_entry **trans_out) -{ - if (tlist == NULL) { - return NSERROR_NOT_FOUND; - } - - if (strcmp(tlist->key, key) != 0) { - return NSERROR_NOT_FOUND; - } - - *trans_out = tlist; - return NSERROR_OK; -} - - -/** - * create and link an entry into translation list - */ -static nserror -translation_add(struct trnsltn_entry **tlist, - const char *lang, - const char *key, - const char *value) -{ - struct trnsltn_entry *tnew; - - tnew = malloc(sizeof(*tnew)); - if (tnew == NULL) { - return NSERROR_NOMEM; - } - tnew->next = *tlist; - tnew->lang = strdup(lang); - tnew->key = strdup(key); - tnew->value = strdup(value); - - *tlist = tnew; - return NSERROR_OK; -} - - -/** - * replace key and value on a translation entry - */ -static nserror -translation_replace(struct trnsltn_entry *tran, - const char *lang, - const char *key, - const char *value) -{ - free(tran->lang); - tran->lang = strdup(lang); - free(tran->key); - tran->key = strdup(key); - free(tran->value); - tran->value = strdup(value); - - return NSERROR_OK; -} - - -/** - * process a line of the input file - * - */ -static nserror -messageline(struct param *param, - struct trnsltn_entry **tlist, - char *line, ssize_t linelen) -{ - nserror res; - char *key; - char *value; - char *lang; - char *plat; - char *tok; - struct trnsltn_entry *tran; - - res = get_key_value(line, linelen, &key, &value); - if (res != NSERROR_OK) { - /* skip line as no valid key value pair found */ - return res; - } - - res = get_lang_plat_tok(key, &lang, &plat, &tok); - if (res != NSERROR_OK) { - /* malformed key */ - return res; - } - - if ((param->platform != NULL) && - (strcmp(plat, "all") != 0) && - (strcmp(plat, param->platform) != 0)) { - /* this translation is not for the selected platform */ - return NSERROR_OK; - } - - res = translation_from_key(*tlist, tok, &tran); - if (res == NSERROR_OK) { - if (strcmp(tran->lang, param->selected) != 0) { - /* current entry is not the selected language */ - if (strcmp(lang, param->selected) == 0) { - /* - * new entry is in selected language and - * current entry is not - */ - res = translation_replace(tran, lang, tok, value); - } else if ((strcmp(lang, param->fallback) != 0) && - (strcmp(tran->lang, param->fallback) != 0)) { - /* - * new entry is in fallback language and - * current entry is not. - */ - res = translation_replace(tran, lang, tok, value); - } - } else { - if (strcmp(tran->lang, lang) == 0) { - /* second entry with matching language */ - res = translation_replace(tran, lang, tok, value); - } - } - } else if (res == NSERROR_NOT_FOUND) { - res = translation_add(tlist, lang, tok, value); - } - - return res; -} - - -/** - * read fatmessages file and create a translation entry list - */ -static nserror -fatmessages_read(struct param *param, struct trnsltn_entry **tlist) -{ - nserror res; - FILE *infile; - char *line = NULL; - size_t linealloc = 0; - ssize_t linelen; - int linenum = 0; - - infile = fopen(param->infilename, "r"); - if (infile == NULL) { - perror("Unable to open input file"); - return NSERROR_NOT_FOUND; - } - - while (1) { - linelen = getline(&line, &linealloc, infile); - if (linelen == -1) { - break; - } - linenum++; - - res = messageline(param, tlist, line, linelen); - if ((res == NSERROR_INVALID) && (param->warnings > 0)) { - fprintf(stderr, "line %d Malformed: \"%s\"\n", - linenum, line); - } - } - - fclose(infile); - - res = translation_list_reverse(tlist); - - return res; -} - - -/** - * write output in NetSurf messages format - */ -static nserror -message_write(struct param *param, struct trnsltn_entry *tlist) -{ - gzFile outf; - const char *mode; - - if (param->compress == 0) { - mode = "wbT"; - } else { - mode = "wb9"; - } - - outf = gzopen(param->outfilename, mode); - if (outf == NULL) { - perror("Unable to open output file"); - return NSERROR_PERMISSION; - } - - gzprintf(outf, - "# This messages file is automatically generated from %s\n" - "# at build-time. Please go and edit that instead of this.\n\n", - param->infilename); - - while (tlist != NULL) { - gzprintf(outf, "%s:%s\n", tlist->key, tlist->value); - tlist = tlist->next; - } - - gzclose(outf); - - return NSERROR_OK; -} - -int main(int argc, char **argv) -{ - nserror res; - struct param param; /* control paramters */ - struct trnsltn_entry *translations = NULL; - - res = process_cmdline(argc, argv, ¶m); - if (res != NSERROR_OK) { - return EXIT_FAILURE; - } - - res = fatmessages_read(¶m, &translations); - if (res != NSERROR_OK) { - return EXIT_FAILURE; - } - - switch (param.format) { - case OUTPUTFMT_NONE: - res = NSERROR_OK; - break; - - case OUTPUTFMT_MESSAGES: - res = message_write(¶m, translations); - break; - } - - if (res != NSERROR_OK) { - return EXIT_FAILURE; - } - - return EXIT_SUCCESS; -} |