/* CONTEXT: Determine whether a GI is valid in the present structural context. Returns RCHIT if valid, RCEND if element has ended, RCREQ if a different element is required, and RCMISS if it is totally invalid. On entry, pos points to the model token to be tested against the GI. TO DO: Save allowed GIs for an error message on an RCMISS. Support a "query" mode (what is allowed now?) by working with a copy of pos. */ int context(struct etd *gi, /* ETD of new GI. */ struct thdr mod[], /* Model of current open element. */ struct mpos pos[], /* Position in open element's model. */ UNCH *statuspt, /* Token status: RCHIT RCMISS RCEND RCREQ RCNREQ*/ int mexts) /* >0=stack level of minus grp; -1=plus; 0=none.*/ { UNCH toccsv, gtypesv; /* Save token's TOCC and GTYPE in case grp ends.*/ if (mexts == -1) { if (STATUS == RCEND) return RCPEX; copypos(savedpos, pos); } Tstart = T; /* Save starting token for AND group testing. */ while (STATUS!=RCMISS && STATUS!=RCEND) { TRACEGI("CONTEXT", gi, mod, pos, Tstart); while (TTYPE==TTOR || TTYPE==TTSEQ || TTYPE==TTAND) { pos[P+1].g = M++; pos[++P].t = 1; HITCLEAR(H); Tstart = T; /* Save starting token for AND group testing. */ TRACEGI("OPENGRP", gi, mod, pos, Tstart); } STATUS = (UNCH)tokenreq(gi, mod, pos); TRACEGI("STATUS", gi, mod, pos, Tstart); if (gi==TOKEN.tu.thetd) { /* Hit in model. */ STATUS = (UNCH)RCHIT; gtypesv = GTYPE; toccsv = TOCC; newtoken(mod, pos, statuspt); return(mexts<=0 ? RCHIT : (gtypesv==TTOR || BITON(toccsv, TOPT)) ? RCMEX : RCHITMEX); } if (STATUS==RCREQ) { if (mexts == -1) break; STATUS = RCHIT; nextetd = TOKEN.tu.thetd; newtoken(mod, pos, statuspt); return(RCREQ); } /* else if (STATUS==RCNREQ) */ if (mexts>0) return(RCMEX); newtoken(mod, pos, statuspt); } if (mexts == -1) { copypos(pos, savedpos); return STATUS = RCPEX; } return((int)STATUS); }
extract(char *infile, char *outfile, char **langIDs) { FILE *fp, *outf; long fpos = 0; char **langID; if ((fp = fopen(infile, "r")) == NULL) { perror(infile); return -1; } if (outfile == NULL) { outf = stdout; } else { if ((outf = fopen(outfile, "w")) == NULL) { perror(outfile); fclose(fp); return(-1); } } while (readstr(fp, strbuf, 0)) { copypos(fp, outf, fpos); fpos = ftell(fp); while (readstr(fp, strbuf, 1)) { if (*strbuf == '\0') break; for (langID = langIDs; *langID; ++langID) { if (strcmp(lang, *langID) == 0) copypos(fp, outf, fpos); } fpos = ftell(fp); } } copypos(fp, outf, fpos); fflush(outf); if (ferror(outf)) { perror(outfile); return -1; } return 0; }
merge(char *base_file, char *lang_file, char *outfile, char *langID) { FILE *fp, *outf; long fpos = 0, filepos; int newmsgs = 0; if ((langf = fopen(lang_file, "r")) == NULL) { perror(lang_file); return -1; } strcpy(langfile, lang_file); if (langID) strcpy(language, langID); else language[0] = '\0'; /* use first language found */ errcount = 0; make_indexfile(NULL); if (errcount) return -1; langfile[0] = '\0'; /* don't print filename in error msgs */ if ((fp = fopen(base_file, "r")) == NULL) { perror(base_file); return -1; } if (outfile == NULL) outf = stdout; else { if ((outf = fopen(outfile, "w")) == NULL) { perror(outfile); return(-1); } } while (readstr(fp, strbuf, 0)) { copypos(fp, outf, fpos); fpos = ftell(fp); filepos = lookup_offset(message_crc(strbuf)); if (filepos == -1) { fprintf(outf, "No translation\n"); ++newmsgs; } else { fseek(langf, filepos, SEEK_SET); readstr(langf, strbuf, 1); copypos(langf, outf, filepos); } while (readstr(fp, strbuf, 1)) if (*strbuf == '\0') break; } copypos(fp, outf, fpos); fflush(outf); if (ferror(outf)) { perror(outfile); return -1; } if (newmsgs) fprintf(stderr, "%d untranslated messages\n", newmsgs); return errcount; }