190 lines
5.0 KiB
C
190 lines
5.0 KiB
C
|
/*
|
||
|
* 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;
|
||
|
}
|