int /* O - Exit code */ main(int argc, /* I - Number of command-line args */ char *argv[]) /* I - Command-line arguments */ { FILE *strings; /* .strings file */ cups_array_t *po; /* .po file */ char iconv[1024]; /* iconv command */ _cups_message_t *msg; /* Current message */ if (argc != 3) { puts("Usage: po2strings filename.po filename.strings"); return (1); } /* * Use the CUPS .po loader to get the message strings... */ if ((po = _cupsMessageLoad(argv[1])) == NULL) { perror(argv[1]); return (1); } /* * Cheat by using iconv to write the .strings file with a UTF-16 encoding. * The .po file uses UTF-8... */ snprintf(iconv, sizeof(iconv), "iconv -f utf-8 -t utf-16 >'%s'", argv[2]); if ((strings = popen(iconv, "w")) == NULL) { perror(argv[2]); _cupsMessageFree(po); return (1); } for (msg = (_cups_message_t *)cupsArrayFirst(po); msg; msg = (_cups_message_t *)cupsArrayNext(po)) { write_string(strings, msg->id); fputs(" = ", strings); write_string(strings, msg->str); fputs(";\n", strings); } printf("%s: %d messages.\n", argv[2], cupsArrayCount(po)); pclose(strings); _cupsMessageFree(po); return (0); }
int /* O - Exit status */ main(int argc, /* I - Number of command-line arguments */ char *argv[]) /* I - Command-line arguments */ { cups_array_t *cat; /* Message catalog */ if (argc != 3) { fputs("Usage: translate cups_language.po language\n", stderr); return (1); } if (access(argv[1], 0)) cat = _cupsMessageLoad("cups.pot", 1); else cat = _cupsMessageLoad(argv[1], 1); if (!cat) { puts("Unable to load message catalog."); return (1); } if (!translate_messages(cat, argv[2])) { puts("Unable to translate message catalog."); return (1); } if (!save_messages(cat, argv[1])) { puts("Unable to save message catalog."); return (1); } return (0); }
static void cups_message_load(cups_lang_t *lang) /* I - Language */ { #if defined(__APPLE__) && defined(CUPS_BUNDLEDIR) lang->strings = appleMessageLoad(lang->language); #else char filename[1024]; /* Filename for language locale file */ _cups_globals_t *cg = _cupsGlobals(); /* Pointer to library globals */ snprintf(filename, sizeof(filename), "%s/%s/cups_%s.po", cg->localedir, lang->language, lang->language); if (strchr(lang->language, '_') && access(filename, 0)) { /* * Country localization not available, look for generic localization... */ snprintf(filename, sizeof(filename), "%s/%.2s/cups_%.2s.po", cg->localedir, lang->language, lang->language); if (access(filename, 0)) { /* * No generic localization, so use POSIX... */ DEBUG_printf(("4cups_message_load: access(\"%s\", 0): %s", filename, strerror(errno))); snprintf(filename, sizeof(filename), "%s/C/cups_C.po", cg->localedir); } } /* * Read the strings from the file... */ lang->strings = _cupsMessageLoad(filename, 1); #endif /* __APPLE__ && CUPS_BUNDLEDIR */ }
int /* O - Exit code */ main(int argc, /* I - Number of command-line args */ char *argv[]) /* I - Command-line arguments */ { int i; /* Looping var */ cups_array_t *po; /* .po file */ _cups_message_t *msg; /* Current message */ cups_array_t *idfmts, /* Format strings in msgid */ *strfmts; /* Format strings in msgstr */ char *idfmt, /* Current msgid format string */ *strfmt; /* Current msgstr format string */ int fmtidx; /* Format index */ int status, /* Exit status */ pass, /* Pass/fail status */ untranslated; /* Untranslated messages */ char idbuf[80], /* Abbreviated msgid */ strbuf[80]; /* Abbreviated msgstr */ if (argc < 2) { puts("Usage: checkpo filename.po [... filenameN.po]"); return (1); } /* * Check every .po file on the command-line... */ for (i = 1, status = 0; i < argc; i ++) { /* * Use the CUPS .po loader to get the message strings... */ if ((po = _cupsMessageLoad(argv[i], 1)) == NULL) { perror(argv[i]); return (1); } if (i > 1) putchar('\n'); printf("%s: ", argv[i]); fflush(stdout); /* * Scan every message for a % string and then match them up with * the corresponding string in the translation... */ pass = 1; untranslated = 0; for (msg = (_cups_message_t *)cupsArrayFirst(po); msg; msg = (_cups_message_t *)cupsArrayNext(po)) { /* * Make sure filter message prefixes are not translated... */ if (!strncmp(msg->id, "ALERT:", 6) || !strncmp(msg->id, "CRIT:", 5) || !strncmp(msg->id, "DEBUG:", 6) || !strncmp(msg->id, "DEBUG2:", 7) || !strncmp(msg->id, "EMERG:", 6) || !strncmp(msg->id, "ERROR:", 6) || !strncmp(msg->id, "INFO:", 5) || !strncmp(msg->id, "NOTICE:", 7) || !strncmp(msg->id, "WARNING:", 8)) { if (pass) { pass = 0; puts("FAIL"); } printf(" Bad prefix on filter message \"%s\"\n", abbreviate(msg->id, idbuf, sizeof(idbuf))); } idfmt = msg->id + strlen(msg->id) - 1; if (idfmt >= msg->id && *idfmt == '\n') { if (pass) { pass = 0; puts("FAIL"); } printf(" Trailing newline in message \"%s\"\n", abbreviate(msg->id, idbuf, sizeof(idbuf))); } for (; idfmt >= msg->id; idfmt --) if (!isspace(*idfmt & 255)) break; if (idfmt >= msg->id && *idfmt == '!') { if (pass) { pass = 0; puts("FAIL"); } printf(" Exclamation in message \"%s\"\n", abbreviate(msg->id, idbuf, sizeof(idbuf))); } if ((idfmt - 2) >= msg->id && !strncmp(idfmt - 2, "...", 3)) { if (pass) { pass = 0; puts("FAIL"); } printf(" Ellipsis in message \"%s\"\n", abbreviate(msg->id, idbuf, sizeof(idbuf))); } if (!msg->str || !msg->str[0]) { untranslated ++; continue; } else if (strchr(msg->id, '%')) { idfmts = collect_formats(msg->id); strfmts = collect_formats(msg->str); fmtidx = 0; for (strfmt = (char *)cupsArrayFirst(strfmts); strfmt; strfmt = (char *)cupsArrayNext(strfmts)) { if (isdigit(strfmt[1] & 255) && strfmt[2] == '$') { /* * Handle positioned format stuff... */ fmtidx = strfmt[1] - '1'; strfmt += 3; if ((idfmt = (char *)cupsArrayIndex(idfmts, fmtidx)) != NULL) idfmt ++; } else { /* * Compare against the current format... */ idfmt = (char *)cupsArrayIndex(idfmts, fmtidx); } fmtidx ++; if (!idfmt || strcmp(strfmt, idfmt)) break; } if (cupsArrayCount(strfmts) != cupsArrayCount(idfmts) || strfmt) { if (pass) { pass = 0; puts("FAIL"); } printf(" Bad translation string \"%s\"\n for \"%s\"\n", abbreviate(msg->str, strbuf, sizeof(strbuf)), abbreviate(msg->id, idbuf, sizeof(idbuf))); fputs(" Translation formats:", stdout); for (strfmt = (char *)cupsArrayFirst(strfmts); strfmt; strfmt = (char *)cupsArrayNext(strfmts)) printf(" %s", strfmt); fputs("\n Original formats:", stdout); for (idfmt = (char *)cupsArrayFirst(idfmts); idfmt; idfmt = (char *)cupsArrayNext(idfmts)) printf(" %s", idfmt); putchar('\n'); putchar('\n'); } free_formats(idfmts); free_formats(strfmts); } /* * Only allow \\, \n, \r, \t, \", and \### character escapes... */ for (strfmt = msg->str; *strfmt; strfmt ++) if (*strfmt == '\\' && strfmt[1] != '\\' && strfmt[1] != 'n' && strfmt[1] != 'r' && strfmt[1] != 't' && strfmt[1] != '\"' && !isdigit(strfmt[1] & 255)) { if (pass) { pass = 0; puts("FAIL"); } printf(" Bad escape \\%c in filter message \"%s\"\n" " for \"%s\"\n", strfmt[1], abbreviate(msg->str, strbuf, sizeof(strbuf)), abbreviate(msg->id, idbuf, sizeof(idbuf))); break; } } if (pass) { if ((untranslated * 10) >= cupsArrayCount(po) && strcmp(argv[i], "cups.pot")) { /* * Only allow 10% of messages to be untranslated before we fail... */ pass = 0; puts("FAIL"); printf(" Too many untranslated messages (%d of %d)\n", untranslated, cupsArrayCount(po)); } else if (untranslated > 0) printf("PASS (%d of %d untranslated)\n", untranslated, cupsArrayCount(po)); else puts("PASS"); } if (!pass) status = 1; _cupsMessageFree(po); } return (status); }