/* 
 * $Id: main.cpp,v 1.18 2006/03/05 05:00:09 ozawa Exp $
 *
 * Copyright 2005- ONGS Inc. All rights reserved.
 * 
 * author: Masanori OZAWA (ozawa@ongs.co.jp)
 * version: $Revision: 1.18 $
 *
 * Redistribution and use in source and binary forms, with or without 
 * modification, are permitted provided that the following conditions
 * are met:
 * 
 *   1. Redistributions of source code must retain the above copyright
 *      notice, this list of conditions and the following disclaimer.
 *   2. Redistributions in binary form must reproduce the above copyright
 *      notice, this list of conditions and the following disclaimer in the
 *      documentation and/or other materials provided with the distribution.
 * 
 * THIS SOFTWARE IS PROVIDED BY ONGS INC ``AS IS'' AND ANY EXPRESS OR
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL ONGS INC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 * 
 * The views and conclusions contained in the software and documentation are
 * those of the authors and should not be interpreted as representing official
 * policies, either expressed or implied, of the ONGS Inc.
 * 
 */

#include "xdtp.h"
#include "XDTPTransform.h"

using namespace XDTP;

static void initialize_locale();
static void print_usage();

/**
 * メイン処理
 * 
 * @author $Author: ozawa $
 * @version $Revision: 1.18 $
 */
int main(int argc, char *argv[])
{
    // initialize locale
    initialize_locale();

    // initialize glibmm
    Glib::init();
    Glib::set_prgname(APP_NAME);
    Glib::set_application_name(APP_NAME);
    
    // analysis command line
    char opt = 0;
    
    StringList input;
    StringList output;
    XDTPTransform xdtp;
    
    try {
        while ((opt = getopt(argc, argv, "hct:v:E:e:x:X:m:o:s:f:")) != -1) {
            switch (opt) {
            case 'c':
                xdtp.skipXMLCheck(true);
                break;
            case 't':
                if (!optarg || 0 >= strlen(optarg)) THROW("bad arguments.");
                xdtp.setOutputType(optarg);
                break;
            case 'v':
                if (!optarg || 0 >= strlen(optarg)) THROW("bad arguments.");
                xdtp.setVerboseMode(atoi(optarg));
                break;
            case 'E':
                if (!optarg || 0 >= strlen(optarg)) THROW("bad arguments.");
                xdtp.setInputEncoding(optarg);
                break;
            case 'e':
                if (!optarg || 0 >= strlen(optarg)) THROW("bad arguments.");
                xdtp.setOutputEncoding(optarg);
                break;
            case 'x':
                if (!optarg || 0 >= strlen(optarg)) THROW("bad arguments.");
                xdtp.addXSLFile(optarg, false);
                break;
            case 'X':
                if (!optarg || 0 >= strlen(optarg)) THROW("bad arguments.");
                xdtp.addXSLFile(optarg, true);
                break;
            case 'm':
                if (!optarg || 0 >= strlen(optarg)) THROW("bad arguments.");
                xdtp.addXDTPModule(optarg);
                break;
            case 'o':
                if (!optarg || 0 >= strlen(optarg)) THROW("bad arguments.");
                xdtp.addOption(optarg);
                break;
            case 's':
                if (!optarg || 0 >= strlen(optarg)) THROW("bad arguments.");
                if (output.size() < input.size()) {
                    output.push_back("-");
                }
                input.push_back(optarg);
                break;
            case 'f':
                if (!optarg || 0 >= strlen(optarg)) THROW("bad arguments.");
                if (output.size() >= input.size()) THROW("bad arguments.");
                output.push_back(optarg);
                break;
            case 'h':
                print_usage();
                exit(0);
                break;
            default:
                THROW("unknown option.");
                break;
            }
        }
    }
    catch (Exception exception) {
        exception.print(stderr);
        print_usage();
        exit(-1);
    }
    catch (...) {
        fprintf(stderr, "%s: exception occuerd: unknown error." LINE_SEP, APP_NAME);
        print_usage();
        exit(-1);
    }
    
    if (output.size() < input.size()) {
        output.push_back("-");
    }
    
    if (1 > input.size() || output.size() != input.size()) {
        fprintf(stderr, "%s: bad arguments." LINE_SEP, APP_NAME);
        print_usage();
        exit(-1);
    }

    // do transform
    bool bSuccess = false;
    
    try {
        StringList::iterator iiter = input.begin();
        StringList::iterator iend = input.end();
        StringList::iterator oiter = output.begin();
        StringList::iterator oend = output.end();

        if (!xdtp.initialize()) {
            THROW("Unable to initialize the XDTPTransform module.");
        }
        for (bSuccess = true; bSuccess && iiter != iend; iiter++, oiter++) {
            bSuccess = xdtp.transform(*iiter, *oiter);
            if (!bSuccess) {
                xdtp.showErrorMsg();
            }
        }
        xdtp.uninitialize();
    }
    catch (Exception exception) {
        exception.print(stderr);
        bSuccess = false;
    }
    catch (Glib::Error error) {
        std::string msg = Glib::locale_from_utf8(error.what());
        fprintf(stderr, "%s: %s" LINE_SEP, APP_NAME, msg.c_str());
        bSuccess = false;
    }
    catch (std::exception exception) {
        fprintf(stderr, "%s: %s" LINE_SEP, APP_NAME, exception.what());
        bSuccess = false;
    }
    catch (...) {
        fprintf(stderr, "%s: exception occuerd: unknown error." LINE_SEP, APP_NAME);
        bSuccess = false;
    }

    return (bSuccess ? 0 : -1);
}

