/* * Copyright (C) 2000-2001 Marc Wandschneider * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation. * * For more information look at the file COPYRIGHT in this package * */ #include #include #include #include #include /** * DANGER!!! DANGER!!! DANGER!!! DANGER!!! DANGER!!! DANGER!!! DANGER!!! * * This has some of the most unbelievably awful code I have ever written * in my entire life in it. WoW, is it horrible. Investigate at your * own risk !!!! * * DANGER!!! DANGER!!! DANGER!!! DANGER!!! DANGER!!! DANGER!!! DANGER!!! */ /** * This utility takes the output of the Qt 'uic' program and changes it * to use our localization scheme instead. Basically, we just strip out * the tr("...") goo and use our localized STRINGIDs instead. * * We take the tr("..."), replace it with something along the lines of: * ID_CONTROLNAME_1 "Moo Cow". * * We understand two types of situations: * * someMethod( tr("Mmooo")); // method on base class * variable->someMethod( tr("Mooo")) // method on instance class * * This output is in .rc file format, which we can then pass to our * rescomp. */ int processFile(const char *, const char *); void stripFileNameUpper(const char *, char *, unsigned int); void stripSpaces(const char *, char *); void genUpperID(const char *, char *, unsigned int, int); static const char *incs = "#include \n#include\"localized.h\"\n"; /** *=------------------------------------------------------------------------= * main *=------------------------------------------------------------------------= */ int main (int argc, char **argv) { if (argc != 3) { fprintf(stderr, "\nUsage: %s [c++ file to strip] [output c++ file]\n - resource output is stdout.\n\n", argv[0]); return -1; } return processFile(argv[1], argv[2]); } /** *=------------------------------------------------------------------------= * processFile *=------------------------------------------------------------------------= * opens up a file looking for text to go and replace with the STRINGIDs * * Parameters: * const char * - [in] file to strip * const char * - [in] output filename * * Output: * int */ int processFile ( const char *file, const char *outputFile ) { char theString[512]; char line[1024], stripped[1024], *pstr; char ctlName[128], ctlNewName[128]; char buf[128], id[256]; FILE *input, *output; bool haveCtlName; int ext = 0; int x, y, j; int res; /** * Get the base name for those strings that don't have an identifier next * to the method name!! */ stripFileNameUpper(file, buf, sizeof(buf)); /** * now start whizzing through the file, and replacing tr(...) with * stringids that we'll generate. */ input = fopen(file, "r"); if (!input) { perror(file); return -1; } output = fopen(outputFile, "w+"); if (!output) { perror(file); return -1; } res = fwrite(incs, sizeof(char), strlen(incs), output); if (res != strlen(incs)) { perror(outputFile); goto Error; } /** * Loop until we're done. */ while (!feof(input)) { pstr = fgets(line, sizeof(line), input); if (!pstr) { if (ferror(input)) { perror(file); goto Error; } else break; } /** * Strip the spaces from the buf first ... makes it easy to process. */ stripSpaces(line, stripped); /** * Does the string even have tr("...") in it?? */ pstr = strstr(stripped, "tr(\""); if (!pstr) { x = strlen(line); res = fwrite(line, sizeof(char), x, output); if (res != x) { fprintf(stderr, "a\n"); perror(outputFile); goto Error; } } else { /** * Look for the ctl name first. */ haveCtlName = 0; x = 0; y = 0; while (stripped + x < pstr) { if (!haveCtlName) { if (isalnum(stripped[x])) ctlName[y++] = stripped[x]; else { ctlName[y] = '\0'; if (y > 0 && stripped[x] == '-' && stripped[x + 1] == '>') haveCtlName = 1; } } x++; } if (haveCtlName) genUpperID(ctlName, ctlNewName, sizeof(ctlNewName), ext++); else genUpperID(buf, ctlNewName, sizeof(ctlNewName), ext++); /** * Great, now investigate the tr and see if it's an empty string * or not. */ x = 0; y = 4; strcpy(line, " "); while (stripped + x < pstr) line[y++] = stripped[x++]; if (*(pstr + 4) == '"') { // don't write out this line ... it's an empty line continue; } else x += 4; strcpy(line + y, "intlLoadStringX("); y = strlen(line); j = 0; while (ctlNewName[j] != '\0') line[y++] = ctlNewName[j++]; line[y++] = ')'; j = 0; while (!(stripped[x] == '"' && stripped[x - 1] != '\\')) theString[j++] = stripped[x++]; theString[j] = '\0'; x += 2; while (stripped[x] != '\0') line[y++] = stripped[x++]; line[y++] = '\n'; line[y] = '\0'; x = strlen(line); res = fwrite(line, sizeof(char), x, output); if (res != x) { fprintf(stderr, "a\n"); perror(outputFile); goto Error; } fprintf(stdout, "%s\t\t\t\"%s\"\n", ctlNewName, theString); } } fclose(input); fclose(output); return 0; Error: fclose(input); fclose(output); unlink(outputFile); return -1; } void stripFileNameUpper ( const char *file, char *buf, unsigned int sizeofBuf ) { char *ptr; int x = 0; if (!buf || !file) { fprintf(stderr, "\nVERY BOGUS INPUT !!!!\n"); return; } /** * Copy it over and then replace everything after the last dot. * NOTE: THIS COULD BE BUGGY IF THE FILENAME PASSED IN IS: * * Boo.MOo * * AND DOESN'T HAVE A PROPER C++ FILE EXTENSION. I DON'T CARE. THIS * SITUATION DOESN'T EXIST FOR MY USES. */ strncpy(buf, file, sizeofBuf); x = strlen(file); buf[x] = '\0'; ptr = strrchr(buf, '.'); if (ptr) *ptr = '\0'; ptr = strrchr(buf, '/'); if (ptr) ptr++; else ptr = buf; x = 0; while (*(ptr + x) != '\0') { if (isalnum(*(ptr + x))) buf[x] = toupper(*(ptr + x)); x++; } } /** *=------------------------------------------------------------------------= * stripSpaces *=------------------------------------------------------------------------= */ void stripSpaces ( const char *buf, char *stripped ) { bool inquotes; int x = 0; int y = 0; inquotes = false; while (buf[x] != '\0') { if (!isspace(buf[x]) || inquotes) { if (buf[x] == '"') inquotes = !inquotes; stripped[y++] = buf[x]; } x++; } stripped[y] = '\0'; } /** *=------------------------------------------------------------------------= * stripUpper *=------------------------------------------------------------------------= */ void genUpperID ( const char *in, char *out, unsigned int sizeofOut, int id ) { char num[8]; int x = 0; int y = 0; if (sizeofOut < 10) { fprintf(stderr, "useless buffer passed in\n"); exit(-1); } out[y++] = 'I'; out[y++] = 'D'; out[y++] = '_'; while (in[x] != '\0') { if (y > (int)sizeofOut) { fprintf(stderr, "blowing a buffer -- abort\n"); exit(-1); } if (isalnum(in[x])) out[y++] = toupper(in[x]); x++; } out[y++] = '_'; snprintf(num, sizeof(num), "%d", id); x = 0; while(num[x] != '\0') out[y++] = num[x++]; out[y] = '\0'; }