| version 1.1.1.2, 2000/01/22 14:16:00 |
version 1.1.1.3, 2003/09/15 07:09:26 |
| Line 37 static char *RCSid = "$Id$"; |
|
| Line 37 static char *RCSid = "$Id$"; |
|
| #include "plot.h" |
#include "plot.h" |
| |
|
| static int get_num __PROTO((char str[])); |
static int get_num __PROTO((char str[])); |
| static void substitute __PROTO((char *str, int max)); |
static void substitute __PROTO((char **, int *, int)); |
| |
|
| #ifdef AMIGA_AC_5 |
#ifdef AMIGA_AC_5 |
| #define O_RDONLY 0 |
#define O_RDONLY 0 |
| Line 74 static int t_num; /* number of token I'm working on * |
|
| Line 74 static int t_num; /* number of token I'm working on * |
|
| |
|
| /* |
/* |
| * scanner() breaks expression[] into lexical units, storing them in token[]. |
* scanner() breaks expression[] into lexical units, storing them in token[]. |
| * The total number of tokens found is returned as the function value. |
* The total number of tokens found is returned as the function |
| * Scanning will stop when '\0' is found in expression[], or when token[] |
* value. Scanning will stop when '\0' is found in expression[], or |
| * is full. |
* when token[] is full. extend_input_line() is called to extend |
| |
* expression array if needed. |
| * |
* |
| * Scanning is performed by following rules: |
* Scanning is performed by following rules: |
| * |
* |
| Line 95 static int t_num; /* number of token I'm working on * |
|
| Line 96 static int t_num; /* number of token I'm working on * |
|
| * 5. !,<,> current char; also next if next is = |
* 5. !,<,> current char; also next if next is = |
| * 6. ", ' all chars up until matching quote |
* 6. ", ' all chars up until matching quote |
| * 7. # this token cuts off scanning of the line (DFK). |
* 7. # this token cuts off scanning of the line (DFK). |
| |
* 8. ` (command substitution: all characters through the |
| |
* matching backtic are replaced by the output of |
| |
* the contained command, then scanning is restarted.) |
| * |
* |
| * white space between tokens is ignored |
* white space between tokens is ignored |
| */ |
*/ |
| int scanner(expression) |
int |
| char expression[]; |
scanner(expressionp, expressionlenp) |
| |
char **expressionp; |
| |
int *expressionlenp; |
| { |
{ |
| register int current; /* index of current char in expression[] */ |
register int current; /* index of current char in expression[] */ |
| |
char *expression = *expressionp; |
| register int quote; |
register int quote; |
| char brace; |
char brace; |
| |
|
| Line 118 char expression[]; |
|
| Line 125 char expression[]; |
|
| token[t_num].is_token = TRUE; /* to start with... */ |
token[t_num].is_token = TRUE; /* to start with... */ |
| |
|
| if (expression[current] == '`') { |
if (expression[current] == '`') { |
| substitute(&expression[current], MAX_LINE_LEN - current); |
substitute(expressionp, expressionlenp, current); |
| |
expression = *expressionp; /* expression might have moved */ |
| goto again; |
goto again; |
| } |
} |
| /* allow _ to be the first character of an identifier */ |
/* allow _ to be the first character of an identifier */ |
| Line 165 char expression[]; |
|
| Line 173 char expression[]; |
|
| && expression[current + 1]) { |
&& expression[current + 1]) { |
| current++; |
current++; |
| token[t_num].length += 2; |
token[t_num].length += 2; |
| |
} else if (quote == '\"' && expression[current] == '`') { |
| |
substitute(expressionp, expressionlenp, current); |
| |
expression = *expressionp; /* it might have moved */ |
| |
current--; |
| } else |
} else |
| token[t_num].length++; |
token[t_num].length++; |
| } |
} |
|
|
| |
|
| #if defined(VMS) || defined(PIPES) || (defined(ATARI) || defined(MTOS)) && defined(__PUREC__) |
#if defined(VMS) || defined(PIPES) || (defined(ATARI) || defined(MTOS)) && defined(__PUREC__) |
| |
|
| /* this really ought to make use of the dynamic-growth of the |
|
| * input line in 3.6. And it definitely should not have |
|
| * static arrays ! |
|
| */ |
|
| /* A macro to reduce clutter ... */ |
/* A macro to reduce clutter ... */ |
| # ifdef AMIGA_AC_5 |
# ifdef AMIGA_AC_5 |
| # define CLOSE_FILE_OR_PIPE ((void) close(fd)) |
# define CLOSE_FILE_OR_PIPE ((void) close(fd)) |
|
|
| # define CLOSE_FILE_OR_PIPE ((void) pclose(f)) |
# define CLOSE_FILE_OR_PIPE ((void) pclose(f)) |
| # endif |
# endif |
| |
|
| static void substitute(str, max) /* substitute output from ` ` */ |
/* substitute output from ` ` |
| char *str; |
* *strp points to the input string. (*strp)[current] is expected to |
| int max; |
* be the initial back tic. Characters through the following back tic |
| |
* are replaced by the output of the command. extend_input_line() |
| |
* is called to extend *strp array if needed. |
| |
*/ |
| |
static void substitute(strp, str_lenp, current) |
| |
char **strp; |
| |
int *str_lenp; |
| |
int current; |
| { |
{ |
| register char *last; |
register char *last; |
| register int i, c; |
register int c; |
| register FILE *f; |
register FILE *f; |
| # ifdef AMIGA_AC_5 |
# ifdef AMIGA_AC_5 |
| int fd; |
int fd; |
| # elif (defined(ATARI) || defined(MTOS)) && defined(__PUREC__) |
# elif (defined(ATARI) || defined(MTOS)) && defined(__PUREC__) |
| char *atari_tmpfile; |
char *atari_tmpfile; |
| char *atari_pgm[MAX_LINE_LEN+100]; |
|
| # endif /* !AMIGA_AC_5 */ |
# endif /* !AMIGA_AC_5 */ |
| static char pgm[MAX_LINE_LEN+1], output[MAX_LINE_LEN+1]; |
char *str, *pgm, *rest = NULL; |
| |
int pgm_len, rest_len; |
| |
|
| # ifdef VMS |
# ifdef VMS |
| int chan, one = 1; |
int chan, one = 1; |
| static $DESCRIPTOR(pgmdsc, pgm); |
struct dsc$descriptor_s pgmdsc = {0, DSC$K_DTYPE_T, DSC$K_CLASS_S, 0}; |
| static $DESCRIPTOR(lognamedsc, MAILBOX); |
static $DESCRIPTOR(lognamedsc, MAILBOX); |
| # endif /* VMS */ |
# endif /* VMS */ |
| |
|
| /* forgive missing closing backquote at end of line */ |
/* forgive missing closing backquote at end of line */ |
| i = 0; |
str = *strp + current; |
| last = str; |
last = str; |
| while (*++last) { |
while (*++last) { |
| if (*last == '`') { |
if (*last == '`') |
| ++last; /* move past it */ |
|
| break; |
break; |
| |
} |
| |
pgm_len = last - str; |
| |
pgm = gp_alloc(pgm_len, "command string"); |
| |
safe_strncpy(pgm, str + 1, pgm_len); /* omit ` to leave room for NUL */ |
| |
|
| |
/* save rest of line, if any */ |
| |
if (*last) { |
| |
last++; /* advance past ` */ |
| |
rest_len = strlen(last) + 1; |
| |
if (rest_len > 1) { |
| |
rest = gp_alloc(rest_len, "input line copy"); |
| |
strcpy(rest, last); |
| } |
} |
| pgm[i++] = *last; |
|
| } |
} |
| pgm[i] = NUL; /* end with null */ |
|
| max -= strlen(last); /* max is now the max length of output sub. */ |
|
| |
|
| # ifdef VMS |
# ifdef VMS |
| pgmdsc.dsc$w_length = i; |
pgmdsc.dsc$a_pointer = pgm; |
| |
pgmdsc.dsc$w_length = pgm_len; |
| if (!((vaxc$errno = sys$crembx(0, &chan, 0, 0, 0, 0, &lognamedsc)) & 1)) |
if (!((vaxc$errno = sys$crembx(0, &chan, 0, 0, 0, 0, &lognamedsc)) & 1)) |
| os_error("sys$crembx failed", NO_CARET); |
os_error("sys$crembx failed", NO_CARET); |
| |
|
|
|
| # elif (defined(ATARI) || defined(MTOS)) && defined(__PUREC__) |
# elif (defined(ATARI) || defined(MTOS)) && defined(__PUREC__) |
| if (system(NULL) == 0) |
if (system(NULL) == 0) |
| os_error("no command shell", NO_CARET); |
os_error("no command shell", NO_CARET); |
| if ((strlen(atari_tmpfile) + strlen(pgm) + 5) > MAX_LINE_LEN + 100) |
|
| os_error("sorry, command to long", NO_CARET); |
|
| atari_tmpfile = tmpnam(NULL); |
atari_tmpfile = tmpnam(NULL); |
| strcpy(atari_pgm, pgm); |
gp_realloc(pgm, pgm_len + 5 + strlen(atari_tmpfile), "command string"); |
| strcat(atari_pgm, " >> "); |
strcat(pgm, " >> "); |
| strcat(atari_pgm, atari_tmpfile); |
strcat(pgm, atari_tmpfile); |
| system(atari_pgm); |
system(pgm); |
| if ((f = fopen(atari_tmpfile, "r")) == NULL) |
if ((f = fopen(atari_tmpfile, "r")) == NULL) |
| # elif defined(AMIGA_AC_5) |
# elif defined(AMIGA_AC_5) |
| if ((fd = open(pgm, "O_RDONLY")) == -1) |
if ((fd = open(pgm, "O_RDONLY")) == -1) |
|
|
| os_error("popen failed", NO_CARET); |
os_error("popen failed", NO_CARET); |
| # endif /* !VMS */ |
# endif /* !VMS */ |
| |
|
| i = 0; |
free(pgm); |
| while ((c = getc(f)) != EOF) { |
|
| output[i++] = ((c == '\n') ? ' ' : c); /* newlines become blanks */ |
/* now replace ` ` with output */ |
| if (i == max) { |
while (1) { |
| CLOSE_FILE_OR_PIPE; |
# if defined(AMIGA_AC_5) |
| int_error("substitution overflow", t_num); |
char ch; |
| } |
if (read(fd, &ch, 1) != 1) |
| |
break; |
| |
c = ch; |
| |
# else |
| |
if ((c = getc(f)) == EOF) |
| |
break; |
| |
# endif /* !AMIGA_AC_5 */ |
| |
/* newlines become blanks */ |
| |
(*strp)[current++] = ((c == '\n') ? ' ' : c); |
| |
if (current == *str_lenp) |
| |
extend_input_line(); |
| } |
} |
| |
(*strp)[current] = 0; |
| |
|
| CLOSE_FILE_OR_PIPE; |
CLOSE_FILE_OR_PIPE; |
| |
|
| if (i + strlen(last) > max) |
|
| int_error("substitution overflowed rest of line", t_num); |
|
| /* tack on rest of line to output */ |
/* tack on rest of line to output */ |
| safe_strncpy(output + i, last, MAX_LINE_LEN - i); |
if (rest) { |
| /* now replace ` ` with output */ |
while (current + rest_len > *str_lenp) |
| safe_strncpy(str, output, max); |
extend_input_line(); |
| |
strcpy(*strp+current, rest); |
| |
free(rest); |
| |
} |
| |
|
| screen_ok = FALSE; |
screen_ok = FALSE; |
| } |
} |
| |
|
| #else /* VMS || PIPES || ATARI && PUREC */ |
#else /* VMS || PIPES || ATARI && PUREC */ |
| |
|
| static void substitute(str, max) |
static void substitute(strp, str_lenp, current) |
| char *str; |
char **strp; |
| int max; |
int *str_lenp; |
| |
int current; |
| { |
{ |
| char line[100]; |
char line[100]; |
| |
|