src/main.cpp
author David Anderson <dvander@alliedmods.net>
Tue Jan 01 20:07:09 2013 -0800 (2013-01-01)
changeset 254 cd167be62cbe
parent 251 ca99a81745fe
permissions -rw-r--r--
Fix Linux build.
dvander@163
     1
/* vim: set ts=4 sw=4 tw=99 et:
dvander@163
     2
 *
dvander@71
     3
 * Copyright (C) 2012 David Anderson
dvander@71
     4
 *
dvander@163
     5
 * This file is part of SourcePawn.
dvander@71
     6
 *
dvander@163
     7
 * SourcePawn is free software: you can redistribute it and/or modify it under
dvander@71
     8
 * the terms of the GNU General Public License as published by the Free
dvander@71
     9
 * Software Foundation, either version 3 of the License, or (at your option)
dvander@71
    10
 * any later version.
dvander@71
    11
 * 
dvander@163
    12
 * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
dvander@71
    13
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
dvander@71
    14
 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
dvander@71
    15
 *
dvander@71
    16
 * You should have received a copy of the GNU General Public License along with
dvander@163
    17
 * SourcePawn. If not, see http://www.gnu.org/licenses/.
dvander@71
    18
 */
dvander@71
    19
#include <stdio.h>
dvander@161
    20
#include <stdlib.h>
dvander@163
    21
#include <string.h>
dvander@71
    22
#include "../include/keima.h"
dvander@251
    23
#include "Utility.h"
dvander@251
    24
#include "Platform.h"
dvander@251
    25
#ifdef WIN32
dvander@251
    26
# include <Windows.h>
dvander@251
    27
# include <direct.h>
dvander@251
    28
#else
dvander@251
    29
# include <unistd.h>
dvander@251
    30
#endif
dvander@71
    31
dvander@161
    32
using namespace Ke;
dvander@71
    33
dvander@161
    34
class MessageReporter : public IMessageReporter
dvander@69
    35
{
dvander@69
    36
  public:
dvander@69
    37
    void onOutOfMemory() {
dvander@69
    38
        fprintf(stderr, "Out of memory!\n");
dvander@69
    39
    }
dvander@69
    40
    void onUncaughtException(const char *message) {
dvander@69
    41
        fprintf(stderr, "Uncaught exception: %s\n", message);
dvander@69
    42
dvander@161
    43
        IStackFrameIterator *iter = Keima::NewStackFrameIterator();
dvander@69
    44
        unsigned index = 0;
dvander@251
    45
dvander@251
    46
        const char *filename = iter->source();
dvander@251
    47
        if (!filename)
dvander@251
    48
            filename = "<anonymous>";
dvander@251
    49
        if (const char *tail = strrchr(filename, '/'))
dvander@251
    50
            filename = tail + 1;
dvander@251
    51
#ifdef WIN32
dvander@251
    52
        if (const char *tail = strrchr(filename, '\\'))
dvander@251
    53
            filename = tail + 1;
dvander@251
    54
#endif
dvander@251
    55
dvander@174
    56
        while (!iter->done() && index < 10) {
dvander@69
    57
            fprintf(stderr, "[%d] %s (%s line %d)\n",
dvander@69
    58
                    index,
dvander@69
    59
                    iter->function(),
dvander@251
    60
                    filename,
dvander@69
    61
                    iter->lineNumber());
dvander@69
    62
            iter->prev();
dvander@69
    63
            index++;
dvander@69
    64
        }
dvander@69
    65
    }
dvander@71
    66
    virtual void beginCompilationErrors(const char *file) {
dvander@232
    67
        fprintf(stderr, "Displaying compilation errors for \"%s\"\n", file);
dvander@71
    68
    }
dvander@71
    69
    virtual void reportCompilationError(const char *message, unsigned line, unsigned col) {
dvander@71
    70
        fprintf(stderr, "  line %d, col %d: %s\n", line, col, message);
dvander@71
    71
    }
dvander@71
    72
    virtual void endCompilationErrors() {
dvander@71
    73
    }
dvander@71
    74
} s_Reporter;
dvander@71
    75
dvander@195
    76
class MainCollector : public Ke::IPublicFunctionListener
dvander@195
    77
{
dvander@195
    78
  public:
dvander@195
    79
    MainCollector()
dvander@195
    80
    {
dvander@195
    81
    }
dvander@195
    82
    void registerPublic(Handle<Function> fun) {
dvander@195
    83
        Local<String> str = fun->name();
dvander@195
    84
        if (str && strcmp(str->chars(), "main") == 0)
dvander@195
    85
            fun_ = fun;
dvander@195
    86
    }
dvander@195
    87
dvander@195
    88
    void unregisterPublic(Handle<Function> fun) {
dvander@195
    89
        if (fun_ == fun)
dvander@195
    90
            fun_ = Handle<Function>();
dvander@195
    91
    }
dvander@195
    92
dvander@195
    93
    Handle<Function> fun() const {
dvander@195
    94
        return fun_;
dvander@195
    95
    }
dvander@195
    96
dvander@195
    97
  private:
dvander@195
    98
    Root<Function> fun_;
dvander@195
    99
};
dvander@195
   100
