a2py.c revision 7c478bd95313f5f23a4c958a745db2134aa03244
/* $RCSfile: a2py.c,v $$Revision: 4.1 $$Date: 92/08/07 18:29:14 $
*
* Copyright (c) 1991-2001, Larry Wall
*
* You may distribute under the terms of either the GNU General Public
* License or the Artistic License, as specified in the README file.
*
* $Log: a2py.c,v $
*/
#if defined(WIN32)
#include <io.h>
#endif
#include "../patchlevel.h"
#endif
#include "util.h"
char *filename;
char *myname;
int checkers = 0;
static void usage(void);
static void
usage()
{
printf("\nThis is the AWK to PERL translator, revision %d.0, version %d\n", PERL_REVISION, PERL_VERSION);
printf("\n -D<number> sets debugging flags."
"\n -F<character> the awk script to translate is always invoked with"
"\n this -F switch."
"\n -n<fieldlist> specifies the names of the input fields if input does"
"\n not have to be split into an array."
"\n -<number> causes a2p to assume that input will always have that"
"\n many fields.\n");
exit(1);
}
#endif
int
{
int i;
break;
switch (argv[0][1]) {
#ifdef DEBUGGING
case 'D':
#if YYDEBUG
#endif
break;
#endif
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
break;
case 'F':
break;
case 'n':
break;
case 'o':
break;
case '-':
goto switch_end;
case 0:
break;
default:
usage();
#else
#endif
}
}
/* open script */
usage();
#endif
argv[0] = "-";
}
argv[0] = "";
if (!*argv[0])
else
/* init tokener */
curarghash = hnew();
/* now parse the report spec */
if (yyparse())
fatal("Translation aborted due to syntax errors.\n");
#ifdef DEBUGGING
if (debug & 2) {
for (i=1; i<mop;) {
type &= 255;
else {
while (len--) {
}
putchar('\n');
}
}
}
if (debug & 8)
#endif
/* first pass to look for numeric variables */
/* second pass to produce new program */
if $running_under_some_shell;\n\
# this emulates #! processing on NIH machines.\n\
# (remove #! line above if indigestible)\n\n");
"eval '$'.$1.'$2;' while $ARGV[0] =~ /^([A-Za-z_0-9]+=)(.*)/ && shift;\n");
" # process any FOO=bar switches\n\n");
}
#ifdef DEBUGGING
if (!(debug & 16))
#endif
if (checkers) {
"Please check my work on the %d line%s I've marked with \"#???\".\n",
"The operation I've selected may be wrong for the operand types.\n");
}
exit(0);
}
int idtype;
int
yylex(void)
{
register char *s = bufptr;
register char *d;
register int tmp;
#if YYDEBUG
if (yydebug)
if (strchr(s,'\n'))
else
#endif
switch (*s) {
default:
"Unrecognized character %c in file %s line %d--ignoring.\n",
goto retry;
case '\\':
s++;
if (*s && *s != '\n') {
yyerror("Ignoring spurious backslash");
goto retry;
}
/*FALLSTHROUGH*/
case 0:
*s = '\0';
if (!rsfp)
RETURN(0);
line++;
RETURN(0);
}
goto retry;
case ' ': case '\t':
s++;
goto retry;
case '\n':
*s = '\0';
case '#':
*s = '\0';
case ';':
tmp = *s++;
if (*s == '\n') {
s++;
}
case '(':
tmp = *s++;
case '{':
case '[':
case ')':
case ']':
case '?':
case ':':
tmp = *s++;
#ifdef EBCDIC
case 7:
#else
case 127:
#endif
s++;
XTERM('}');
case '}':
for (d = s + 1; isspace(*d); d++) ;
if (!*d)
s = d - 1;
*s = 127;
XTERM(';');
case ',':
tmp = *s++;
case '~':
s++;
case '+':
case '-':
if (s[1] == *s) {
s++;
if (*s++ == '+')
else
}
/* FALL THROUGH */
case '*':
case '%':
case '^':
tmp = *s++;
if (*s == '=') {
if (tmp == '^')
else
s++;
}
case '&':
s++;
tmp = *s++;
if (tmp == '&')
s--;
XTERM('&');
case '|':
s++;
tmp = *s++;
if (tmp == '|')
s--;
while (*s == ' ' || *s == '\t')
s++;
XTERM('p');
else
XTERM('|');
case '=':
s++;
tmp = *s++;
if (tmp == '=') {
}
s--;
case '!':
s++;
tmp = *s++;
if (tmp == '=') {
}
if (tmp == '~') {
}
s--;
case '<':
s++;
tmp = *s++;
if (tmp == '=') {
}
s--;
XTERM('<');
case '>':
s++;
tmp = *s++;
if (tmp == '>') {
}
if (tmp == '=') {
}
s--;
XTERM('>');
#define SNARFWORD \
d = tokenbuf; \
*d++ = *s++; \
*d = '\0'; \
d = tokenbuf; \
if (*s == '(') \
else \
case '$':
s++;
if (*s == '0') {
s++;
need_entire = TRUE;
ID("0");
}
if (isdigit(*s)) {
for (d = s; isdigit(*s); s++) ;
}
case '/': /* may either be division or pattern */
if (expectterm) {
s = scanpat(s);
}
tmp = *s++;
if (*s == '=') {
s++;
}
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9': case '.':
s = scannum(s);
case '"':
s++;
if (!*s)
s++;
case 'a': case 'A':
if (strEQ(d,"ARGC"))
if (strEQ(d,"ARGV")) {
}
if (strEQ(d,"atan2")) {
}
ID(d);
case 'b': case 'B':
if (strEQ(d,"break"))
if (strEQ(d,"BEGIN"))
ID(d);
case 'c': case 'C':
if (strEQ(d,"continue"))
if (strEQ(d,"cos")) {
}
if (strEQ(d,"close")) {
do_fancy_opens = 1;
}
if (strEQ(d,"chdir"))
*d = toupper(*d);
else if (strEQ(d,"crypt"))
*d = toupper(*d);
else if (strEQ(d,"chop"))
*d = toupper(*d);
else if (strEQ(d,"chmod"))
*d = toupper(*d);
else if (strEQ(d,"chown"))
*d = toupper(*d);
ID(d);
case 'd': case 'D':
if (strEQ(d,"do"))
if (strEQ(d,"delete"))
if (strEQ(d,"die"))
*d = toupper(*d);
ID(d);
case 'e': case 'E':
if (strEQ(d,"END"))
if (strEQ(d,"else"))
if (strEQ(d,"exit")) {
saw_line_op = TRUE;
}
if (strEQ(d,"exp")) {
}
if (strEQ(d,"elsif"))
*d = toupper(*d);
else if (strEQ(d,"eq"))
*d = toupper(*d);
else if (strEQ(d,"eval"))
*d = toupper(*d);
else if (strEQ(d,"eof"))
*d = toupper(*d);
else if (strEQ(d,"each"))
*d = toupper(*d);
else if (strEQ(d,"exec"))
*d = toupper(*d);
ID(d);
case 'f': case 'F':
if (strEQ(d,"FS")) {
saw_FS++;
for (d = s; *d && isspace(*d); d++) ;
if (*d == '=') {
for (d++; *d && isspace(*d); d++) ;
if (*d == '"' && d[2] == '"')
const_FS = d[1];
}
}
}
if (strEQ(d,"for"))
else if (strEQ(d,"function"))
if (strEQ(d,"FILENAME"))
d = "ARGV";
if (strEQ(d,"foreach"))
*d = toupper(*d);
else if (strEQ(d,"format"))
*d = toupper(*d);
else if (strEQ(d,"fork"))
*d = toupper(*d);
else if (strEQ(d,"fh"))
*d = toupper(*d);
ID(d);
case 'g': case 'G':
if (strEQ(d,"getline"))
if (strEQ(d,"gsub"))
if (strEQ(d,"ge"))
*d = toupper(*d);
else if (strEQ(d,"gt"))
*d = toupper(*d);
else if (strEQ(d,"goto"))
*d = toupper(*d);
else if (strEQ(d,"gmtime"))
*d = toupper(*d);
ID(d);
case 'h': case 'H':
if (strEQ(d,"hex"))
*d = toupper(*d);
ID(d);
case 'i': case 'I':
if (strEQ(d,"if"))
if (strEQ(d,"in"))
if (strEQ(d,"index")) {
}
if (strEQ(d,"int")) {
}
ID(d);
case 'j': case 'J':
if (strEQ(d,"join"))
*d = toupper(*d);
ID(d);
case 'k': case 'K':
if (strEQ(d,"keys"))
*d = toupper(*d);
else if (strEQ(d,"kill"))
*d = toupper(*d);
ID(d);
case 'l': case 'L':
if (strEQ(d,"length")) {
}
if (strEQ(d,"log")) {
}
if (strEQ(d,"last"))
*d = toupper(*d);
else if (strEQ(d,"local"))
*d = toupper(*d);
else if (strEQ(d,"lt"))
*d = toupper(*d);
else if (strEQ(d,"le"))
*d = toupper(*d);
else if (strEQ(d,"locatime"))
*d = toupper(*d);
else if (strEQ(d,"link"))
*d = toupper(*d);
ID(d);
case 'm': case 'M':
if (strEQ(d,"match")) {
}
if (strEQ(d,"m"))
*d = toupper(*d);
ID(d);
case 'n': case 'N':
if (strEQ(d,"NF"))
if (strEQ(d,"next")) {
saw_line_op = TRUE;
}
if (strEQ(d,"ne"))
*d = toupper(*d);
ID(d);
case 'o': case 'O':
if (strEQ(d,"ORS")) {
d = "\\";
}
if (strEQ(d,"OFS")) {
d = ",";
}
if (strEQ(d,"OFMT")) {
d = "#";
}
if (strEQ(d,"open"))
*d = toupper(*d);
else if (strEQ(d,"ord"))
*d = toupper(*d);
else if (strEQ(d,"oct"))
*d = toupper(*d);
ID(d);
case 'p': case 'P':
if (strEQ(d,"print")) {
}
if (strEQ(d,"printf")) {
}
if (strEQ(d,"push"))
*d = toupper(*d);
else if (strEQ(d,"pop"))
*d = toupper(*d);
ID(d);
case 'q': case 'Q':
ID(d);
case 'r': case 'R':
if (strEQ(d,"RS")) {
d = "/";
}
if (strEQ(d,"rand")) {
}
if (strEQ(d,"return"))
if (strEQ(d,"reset"))
*d = toupper(*d);
else if (strEQ(d,"redo"))
*d = toupper(*d);
else if (strEQ(d,"rename"))
*d = toupper(*d);
ID(d);
case 's': case 'S':
if (strEQ(d,"split")) {
}
if (strEQ(d,"substr")) {
}
if (strEQ(d,"sub"))
if (strEQ(d,"sprintf")) {
/* In old awk, { print sprintf("str%sg"),"in" } prints
* "string"; in new awk, "in" is not considered an argument to
* sprintf, so the statement breaks. To support both, the
* grammar treats arguments to SPRINTF_OLD like old awk,
* SPRINTF_NEW like new. Here we return the appropriate one.
*/
}
if (strEQ(d,"sqrt")) {
}
if (strEQ(d,"SUBSEP")) {
d = ";";
}
if (strEQ(d,"sin")) {
}
if (strEQ(d,"srand")) {
}
if (strEQ(d,"system")) {
}
if (strEQ(d,"s"))
*d = toupper(*d);
else if (strEQ(d,"shift"))
*d = toupper(*d);
else if (strEQ(d,"select"))
*d = toupper(*d);
else if (strEQ(d,"seek"))
*d = toupper(*d);
else if (strEQ(d,"stat"))
*d = toupper(*d);
else if (strEQ(d,"study"))
*d = toupper(*d);
else if (strEQ(d,"sleep"))
*d = toupper(*d);
else if (strEQ(d,"symlink"))
*d = toupper(*d);
else if (strEQ(d,"sort"))
*d = toupper(*d);
ID(d);
case 't': case 'T':
if (strEQ(d,"tr"))
*d = toupper(*d);
else if (strEQ(d,"tell"))
*d = toupper(*d);
else if (strEQ(d,"time"))
*d = toupper(*d);
else if (strEQ(d,"times"))
*d = toupper(*d);
ID(d);
case 'u': case 'U':
if (strEQ(d,"until"))
*d = toupper(*d);
else if (strEQ(d,"unless"))
*d = toupper(*d);
else if (strEQ(d,"umask"))
*d = toupper(*d);
else if (strEQ(d,"unshift"))
*d = toupper(*d);
else if (strEQ(d,"unlink"))
*d = toupper(*d);
else if (strEQ(d,"utime"))
*d = toupper(*d);
ID(d);
case 'v': case 'V':
if (strEQ(d,"values"))
*d = toupper(*d);
ID(d);
case 'w': case 'W':
if (strEQ(d,"while"))
if (strEQ(d,"write"))
*d = toupper(*d);
else if (strEQ(d,"wait"))
*d = toupper(*d);
ID(d);
case 'x': case 'X':
if (strEQ(d,"x"))
*d = toupper(*d);
ID(d);
case 'y': case 'Y':
if (strEQ(d,"y"))
*d = toupper(*d);
ID(d);
case 'z': case 'Z':
ID(d);
}
}
char *
scanpat(register char *s)
{
register char *d;
switch (*s++) {
case '/':
break;
default:
}
d = tokenbuf;
for (; *s; s++,d++) {
if (*s == '\\') {
if (s[1] == '/')
*d++ = *s++;
else if (s[1] == '\\')
*d++ = *s++;
else if (s[1] == '[')
*d++ = *s++;
}
else if (*s == '[') {
*d++ = *s++;
do {
if (*s == '\\' && s[1])
*d++ = *s++;
if (*s == '/' || (*s == '-' && s[1] == ']'))
*d++ = '\\';
*d++ = *s++;
} while (*s && *s != ']');
}
else if (*s == '/')
break;
*d = *s;
}
*d = '\0';
if (!*s)
s++;
return s;
}
void
yyerror(char *s)
{
}
char *
scannum(register char *s)
{
register char *d;
switch (*s) {
case '1': case '2': case '3': case '4': case '5':
case '6': case '7': case '8': case '9': case '0' : case '.':
d = tokenbuf;
while (isdigit(*s)) {
*d++ = *s++;
}
if (*s == '.') {
if (isdigit(s[1])) {
*d++ = *s++;
while (isdigit(*s)) {
*d++ = *s++;
}
}
else
s++;
}
*d++ = *s++;
if (*s == '+' || *s == '-')
*d++ = *s++;
while (isdigit(*s))
*d++ = *s++;
}
*d = '\0';
break;
}
return s;
}
int
{
if (!len)
fatal("Recompile a2p with larger OPSMAX\n");
return retval;
}
int
{
if (type > 255)
fatal("Recompile a2p with larger OPSMAX\n");
return retval;
}
int
{
if (type > 255)
fatal("Recompile a2p with larger OPSMAX\n");
return retval;
}
int
{
if (type > 255)
fatal("Recompile a2p with larger OPSMAX\n");
return retval;
}
int
{
if (type > 255)
fatal("Recompile a2p with larger OPSMAX\n");
return retval;
}
int
{
if (type > 255)
fatal("Recompile a2p with larger OPSMAX\n");
return retval;
}
int
{
if (type > 255)
fatal("Recompile a2p with larger OPSMAX\n");
return retval;
}
int depth = 0;
void
{
register int type;
register int len;
register int i;
type &= 255;
for (i=depth; i; i--)
printf(" ");
}
else {
depth++;
for (i=1; i<=len; i++)
depth--;
for (i=depth; i; i--)
printf(" ");
printf(")\n");
}
}
int
{
if (!arg)
return 0;
else
return arg;
}
void
{
register char *s;
register char *t;
if (*s == ';' && s[1] == ' ' && s[2] == '\n') {
s++;
}
else if (*s == '\n') {
t--;
if (*t == '\n' && t-s > 1) {
if (s[-1] == '{')
s--;
strcpy(s+1,t);
}
s++;
}
}
}
void
{
register char *d, *s, *t, *e;
d = tokenbuf;
pos = 0;
*d++ = *s;
pos++;
if (*s == '\n') {
*d = '\0';
d = tokenbuf;
pos = 0;
putone();
}
else if (*s == '\t')
pos += 7;
*d-- = '\0';
newpos = 0;
if (*t == '\t')
newpos += 8;
else
newpos += 1;
}
e = d;
d--;
if (d < t+10) {
d = e;
while (d > tokenbuf &&
(*d != ' ' || d[-1] != '|' || d[-2] != '|') )
d--;
}
if (d < t+10) {
d = e;
while (d > tokenbuf &&
(*d != ' ' || d[-1] != '&' || d[-2] != '&') )
d--;
}
if (d < t+10) {
d = e;
d--;
}
if (d < t+10) {
d = e;
while (d > tokenbuf && *d != ' ')
d--;
}
if (d > t+3) {
char save[2048];
*d = '\n';
d[1] = '\0';
putone();
putchar('\n');
*t++ = ' ';
*t++ = ' ';
newpos += 2;
}
d = t + strlen(t);
}
else
d = e + 1;
}
}
}
void
putone(void)
{
register char *t;
for (t = tokenbuf; *t; t++) {
*t &= 127;
if (*t == 127) {
*t = ' ';
checkers++;
}
}
t = tokenbuf;
if (*t == '#') {
return;
return;
}
}
int
{
int dummy;
return arg;
}
int
rememberargs(int arg)
{
int type;
if (!arg)
return arg;
}
}
else
return arg;
}
int
{
if (str)
return arg;
}
int
{
int type;
int numargs;
if (!arg)
return prevargs;
}
char tmpbuf[128];
}
}
else
fatal("panic: unknown argument type %d, arg %d, line %d\n",
return numargs;
}
int
{
int type;
int numargs;
if (!arg)
return prevargs;
}
else {
}
else
fatal("Can't pass expression by reference as arg %d of %s\n",
}
}
return numargs;
}