460 lines
12 KiB
C
Executable File
460 lines
12 KiB
C
Executable File
/*
|
|
* awk -- common header file.
|
|
*
|
|
* Copyright (c) 1995 by Sun Microsystems, Inc.
|
|
*
|
|
* Copyright 1986, 1994 by Mortice Kern Systems Inc. All rights reserved.
|
|
*
|
|
* This Software is unpublished, valuable, confidential property of
|
|
* Mortice Kern Systems Inc. Use is authorized only in accordance
|
|
* with the terms and conditions of the source licence agreement
|
|
* protecting this Software. Any unauthorized use or disclosure of
|
|
* this Software is strictly prohibited and will result in the
|
|
* termination of the licence agreement.
|
|
*
|
|
* This version uses the POSIX.2 compatible <regex.h> routines.
|
|
*
|
|
* Based on MKS awk(1) ported to be /usr/xpg4/bin/awk with POSIX/XCU4 changes
|
|
*
|
|
*/
|
|
|
|
#ident "@(#)awk.h 1.1 95/03/09 SMI"
|
|
|
|
#include <stdio.h>
|
|
#include <ctype.h>
|
|
#include <string.h>
|
|
#include <math.h>
|
|
#include <limits.h>
|
|
#include <stdlib.h>
|
|
#include <regex.h>
|
|
#include <errno.h>
|
|
#include <sys/types.h>
|
|
#include <locale.h>
|
|
#include <wchar.h>
|
|
#include <widec.h>
|
|
|
|
#define YYMAXDEPTH 300 /* Max # of productions (used by yacc) */
|
|
#define YYSSIZE 300 /* Size of State/Value stacks (MKS YACC) */
|
|
#define MAXDIGINT 9 /* Number of digits in an INT */
|
|
#define FNULL ((FILE *)0)
|
|
#define NNULL ((NODE *)0)
|
|
#define SNULL ((STRING)0)
|
|
#define LARGE INT_MAX /* Large integer */
|
|
#define NPFILE 32 /* Number of -[fl] options allowed */
|
|
#define NRECUR 3000 /* Maximum recursion depth */
|
|
|
|
#define M_LDATA 1
|
|
#ifdef M_LDATA
|
|
# define NLINE 20000 /* Longest input record */
|
|
# define NFIELD 4000 /* Number of fields allowed */
|
|
# define NBUCKET 1024 /* # of symtab buckets (power of 2) */
|
|
#else
|
|
# define NLINE 2048 /* Longest input record */
|
|
# define NFIELD 1024 /* Number of fields allowed */
|
|
# define NBUCKET 256 /* # of symtab buckets (power of 2) */
|
|
#endif
|
|
|
|
#define NSNODE 40 /* Number of cached nodes */
|
|
#define NCONTEXT 50 /* Amount of context for error msgs */
|
|
#define hashbuck(n) ((n)&(NBUCKET-1))
|
|
#if BSD
|
|
/*
|
|
* A speedup for BSD. Use their routines which are
|
|
* already optimised. Note that BSD bcopy does not
|
|
* return a value.
|
|
*/
|
|
int bcmp();
|
|
#define memcmp(b1,b2,n) bcmp(b1,b2,n)
|
|
void bcopy();
|
|
#define memcpy(b1,b2,n) bcopy(b2,b1,(int)n)
|
|
#endif /*BSD*/
|
|
#define vlook(n) vlookup(n, 0)
|
|
|
|
/*
|
|
* Basic AWK internal types.
|
|
*/
|
|
typedef double REAL;
|
|
typedef long INT;
|
|
typedef wchar_t *STRING;
|
|
typedef struct NODE *(*FUNCTION)(struct NODE * np);
|
|
typedef regex_t *REGEXP;
|
|
|
|
/*
|
|
* Node in the AWK interpreter expression tree.
|
|
*/
|
|
typedef struct NODE {
|
|
ushort n_type;
|
|
struct NODE *n_next; /* Symbol table/PARM link */
|
|
ushort n_flags; /* Node flags, type */
|
|
|
|
|
|
|
|
|
|
union {
|
|
struct {
|
|
ushort N_hash; /* Full hash value */
|
|
struct NODE *N_alink; /* Array link */
|
|
union {
|
|
struct {
|
|
STRING N_string;
|
|
size_t N_strlen;
|
|
} n_str;
|
|
INT N_int;
|
|
REAL N_real;
|
|
FUNCTION N_function;
|
|
struct NODE *N_ufunc;
|
|
} n_tun;
|
|
wchar_t N_name[1];
|
|
} n_term;
|
|
struct {
|
|
struct NODE *N_left;
|
|
struct NODE *N_right;
|
|
ushort N_lineno;
|
|
} n_op;
|
|
struct {
|
|
struct NODE *N_left; /* Used for fliplist */
|
|
struct NODE *N_right;
|
|
REGEXP N_regexp; /* Regular expression */
|
|
} n_re;
|
|
} n_un;
|
|
} NODE;
|
|
|
|
/*
|
|
* Definitions to make the node access much easier.
|
|
*/
|
|
#define n_hash n_un.n_term.N_hash /* full hash value is sym tbl */
|
|
#define n_scope n_un.n_term.N_hash /* local variable scope level */
|
|
#define n_alink n_un.n_term.N_alink /* link to array list */
|
|
#define n_string n_un.n_term.n_tun.n_str.N_string
|
|
#define n_strlen n_un.n_term.n_tun.n_str.N_strlen
|
|
#define n_int n_un.n_term.n_tun.N_int
|
|
#define n_real n_un.n_term.n_tun.N_real
|
|
#define n_function n_un.n_term.n_tun.N_function
|
|
#define n_ufunc n_un.n_term.n_tun.N_ufunc
|
|
#define n_name n_un.n_term.N_name
|
|
#define n_left n_un.n_op.N_left
|
|
#define n_right n_un.n_op.N_right
|
|
#define n_lineno n_un.n_op.N_lineno
|
|
#define n_keywtype n_un.n_op.N_lineno
|
|
#define n_regexp n_un.n_re.N_regexp
|
|
/*
|
|
* Compress the types that are actually used in the final tree
|
|
* to save space in the intermediate file. Allows 1 byte to
|
|
* represent all types
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
* n_flags bit assignments.
|
|
*/
|
|
#define FALLOC 0x01 /* Allocated node */
|
|
#define FSTATIC 0x00 /* Not allocated */
|
|
#define FMATCH 0x02 /* pattern,pattern (first part matches) */
|
|
#define FSPECIAL 0x04 /* Special pre-computed variable */
|
|
#define FINARRAY 0x08 /* NODE installed in N_alink array list */
|
|
#define FNOALLOC 0x10 /* mark node FALLOC, but don't malloc */
|
|
#define FSENSE 0x20 /* Sense if string looks like INT/REAL */
|
|
#define FSAVE (FSPECIAL|FINARRAY) /* assign leaves on */
|
|
|
|
#define FINT 0x40 /* Node has integer type */
|
|
#define FREAL 0x80 /* Node has real type */
|
|
#define FSTRING 0x100 /* Node has string type */
|
|
#define FNONTOK 0x200 /* Node has non-token type */
|
|
#define FVINT 0x400 /* Node looks like an integer */
|
|
#define FVREAL 0x800 /* Node looks like a real number */
|
|
#define FLARRAY 0x1000 /* Local array node */
|
|
|
|
/*
|
|
* n_flags macros
|
|
* These work when given an argument of np->n_flags
|
|
*/
|
|
#define isleaf(f) (!((f)&FNONTOK))
|
|
#define isstring(f) ((f)&FSTRING)
|
|
#define isastring(f) (((f)&(FSTRING|FALLOC))==(FSTRING|FALLOC))
|
|
#define isnumber(f) ((f)&(FINT|FVINT|FREAL|FVREAL))
|
|
#define isreal(f) ((f)&(FREAL|FVREAL))
|
|
#define isint(f) ((f)&(FINT|FVINT))
|
|
|
|
/*
|
|
* Prototype file size is defined in awksize.h
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
* Awkrun prototype default name
|
|
*/
|
|
#if defined(DOS)
|
|
# if defined(__386__)
|
|
# define AWK_PROTOTYPE M_ETCDIR(awkrunf.dos)
|
|
# define AWK_LPROTOTYPE M_ETCDIR(awkrunf.dos)
|
|
# else
|
|
# define AWK_PROTOTYPE M_ETCDIR(awkrun.dos)
|
|
# define AWK_LPROTOTYPE M_ETCDIR(awkrunl.dos)
|
|
# endif
|
|
#elif defined(OS2)
|
|
# define AWK_PROTOTYPE M_ETCDIR(awkrun.os2)
|
|
#elif defined(NT)
|
|
# define AWK_PROTOTYPE M_ETCDIR(awkrun.nt)
|
|
#else
|
|
# define AWK_PROTOTYPE M_ETCDIR(awkrun.mod)
|
|
#endif
|
|
|
|
/*
|
|
* This is a kludge that gets around a bug in compact & large
|
|
* models under DOS. It also makes the generated
|
|
* code faster even if there wasn't a bug. UNIX people: try
|
|
* to ignore these noisy "near" declarations.
|
|
*/
|
|
#ifndef DOS
|
|
#define near
|
|
#endif
|
|
|
|
typedef wchar_t near *LOCCHARP; /* pointer to local strings */
|
|
/*
|
|
* Form of builtin symbols
|
|
* This should be a union because only one of r_ivalue
|
|
* and r_svalue is needed, but (alas) unions cannot be
|
|
* initialised.
|
|
*/
|
|
typedef struct RESERVED {
|
|
LOCCHARP r_name;
|
|
int r_type; /* Type of node */
|
|
INT r_ivalue; /* Integer value or wcslen(r_svalue) */
|
|
STRING r_svalue; /* String value */
|
|
} RESERVED;
|
|
|
|
/*
|
|
* Table of builtin functions.
|
|
*/
|
|
typedef struct RESFUNC {
|
|
LOCCHARP rf_name;
|
|
int rf_type; /* FUNC || GETLINE */
|
|
FUNCTION rf_func; /* Function pointer */
|
|
} RESFUNC;
|
|
|
|
/*
|
|
* Structure holding list of open files.
|
|
*/
|
|
typedef struct OFILE {
|
|
ushort f_mode; /* Open mode: WRITE, APPEND, PIPE */
|
|
FILE *f_fp; /* File pointer if open */
|
|
char *f_name; /* Remembered file name */
|
|
} OFILE;
|
|
|
|
/* Global functions -- awk.y */
|
|
int yyparse(void);
|
|
|
|
/* Global functions -- awk1.c */
|
|
#ifdef __WATCOMC__
|
|
# pragma aux yyerror aborts;
|
|
# pragma aux awkerr aborts;
|
|
# pragma aux awkperr aborts;
|
|
#endif
|
|
void yyerror(char *msg, ...);
|
|
void awkerr(char *fmt, ...);
|
|
void awkperr(char *fmt, ...);
|
|
void uexit(NODE *);
|
|
int yylex(void);
|
|
NODE *renode(wchar_t *restr);
|
|
wchar_t *emalloc(unsigned);
|
|
wchar_t *erealloc(wchar_t *, unsigned);
|
|
|
|
/* Global functions -- awk2.c */
|
|
void awk(void);
|
|
void dobegin(void);
|
|
void doend(int status);
|
|
int nextrecord(wchar_t *buf, FILE *fp);
|
|
wchar_t *defrecord(wchar_t *bp, int lim, FILE *fp);
|
|
wchar_t *charrecord(wchar_t *bp, int lim, FILE *fp);
|
|
wchar_t *multirecord(wchar_t *bp, int lim, FILE *fp);
|
|
wchar_t *whitefield(wchar_t **endp);
|
|
wchar_t *blackfield(wchar_t **endp);
|
|
wchar_t *refield(wchar_t **endp);
|
|
void s_print(NODE *np);
|
|
void s_prf(NODE *np);
|
|
size_t xprintf(NODE *np, FILE *fp, wchar_t **cp);
|
|
void awkclose(OFILE *op);
|
|
|
|
/* Global functions -- awk3.c */
|
|
void strassign(NODE *np, STRING string, int flags, size_t length);
|
|
NODE *nassign(NODE *np, NODE *value);
|
|
NODE *assign(NODE *np, NODE *value);
|
|
void delarray(NODE *np);
|
|
NODE *node(int type, NODE *left, NODE *right);
|
|
NODE *intnode(INT i);
|
|
NODE *realnode(REAL r);
|
|
NODE *stringnode(STRING str, int aflag, size_t wcslen);
|
|
NODE *vlookup(wchar_t *name, int nocreate);
|
|
NODE *emptynode(int type, size_t nlength);
|
|
void freenode(NODE *np);
|
|
void execute(NODE *np);
|
|
INT exprint(NODE *np);
|
|
REAL exprreal(NODE *np);
|
|
STRING exprstring(NODE *np);
|
|
STRING strsave(wchar_t *string);
|
|
NODE *exprreduce(NODE *np);
|
|
NODE *getlist(NODE **npp);
|
|
NODE *symwalk(int *buckp, NODE **npp);
|
|
REGEXP getregexp(NODE *np);
|
|
void addsymtab(NODE *np);
|
|
void delsymtab(NODE *np, int fflag);
|
|
NODE * finstall(LOCCHARP name, FUNCTION f, int type);
|
|
void kinstall(LOCCHARP name, int type);
|
|
void fieldsplit(void);
|
|
void promote(NODE *);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Global functions -- awk4.c */
|
|
NODE *f_exp(NODE *np);
|
|
NODE *f_int(NODE *np);
|
|
NODE *f_log(NODE *np);
|
|
NODE *f_sqrt(NODE *np);
|
|
NODE *f_getline(NODE *np);
|
|
NODE *f_index(NODE *np);
|
|
NODE *f_length(NODE *np);
|
|
NODE *f_split(NODE *np);
|
|
NODE *f_sprintf(NODE *np);
|
|
NODE *f_substr(NODE *np);
|
|
NODE *f_rand(NODE *np);
|
|
NODE *f_srand(NODE *np);
|
|
NODE *f_sin(NODE *np);
|
|
NODE *f_cos(NODE *np);
|
|
NODE *f_atan2(NODE *np);
|
|
NODE *f_sub(NODE *np);
|
|
NODE *f_gsub(NODE *np);
|
|
NODE *f_match(NODE *np);
|
|
NODE *f_system(NODE *np);
|
|
NODE *f_ord(NODE *np);
|
|
NODE *f_tolower(NODE *np);
|
|
NODE *f_toupper(NODE *np);
|
|
NODE *f_close(NODE *np);
|
|
NODE *f_asort(NODE *np);
|
|
|
|
/* In awk0.c */
|
|
|
|
|
|
|
|
extern wchar_t _null[];
|
|
extern char r[];
|
|
extern char w[];
|
|
extern wchar_t s_OFMT[];
|
|
extern wchar_t s_CONVFMT[];
|
|
extern wchar_t s_NR[];
|
|
extern wchar_t s_NF[];
|
|
extern wchar_t s_OFS[];
|
|
extern wchar_t s_ORS[];
|
|
extern wchar_t s_RS[];
|
|
extern wchar_t s_FS[];
|
|
extern wchar_t s_FNR[];
|
|
extern wchar_t s_SUBSEP[];
|
|
extern wchar_t s_ARGC[], s_ARGV[], s_ENVIRON[];
|
|
extern wchar_t s_FILENAME[], s_SYMTAB[];
|
|
extern wchar_t s_BEGIN[], s_END[], s_next[];
|
|
extern wchar_t _begin[], _end[];
|
|
extern wchar_t s_exp[], s_getline[], s_index[], s_int[], s_length[], s_log[];
|
|
extern wchar_t s_split[], s_sprintf[], s_sqrt[], s_substr[];
|
|
extern wchar_t s_rand[], s_srand[], s_sin[], s_cos[], s_atan2[];
|
|
extern wchar_t s_sub[], s_gsub[], s_match[], s_system[], s_ord[];
|
|
extern wchar_t s_toupper[], s_tolower[], s_asort[];
|
|
extern wchar_t s_close[];
|
|
extern wchar_t redelim;
|
|
extern unsigned char inprint;
|
|
extern unsigned char funparm;
|
|
extern unsigned char splitdone;
|
|
extern uint_t npattern;
|
|
extern uint_t nfield;
|
|
extern uint_t fcount;
|
|
extern uint_t phase;
|
|
extern uint_t running;
|
|
extern uchar_t catterm;
|
|
extern uint_t lexlast;
|
|
extern uint_t lineno;
|
|
extern uchar_t needsplit, needenviron, doing_begin, begin_getline;
|
|
extern ushort slevel;
|
|
extern ushort loopexit;
|
|
extern wchar_t radixpoint;
|
|
extern REGEXP resep;
|
|
extern RESERVED reserved[];
|
|
extern RESFUNC resfuncs[];
|
|
extern long NIOSTREAM; /* Maximum open I/O streams */
|
|
extern OFILE *ofiles;
|
|
extern wchar_t *linebuf;
|
|
extern size_t lbuflen;
|
|
extern char interr[];
|
|
extern char nomem[];
|
|
extern NODE *symtab[NBUCKET];
|
|
extern NODE *yytree;
|
|
extern NODE *freelist;
|
|
extern wchar_t *(*awkrecord)(wchar_t *, int, FILE *);
|
|
extern wchar_t *(*awkfield)(wchar_t **);
|
|
|
|
extern NODE *constant;
|
|
extern NODE *const0;
|
|
extern NODE *const1;
|
|
extern NODE *constundef;
|
|
extern NODE *field0;
|
|
extern NODE *incNR;
|
|
extern NODE *incFNR;
|
|
extern NODE *clrFNR;
|
|
extern NODE *ARGVsubi;
|
|
extern NODE *varNR;
|
|
extern NODE *varFNR;
|
|
extern NODE *varNF;
|
|
extern NODE *varOFMT;
|
|
extern NODE *varCONVFMT;
|
|
extern NODE *varOFS;
|
|
extern NODE *varORS;
|
|
extern NODE *varFS;
|
|
extern NODE *varRS;
|
|
extern NODE *varARGC;
|
|
extern NODE *varSUBSEP;
|
|
extern NODE *varENVIRON;
|
|
extern NODE *varSYMTAB;
|
|
extern NODE *varFILENAME;
|
|
extern NODE *curnode;
|
|
extern NODE *inc_oper;
|
|
extern NODE *asn_oper;
|
|
|
|
extern char *mbunconvert(wchar_t *);
|
|
extern wchar_t *mbstowcsdup(char *);
|
|
extern char *wcstombsdup(wchar_t *);
|
|
extern void awkerr(char *, ...);
|
|
/*
|
|
* The following defines the expected max length in chars of a printed number.
|
|
* This should be the longest expected size for any type of number
|
|
* ie. float, long etc. This number is used to calculate the approximate
|
|
* number of chars needed to hold the number.
|
|
*/
|
|
#ifdef M_NUMSIZE
|
|
#define NUMSIZE M_NUMSIZE
|
|
#else
|
|
#define NUMSIZE 30
|
|
#endif
|
|
|
|
#define M_MB_L(s) L##s
|
|
#ifdef __STDC__
|
|
#define ANSI(x) x
|
|
#define _VOID void /* Used in VOID *malloc() */
|
|
#else
|
|
#define const
|
|
#define signed
|
|
#define volatile
|
|
#define ANSI(x) ()
|
|
#define _VOID char /* Used in _VOID *malloc() */
|
|
#endif
|
|
|
|
#define iswblank(x) (((x) == ' ' || (x) == '\t') ? 1 : 0 )
|