From 9b3d10282739aa06216e96dc614433bb3e64b1f3 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Sun, 2 Nov 2014 13:32:30 -0600 Subject: BAS: Another file is closer to the NuttX coding style --- apps/interpreters/bas/auto.c | 5 - apps/interpreters/bas/bas.c | 23 - apps/interpreters/bas/main.c | 5 - apps/interpreters/bas/program.c | 1520 +++++++++++++++++++++++-------------- apps/interpreters/bas/statement.c | 1 - apps/interpreters/bas/value.c | 5 - apps/interpreters/bas/var.c | 5 - 7 files changed, 934 insertions(+), 630 deletions(-) (limited to 'apps/interpreters') diff --git a/apps/interpreters/bas/auto.c b/apps/interpreters/bas/auto.c index 2de1dd16b..0dda108b3 100644 --- a/apps/interpreters/bas/auto.c +++ b/apps/interpreters/bas/auto.c @@ -61,11 +61,6 @@ * Included Files ****************************************************************************/ -#undef _POSIX_SOURCE -#define _POSIX_SOURCE 1 -#undef _POSIX_C_SOURCE -#define _POSIX_C_SOURCE 2 - #include "config.h" #include diff --git a/apps/interpreters/bas/bas.c b/apps/interpreters/bas/bas.c index 84f3516f2..e621c5939 100644 --- a/apps/interpreters/bas/bas.c +++ b/apps/interpreters/bas/bas.c @@ -107,29 +107,6 @@ static struct Value *eval(struct Value *value, const char *desc); * Private Functions ****************************************************************************/ -static char *mytmpnam(void) -{ - static char buf[_POSIX_PATH_MAX]; - const char *tmpdir; - unsigned int i; - int fd = -1; - - if ((tmpdir = getenv("TMPDIR")) == (char *)0) - tmpdir = "/tmp"; - if ((strlen(tmpdir) + 1 + 8 + 1) >= _POSIX_PATH_MAX) - return (char *)0; - i = getpid(); - while (i < 0xffffffff && - (snprintf(buf, sizeof(buf), "%s/%08x", tmpdir, i), - (fd = open(buf, O_RDWR | O_CREAT | O_EXCL, 0600))) == -1 && - errno == EEXIST) - ++i; - if (fd == -1) - return (char *)0; - close(fd); - return buf; -} - static int cat(const char *filename) { int fd; diff --git a/apps/interpreters/bas/main.c b/apps/interpreters/bas/main.c index 7a0f95ee4..5d0bc5f6b 100644 --- a/apps/interpreters/bas/main.c +++ b/apps/interpreters/bas/main.c @@ -60,11 +60,6 @@ * Included Files ****************************************************************************/ -#undef _POSIX_SOURCE -#define _POSIX_SOURCE 1 -#undef _POSIX_C_SOURCE -#define _POSIX_C_SOURCE 2 - #include "config.h" #include diff --git a/apps/interpreters/bas/program.c b/apps/interpreters/bas/program.c index f90201908..900016063 100644 --- a/apps/interpreters/bas/program.c +++ b/apps/interpreters/bas/program.c @@ -1,19 +1,75 @@ -/* Program storage. */ -/* #includes */ /*{{{C}}}*//*{{{*/ -#undef _POSIX_SOURCE -#define _POSIX_SOURCE 1 -#undef _POSIX_C_SOURCE -#define _POSIX_C_SOURCE 2 +/**************************************************************************** + * apps/examples/interpreters/bas/value.c + * Program storage. + * + * Copyright (c) 1999-2014 Michael Haardt + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + * + * Adapted to NuttX and re-released under a 3-clause BSD license: + * + * Copyright (C) 2014 Gregory Nutt. All rights reserved. + * Authors: Alan Carvalho de Assis + * Gregory Nutt + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ #include "config.h" #include #include #ifdef HAVE_GETTEXT -#include -#define _(String) gettext(String) +# include +# define _(String) gettext(String) #else -#define _(String) String +# define _(String) String #endif #include #include @@ -23,755 +79,1047 @@ #include "error.h" #include "fs.h" #include "program.h" -/*}}}*/ - -struct Program *Program_new(struct Program *this) /*{{{*/ -{ - this->trace=0; - this->size=0; - this->numbered=1; - this->capacity=0; - this->runnable=0; - this->unsaved=0; - this->code=(struct Token**)0; - this->scope=(struct Scope*)0; + +/**************************************************************************** + * Private Types + ****************************************************************************/ + +/* The list of line numbers is circular, which avoids the need to have one + * extra pointer for the head (for ordered output). Instead only a pointer + * to the tail is needed. The tail's next element is the head of the list. + * + * tail --> last element <-- ... <-- first element <--, + * \ / + * \_________________________________/ + */ + +struct Xref + { + const void *key; + struct LineNumber + { + struct Pc line; + struct LineNumber *next; + } *lines; + struct Xref *l, *r; + }; + +/**************************************************************************** + * Private Functions + ****************************************************************************/ + +static void Xref_add(struct Xref **root, + int (*cmp) (const void *, const void *), const void *key, + struct Pc *line) +{ + int res; + struct LineNumber **tail; + struct LineNumber *new; + + while (*root && (res = cmp(key, (*root)->key))) + { + root = (res < 0) ? &(*root)->l : &(*root)->r; + } + + if (*root == (struct Xref *)0) + { + *root = malloc(sizeof(struct Xref)); + (*root)->key = key; + (*root)->l = (*root)->r = (struct Xref *)0; + + /* create new circular list */ + + (*root)->lines = new = malloc(sizeof(struct LineNumber)); + new->line = *line; + new->next = new; + } + else + { + /* add to existing circular list */ + + tail = &(*root)->lines; + if ((*tail)->line.line != line->line) + { + new = malloc(sizeof(struct LineNumber)); + new->line = *line; + new->next = (*tail)->next; + (*tail)->next = new; + *tail = new; + } + } +} + +static void Xref_destroy(struct Xref *root) +{ + if (root) + { + struct LineNumber *cur, *next, *tail; + + Xref_destroy(root->l); + Xref_destroy(root->r); + cur = tail = root->lines; + do + { + next = cur->next; + free(cur); + cur = next; + } + while (cur != tail); + + free(root); + } +} + +static void Xref_print(struct Xref *root, + void (*print) (const void *key, struct Program * p, + int chn), struct Program *p, int chn) +{ + if (root) + { + const struct LineNumber *cur, *tail; + + Xref_print(root->l, print, p, chn); + print(root->key, p, chn); + cur = tail = root->lines; + do + { + char buf[128]; + + cur = cur->next; + if (FS_charpos(chn) > 72) + { + FS_putChars(chn, "\n "); + } + + sprintf(buf, " %ld", Program_lineNumber(p, &cur->line)); + FS_putChars(chn, buf); + } + while (cur != tail); + + FS_putChar(chn, '\n'); + Xref_print(root->r, print, p, chn); + } +} + +static int cmpLine(const void *a, const void *b) +{ + const register struct Pc *pcA = (const struct Pc *)a, *pcB = + (const struct Pc *)b; + + return pcA->line - pcB->line; +} + +static void printLine(const void *k, struct Program *p, int chn) +{ + char buf[80]; + + sprintf(buf, "%8ld", Program_lineNumber(p, (const struct Pc *)k)); + FS_putChars(chn, buf); +} + +static int cmpName(const void *a, const void *b) +{ + const register char *funcA = (const char *)a, *funcB = (const char *)b; + + return strcmp(funcA, funcB); +} + +static void printName(const void *k, struct Program *p, int chn) +{ + size_t len = strlen((const char *)k); + + FS_putChars(chn, (const char *)k); + if (len < 8) + { + FS_putChars(chn, " " + len); + } +} + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +struct Program *Program_new(struct Program *this) +{ + this->trace = 0; + this->size = 0; + this->numbered = 1; + this->capacity = 0; + this->runnable = 0; + this->unsaved = 0; + this->code = (struct Token **)0; + this->scope = (struct Scope *)0; String_new(&this->name); return this; } -/*}}}*/ -void Program_destroy(struct Program *this) /*{{{*/ + +void Program_destroy(struct Program *this) { - while (this->size) Token_destroy(this->code[--this->size]); - if (this->capacity) free(this->code); - this->code=(struct Token**)0; - this->scope=(struct Scope*)0; + while (this->size) + { + Token_destroy(this->code[--this->size]); + } + + if (this->capacity) + { + free(this->code); + } + + this->code = (struct Token **)0; + this->scope = (struct Scope *)0; String_destroy(&this->name); } -/*}}}*/ -void Program_norun(struct Program *this) /*{{{*/ + +void Program_norun(struct Program *this) { - this->runnable=0; - this->scope=(struct Scope*)0; + this->runnable = 0; + this->scope = (struct Scope *)0; } -/*}}}*/ -void Program_store(struct Program *this, struct Token *line, long int where) /*{{{*/ + +void Program_store(struct Program *this, struct Token *line, long int where) { int i; - assert(line->type==T_INTEGER || line->type==T_UNNUMBERED); - this->runnable=0; - this->unsaved=1; - if (line->type==T_UNNUMBERED) this->numbered=0; - if (where) - { - int last=-1; + assert(line->type == T_INTEGER || line->type == T_UNNUMBERED); + this->runnable = 0; + this->unsaved = 1; + if (line->type == T_UNNUMBERED) + { + this->numbered = 0; + } - for (i=0; isize; ++i) + if (where) { - assert(this->code[i]->type==T_INTEGER || this->code[i]->type==T_UNNUMBERED); - if (where>last && wherecode[i]->u.integer) - { - if ((this->size+1)>=this->capacity) + int last = -1; + + for (i = 0; i < this->size; ++i) { - this->code=realloc(this->code,sizeof(struct Token*)*(this->capacity?(this->capacity*=2):(this->capacity=256))); + assert(this->code[i]->type == T_INTEGER || + this->code[i]->type == T_UNNUMBERED); + if (where > last && where < this->code[i]->u.integer) + { + if ((this->size + 1) >= this->capacity) + { + this->code = + realloc(this->code, + sizeof(struct Token *) * + (this->capacity ? (this->capacity *= + 2) : (this->capacity = 256))); + } + + memmove(&this->code[i + 1], &this->code[i], + (this->size - i) * sizeof(struct Token *)); + this->code[i] = line; + ++this->size; + return; + } + else if (where == this->code[i]->u.integer) + { + Token_destroy(this->code[i]); + this->code[i] = line; + return; + } + + last = this->code[i]->u.integer; } - memmove(&this->code[i+1],&this->code[i],(this->size-i)*sizeof(struct Token*)); - this->code[i]=line; - ++this->size; - return; - } - else if (where==this->code[i]->u.integer) - { - Token_destroy(this->code[i]); - this->code[i]=line; - return; - } - last=this->code[i]->u.integer; - } - } - else i=this->size; - if ((this->size+1)>=this->capacity) - { - this->code=realloc(this->code,sizeof(struct Token*)*(this->capacity?(this->capacity*=2):(this->capacity=256))); - } - this->code[i]=line; + } + else + { + i = this->size; + } + + if ((this->size + 1) >= this->capacity) + { + this->code = + realloc(this->code, + sizeof(struct Token *) * + (this->capacity ? (this->capacity *= 2) + : (this->capacity = 256))); + } + + this->code[i] = line; ++this->size; } -/*}}}*/ -void Program_delete(struct Program *this, const struct Pc *from, const struct Pc *to) /*{{{*/ + +void Program_delete(struct Program *this, const struct Pc *from, + const struct Pc *to) { int i, first, last; - this->runnable=0; - this->unsaved=1; - first=from ? from->line : 0; - last=to ? to->line : this->size-1; - for (i=first; i<=last; ++i) Token_destroy(this->code[i]); - if ((last+1)!=this->size) memmove(&this->code[first],&this->code[last+1],(this->size-last+1)*sizeof(struct Token*)); - this->size-=(last-first+1); + this->runnable = 0; + this->unsaved = 1; + first = from ? from->line : 0; + last = to ? to->line : this->size - 1; + for (i = first; i <= last; ++i) + { + Token_destroy(this->code[i]); + } + + if ((last + 1) != this->size) + { + memmove(&this->code[first], &this->code[last + 1], + (this->size - last + 1) * sizeof(struct Token *)); + } + + this->size -= (last - first + 1); } -/*}}}*/ -void Program_addScope(struct Program *this, struct Scope *scope) /*{{{*/ + +void Program_addScope(struct Program *this, struct Scope *scope) { struct Scope *s; - s=this->scope; - this->scope=scope; - scope->next=s; + s = this->scope; + this->scope = scope; + scope->next = s; } -/*}}}*/ -struct Pc *Program_goLine(struct Program *this, long int line, struct Pc *pc) /*{{{*/ + +struct Pc *Program_goLine(struct Program *this, long int line, struct Pc *pc) { int i; - for (i=0; isize; ++i) - { - if (this->code[i]->type==T_INTEGER && line==this->code[i]->u.integer) + for (i = 0; i < this->size; ++i) { - pc->line=i; - pc->token=this->code[i]+1; - return pc; + if (this->code[i]->type == T_INTEGER && line == this->code[i]->u.integer) + { + pc->line = i; + pc->token = this->code[i] + 1; + return pc; + } } - } - return (struct Pc*)0; + + return (struct Pc *)0; } -/*}}}*/ -struct Pc *Program_fromLine(struct Program *this, long int line, struct Pc *pc) /*{{{*/ + +struct Pc *Program_fromLine(struct Program *this, long int line, struct Pc *pc) { int i; - for (i=0; isize; ++i) - { - if (this->code[i]->type==T_INTEGER && this->code[i]->u.integer>=line) + for (i = 0; i < this->size; ++i) { - pc->line=i; - pc->token=this->code[i]+1; - return pc; + if (this->code[i]->type == T_INTEGER && this->code[i]->u.integer >= line) + { + pc->line = i; + pc->token = this->code[i] + 1; + return pc; + } } - } - return (struct Pc*)0; + + return (struct Pc *)0; } -/*}}}*/ -struct Pc *Program_toLine(struct Program *this, long int line, struct Pc *pc) /*{{{*/ + +struct Pc *Program_toLine(struct Program *this, long int line, struct Pc *pc) { int i; - for (i=this->size-1; i>=0; --i) - { - if (this->code[i]->type==T_INTEGER && this->code[i]->u.integer<=line) + for (i = this->size - 1; i >= 0; --i) { - pc->line=i; - pc->token=this->code[i]+1; - return pc; + if (this->code[i]->type == T_INTEGER && this->code[i]->u.integer <= line) + { + pc->line = i; + pc->token = this->code[i] + 1; + return pc; + } } - } - return (struct Pc*)0; + + return (struct Pc *)0; } -/*}}}*/ -int Program_scopeCheck(struct Program *this, struct Pc *pc, struct Pc *fn) /*{{{*/ + +int Program_scopeCheck(struct Program *this, struct Pc *pc, struct Pc *fn) { struct Scope *scope; - if (fn==(struct Pc*)0) /* jump from global block must go to global pc */ - { - for (scope=this->scope; scope; scope=scope->next) + if (fn == (struct Pc *)0) /* jump from global block must go to global pc */ { - if (pc->linebegin.line) continue; - if (pc->line==scope->begin.line && pc->token<=scope->begin.token) continue; - if (pc->line>scope->end.line) continue; - if (pc->line==scope->end.line && pc->token>scope->end.token) continue; - return -1; + for (scope = this->scope; scope; scope = scope->next) + { + if (pc->line < scope->begin.line) + { + continue; + } + + if (pc->line == scope->begin.line && pc->token <= scope->begin.token) + { + continue; + } + + if (pc->line > scope->end.line) + { + continue; + } + + if (pc->line == scope->end.line && pc->token > scope->end.token) + { + continue; + } + + return -1; + } } - } - else /* jump from local block must go to local block */ - { - scope=&(fn->token+1)->u.identifier->sym->u.sub.u.def.scope; - if (pc->linebegin.line) return -1; - if (pc->line==scope->begin.line && pc->token<=scope->begin.token) return -1; - if (pc->line>scope->end.line) return -1; - if (pc->line==scope->end.line && pc->token>scope->end.token) return -1; - } + + /* jump from local block must go to local block */ + + else + { + scope = &(fn->token + 1)->u.identifier->sym->u.sub.u.def.scope; + if (pc->line < scope->begin.line) + { + return -1; + } + + if (pc->line == scope->begin.line && pc->token <= scope->begin.token) + { + return -1; + } + + if (pc->line > scope->end.line) + { + return -1; + } + + if (pc->line == scope->end.line && pc->token > scope->end.token) + { + return -1; + } + } + return 0; } -/*}}}*/ -struct Pc *Program_dataLine(struct Program *this, long int line, struct Pc *pc) /*{{{*/ + +struct Pc *Program_dataLine(struct Program *this, long int line, struct Pc *pc) { - if ((pc=Program_goLine(this,line,pc))==(struct Pc*)0) return (struct Pc*)0; - while (pc->token->type!=T_DATA) - { - if (pc->token->type==T_EOL) return (struct Pc*)0; - else ++pc->token; - } + if ((pc = Program_goLine(this, line, pc)) == (struct Pc *)0) + { + return (struct Pc *)0; + } + + while (pc->token->type != T_DATA) + { + if (pc->token->type == T_EOL) + { + return (struct Pc *)0; + } + else + { + ++pc->token; + } + } + return pc; } -/*}}}*/ -struct Pc *Program_imageLine(struct Program *this, long int line, struct Pc *pc) /*{{{*/ + +struct Pc *Program_imageLine(struct Program *this, long int line, struct Pc *pc) { - if ((pc=Program_goLine(this,line,pc))==(struct Pc*)0) return (struct Pc*)0; - while (pc->token->type!=T_IMAGE) - { - if (pc->token->type==T_EOL) return (struct Pc*)0; - else ++pc->token; - } + if ((pc = Program_goLine(this, line, pc)) == (struct Pc *)0) + { + return (struct Pc *)0; + } + + while (pc->token->type != T_IMAGE) + { + if (pc->token->type == T_EOL) + { + return (struct Pc *)0; + } + else + { + ++pc->token; + } + } + ++pc->token; - if (pc->token->type!=T_STRING) return (struct Pc*)0; + if (pc->token->type != T_STRING) + { + return (struct Pc *)0; + } + return pc; } -/*}}}*/ -long int Program_lineNumber(const struct Program *this, const struct Pc *pc) /*{{{*/ + +long int Program_lineNumber(const struct Program *this, const struct Pc *pc) { - if (pc->line==-1) return 0; - if (this->numbered) return (this->code[pc->line]->u.integer); - else return (pc->line+1); + if (pc->line == -1) + { + return 0; + } + + if (this->numbered) + { + return (this->code[pc->line]->u.integer); + } + else + { + return (pc->line + 1); + } } -/*}}}*/ -struct Pc *Program_beginning(struct Program *this, struct Pc *pc) /*{{{*/ + +struct Pc *Program_beginning(struct Program *this, struct Pc *pc) { - if (this->size==0) return (struct Pc*)0; + if (this->size == 0) + { + return (struct Pc *)0; + } else - { - pc->line=0; - pc->token=this->code[0]+1; - return pc; - } + { + pc->line = 0; + pc->token = this->code[0] + 1; + return pc; + } } -/*}}}*/ -struct Pc *Program_end(struct Program *this, struct Pc *pc) /*{{{*/ + +struct Pc *Program_end(struct Program *this, struct Pc *pc) { - if (this->size==0) return (struct Pc*)0; + if (this->size == 0) + { + return (struct Pc *)0; + } else - { - pc->line=this->size-1; - pc->token=this->code[this->size-1]; - while (pc->token->type!=T_EOL) ++pc->token; - return pc; - } + { + pc->line = this->size - 1; + pc->token = this->code[this->size - 1]; + while (pc->token->type != T_EOL) + { + ++pc->token; + } + + return pc; + } } -/*}}}*/ -struct Pc *Program_nextLine(struct Program *this, struct Pc *pc) /*{{{*/ + +struct Pc *Program_nextLine(struct Program *this, struct Pc *pc) { - if (pc->line+1==this->size) return (struct Pc*)0; + if (pc->line + 1 == this->size) + { + return (struct Pc *)0; + } else - { - pc->token=this->code[++pc->line]+1; - return pc; - } + { + pc->token = this->code[++pc->line] + 1; + return pc; + } } -/*}}}*/ -int Program_skipEOL(struct Program *this, struct Pc *pc, int dev, int tr) /*{{{*/ + +int Program_skipEOL(struct Program *this, struct Pc *pc, int dev, int tr) { - if (pc->token->type==T_EOL) - { - if (pc->line==-1 || pc->line+1==this->size) return 0; + if (pc->token->type == T_EOL) + { + if (pc->line == -1 || pc->line + 1 == this->size) + { + return 0; + } + else + { + pc->token = this->code[++pc->line] + 1; + Program_trace(this, pc, dev, tr); + return 1; + } + } + else { - pc->token=this->code[++pc->line]+1; - Program_trace(this,pc,dev,tr); return 1; } - } - else return 1; } -/*}}}*/ -void Program_trace(struct Program *this, struct Pc *pc, int dev, int tr) /*{{{*/ + +void Program_trace(struct Program *this, struct Pc *pc, int dev, int tr) { - if (tr && this->trace && pc->line!=-1) - { - char buf[40]; + if (tr && this->trace && pc->line != -1) + { + char buf[40]; - sprintf(buf,"<%ld>\n",this->code[pc->line]->u.integer); - FS_putChars(dev,buf); - } + sprintf(buf, "<%ld>\n", this->code[pc->line]->u.integer); + FS_putChars(dev, buf); + } } -/*}}}*/ -void Program_PCtoError(struct Program *this, struct Pc *pc, struct Value *v) /*{{{*/ + +void Program_PCtoError(struct Program *this, struct Pc *pc, struct Value *v) { struct String s; String_new(&s); - if (pc->line>=0) - { - if (pc->line<(this->size-1) || pc->token->type!=T_EOL) + if (pc->line >= 0) { - String_appendPrintf(&s,_(" in line %ld at:\n"),Program_lineNumber(this,pc)); - Token_toString(this->code[pc->line],(struct Token*)0,&s,(int*)0,-1); - Token_toString(this->code[pc->line],pc->token,&s,(int*)0,-1); - String_appendPrintf(&s,"^\n"); + if (pc->line < (this->size - 1) || pc->token->type != T_EOL) + { + String_appendPrintf(&s, _(" in line %ld at:\n"), + Program_lineNumber(this, pc)); + Token_toString(this->code[pc->line], (struct Token *)0, &s, (int *)0, + -1); + Token_toString(this->code[pc->line], pc->token, &s, (int *)0, -1); + String_appendPrintf(&s, "^\n"); + } + else + { + String_appendPrintf(&s, _(" at: end of program\n")); + } } - else + else { - String_appendPrintf(&s,_(" at: end of program\n")); + String_appendPrintf(&s, _(" at: ")); + if (pc->token->type != T_EOL) + { + Token_toString(pc->token, (struct Token *)0, &s, (int *)0, -1); + } + else + { + String_appendPrintf(&s, _("end of line\n")); + } } - } - else - { - String_appendPrintf(&s,_(" at: ")); - if (pc->token->type!=T_EOL) Token_toString(pc->token,(struct Token*)0,&s,(int*)0,-1); - else String_appendPrintf(&s,_("end of line\n")); - } - Value_errorSuffix(v,s.character); + + Value_errorSuffix(v, s.character); String_destroy(&s); } -/*}}}*/ -struct Value *Program_merge(struct Program *this, int dev, struct Value *value) /*{{{*/ + +struct Value *Program_merge(struct Program *this, int dev, struct Value *value) { struct String s; - int l,err=0; + int l, err = 0; - l=0; - while (String_new(&s),(err=FS_appendToString(dev,&s,1))!=-1 && s.length) - { - struct Token *line; - - ++l; - if (l!=1 || s.character[0]!='#') + l = 0; + while (String_new(&s), (err = FS_appendToString(dev, &s, 1)) != -1 && + s.length) { - line=Token_newCode(s.character); - if (line->type==T_INTEGER && line->u.integer>0) Program_store(this,line,this->numbered?line->u.integer:0); - else if (line->type==T_UNNUMBERED) Program_store(this,line,0); - else - { - Token_destroy(line); - return Value_new_ERROR(value,INVALIDLINE,l); - } + struct Token *line; + + ++l; + if (l != 1 || s.character[0] != '#') + { + line = Token_newCode(s.character); + if (line->type == T_INTEGER && line->u.integer > 0) + { + Program_store(this, line, this->numbered ? line->u.integer : 0); + } + else if (line->type == T_UNNUMBERED) + { + Program_store(this, line, 0); + } + else + { + Token_destroy(line); + return Value_new_ERROR(value, INVALIDLINE, l); + } + } + + String_destroy(&s); } - String_destroy(&s); - } + String_destroy(&s); - if (err) return Value_new_ERROR(value,IOERROR,FS_errmsg); - return (struct Value*)0; + if (err) + { + return Value_new_ERROR(value, IOERROR, FS_errmsg); + } + + return (struct Value *)0; } -/*}}}*/ -int Program_lineNumberWidth(struct Program *this) /*{{{*/ + +int Program_lineNumberWidth(struct Program *this) { - int i,w=0; + int i, w = 0; + + for (i = 0; i < this->size; ++i) + { + if (this->code[i]->type == T_INTEGER) + { + int nw, ln; + for (ln = this->code[i]->u.integer, nw = 1; ln /= 10; ++nw); + if (nw > w) + { + w = nw; + } + } + } - for (i=0; isize; ++i) if (this->code[i]->type==T_INTEGER) - { - int nw,ln; - for (ln=this->code[i]->u.integer,nw=1; ln/=10; ++nw); - if (nw>w) w=nw; - } return w; } -/*}}}*/ -struct Value *Program_list(struct Program *this, int dev, int watchIntr, struct Pc *from, struct Pc *to, struct Value *value) /*{{{*/ + +struct Value *Program_list(struct Program *this, int dev, int watchIntr, + struct Pc *from, struct Pc *to, struct Value *value) { - int i,w; - int indent=0; + int i, w; + int indent = 0; struct String s; - w=Program_lineNumberWidth(this); - for (i=0; isize; ++i) - { - String_new(&s); - Token_toString(this->code[i],(struct Token*)0,&s,&indent,w); - if ((from==(struct Pc *)0 || from->line<=i) && (to==(struct Pc*)0 || to->line>=i)) + w = Program_lineNumberWidth(this); + for (i = 0; i < this->size; ++i) { - if (FS_putString(dev,&s)==-1) return Value_new_ERROR(value,IOERROR,FS_errmsg); - if (watchIntr && FS_intr) return Value_new_ERROR(value,BREAK); + String_new(&s); + Token_toString(this->code[i], (struct Token *)0, &s, &indent, w); + if ((from == (struct Pc *)0 || from->line <= i) && + (to == (struct Pc *)0 || to->line >= i)) + { + if (FS_putString(dev, &s) == -1) + { + return Value_new_ERROR(value, IOERROR, FS_errmsg); + } + if (watchIntr && FS_intr) + { + return Value_new_ERROR(value, BREAK); + } + } + + String_destroy(&s); } - String_destroy(&s); - } - return (struct Value*)0; + + return (struct Value *)0; } -/*}}}*/ -struct Value *Program_analyse(struct Program *this, struct Pc *pc, struct Value *value) /*{{{*/ + +struct Value *Program_analyse(struct Program *this, struct Pc *pc, + struct Value *value) { int i; - for (i=0; isize; ++i) - { - pc->token=this->code[i]; - pc->line=i; - if (pc->token->type==T_INTEGER || pc->token->type==T_UNNUMBERED) ++pc->token; - for (;;) + for (i = 0; i < this->size; ++i) { - if (pc->token->type==T_GOTO || pc->token->type==T_RESUME || pc->token->type==T_RETURN || pc->token->type==T_END || pc->token->type==T_STOP) - { - ++pc->token; - while (pc->token->type==T_INTEGER) + pc->token = this->code[i]; + pc->line = i; + if (pc->token->type == T_INTEGER || pc->token->type == T_UNNUMBERED) { ++pc->token; - if (pc->token->type==T_COMMA) ++pc->token; - else break; } - if (pc->token->type==T_COLON) + + for (;;) { - ++pc->token; - switch (pc->token->type) - { - case T_EOL: - case T_DEFPROC: - case T_SUB: - case T_DEFFN: - case T_FUNCTION: - case T_COLON: - case T_REM: - case T_QUOTE: break; /* those are fine to be unreachable */ - default: return Value_new_ERROR(value,UNREACHABLE); - } + if (pc->token->type == T_GOTO || pc->token->type == T_RESUME || + pc->token->type == T_RETURN || pc->token->type == T_END || + pc->token->type == T_STOP) + { + ++pc->token; + while (pc->token->type == T_INTEGER) + { + ++pc->token; + if (pc->token->type == T_COMMA) + { + ++pc->token; + } + else + { + break; + } + } + + if (pc->token->type == T_COLON) + { + ++pc->token; + switch (pc->token->type) + { + case T_EOL: + case T_DEFPROC: + case T_SUB: + case T_DEFFN: + case T_FUNCTION: + case T_COLON: + case T_REM: + case T_QUOTE: + break; /* those are fine to be unreachable */ + + default: + return Value_new_ERROR(value, UNREACHABLE); + } + } + } + + if (pc->token->type == T_EOL) + { + break; + } + else + { + ++pc->token; + } } - } - if (pc->token->type==T_EOL) break; - else ++pc->token; } - } - return (struct Value*)0; + + return (struct Value *)0; } -/*}}}*/ -void Program_renum(struct Program *this, int first, int inc) /*{{{*/ + +void Program_renum(struct Program *this, int first, int inc) { int i; struct Token *token; - for (i=0; isize; ++i) - { - for (token=this->code[i]; token->type!=T_EOL; ) + for (i = 0; i < this->size; ++i) { - if (token->type==T_GOTO || token->type==T_GOSUB || token->type==T_RESTORE || token->type==T_RESUME || token->type==T_USING) - { - ++token; - while (token->type==T_INTEGER) + for (token = this->code[i]; token->type != T_EOL;) { - struct Pc dst; + if (token->type == T_GOTO || token->type == T_GOSUB || + token->type == T_RESTORE || token->type == T_RESUME || + token->type == T_USING) + { + ++token; + while (token->type == T_INTEGER) + { + struct Pc dst; + + if (Program_goLine(this, token->u.integer, &dst)) + { + token->u.integer = first + dst.line * inc; + } - if (Program_goLine(this,token->u.integer,&dst)) token->u.integer=first+dst.line*inc; - ++token; - if (token->type==T_COMMA) ++token; - else break; + ++token; + if (token->type == T_COMMA) + { + ++token; + } + else + { + break; + } + } + } + else + { + ++token; + } } - } - else ++token; } - } - for (i=0; isize; ++i) - { - assert(this->code[i]->type==T_INTEGER || this->code[i]->type==T_UNNUMBERED); - this->code[i]->type=T_INTEGER; - this->code[i]->u.integer=first+i*inc; - } - this->numbered=1; - this->runnable=0; - this->unsaved=1; + for (i = 0; i < this->size; ++i) + { + assert(this->code[i]->type == T_INTEGER || + this->code[i]->type == T_UNNUMBERED); + this->code[i]->type = T_INTEGER; + this->code[i]->u.integer = first + i * inc; + } + + this->numbered = 1; + this->runnable = 0; + this->unsaved = 1; } -/*}}}*/ -void Program_unnum(struct Program *this) /*{{{*/ + +void Program_unnum(struct Program *this) { char *ref; int i; struct Token *token; - ref=malloc(this->size); - memset(ref,0,this->size); - for (i=0; isize; ++i) - { - for (token=this->code[i]; token->type!=T_EOL; ++token) + ref = malloc(this->size); + memset(ref, 0, this->size); + for (i = 0; i < this->size; ++i) { - if (token->type==T_GOTO || token->type==T_GOSUB || token->type==T_RESTORE || token->type==T_RESUME) - { - ++token; - while (token->type==T_INTEGER) + for (token = this->code[i]; token->type != T_EOL; ++token) { - struct Pc dst; + if (token->type == T_GOTO || token->type == T_GOSUB || + token->type == T_RESTORE || token->type == T_RESUME) + { + ++token; + while (token->type == T_INTEGER) + { + struct Pc dst; + + if (Program_goLine(this, token->u.integer, &dst)) + { + ref[dst.line] = 1; + } - if (Program_goLine(this,token->u.integer,&dst)) ref[dst.line]=1; - ++token; - if (token->type==T_COMMA) ++token; - else break; + ++token; + if (token->type == T_COMMA) + { + ++token; + } + else + { + break; + } + } + } } - } } - } - for (i=0; isize; ++i) - { - assert(this->code[i]->type==T_INTEGER || this->code[i]->type==T_UNNUMBERED); - if (!ref[i]) + + for (i = 0; i < this->size; ++i) { - this->code[i]->type=T_UNNUMBERED; - this->numbered=0; + assert(this->code[i]->type == T_INTEGER || + this->code[i]->type == T_UNNUMBERED); + if (!ref[i]) + { + this->code[i]->type = T_UNNUMBERED; + this->numbered = 0; + } } - } + free(ref); - this->runnable=0; - this->unsaved=1; -} -/*}}}*/ -int Program_setname(struct Program *this, const char *filename) /*{{{*/ -{ - if (this->name.length) String_delete(&this->name,0,this->name.length); - if (filename) return String_appendChars(&this->name,filename); - else return 0; + this->runnable = 0; + this->unsaved = 1; } -/*}}}*/ -/* - -The list of line numbers is circular, which avoids the need to have one -extra pointer for the head (for ordered output). Instead only a pointer -to the tail is needed. The tail's next element is the head of the list. - -tail --> last element <-- ... <-- first element <--, - \ / - \_________________________________/ - -*/ - -struct Xref -{ - const void *key; - struct LineNumber - { - struct Pc line; - struct LineNumber *next; - } *lines; - struct Xref *l,*r; -}; - -static void Xref_add(struct Xref **root, int (*cmp)(const void*,const void*), const void *key, struct Pc *line) /*{{{*/ +int Program_setname(struct Program *this, const char *filename) { - int res; - struct LineNumber **tail; - struct LineNumber *new; - - while (*root && (res=cmp(key,(*root)->key))) root=(res<0)?&(*root)->l:&(*root)->r; - if (*root==(struct Xref*)0) - { - *root=malloc(sizeof(struct Xref)); - (*root)->key=key; - (*root)->l=(*root)->r=(struct Xref*)0; - /* create new circular list */ - (*root)->lines=new=malloc(sizeof(struct LineNumber)); - new->line=*line; - new->next=new; - } - else - { - /* add to existing circular list */ - tail=&(*root)->lines; - if ((*tail)->line.line!=line->line) + if (this->name.length) { - new=malloc(sizeof(struct LineNumber)); - new->line=*line; - new->next=(*tail)->next; - (*tail)->next=new; - *tail=new; + String_delete(&this->name, 0, this->name.length); } - } -} -/*}}}*/ -static void Xref_destroy(struct Xref *root) /*{{{*/ -{ - if (root) - { - struct LineNumber *cur,*next,*tail; - Xref_destroy(root->l); - Xref_destroy(root->r); - cur=tail=root->lines; - do + if (filename) { - next=cur->next; - free(cur); - cur=next; - } while (cur!=tail); - free(root); - } -} -/*}}}*/ -static void Xref_print(struct Xref *root, void (*print)(const void *key, struct Program *p, int chn), struct Program *p, int chn) /*{{{*/ -{ - if (root) - { - const struct LineNumber *cur,*tail; - - Xref_print(root->l,print,p,chn); - print(root->key,p,chn); - cur=tail=root->lines; - do + return String_appendChars(&this->name, filename); + } + else { - char buf[128]; - - cur=cur->next; - if (FS_charpos(chn)>72) FS_putChars(chn,"\n "); - sprintf(buf," %ld",Program_lineNumber(p,&cur->line)); - FS_putChars(chn,buf); - } while (cur!=tail); - FS_putChar(chn,'\n'); - Xref_print(root->r,print,p,chn); - } + return 0; + } } -/*}}}*/ -static int cmpLine(const void *a, const void *b) /*{{{*/ -{ - const register struct Pc *pcA=(const struct Pc*)a,*pcB=(const struct Pc*)b; - return pcA->line-pcB->line; -} -/*}}}*/ -static void printLine(const void *k, struct Program *p, int chn) /*{{{*/ +void Program_xref(struct Program *this, int chn) { - char buf[80]; + struct Pc pc; + struct Xref *func, *var, *gosub, *goto_; + int nl = 0; - sprintf(buf,"%8ld",Program_lineNumber(p,(const struct Pc*)k)); - FS_putChars(chn,buf); -} -/*}}}*/ -static int cmpName(const void *a, const void *b) /*{{{*/ -{ - const register char *funcA=(const char*)a,*funcB=(const char*)b; + assert(this->runnable); + func = (struct Xref *)0; + var = (struct Xref *)0; + gosub = (struct Xref *)0; + goto_ = (struct Xref *)0; - return strcmp(funcA,funcB); -} -/*}}}*/ -static void printName(const void *k, struct Program *p, int chn) /*{{{*/ -{ - size_t len=strlen((const char*)k); + for (pc.line = 0; pc.line < this->size; ++pc.line) + { + struct On *on; - FS_putChars(chn,(const char*)k); - if (len<8) FS_putChars(chn," "+len); -} -/*}}}*/ + for (on = (struct On *)0, pc.token = this->code[pc.line]; + pc.token->type != T_EOL; ++pc.token) + { + switch (pc.token->type) + { + case T_ON: + { + on = &pc.token->u.on; + break; + } -void Program_xref(struct Program *this, int chn) /*{{{*/ -{ - struct Pc pc; - struct Xref *func,*var,*gosub,*goto_; - int nl=0; + case T_GOTO: + { + if (on) + { + int key; - assert(this->runnable); - func=(struct Xref*)0; - var=(struct Xref*)0; - gosub=(struct Xref*)0; - goto_=(struct Xref*)0; + for (key = 0; key < on->pcLength; ++key) + Xref_add(&goto_, cmpLine, &on->pc[key], &pc); + on = (struct On *)0; + } + else + Xref_add(&goto_, cmpLine, &pc.token->u.gotopc, &pc); + break; + } - for (pc.line=0; pc.linesize; ++pc.line) - { - struct On *on; + case T_GOSUB: + { + if (on) + { + int key; - for (on=(struct On*)0,pc.token=this->code[pc.line]; pc.token->type!=T_EOL; ++pc.token) - { - switch (pc.token->type) - { - case T_ON: /*{{{*/ - { - on=&pc.token->u.on; - break; - } - /*}}}*/ - case T_GOTO: /*{{{*/ - { - if (on) - { - int key; + for (key = 0; key < on->pcLength; ++key) + Xref_add(&gosub, cmpLine, &on->pc[key], &pc); + on = (struct On *)0; + } + else + Xref_add(&gosub, cmpLine, &pc.token->u.gosubpc, &pc); + break; + } - for (key=0; keypcLength; ++key) Xref_add(&goto_,cmpLine,&on->pc[key],&pc); - on=(struct On*)0; - } - else Xref_add(&goto_,cmpLine,&pc.token->u.gotopc,&pc); - break; - } - /*}}}*/ - case T_GOSUB: /*{{{*/ - { - if (on) - { - int key; + case T_DEFFN: + case T_DEFPROC: + case T_FUNCTION: + case T_SUB: + { + ++pc.token; + Xref_add(&func, cmpName, &pc.token->u.identifier->name, &pc); + break; + } - for (key=0; keypcLength; ++key) Xref_add(&gosub,cmpLine,&on->pc[key],&pc); - on=(struct On*)0; - } - else Xref_add(&gosub,cmpLine,&pc.token->u.gosubpc,&pc); - break; - } - /*}}}*/ - case T_DEFFN: - case T_DEFPROC: - case T_FUNCTION: - case T_SUB: /*{{{*/ - { - ++pc.token; - Xref_add(&func,cmpName,&pc.token->u.identifier->name,&pc); - break; + default: + break; + } } - /*}}}*/ - default: break; - } } - } - for (pc.line=0; pc.linesize; ++pc.line) - { - for (pc.token=this->code[pc.line]; pc.token->type!=T_EOL; ++pc.token) + for (pc.line = 0; pc.line < this->size; ++pc.line) { - switch (pc.token->type) - { - case T_DEFFN: - case T_DEFPROC: - case T_FUNCTION: - case T_SUB: /* skip identifier already added above */ /*{{{*/ + for (pc.token = this->code[pc.line]; pc.token->type != T_EOL; ++pc.token) { - ++pc.token; - break; - } - /*}}}*/ - case T_IDENTIFIER: /*{{{*/ - { - /* formal parameters have no assigned symbol */ - if (pc.token->u.identifier->sym) switch (pc.token->u.identifier->sym->type) - { - case GLOBALVAR: - { - Xref_add(&var,cmpName,&pc.token->u.identifier->name,&pc); - break; - } - case USERFUNCTION: + switch (pc.token->type) { - Xref_add(&func,cmpName,&pc.token->u.identifier->name,&pc); + case T_DEFFN: + case T_DEFPROC: + case T_FUNCTION: + case T_SUB: /* skip identifier already added above */ + { + ++pc.token; + break; + } + + case T_IDENTIFIER: + { + /* formal parameters have no assigned symbol */ + + if (pc.token->u.identifier->sym) + { + switch (pc.token->u.identifier->sym->type) + { + case GLOBALVAR: + { + Xref_add(&var, cmpName, &pc.token->u.identifier->name, + &pc); + break; + } + case USERFUNCTION: + { + Xref_add(&func, cmpName, + &pc.token->u.identifier->name, &pc); + break; + } + default: + break; + } + } + break; + } + + default: break; } - default: break; - } - break; } - /*}}}*/ - default: break; - } } - } if (func) - { - FS_putChars(chn,_("Function Referenced in line\n")); - Xref_print(func,printName,this,chn); - Xref_destroy(func); - nl=1; - } + { + FS_putChars(chn, _("Function Referenced in line\n")); + Xref_print(func, printName, this, chn); + Xref_destroy(func); + nl = 1; + } if (var) - { - if (nl) FS_putChar(chn,'\n'); - FS_putChars(chn,_("Variable Referenced in line\n")); - Xref_print(var,printName,this,chn); - Xref_destroy(func); - nl=1; - } + { + if (nl) + { + FS_putChar(chn, '\n'); + } + + FS_putChars(chn, _("Variable Referenced in line\n")); + Xref_print(var, printName, this, chn); + Xref_destroy(func); + nl = 1; + } if (gosub) - { - if (nl) FS_putChar(chn,'\n'); - FS_putChars(chn,_("Gosub Referenced in line\n")); - Xref_print(gosub,printLine,this,chn); - Xref_destroy(gosub); - nl=1; - } + { + if (nl) + { + FS_putChar(chn, '\n'); + } + + FS_putChars(chn, _("Gosub Referenced in line\n")); + Xref_print(gosub, printLine, this, chn); + Xref_destroy(gosub); + nl = 1; + } if (goto_) - { - if (nl) FS_putChar(chn,'\n'); - FS_putChars(chn,_("Goto Referenced in line\n")); - Xref_print(goto_,printLine,this,chn); - Xref_destroy(goto_); - nl=1; - } -} -/*}}}*/ + { + if (nl) + { + FS_putChar(chn, '\n'); + } + + FS_putChars(chn, _("Goto Referenced in line\n")); + Xref_print(goto_, printLine, this, chn); + Xref_destroy(goto_); + nl = 1; + } +} diff --git a/apps/interpreters/bas/statement.c b/apps/interpreters/bas/statement.c index 3f413c74d..774adee6f 100644 --- a/apps/interpreters/bas/statement.c +++ b/apps/interpreters/bas/statement.c @@ -1,4 +1,3 @@ -/* #includes */ /*{{{C}}}*/ #include "config.h" #ifdef HAVE_GETTEXT diff --git a/apps/interpreters/bas/value.c b/apps/interpreters/bas/value.c index a1d9c05fa..d7c591442 100644 --- a/apps/interpreters/bas/value.c +++ b/apps/interpreters/bas/value.c @@ -60,11 +60,6 @@ * Included Files ****************************************************************************/ -#undef _POSIX_SOURCE -#define _POSIX_SOURCE 1 -#undef _POSIX_C_SOURCE -#define _POSIX_C_SOURCE 2 - #include "config.h" #include diff --git a/apps/interpreters/bas/var.c b/apps/interpreters/bas/var.c index 3b9c49df9..f148de88b 100644 --- a/apps/interpreters/bas/var.c +++ b/apps/interpreters/bas/var.c @@ -2,11 +2,6 @@ * Included Files ****************************************************************************/ -#undef _POSIX_SOURCE -#define _POSIX_SOURCE 1 -#undef _POSIX_C_SOURCE -#define _POSIX_C_SOURCE 2 - #include "config.h" #include -- cgit v1.2.3