/*
 *  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