diff --git a/picoc.c b/picoc.c index a3a4d01..85432dc 100644 --- a/picoc.c +++ b/picoc.c @@ -1,6 +1,7 @@ #include "picoc.h" -#define CALL_MAIN "main();" +#define CALL_MAIN_NO_ARGS "main();" +#define CALL_MAIN_WITH_ARGS "main(__argc,__argv);" /* initialise everything */ @@ -34,6 +35,27 @@ void Cleanup() /* platform-dependent code for running programs is in this file */ #ifdef UNIX_HOST +void CallMain(int argc, char **argv) +{ + /* check if the program wants arguments */ + struct Value *FuncValue; + + VariableGet(NULL, TableStrRegister("main"), &FuncValue); + if (FuncValue->Typ->Base != TypeFunction) + ProgramFail(NULL, "main is not a function - can't call it"); + + if (FuncValue->Val->FuncDef.NumParams == 0) + Parse("", CALL_MAIN_NO_ARGS, strlen(CALL_MAIN_NO_ARGS), TRUE); + else + { + /* define the arguments */ + VariableDefinePlatformVar(NULL, "__argc", &IntType, (union AnyValue *)&argc, FALSE); + VariableDefinePlatformVar(NULL, "__argv", CharPtrPtrType, (union AnyValue *)&argv, FALSE); + + Parse("", CALL_MAIN_WITH_ARGS, strlen(CALL_MAIN_WITH_ARGS), TRUE); + } +} + int main(int argc, char **argv) { int ParamCount = 1; @@ -41,9 +63,9 @@ int main(int argc, char **argv) if (argc < 2) { - printf("Format: picoc ... - run a program (calls main to start it)\n" + printf("Format: picoc ... - run a program (calls main() to start it)\n" " picoc -i - interactive mode\n" - " picoc -m ... - run a program without calling main\n"); + " picoc -m ... - run a program without calling main()\n"); exit(1); } @@ -65,11 +87,11 @@ int main(int argc, char **argv) return 1; } - for (; ParamCount < argc; ParamCount++) + for (; ParamCount < argc && strcmp(argv[ParamCount], "-") != 0; ParamCount++) PlatformScanFile(argv[ParamCount]); if (!DontRunMain) - Parse("startup", CALL_MAIN, strlen(CALL_MAIN), TRUE); + CallMain(argc - ParamCount, &argv[ParamCount]); } Cleanup(); diff --git a/picoc.h b/picoc.h index 59fd36b..9bc30a1 100644 --- a/picoc.h +++ b/picoc.h @@ -286,6 +286,7 @@ extern struct ValueType TypeType; extern struct ValueType FunctionType; extern struct ValueType MacroType; extern struct ValueType *CharPtrType; +extern struct ValueType *CharPtrPtrType; extern struct ValueType *CharArrayType; extern struct ValueType *VoidPtrType; extern char *StrEmpty; diff --git a/tests/31_args.c b/tests/31_args.c new file mode 100644 index 0000000..920dcce --- /dev/null +++ b/tests/31_args.c @@ -0,0 +1,12 @@ +#include + +int main(int argc, char **argv) +{ + int Count; + + printf("hello world %d\n", argc); + for (Count = 0; Count < argc; Count++) + printf("arg %d: %s\n", Count, argv[Count]); + + return 0; +} diff --git a/tests/31_args.expect b/tests/31_args.expect new file mode 100644 index 0000000..bf25112 --- /dev/null +++ b/tests/31_args.expect @@ -0,0 +1,6 @@ +hello world 5 +arg 0: - +arg 1: arg1 +arg 2: arg2 +arg 3: arg3 +arg 4: arg4 diff --git a/tests/Makefile b/tests/Makefile index a31a8a9..b355bf8 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -28,6 +28,7 @@ TESTS= 00_assignment.test \ 28_strings.test \ 29_array_address.test \ 30_hanoi.test \ + 31_args.test \ 34_array_assignment.test \ 35_sizeof.test \ 36_array_initialisers.test \ @@ -38,7 +39,12 @@ TESTS= 00_assignment.test \ %.test: %.expect %.c @echo Test: $*... - -@../picoc -m $*.c 2>&1 >$*.output + @if [ "x`echo $* | grep args`" != "x" ]; \ + then \ + ../picoc $*.c - arg1 arg2 arg3 arg4 2>&1 >$*.output; \ + else \ + ../picoc -m $*.c 2>&1 >$*.output; \ + fi @if [ "x`diff -qbu $*.expect $*.output`" != "x" ]; \ then \ echo "error in test $*"; \ diff --git a/type.c b/type.c index a63f765..6ba13bf 100644 --- a/type.c +++ b/type.c @@ -18,6 +18,7 @@ struct ValueType FunctionType; struct ValueType MacroType; struct ValueType EnumType; struct ValueType *CharPtrType; +struct ValueType *CharPtrPtrType; struct ValueType *CharArrayType; struct ValueType *VoidPtrType; @@ -139,6 +140,7 @@ void TypeInit() #endif CharArrayType = TypeAdd(NULL, &CharType, TypeArray, 0, StrEmpty, sizeof(char)); CharPtrType = TypeAdd(NULL, &CharType, TypePointer, 0, StrEmpty, sizeof(void *)); + CharPtrPtrType = TypeAdd(NULL, CharPtrType, TypePointer, 0, StrEmpty, sizeof(void *)); VoidPtrType = TypeAdd(NULL, &VoidType, TypePointer, 0, StrEmpty, sizeof(void *)); }