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]; |
|
|