summaryrefslogblamecommitdiffstats
path: root/amend/main.c
blob: bc9e58778be5031f388d5bf6d3912dad9567e2ce (plain) (tree)























































































                                                                             




































































































                                                                               
/*
 * Copyright (C) 2007 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include "ast.h"
#include "lexer.h"
#include "parser.h"
#include "register.h"
#include "execute.h"

void
lexTest()
{
    int token;
    do {
        token = yylex();
        if (token == 0) {
            printf(" EOF");
            fflush(stdout);
            break;
        } else {
            printf(" %s", tokenToString(token));
            fflush(stdout);
            if (token == TOK_IDENTIFIER) {
                if (strcmp(yylval.literalString, "assert") == 0) {
                    setLexerArgumentType(AM_BOOLEAN_ARGS);
                } else {
                    setLexerArgumentType(AM_WORD_ARGS);
                }
                do {
                    token = yylex();
                    printf(" %s", tokenToString(token));
                    fflush(stdout);
                } while (token != TOK_EOL && token != TOK_EOF && token != 0);
            } else if (token != TOK_EOL) {
                fprintf(stderr, "syntax error: expected identifier\n");
                break;
            }
        }
    } while (token != 0);
    printf("\n");
}

void
usage()
{
    printf("usage: amend [--debug-lex|--debug-ast] [<filename>]\n");
    exit(1);
}

extern const AmCommandList *gCommands;
int
main(int argc, char *argv[])
{
    FILE *inputFile = NULL;
    bool debugLex = false;
    bool debugAst = false;
    const char *fileName = NULL;
    int err;

#if 1
    extern int test_symtab(void);
    int ret = test_symtab();
    if (ret != 0) {
        fprintf(stderr, "test_symtab() failed: %d\n", ret);
        exit(ret);
    }
    extern int test_cmd_fn(void);
    ret = test_cmd_fn();
    if (ret != 0) {
        fprintf(stderr, "test_cmd_fn() failed: %d\n", ret);
        exit(ret);
    }
#endif

    argc--;
    argv++;
    while (argc > 0) {
        if (strcmp("--debug-lex", argv[0]) == 0) {
            debugLex = true;
        } else if (strcmp("--debug-ast", argv[0]) == 0) {
            debugAst = true;
        } else if (argv[0][0] == '-') {
            fprintf(stderr, "amend: Unknown option \"%s\"\n", argv[0]);
            usage();
        } else {
            fileName = argv[0];
        }
        argc--;
        argv++;
    }

    if (fileName != NULL) {
        inputFile = fopen(fileName, "r");
        if (inputFile == NULL) {
            fprintf(stderr, "amend: Can't open input file '%s'\n", fileName);
            usage();
        }
    }

    commandInit();
//xxx clean up

    err = registerUpdateCommands();
    if (err < 0) {
        fprintf(stderr, "amend: Error registering commands: %d\n", err);
        exit(-err);
    }
    err = registerUpdateFunctions();
    if (err < 0) {
        fprintf(stderr, "amend: Error registering functions: %d\n", err);
        exit(-err);
    }

#if AMEND_LEXER_BUFFER_INPUT
    if (inputFile == NULL) {
        fprintf(stderr, "amend: No input file\n");
        usage();
    }
    char *fileData;
    int fileDataLen;
    fseek(inputFile, 0, SEEK_END);
    fileDataLen = ftell(inputFile);
    rewind(inputFile);
    if (fileDataLen < 0) {
        fprintf(stderr, "amend: Can't get file length\n");
        exit(2);
    } else if (fileDataLen == 0) {
        printf("amend: Empty input file\n");
        exit(0);
    }
    fileData = (char *)malloc(fileDataLen + 1);
    if (fileData == NULL) {
        fprintf(stderr, "amend: Can't allocate %d bytes\n", fileDataLen + 1);
        exit(2);
    }
    size_t nread = fread(fileData, 1, fileDataLen, inputFile);
    if (nread != (size_t)fileDataLen) {
        fprintf(stderr, "amend: Didn't read %d bytes, only %zd\n", fileDataLen,
                nread);
        exit(2);
    }
    fileData[fileDataLen] = '\0';
    setLexerInputBuffer(fileData, fileDataLen);
#else
    if (inputFile == NULL) {
        inputFile = stdin;
    }
    yyset_in(inputFile);
#endif

    if (debugLex) {
        lexTest();
    } else {
        int ret = yyparse();
        if (ret != 0) {
            fprintf(stderr, "amend: Parse failed (%d)\n", ret);
            exit(2);
        } else {
            if (debugAst) {
                dumpCommandList(gCommands);
            }
printf("amend: Parse successful.\n");
            ret = execCommandList((ExecContext *)1, gCommands);
            if (ret != 0) {
                fprintf(stderr, "amend: Execution failed (%d)\n", ret);
                exit(3);
            }
printf("amend: Execution successful.\n");
        }
    }

    return 0;
}