/*
* Copyright (C) 2000-2001 Marc Wandschneider <mw@kiltdown.org>
*
* 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 <ctype.h>
#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
/**
* 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 <intl.h>\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';
}
syntax highlighted by Code2HTML, v. 0.9.1