dvander@163
   101
intptr_t PrintFloat(void *blah, intptr_t *params)
dvander@71
   102
{
dvander@163
   103
    fprintf(stdout, "%f", *reinterpret_cast<float *>(&params[1]));
dvander@163
   104
    return 0;
dvander@163
   105
}
dvander@71
   106
dvander@163
   107
intptr_t PrintNum(void *blah, intptr_t *params)
dvander@163
   108
{
dvander@163
   109
    fprintf(stdout, "%i", *reinterpret_cast<int *>(&params[1]));
dvander@163
   110
    return 0;
dvander@163
   111
}
dvander@71
   112
dvander@163
   113
intptr_t PrintString(void *blah, intptr_t *params)
dvander@71
   114
{
dvander@163
   115
    fprintf(stdout, "%s", *reinterpret_cast<const char **>(&params[1]));
dvander@163
   116
    return 0;
dvander@71
   117
}
dvander@71
   118
dvander@71
   119
int main(int argc, char **argv)
dvander@71
   120
{
dvander@71
   121
    if (argc < 2) {
dvander@71
   122
        fprintf(stderr, "Usage: <file>\n");
dvander@71
   123
        return 1;
dvander@71
   124
    }
dvander@71
   125
dvander@161
   126
    if (!Keima::Initialize())
dvander@71
   127
        return 1;
dvander@163
   128
dvander@251
   129
    ke::AutoFree<char> fullpath;
dvander@251
   130
    if (!ke::OS::GetAbsolutePath(argv[1], fullpath))
dvander@251
   131
        return 1;
dvander@251
   132
dvander@251
   133
    ke::AutoFree<char> path, name;
dvander@251
   134
    if (!ke::OS::SplitPath(*fullpath, path, name))
dvander@251
   135
        return 1;
dvander@251
   136
dvander@163
   137
    int rval = 0;
dvander@163
   138
dvander@161
   139
    Keima::InstallMessageReporter(&s_Reporter);
dvander@232
   140
    do {
dvander@195
   141
        MainCollector entry;
dvander@195
   142
        Keima::SetPublicFunctionListener(&entry);
dvander@195
   143
dvander@161
   144
        HandleScope scope;
dvander@251
   145
        Local<Package> package = Package::New(Handle<Package>(), Handle<String>(), *path, Package::Normal);
dvander@251
   146
        if (!package) {
dvander@251
   147
            rval = 1;
dvander@251
   148
            break;
dvander@251
   149
        }
dvander@251
   150
dvander@251
   151
        if (!Keima::Compile(package, *name)) {
dvander@232
   152
            rval = 1;
dvander@232
   153
            break;
dvander@232
   154
        }
dvander@71
   155
dvander@163
   156
        Keima::CollectGarbage();
dvander@163
   157
dvander@196
   158
        Keima::BindNative("PrintFloat", (void *)PrintFloat);
dvander@196
   159
        Keima::BindNative("PrintNum", (void *)PrintNum);
dvander@196
   160
        Keima::BindNative("PrintString", (void *)PrintString);
dvander@163
   161
dvander@195
   162
        Handle<Function> fun = entry.fun();
dvander@163
   163
dvander@163
   164
        if (!fun) {
dvander@195
   165
            fprintf(stdout, "Not running; no public 'main'.\n");
dvander@163
   166
        } else {
dvander@163
   167
            if (!Keima::Invoke(fun, NULL, 0, true, &rval))
dvander@163
   168
                rval = 1;
dvander@163
   169
        }
dvander@232
   170
    } while (0);
dvander@71
   171
dvander@161
   172
    Keima::Shutdown();
dvander@163
   173
dvander@163
   174
    return rval;
dvander@71
   175
}
danderson@92
   176
danderson@92
   177
/* Overload a few things to prevent libstdc++ linking */
danderson@92
   178
#if defined __linux__ || defined __APPLE__
danderson@92
   179
extern "C" void __cxa_pure_virtual(void)
danderson@92
   180
{
danderson@92
   181
}
danderson@92
   182
danderson@92
   183
void *operator new(size_t size)
danderson@92
   184
{
dvander@163
   185
    return malloc(size);
danderson@92
   186
}
danderson@92
   187
danderson@92
   188
void *operator new[](size_t size) 
danderson@92
   189
{
dvander@163
   190
    return malloc(size);
danderson@92
   191
}
danderson@92
   192
danderson@92
   193
void operator delete(void *ptr) 
danderson@92
   194
{
dvander@163
   195
    free(ptr);
danderson@92
   196
}
danderson@92
   197
danderson@92
   198
void operator delete[](void * ptr)
danderson@92
   199
{
dvander@163
   200
    free(ptr);
danderson@92
   201
}
danderson@92
   202
#endif
danderson@92
   203