diff --git a/TODO b/TODO index 35a1739..fc2fa89 100644 --- a/TODO +++ b/TODO @@ -27,6 +27,7 @@ Improvements: Need test/debug: * all break/continue variations +* getchar()/gets() tests Also: * Remove Var parameter from HeapPopStack() once we're certain it all works diff --git a/clibrary.c b/clibrary.c index a238f2c..e585184 100644 --- a/clibrary.c +++ b/clibrary.c @@ -161,12 +161,30 @@ void LibPrintf(struct ParseState *Parser, struct Value *ReturnValue, struct Valu } } +/* get a line of input. protected from buffer overrun */ void LibGets(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { + struct Value *CharArray = Param[0]->Val->Pointer.Segment; + char *ReadBuffer = CharArray->Val->Array.Data + Param[0]->Val->Pointer.Offset; + int MaxLength = CharArray->Val->Array.Size - Param[0]->Val->Pointer.Offset; + char *Result; + + ReturnValue->Val->Pointer.Segment = 0; + ReturnValue->Val->Pointer.Offset = 0; + + if (Param[0]->Val->Pointer.Offset < 0 || MaxLength < 0) + return; /* no room for data */ + + Result = PlatformGetLine(ReadBuffer, MaxLength); + if (Result == NULL) + return; + + ReturnValue->Val->Pointer = Param[0]->Val->Pointer; } void LibGetc(struct ParseState *Parser, struct Value *ReturnValue, struct Value **Param, int NumArgs) { + ReturnValue->Val->Integer = PlatformGetCharacter(); } /* list of all library functions and their prototypes */ @@ -174,6 +192,6 @@ struct LibraryFunction CLibrary[] = { { LibPrintf, "void printf(char *, ...)" }, { LibGets, "void gets(char *, int)" }, - { LibGetc, "int getc()" }, + { LibGetc, "int getchar()" }, { NULL, NULL } }; diff --git a/picoc.h b/picoc.h index 9003061..0b95b26 100644 --- a/picoc.h +++ b/picoc.h @@ -326,6 +326,7 @@ void LexFail(struct LexState *Lexer, const char *Message, ...); void PlatformCleanup(); void PlatformScanFile(const char *FileName); char *PlatformGetLine(char *Buf, int MaxLen); +int PlatformGetCharacter(); void PlatformPutc(unsigned char OutCh); void PlatformPrintf(const char *Format, ...); void PlatformVPrintf(const char *Format, va_list Args); diff --git a/platform_surveyor.c b/platform_surveyor.c index ad4bdda..e568baa 100644 --- a/platform_surveyor.c +++ b/platform_surveyor.c @@ -37,8 +37,8 @@ void PlatformPutc(unsigned char OutCh) putchar(OutCh); } -/* write a character to the console */ -int PlatformGetc() +/* read a character */ +int PlatformGetCharacter() { return getch(); } diff --git a/platform_unix.c b/platform_unix.c index 7859f3f..f883aac 100644 --- a/platform_unix.c +++ b/platform_unix.c @@ -17,6 +17,13 @@ char *PlatformGetLine(char *Buf, int MaxLen) return fgets(Buf, MaxLen, stdin); } +/* get a character of interactive input */ +int PlatformGetCharacter() +{ + fflush(stdout); + return getchar(); +} + /* write a character to the console */ void PlatformPutc(unsigned char OutCh) {