/**
 * ロケールを設定します。
 */
static void initialize_locale()
{
    char *tmp = getenv("LC_ALL");
    char *lang = getenv("LANG");
    
    if (tmp) {
        setlocale(LC_ALL, tmp);
        return;
    }
    
    if (!lang) lang = "C";
    
    tmp = getenv("LC_COLLATE");
    setlocale(LC_COLLATE, (tmp ? tmp : lang));
    tmp = getenv("LC_CTYPE");
    setlocale(LC_CTYPE, (tmp ? tmp : lang));
    tmp = getenv("LC_MESSAGES");
    setlocale(LC_MESSAGES, (tmp ? tmp : lang));
    tmp = getenv("LC_MONETARY");
    setlocale(LC_MONETARY, (tmp ? tmp : lang));
    tmp = getenv("LC_NUMERIC");
    setlocale(LC_NUMERIC, (tmp ? tmp : lang));
    tmp = getenv("LC_TIME");
    setlocale(LC_TIME, (tmp ? tmp : lang));
}

/**
 * 使い方を出力します。
 */
static void print_usage()
{
    printf("%s version %d.%d.%d%sby ONGS Inc." LINE_SEP
           "Usage: %s [-h]" LINE_SEP
           "Usage: %s [-c] [-t output_type] [-v [012]] " LINE_SEP
           "          [-E input_encoding] [-e output_encoding] " LINE_SEP
           "          [-x/X xsl_path]... [-m module_path]... " LINE_SEP
           "          [-o option]... -s src_path [-f output_path] " LINE_SEP
           "          [-s src_path [-f output_path]]..." LINE_SEP
           LINE_SEP
           "\t-h : show help." LINE_SEP
           "\t-c : skip XML check." LINE_SEP
           "\t-t : output type. (default: %s)" LINE_SEP
           "\t-v : enable(1,2)/disable(0) verbose mode." LINE_SEP
           "\t-E : input encoding." LINE_SEP
           "\t-e : output encoding. (default: %s)" LINE_SEP
           "\t-x : your xsl transform file." LINE_SEP
           "\t-X : your xsl transform & output-type file." LINE_SEP
           "\t-m : your xdtp transform module." LINE_SEP
           "\t-o : an option for your xdtp transform module." LINE_SEP
           "\t-s : input xml file." LINE_SEP
           "\t-f : output file." LINE_SEP
           LINE_SEP,
           APP_NAME,
           MAJOR_VERSION, MINOR_VERSION, MICRO_VERSION,
#ifdef CURRENT_VERSION
           "-" CURRENT_VERSION " ",
#else
           " ",
#endif
           APP_NAME, APP_NAME, DEFAULT_OUTPUT_TYPE, DEFAULT_OUTPUT_ENCODING);
}


syntax highlighted by Code2HTML, v. 0.9.1