diff -ur gettext-0.10.35/src/xgettext.c gettext-0.10.35-dml/src/xgettext.c --- gettext-0.10.35/src/xgettext.c Wed Apr 29 18:57:50 1998 +++ gettext-0.10.35-dml/src/xgettext.c Sat Jan 13 00:40:22 2001 @@ -711,6 +711,195 @@ NULL, /* comment_special */ }; +/* DML scanner */ +struct dml_parser_state { + FILE *in; + char *filename; + int line; + int close; + + char *buf; + int buflen, bufpos; + int seen; + message_list_ty *mlp; +}; + +static void +dml_open_file(ctx) + struct dml_parser_state *ctx; +{ + size_t len1, len2; + int j; + const char *dir; + char *new_name; + + ctx->line = 1; + ctx->close = 1; + ctx->buf = NULL; + ctx->buflen = 0; + ctx->bufpos = 0; + + if (strcmp(ctx->filename, "-") == 0) { + ctx->filename = xstrdup(_("standard input")); + ctx->in = stdin; + ctx->close = 0; + return; + } + if (ctx->filename[0] == '/') { + ctx->in = fopen(ctx->filename, "r"); + if (ctx->in == 0) + error(EXIT_FAILURE, errno, _("\ +error while opening \"%s\" for reading"), + ctx->filename); + ctx->filename = xstrdup(ctx->filename); + return; + } + + len2 = strlen(ctx->filename); + for (j = 0;; ++j) { + dir = dir_list_nth(j); + if (dir == NULL) + error(EXIT_FAILURE, ENOENT, _("\ +error while opening \"%s\" for reading"), ctx->filename); + + if (dir[0] == '.' && dir[1] == '\0') + new_name = xstrdup(ctx->filename); + else { + len1 = strlen(dir); + new_name = xmalloc(len1 + len2 + 2); + stpcpy(stpcpy(stpcpy(new_name, dir), "/"), ctx->filename); + } + + ctx->in = fopen(new_name, "r"); + if (ctx->in != NULL) + break; + + if (errno != ENOENT) + error(EXIT_FAILURE, errno, _("\ +error while opening \"%s\" for reading"), new_name); + free(new_name); + } + + ctx->filename = new_name; +} + +static void dml_remember_a_message(ctx) + struct dml_parser_state *ctx; +{ + char *msgid; + message_ty *mp; + char *msgstr; + + msgid = ctx->buf; + + /* See whether we shall exclude this message. */ + if (exclude != NULL && message_list_search(exclude, msgid) != NULL) + return; + + /* See if we have seen this message before. */ + mp = message_list_search(ctx->mlp, msgid); + if (mp == NULL) { + static lex_pos_ty pos = { __FILE__, __LINE__ }; + + /* Allocate a new message and append the message to the list. */ + mp = message_alloc(xstrdup(msgid), NULL); + /* Do not free msgid. */ + message_list_append(ctx->mlp, mp); + + /* Construct the msgstr from the prefix and suffix, otherwise use the + empty string. */ + if (msgstr_prefix) { + msgstr = (char *) xmalloc(strlen(msgstr_prefix) + + strlen(msgid) + + strlen(msgstr_suffix) + + 1); + stpcpy(stpcpy + (stpcpy(msgstr, msgstr_prefix), msgid), + msgstr_suffix); + } else + msgstr = ""; + message_variant_append(mp, MESSAGE_DOMAIN_DEFAULT, msgstr, + strlen(msgstr) + 1, &pos); + + mp->is_c_format = no; + mp->do_wrap = yes; /* By default we wrap. Is it ok? */ + } + + /* Remember where we saw this msgid. */ + if (line_comment) + message_comment_filepos(mp, ctx->filename, ctx->line); +} + +/* Read a string until '}}' is found. */ +static void +dml_get_string(ctx) + struct dml_parser_state *ctx; +{ + int c, last_brace = 0; + + ctx->seen = ctx->line; + ctx->bufpos = 0; + + for (;;) { + c = fgetc(ctx->in); + if (c == EOF) + error(EXIT_FAILURE, 0, _("%s:%d: unmatched {{"), + ctx->filename, ctx->seen); + if (c == '\n') + ctx->line++; + + if (c == '}') { + if (last_brace) + break; + last_brace = 1; + } else + last_brace = 0; + if (ctx->bufpos == ctx->buflen) { + if (ctx->buflen == 0) + ctx->buflen = 128; + ctx->buf = xrealloc(ctx->buf, ctx->buflen *= 2); + } + ctx->buf[ctx->bufpos++] = c; + } + + /* remove last } */ + ctx->buf[--ctx->bufpos] = 0; + dml_remember_a_message(ctx); +} + +/* We don't really bother scanning the shell syntax. + We just hunt for strings in {{ }} + */ +static void +scanner_dml(filename, mlp) + char *filename; + message_list_ty *mlp; +{ + struct dml_parser_state ctx; + int c; + + ctx.filename = filename; + ctx.mlp = mlp; + dml_open_file(&ctx); + + for (;;) { + while ((c = fgetc(ctx.in)) != EOF) + if (c == '{' && + ((c = fgetc(ctx.in)) == EOF || c == '{')) + break; + else if (c == '\n') + ctx.line++; + + if (c == EOF) + break; + dml_get_string(&ctx); + } + + if (ctx.close) + fclose(ctx.in); + free(ctx.buf); + free(ctx.filename); +} static void read_exclusion_file (file_name) @@ -1330,6 +1519,7 @@ { "C", scanner_c, }, { "C++", scanner_cxx, }, { "PO", read_po_file, }, + { "DML", scanner_dml, }, /* Here will follow more languages and their scanners: awk, perl, etc... Make sure new scanners honor the --exlude-file option. */ };