summaryrefslogtreecommitdiffstats
path: root/src/qscxmlcpp/qscxmlcpp.cpp
blob: 0a2828679b5af2924ce244a8b3ed9dbc08e7d964 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/****************************************************************************
 **
 ** Copyright (c) 2015 Digia Plc
 ** For any questions to Digia, please use contact form at http://qt.digia.com/
 **
 ** All Rights Reserved.
 **
 ** NOTICE: All information contained herein is, and remains
 ** the property of Digia Plc and its suppliers,
 ** if any. The intellectual and technical concepts contained
 ** herein are proprietary to Digia Plc
 ** and its suppliers and may be covered by Finnish and Foreign Patents,
 ** patents in process, and are protected by trade secret or copyright law.
 ** Dissemination of this information or reproduction of this material
 ** is strictly forbidden unless prior written permission is obtained
 ** from Digia Plc.
 ****************************************************************************/

#include <QScxml/scxmlparser.h>
#include <QScxml/scxmlcppdumper.h>

#include <QCoreApplication>
#include <QFile>
#include <QFileInfo>

int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);
    QStringList args = a.arguments();
    QString usage = QStringLiteral("\nusage: %1 [-namespace <namespace>] [-o <base/out/name>] [-oh <header/out>] [-ocpp <cpp/out>] [-use-private-api]\n").arg(QFileInfo(args.value(0)).baseName());
           usage += QStringLiteral("      [-classname <stateMachineClassName>] [-name-qobjects] <input.scxml>\n\n");
           usage += QStringLiteral("compiles the given input.scxml file to a header and cpp file\n");

    QTextStream errs(stderr, QIODevice::WriteOnly);
    QTextStream outs(stderr, QIODevice::WriteOnly);

    Scxml::CppDumpOptions options;
    QString scxmlFileName;
    QString outFileName;
    QString outHFileName;
    QString outCppFileName;
    for (int iarg = 1; iarg < args.size(); ++iarg) {
        QString arg = args.at(iarg);
        if (arg == QLatin1String("-namespace")) {
            options.namespaceName = args.value(++iarg);
        } else if (arg == QLatin1String("-o")) {
            outFileName = args.value(++iarg);
        } else if (arg == QLatin1String("-oh")) {
            outHFileName = args.value(++iarg);
        } else if (arg == QLatin1String("-ocpp")) {
            outCppFileName = args.value(++iarg);
        } else if (arg == QLatin1String("-use-private-api")) {
            options.usePrivateApi = true;
        } else if (arg == QLatin1String("-classname")) {
            options.classname = args.value(++iarg);
        } else if (arg == QLatin1String("-name-qobjects")) {
            options.nameQObjects = true;
        } else if (scxmlFileName.isEmpty()) {
            scxmlFileName = arg;
        } else {
            errs << QStringLiteral("Unexpected argument: %1").arg(arg) << endl;
            errs << usage;
            exit(-1);
        }
    }
    if (scxmlFileName.isEmpty()) {
        errs << QStringLiteral("Error: no input files.") << endl;
        exit(-2);
    }
    QFile file(scxmlFileName);
    if (!file.open(QFile::ReadOnly)) {
        errs << QStringLiteral("Error: cannot open input file %1").arg(scxmlFileName);
        exit(-3);
    }
    if (outFileName.isEmpty())
        outFileName = QFileInfo(scxmlFileName).baseName();
    if (outHFileName.isEmpty())
        outHFileName = outFileName + QLatin1String(".h");
    if (outCppFileName.isEmpty())
        outCppFileName = outFileName + QLatin1String(".cpp");

    QXmlStreamReader reader(&file);
    Scxml::ScxmlParser parser(&reader,
                              Scxml::ScxmlParser::loaderForDir(QFileInfo(file.fileName()).absolutePath()));
    parser.setFileName(file.fileName());
    parser.parse();
    if (!parser.errors().isEmpty()) {
        foreach (const Scxml::ErrorMessage &error, parser.errors()) {
            errs << error.fileName
                 << QLatin1Char(':')
                 << error.line
                 << QLatin1Char(':')
                 << error.column
                 << QStringLiteral(": ")
                 << error.severityString()
                 << QStringLiteral(": ")
                 << error.msg
                 << endl;
        }
        return -7;
    }

    if (auto doc = parser.scxmlDocument()) {
        QFile outH(outHFileName);
        if (!outH.open(QFile::WriteOnly)) {
            errs << QStringLiteral("Error: cannot open '%1': %2").arg(outH.fileName(), outH.errorString()) << endl;
            exit(-4);
        }

        QFile outCpp(outCppFileName);
        if (!outCpp.open(QFile::WriteOnly)) {
            errs << QStringLiteral("Error: cannot open '%1': %2").arg(outCpp.fileName(), outCpp.errorString()) << endl;
            exit(-5);
        }

        QTextStream h(&outH);
        QTextStream c(&outCpp);
        Scxml::CppDumper dumper(h, c, QFileInfo(outH).fileName(), options);
        dumper.dump(doc);
        outH.close();
        outCpp.close();
        a.exit();
        return 0;
    } else {
        a.exit();
        return -6;
    }
}