mirror of
https://github.com/jart/cosmopolitan.git
synced 2025-02-07 06:53:33 +00:00
Upgrade the One True Awk
This commit is contained in:
parent
b9d6e6e348
commit
49a32136f8
15 changed files with 5280 additions and 4322 deletions
3
third_party/awk/BUILD.mk
vendored
3
third_party/awk/BUILD.mk
vendored
|
@ -31,8 +31,7 @@ THIRD_PARTY_AWK_A_DEPS := \
|
||||||
$(call uniq,$(foreach x,$(THIRD_PARTY_AWK_A_DIRECTDEPS),$($(x))))
|
$(call uniq,$(foreach x,$(THIRD_PARTY_AWK_A_DIRECTDEPS),$($(x))))
|
||||||
|
|
||||||
THIRD_PARTY_AWK_CHECKS = \
|
THIRD_PARTY_AWK_CHECKS = \
|
||||||
$(THIRD_PARTY_AWK_A).pkg \
|
$(THIRD_PARTY_AWK_A).pkg
|
||||||
$(THIRD_PARTY_AWK_HDRS:%=o/$(MODE)/%.ok)
|
|
||||||
|
|
||||||
$(THIRD_PARTY_AWK_A): \
|
$(THIRD_PARTY_AWK_A): \
|
||||||
third_party/awk/ \
|
third_party/awk/ \
|
||||||
|
|
5
third_party/awk/README.cosmo
vendored
5
third_party/awk/README.cosmo
vendored
|
@ -10,8 +10,7 @@ SOURCE
|
||||||
|
|
||||||
https://github.com/onetrueawk/awk
|
https://github.com/onetrueawk/awk
|
||||||
|
|
||||||
commit b92d8cecd132ce8e02a373e28dd42e6be34d3d59
|
commit 2bab10b60b3f4d3bbefdcb60410655f317d1a452
|
||||||
Author: ozan yigit <ozan.yigit@gmail.com>
|
date Thu Mar 14 14:25:30 2024 +0200
|
||||||
Date: Mon May 30 11:34:52 2022 -0400
|
|
||||||
|
|
||||||
added YACC definition for byacc.
|
added YACC definition for byacc.
|
||||||
|
|
244
third_party/awk/awk.h
vendored
244
third_party/awk/awk.h
vendored
|
@ -1,10 +1,35 @@
|
||||||
#ifndef COSMOPOLITAN_THIRD_PARTY_AWK_AWK_H_
|
/****************************************************************
|
||||||
#define COSMOPOLITAN_THIRD_PARTY_AWK_AWK_H_
|
Copyright (C) Lucent Technologies 1997
|
||||||
#include "libc/assert.h"
|
All Rights Reserved
|
||||||
#include "libc/limits.h"
|
|
||||||
#include "libc/literal.h"
|
Permission to use, copy, modify, and distribute this software and
|
||||||
#include "libc/stdio/stdio.h"
|
its documentation for any purpose and without fee is hereby
|
||||||
COSMOPOLITAN_C_START_
|
granted, provided that the above copyright notice appear in all
|
||||||
|
copies and that both that the copyright notice and this
|
||||||
|
permission notice and warranty disclaimer appear in supporting
|
||||||
|
documentation, and that the name Lucent Technologies or any of
|
||||||
|
its entities not be used in advertising or publicity pertaining
|
||||||
|
to distribution of the software without specific, written prior
|
||||||
|
permission.
|
||||||
|
|
||||||
|
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||||
|
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
|
||||||
|
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
|
||||||
|
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||||
|
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
THIS SOFTWARE.
|
||||||
|
****************************************************************/
|
||||||
|
|
||||||
|
#include <assert.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
#if __STDC_VERSION__ <= 199901L
|
||||||
|
#define noreturn
|
||||||
|
#else
|
||||||
|
#include <stdnoreturn.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
typedef double Awkfloat;
|
typedef double Awkfloat;
|
||||||
|
|
||||||
|
@ -12,7 +37,7 @@ typedef double Awkfloat;
|
||||||
|
|
||||||
typedef unsigned char uschar;
|
typedef unsigned char uschar;
|
||||||
|
|
||||||
#define xfree(a) { if ((a) != NULL) { free((void *)(intptr_t)(a)); (a) = NULL; } }
|
#define xfree(a) { free((void *)(intptr_t)(a)); (a) = NULL; }
|
||||||
/*
|
/*
|
||||||
* We sometimes cheat writing read-only pointers to NUL-terminate them
|
* We sometimes cheat writing read-only pointers to NUL-terminate them
|
||||||
* and then put back the original value
|
* and then put back the original value
|
||||||
|
@ -39,6 +64,8 @@ extern bool safe; /* false => unsafe, true => safe */
|
||||||
#define RECSIZE (8 * 1024) /* sets limit on records, fields, etc., etc. */
|
#define RECSIZE (8 * 1024) /* sets limit on records, fields, etc., etc. */
|
||||||
extern int recsize; /* size of current record, orig RECSIZE */
|
extern int recsize; /* size of current record, orig RECSIZE */
|
||||||
|
|
||||||
|
extern size_t awk_mb_cur_max; /* max size of a multi-byte character */
|
||||||
|
|
||||||
extern char EMPTY[]; /* this avoid -Wwritable-strings issues */
|
extern char EMPTY[]; /* this avoid -Wwritable-strings issues */
|
||||||
extern char **FS;
|
extern char **FS;
|
||||||
extern char **RS;
|
extern char **RS;
|
||||||
|
@ -53,6 +80,8 @@ extern char **SUBSEP;
|
||||||
extern Awkfloat *RSTART;
|
extern Awkfloat *RSTART;
|
||||||
extern Awkfloat *RLENGTH;
|
extern Awkfloat *RLENGTH;
|
||||||
|
|
||||||
|
extern bool CSV; /* true for csv input */
|
||||||
|
|
||||||
extern char *record; /* points to $0 */
|
extern char *record; /* points to $0 */
|
||||||
extern int lineno; /* line number in awk program */
|
extern int lineno; /* line number in awk program */
|
||||||
extern int errorflag; /* 1 if error has occurred */
|
extern int errorflag; /* 1 if error has occurred */
|
||||||
|
@ -200,7 +229,8 @@ extern int pairstack[], paircnt;
|
||||||
|
|
||||||
/* structures used by regular expression matching machinery, mostly b.c: */
|
/* structures used by regular expression matching machinery, mostly b.c: */
|
||||||
|
|
||||||
#define NCHARS (256+3) /* 256 handles 8-bit chars; 128 does 7-bit */
|
#define NCHARS (1256+3) /* 256 handles 8-bit chars; 128 does 7-bit */
|
||||||
|
/* BUG: some overflows (caught) if we use 256 */
|
||||||
/* watch out in match(), etc. */
|
/* watch out in match(), etc. */
|
||||||
#define HAT (NCHARS+2) /* matches ^ in regular expr */
|
#define HAT (NCHARS+2) /* matches ^ in regular expr */
|
||||||
#define NSTATES 32
|
#define NSTATES 32
|
||||||
|
@ -211,12 +241,24 @@ typedef struct rrow {
|
||||||
int i;
|
int i;
|
||||||
Node *np;
|
Node *np;
|
||||||
uschar *up;
|
uschar *up;
|
||||||
|
int *rp; /* rune representation of char class */
|
||||||
} lval; /* because Al stores a pointer in it! */
|
} lval; /* because Al stores a pointer in it! */
|
||||||
int *lfollow;
|
int *lfollow;
|
||||||
} rrow;
|
} rrow;
|
||||||
|
|
||||||
|
typedef struct gtte { /* gototab entry */
|
||||||
|
unsigned int ch;
|
||||||
|
unsigned int state;
|
||||||
|
} gtte;
|
||||||
|
|
||||||
|
typedef struct gtt { /* gototab */
|
||||||
|
size_t allocated;
|
||||||
|
size_t inuse;
|
||||||
|
gtte *entries;
|
||||||
|
} gtt;
|
||||||
|
|
||||||
typedef struct fa {
|
typedef struct fa {
|
||||||
unsigned int **gototab;
|
gtt *gototab;
|
||||||
uschar *out;
|
uschar *out;
|
||||||
uschar *restr;
|
uschar *restr;
|
||||||
int **posns;
|
int **posns;
|
||||||
|
@ -229,185 +271,5 @@ typedef struct fa {
|
||||||
struct rrow re[1]; /* variable: actual size set by calling malloc */
|
struct rrow re[1]; /* variable: actual size set by calling malloc */
|
||||||
} fa;
|
} fa;
|
||||||
|
|
||||||
extern int yywrap(void);
|
|
||||||
extern void setfname(Cell *);
|
|
||||||
extern int constnode(Node *);
|
|
||||||
extern char *strnode(Node *);
|
|
||||||
extern Node *notnull(Node *);
|
|
||||||
extern int yyparse(void);
|
|
||||||
|
|
||||||
extern int yylex(void);
|
#include "proto.h"
|
||||||
extern void startreg(void);
|
|
||||||
extern int input(void);
|
|
||||||
extern void unput(int);
|
|
||||||
extern void unputstr(const char *);
|
|
||||||
extern int yylook(void);
|
|
||||||
extern int yyback(int *, int);
|
|
||||||
extern int yyinput(void);
|
|
||||||
|
|
||||||
extern fa *makedfa(const char *, bool);
|
|
||||||
extern fa *mkdfa(const char *, bool);
|
|
||||||
extern int makeinit(fa *, bool);
|
|
||||||
extern void penter(Node *);
|
|
||||||
extern void freetr(Node *);
|
|
||||||
extern int hexstr(const uschar **);
|
|
||||||
extern int quoted(const uschar **);
|
|
||||||
extern char *cclenter(const char *);
|
|
||||||
extern wontreturn void overflo(const char *);
|
|
||||||
extern void cfoll(fa *, Node *);
|
|
||||||
extern int first(Node *);
|
|
||||||
extern void follow(Node *);
|
|
||||||
extern int member(int, const char *);
|
|
||||||
extern int match(fa *, const char *);
|
|
||||||
extern int pmatch(fa *, const char *);
|
|
||||||
extern int nematch(fa *, const char *);
|
|
||||||
extern bool fnematch(fa *, FILE *, char **, int *, int);
|
|
||||||
extern Node *reparse(const char *);
|
|
||||||
extern Node *regexp(void);
|
|
||||||
extern Node *primary(void);
|
|
||||||
extern Node *concat(Node *);
|
|
||||||
extern Node *alt(Node *);
|
|
||||||
extern Node *unary(Node *);
|
|
||||||
extern int relex(void);
|
|
||||||
extern int cgoto(fa *, int, int);
|
|
||||||
extern void freefa(fa *);
|
|
||||||
|
|
||||||
extern int pgetc(void);
|
|
||||||
extern char *cursource(void);
|
|
||||||
|
|
||||||
extern Node *nodealloc(int);
|
|
||||||
extern Node *exptostat(Node *);
|
|
||||||
extern Node *node1(int, Node *);
|
|
||||||
extern Node *node2(int, Node *, Node *);
|
|
||||||
extern Node *node3(int, Node *, Node *, Node *);
|
|
||||||
extern Node *node4(int, Node *, Node *, Node *, Node *);
|
|
||||||
extern Node *stat3(int, Node *, Node *, Node *);
|
|
||||||
extern Node *op2(int, Node *, Node *);
|
|
||||||
extern Node *op1(int, Node *);
|
|
||||||
extern Node *stat1(int, Node *);
|
|
||||||
extern Node *op3(int, Node *, Node *, Node *);
|
|
||||||
extern Node *op4(int, Node *, Node *, Node *, Node *);
|
|
||||||
extern Node *stat2(int, Node *, Node *);
|
|
||||||
extern Node *stat4(int, Node *, Node *, Node *, Node *);
|
|
||||||
extern Node *celltonode(Cell *, int);
|
|
||||||
extern Node *rectonode(void);
|
|
||||||
extern Node *makearr(Node *);
|
|
||||||
extern Node *pa2stat(Node *, Node *, Node *);
|
|
||||||
extern Node *linkum(Node *, Node *);
|
|
||||||
extern void defn(Cell *, Node *, Node *);
|
|
||||||
extern int isarg(const char *);
|
|
||||||
extern const char *tokname(int);
|
|
||||||
extern Cell *(*proctab[])(Node **, int);
|
|
||||||
extern int ptoi(void *);
|
|
||||||
extern Node *itonp(int);
|
|
||||||
|
|
||||||
extern void syminit(void);
|
|
||||||
extern void arginit(int, char **);
|
|
||||||
extern void envinit(char **);
|
|
||||||
extern Array *makesymtab(int);
|
|
||||||
extern void freesymtab(Cell *);
|
|
||||||
extern void freeelem(Cell *, const char *);
|
|
||||||
extern Cell *setsymtab(const char *, const char *, double, unsigned int, Array *);
|
|
||||||
extern int hash(const char *, int);
|
|
||||||
extern void rehash(Array *);
|
|
||||||
extern Cell *lookup(const char *, Array *);
|
|
||||||
extern double setfval(Cell *, double);
|
|
||||||
extern void funnyvar(Cell *, const char *);
|
|
||||||
extern char *setsval(Cell *, const char *);
|
|
||||||
extern double getfval(Cell *);
|
|
||||||
extern char *getsval(Cell *);
|
|
||||||
extern char *getpssval(Cell *); /* for print */
|
|
||||||
extern char *tostring(const char *);
|
|
||||||
extern char *tostringN(const char *, size_t);
|
|
||||||
extern char *qstring(const char *, int);
|
|
||||||
extern Cell *catstr(Cell *, Cell *);
|
|
||||||
|
|
||||||
extern void recinit(unsigned int);
|
|
||||||
extern void initgetrec(void);
|
|
||||||
extern void makefields(int, int);
|
|
||||||
extern void growfldtab(int n);
|
|
||||||
extern void savefs(void);
|
|
||||||
extern int getrec(char **, int *, bool);
|
|
||||||
extern void nextfile(void);
|
|
||||||
extern int readrec(char **buf, int *bufsize, FILE *inf, bool isnew);
|
|
||||||
extern char *getargv(int);
|
|
||||||
extern void setclvar(char *);
|
|
||||||
extern void fldbld(void);
|
|
||||||
extern void cleanfld(int, int);
|
|
||||||
extern void newfld(int);
|
|
||||||
extern void setlastfld(int);
|
|
||||||
extern int refldbld(const char *, const char *);
|
|
||||||
extern void recbld(void);
|
|
||||||
extern Cell *fieldadr(int);
|
|
||||||
extern void yyerror(const char *);
|
|
||||||
extern void bracecheck(void);
|
|
||||||
extern void bcheck2(int, int, int);
|
|
||||||
extern void SYNTAX(const char *, ...)
|
|
||||||
__attribute__((__format__(__printf__, 1, 2)));
|
|
||||||
extern wontreturn void FATAL(const char *, ...)
|
|
||||||
__attribute__((__format__(__printf__, 1, 2)));
|
|
||||||
extern void WARNING(const char *, ...)
|
|
||||||
__attribute__((__format__(__printf__, 1, 2)));
|
|
||||||
extern void error(void);
|
|
||||||
extern void eprint(void);
|
|
||||||
extern void bclass(int);
|
|
||||||
extern double errcheck(double, const char *);
|
|
||||||
extern int isclvar(const char *);
|
|
||||||
extern bool is_valid_number(const char *s, bool trailing_stuff_ok,
|
|
||||||
bool *no_trailing, double *result);
|
|
||||||
#define is_number(s, val) is_valid_number(s, false, NULL, val)
|
|
||||||
|
|
||||||
extern int adjbuf(char **pb, int *sz, int min, int q, char **pbp, const char *what);
|
|
||||||
extern void run(Node *);
|
|
||||||
extern Cell *execute(Node *);
|
|
||||||
extern Cell *program(Node **, int);
|
|
||||||
extern Cell *call(Node **, int);
|
|
||||||
extern Cell *copycell(Cell *);
|
|
||||||
extern Cell *arg(Node **, int);
|
|
||||||
extern Cell *jump(Node **, int);
|
|
||||||
extern Cell *awkgetline(Node **, int);
|
|
||||||
extern Cell *getnf(Node **, int);
|
|
||||||
extern Cell *array(Node **, int);
|
|
||||||
extern Cell *awkdelete(Node **, int);
|
|
||||||
extern Cell *intest(Node **, int);
|
|
||||||
extern Cell *matchop(Node **, int);
|
|
||||||
extern Cell *boolop(Node **, int);
|
|
||||||
extern Cell *relop(Node **, int);
|
|
||||||
extern void tfree(Cell *);
|
|
||||||
extern Cell *gettemp(void);
|
|
||||||
extern Cell *field(Node **, int);
|
|
||||||
extern Cell *indirect(Node **, int);
|
|
||||||
extern Cell *substr(Node **, int);
|
|
||||||
extern Cell *sindex(Node **, int);
|
|
||||||
extern int format(char **, int *, const char *, Node *);
|
|
||||||
extern Cell *awksprintf(Node **, int);
|
|
||||||
extern Cell *awkprintf(Node **, int);
|
|
||||||
extern Cell *arith(Node **, int);
|
|
||||||
extern double ipow(double, int);
|
|
||||||
extern Cell *incrdecr(Node **, int);
|
|
||||||
extern Cell *assign(Node **, int);
|
|
||||||
extern Cell *cat(Node **, int);
|
|
||||||
extern Cell *pastat(Node **, int);
|
|
||||||
extern Cell *dopa2(Node **, int);
|
|
||||||
extern Cell *split(Node **, int);
|
|
||||||
extern Cell *condexpr(Node **, int);
|
|
||||||
extern Cell *ifstat(Node **, int);
|
|
||||||
extern Cell *whilestat(Node **, int);
|
|
||||||
extern Cell *dostat(Node **, int);
|
|
||||||
extern Cell *forstat(Node **, int);
|
|
||||||
extern Cell *instat(Node **, int);
|
|
||||||
extern Cell *bltin(Node **, int);
|
|
||||||
extern Cell *printstat(Node **, int);
|
|
||||||
extern Cell *nullproc(Node **, int);
|
|
||||||
extern FILE *redirect(int, Node *);
|
|
||||||
extern FILE *openfile(int, const char *, bool *);
|
|
||||||
extern const char *filename(FILE *);
|
|
||||||
extern Cell *closefile(Node **, int);
|
|
||||||
extern void closeall(void);
|
|
||||||
extern Cell *sub(Node **, int);
|
|
||||||
extern Cell *gsub(Node **, int);
|
|
||||||
|
|
||||||
extern const char *flags2str(int flags);
|
|
||||||
|
|
||||||
COSMOPOLITAN_C_END_
|
|
||||||
#endif /* COSMOPOLITAN_THIRD_PARTY_AWK_AWK_H_ */
|
|
||||||
|
|
6663
third_party/awk/awkgram.tab.c
vendored
6663
third_party/awk/awkgram.tab.c
vendored
File diff suppressed because it is too large
Load diff
252
third_party/awk/awkgram.tab.h
vendored
252
third_party/awk/awkgram.tab.h
vendored
|
@ -1,113 +1,145 @@
|
||||||
#ifndef COSMOPOLITAN_THIRD_PARTY_AWK_AWKGRAM_TAB_H_
|
#ifndef YY_YY_AWKGRAM_TAB_H_INCLUDED
|
||||||
#define COSMOPOLITAN_THIRD_PARTY_AWK_AWKGRAM_TAB_H_
|
# define YY_YY_AWKGRAM_TAB_H_INCLUDED
|
||||||
#include "third_party/awk/awk.h"
|
/* Debug traces. */
|
||||||
COSMOPOLITAN_C_START_
|
#ifndef YYDEBUG
|
||||||
|
# define YYDEBUG 0
|
||||||
|
#endif
|
||||||
|
#if YYDEBUG
|
||||||
|
extern int yydebug;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Token kinds. */
|
||||||
|
#ifndef YYTOKENTYPE
|
||||||
|
# define YYTOKENTYPE
|
||||||
|
enum yytokentype
|
||||||
|
{
|
||||||
|
YYEMPTY = -2,
|
||||||
|
YYEOF = 0, /* "end of file" */
|
||||||
|
YYerror = 256, /* error */
|
||||||
|
YYUNDEF = 257, /* "invalid token" */
|
||||||
|
FIRSTTOKEN = 258, /* FIRSTTOKEN */
|
||||||
|
PROGRAM = 259, /* PROGRAM */
|
||||||
|
PASTAT = 260, /* PASTAT */
|
||||||
|
PASTAT2 = 261, /* PASTAT2 */
|
||||||
|
XBEGIN = 262, /* XBEGIN */
|
||||||
|
XEND = 263, /* XEND */
|
||||||
|
NL = 264, /* NL */
|
||||||
|
ARRAY = 265, /* ARRAY */
|
||||||
|
MATCH = 266, /* MATCH */
|
||||||
|
NOTMATCH = 267, /* NOTMATCH */
|
||||||
|
MATCHOP = 268, /* MATCHOP */
|
||||||
|
FINAL = 269, /* FINAL */
|
||||||
|
DOT = 270, /* DOT */
|
||||||
|
ALL = 271, /* ALL */
|
||||||
|
CCL = 272, /* CCL */
|
||||||
|
NCCL = 273, /* NCCL */
|
||||||
|
CHAR = 274, /* CHAR */
|
||||||
|
OR = 275, /* OR */
|
||||||
|
STAR = 276, /* STAR */
|
||||||
|
QUEST = 277, /* QUEST */
|
||||||
|
PLUS = 278, /* PLUS */
|
||||||
|
EMPTYRE = 279, /* EMPTYRE */
|
||||||
|
ZERO = 280, /* ZERO */
|
||||||
|
AND = 281, /* AND */
|
||||||
|
BOR = 282, /* BOR */
|
||||||
|
APPEND = 283, /* APPEND */
|
||||||
|
EQ = 284, /* EQ */
|
||||||
|
GE = 285, /* GE */
|
||||||
|
GT = 286, /* GT */
|
||||||
|
LE = 287, /* LE */
|
||||||
|
LT = 288, /* LT */
|
||||||
|
NE = 289, /* NE */
|
||||||
|
IN = 290, /* IN */
|
||||||
|
ARG = 291, /* ARG */
|
||||||
|
BLTIN = 292, /* BLTIN */
|
||||||
|
BREAK = 293, /* BREAK */
|
||||||
|
CLOSE = 294, /* CLOSE */
|
||||||
|
CONTINUE = 295, /* CONTINUE */
|
||||||
|
DELETE = 296, /* DELETE */
|
||||||
|
DO = 297, /* DO */
|
||||||
|
EXIT = 298, /* EXIT */
|
||||||
|
FOR = 299, /* FOR */
|
||||||
|
FUNC = 300, /* FUNC */
|
||||||
|
SUB = 301, /* SUB */
|
||||||
|
GSUB = 302, /* GSUB */
|
||||||
|
IF = 303, /* IF */
|
||||||
|
INDEX = 304, /* INDEX */
|
||||||
|
LSUBSTR = 305, /* LSUBSTR */
|
||||||
|
MATCHFCN = 306, /* MATCHFCN */
|
||||||
|
NEXT = 307, /* NEXT */
|
||||||
|
NEXTFILE = 308, /* NEXTFILE */
|
||||||
|
ADD = 309, /* ADD */
|
||||||
|
MINUS = 310, /* MINUS */
|
||||||
|
MULT = 311, /* MULT */
|
||||||
|
DIVIDE = 312, /* DIVIDE */
|
||||||
|
MOD = 313, /* MOD */
|
||||||
|
ASSIGN = 314, /* ASSIGN */
|
||||||
|
ASGNOP = 315, /* ASGNOP */
|
||||||
|
ADDEQ = 316, /* ADDEQ */
|
||||||
|
SUBEQ = 317, /* SUBEQ */
|
||||||
|
MULTEQ = 318, /* MULTEQ */
|
||||||
|
DIVEQ = 319, /* DIVEQ */
|
||||||
|
MODEQ = 320, /* MODEQ */
|
||||||
|
POWEQ = 321, /* POWEQ */
|
||||||
|
PRINT = 322, /* PRINT */
|
||||||
|
PRINTF = 323, /* PRINTF */
|
||||||
|
SPRINTF = 324, /* SPRINTF */
|
||||||
|
ELSE = 325, /* ELSE */
|
||||||
|
INTEST = 326, /* INTEST */
|
||||||
|
CONDEXPR = 327, /* CONDEXPR */
|
||||||
|
POSTINCR = 328, /* POSTINCR */
|
||||||
|
PREINCR = 329, /* PREINCR */
|
||||||
|
POSTDECR = 330, /* POSTDECR */
|
||||||
|
PREDECR = 331, /* PREDECR */
|
||||||
|
VAR = 332, /* VAR */
|
||||||
|
IVAR = 333, /* IVAR */
|
||||||
|
VARNF = 334, /* VARNF */
|
||||||
|
CALL = 335, /* CALL */
|
||||||
|
NUMBER = 336, /* NUMBER */
|
||||||
|
STRING = 337, /* STRING */
|
||||||
|
REGEXPR = 338, /* REGEXPR */
|
||||||
|
GETLINE = 339, /* GETLINE */
|
||||||
|
RETURN = 340, /* RETURN */
|
||||||
|
SPLIT = 341, /* SPLIT */
|
||||||
|
SUBSTR = 342, /* SUBSTR */
|
||||||
|
WHILE = 343, /* WHILE */
|
||||||
|
CAT = 344, /* CAT */
|
||||||
|
NOT = 345, /* NOT */
|
||||||
|
UMINUS = 346, /* UMINUS */
|
||||||
|
UPLUS = 347, /* UPLUS */
|
||||||
|
POWER = 348, /* POWER */
|
||||||
|
DECR = 349, /* DECR */
|
||||||
|
INCR = 350, /* INCR */
|
||||||
|
INDIRECT = 351, /* INDIRECT */
|
||||||
|
LASTTOKEN = 352 /* LASTTOKEN */
|
||||||
|
};
|
||||||
|
typedef enum yytokentype yytoken_kind_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* Value type. */
|
||||||
|
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
|
||||||
|
union YYSTYPE
|
||||||
|
{
|
||||||
|
#line 41 "awkgram.y"
|
||||||
|
|
||||||
|
Node *p;
|
||||||
|
Cell *cp;
|
||||||
|
int i;
|
||||||
|
char *s;
|
||||||
|
|
||||||
|
#line 168 "awkgram.tab.h"
|
||||||
|
|
||||||
|
};
|
||||||
|
typedef union YYSTYPE YYSTYPE;
|
||||||
|
# define YYSTYPE_IS_TRIVIAL 1
|
||||||
|
# define YYSTYPE_IS_DECLARED 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define FIRSTTOKEN 257
|
|
||||||
#define PROGRAM 258
|
|
||||||
#define PASTAT 259
|
|
||||||
#define PASTAT2 260
|
|
||||||
#define XBEGIN 261
|
|
||||||
#define XEND 262
|
|
||||||
#define NL 263
|
|
||||||
#define ARRAY 264
|
|
||||||
#define MATCH 265
|
|
||||||
#define NOTMATCH 266
|
|
||||||
#define MATCHOP 267
|
|
||||||
#define FINAL 268
|
|
||||||
#define DOT 269
|
|
||||||
#define ALL 270
|
|
||||||
#define CCL 271
|
|
||||||
#define NCCL 272
|
|
||||||
#define CHAR 273
|
|
||||||
#define OR 274
|
|
||||||
#define STAR 275
|
|
||||||
#define QUEST 276
|
|
||||||
#define PLUS 277
|
|
||||||
#define EMPTYRE 278
|
|
||||||
#define ZERO 279
|
|
||||||
#define AND 280
|
|
||||||
#define BOR 281
|
|
||||||
#define APPEND 282
|
|
||||||
#define EQ 283
|
|
||||||
#define GE 284
|
|
||||||
#define GT 285
|
|
||||||
#define LE 286
|
|
||||||
#define LT 287
|
|
||||||
#define NE 288
|
|
||||||
#define IN 289
|
|
||||||
#define ARG 290
|
|
||||||
#define BLTIN 291
|
|
||||||
#define BREAK 292
|
|
||||||
#define CLOSE 293
|
|
||||||
#define CONTINUE 294
|
|
||||||
#define DELETE 295
|
|
||||||
#define DO 296
|
|
||||||
#define EXIT 297
|
|
||||||
#define FOR 298
|
|
||||||
#define FUNC 299
|
|
||||||
#define SUB 300
|
|
||||||
#define GSUB 301
|
|
||||||
#define IF 302
|
|
||||||
#define INDEX 303
|
|
||||||
#define LSUBSTR 304
|
|
||||||
#define MATCHFCN 305
|
|
||||||
#define NEXT 306
|
|
||||||
#define NEXTFILE 307
|
|
||||||
#define ADD 308
|
|
||||||
#define MINUS 309
|
|
||||||
#define MULT 310
|
|
||||||
#define DIVIDE 311
|
|
||||||
#define MOD 312
|
|
||||||
#define ASSIGN 313
|
|
||||||
#define ASGNOP 314
|
|
||||||
#define ADDEQ 315
|
|
||||||
#define SUBEQ 316
|
|
||||||
#define MULTEQ 317
|
|
||||||
#define DIVEQ 318
|
|
||||||
#define MODEQ 319
|
|
||||||
#define POWEQ 320
|
|
||||||
#define PRINT 321
|
|
||||||
#define PRINTF 322
|
|
||||||
#define SPRINTF 323
|
|
||||||
#define ELSE 324
|
|
||||||
#define INTEST 325
|
|
||||||
#define CONDEXPR 326
|
|
||||||
#define POSTINCR 327
|
|
||||||
#define PREINCR 328
|
|
||||||
#define POSTDECR 329
|
|
||||||
#define PREDECR 330
|
|
||||||
#define VAR 331
|
|
||||||
#define IVAR 332
|
|
||||||
#define VARNF 333
|
|
||||||
#define CALL 334
|
|
||||||
#define NUMBER 335
|
|
||||||
#define STRING 336
|
|
||||||
#define REGEXPR 337
|
|
||||||
#define GETLINE 338
|
|
||||||
#define RETURN 339
|
|
||||||
#define SPLIT 340
|
|
||||||
#define SUBSTR 341
|
|
||||||
#define WHILE 342
|
|
||||||
#define CAT 343
|
|
||||||
#define NOT 344
|
|
||||||
#define UMINUS 345
|
|
||||||
#define UPLUS 346
|
|
||||||
#define POWER 347
|
|
||||||
#define DECR 348
|
|
||||||
#define INCR 349
|
|
||||||
#define INDIRECT 350
|
|
||||||
#define LASTTOKEN 351
|
|
||||||
#ifndef YYSTYPE_DEFINED
|
|
||||||
#define YYSTYPE_DEFINED
|
|
||||||
typedef union {
|
|
||||||
Node *p;
|
|
||||||
Cell *cp;
|
|
||||||
int i;
|
|
||||||
char *s;
|
|
||||||
} YYSTYPE;
|
|
||||||
#endif /* YYSTYPE_DEFINED */
|
|
||||||
extern YYSTYPE yylval;
|
extern YYSTYPE yylval;
|
||||||
|
|
||||||
COSMOPOLITAN_C_END_
|
|
||||||
#endif /* COSMOPOLITAN_THIRD_PARTY_AWK_AWKGRAM_TAB_H_ */
|
int yyparse (void);
|
||||||
|
|
||||||
|
|
||||||
|
#endif /* !YY_YY_AWKGRAM_TAB_H_INCLUDED */
|
||||||
|
|
511
third_party/awk/b.c
vendored
511
third_party/awk/b.c
vendored
|
@ -1,39 +1,39 @@
|
||||||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
/****************************************************************
|
||||||
│ vi: set noet ft=c ts=8 sw=8 fenc=utf-8 :vi │
|
Copyright (C) Lucent Technologies 1997
|
||||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
All Rights Reserved
|
||||||
│ │
|
|
||||||
│ Copyright (C) Lucent Technologies 1997 │
|
Permission to use, copy, modify, and distribute this software and
|
||||||
│ All Rights Reserved │
|
its documentation for any purpose and without fee is hereby
|
||||||
│ │
|
granted, provided that the above copyright notice appear in all
|
||||||
│ Permission to use, copy, modify, and distribute this software and │
|
copies and that both that the copyright notice and this
|
||||||
│ its documentation for any purpose and without fee is hereby │
|
permission notice and warranty disclaimer appear in supporting
|
||||||
│ granted, provided that the above copyright notice appear in all │
|
documentation, and that the name Lucent Technologies or any of
|
||||||
│ copies and that both that the copyright notice and this │
|
its entities not be used in advertising or publicity pertaining
|
||||||
│ permission notice and warranty disclaimer appear in supporting │
|
to distribution of the software without specific, written prior
|
||||||
│ documentation, and that the name Lucent Technologies or any of │
|
permission.
|
||||||
│ its entities not be used in advertising or publicity pertaining │
|
|
||||||
│ to distribution of the software without specific, written prior │
|
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||||
│ permission. │
|
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
|
||||||
│ │
|
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
|
||||||
│ LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, │
|
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
│ INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. │
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
|
||||||
│ IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY │
|
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||||
│ SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES │
|
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
│ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER │
|
THIS SOFTWARE.
|
||||||
│ IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, │
|
****************************************************************/
|
||||||
│ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF │
|
|
||||||
│ THIS SOFTWARE. │
|
|
||||||
│ │
|
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
|
||||||
#define DEBUG
|
|
||||||
#include "libc/calls/calls.h"
|
|
||||||
#include "libc/mem/mem.h"
|
|
||||||
#include "libc/str/str.h"
|
|
||||||
#include "third_party/awk/awk.h"
|
|
||||||
#include "third_party/awk/awkgram.tab.h"
|
|
||||||
|
|
||||||
/* lasciate ogne speranza, voi ch'intrate. */
|
/* lasciate ogne speranza, voi ch'intrate. */
|
||||||
|
|
||||||
|
#define DEBUG
|
||||||
|
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <limits.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "awk.h"
|
||||||
|
#include "awkgram.tab.h"
|
||||||
|
|
||||||
#define MAXLIN 22
|
#define MAXLIN 22
|
||||||
|
|
||||||
#define type(v) (v)->nobj /* badly overloaded here */
|
#define type(v) (v)->nobj /* badly overloaded here */
|
||||||
|
@ -80,6 +80,44 @@ int patlen;
|
||||||
fa *fatab[NFA];
|
fa *fatab[NFA];
|
||||||
int nfatab = 0; /* entries in fatab */
|
int nfatab = 0; /* entries in fatab */
|
||||||
|
|
||||||
|
extern int u8_nextlen(const char *s);
|
||||||
|
|
||||||
|
|
||||||
|
/* utf-8 mechanism:
|
||||||
|
|
||||||
|
For most of Awk, utf-8 strings just "work", since they look like
|
||||||
|
null-terminated sequences of 8-bit bytes.
|
||||||
|
|
||||||
|
Functions like length(), index(), and substr() have to operate
|
||||||
|
in units of utf-8 characters. The u8_* functions in run.c
|
||||||
|
handle this.
|
||||||
|
|
||||||
|
Regular expressions are more complicated, since the basic
|
||||||
|
mechanism of the goto table used 8-bit byte indices into the
|
||||||
|
gototab entries to compute the next state. Unicode is a lot
|
||||||
|
bigger, so the gototab entries are now structs with a character
|
||||||
|
and a next state. These are sorted by code point and binary
|
||||||
|
searched.
|
||||||
|
|
||||||
|
Throughout the RE mechanism in b.c, utf-8 characters are
|
||||||
|
converted to their utf-32 value. This mostly shows up in
|
||||||
|
cclenter, which expands character class ranges like a-z and now
|
||||||
|
alpha-omega. The size of a gototab array is still about 256.
|
||||||
|
This should be dynamic, but for now things work ok for a single
|
||||||
|
code page of Unicode, which is the most likely case.
|
||||||
|
|
||||||
|
The code changes are localized in run.c and b.c. I have added a
|
||||||
|
handful of functions to somewhat better hide the implementation,
|
||||||
|
but a lot more could be done.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
static int entry_cmp(const void *l, const void *r);
|
||||||
|
static int get_gototab(fa*, int, int);
|
||||||
|
static int set_gototab(fa*, int, int, int);
|
||||||
|
static void clear_gototab(fa*, int);
|
||||||
|
extern int u8_rune(int *, const char *);
|
||||||
|
|
||||||
static int *
|
static int *
|
||||||
intalloc(size_t n, const char *f)
|
intalloc(size_t n, const char *f)
|
||||||
{
|
{
|
||||||
|
@ -105,7 +143,7 @@ resizesetvec(const char *f)
|
||||||
static void
|
static void
|
||||||
resize_state(fa *f, int state)
|
resize_state(fa *f, int state)
|
||||||
{
|
{
|
||||||
unsigned int **p;
|
gtt *p;
|
||||||
uschar *p2;
|
uschar *p2;
|
||||||
int **p3;
|
int **p3;
|
||||||
int i, new_count;
|
int i, new_count;
|
||||||
|
@ -115,7 +153,7 @@ resize_state(fa *f, int state)
|
||||||
|
|
||||||
new_count = state + 10; /* needs to be tuned */
|
new_count = state + 10; /* needs to be tuned */
|
||||||
|
|
||||||
p = (unsigned int **) realloc(f->gototab, new_count * sizeof(f->gototab[0]));
|
p = (gtt *) realloc(f->gototab, new_count * sizeof(gtt));
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
f->gototab = p;
|
f->gototab = p;
|
||||||
|
@ -131,10 +169,12 @@ resize_state(fa *f, int state)
|
||||||
f->posns = p3;
|
f->posns = p3;
|
||||||
|
|
||||||
for (i = f->state_count; i < new_count; ++i) {
|
for (i = f->state_count; i < new_count; ++i) {
|
||||||
f->gototab[i] = (unsigned int *) calloc(NCHARS, sizeof(**f->gototab));
|
f->gototab[i].entries = (gtte *) calloc(NCHARS, sizeof(gtte));
|
||||||
if (f->gototab[i] == NULL)
|
if (f->gototab[i].entries == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
f->out[i] = 0;
|
f->gototab[i].allocated = NCHARS;
|
||||||
|
f->gototab[i].inuse = 0;
|
||||||
|
f->out[i] = 0;
|
||||||
f->posns[i] = NULL;
|
f->posns[i] = NULL;
|
||||||
}
|
}
|
||||||
f->state_count = new_count;
|
f->state_count = new_count;
|
||||||
|
@ -230,8 +270,7 @@ int makeinit(fa *f, bool anchor)
|
||||||
}
|
}
|
||||||
if ((f->posns[2])[1] == f->accept)
|
if ((f->posns[2])[1] == f->accept)
|
||||||
f->out[2] = 1;
|
f->out[2] = 1;
|
||||||
for (i = 0; i < NCHARS; i++)
|
clear_gototab(f, 2);
|
||||||
f->gototab[2][i] = 0;
|
|
||||||
f->curstat = cgoto(f, 2, HAT);
|
f->curstat = cgoto(f, 2, HAT);
|
||||||
if (anchor) {
|
if (anchor) {
|
||||||
*f->posns[2] = k-1; /* leave out position 0 */
|
*f->posns[2] = k-1; /* leave out position 0 */
|
||||||
|
@ -300,14 +339,14 @@ void freetr(Node *p) /* free parse tree */
|
||||||
/* in the parsing of regular expressions, metacharacters like . have */
|
/* in the parsing of regular expressions, metacharacters like . have */
|
||||||
/* to be seen literally; \056 is not a metacharacter. */
|
/* to be seen literally; \056 is not a metacharacter. */
|
||||||
|
|
||||||
int hexstr(const uschar **pp) /* find and eval hex string at pp, return new p */
|
int hexstr(const uschar **pp, int max) /* find and eval hex string at pp, return new p */
|
||||||
{ /* only pick up one 8-bit byte (2 chars) */
|
{ /* only pick up one 8-bit byte (2 chars) */
|
||||||
const uschar *p;
|
const uschar *p;
|
||||||
int n = 0;
|
int n = 0;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i = 0, p = *pp; i < 2 && isxdigit(*p); i++, p++) {
|
for (i = 0, p = *pp; i < max && isxdigit(*p); i++, p++) {
|
||||||
if (isdigit(*p))
|
if (isdigit((int) *p))
|
||||||
n = 16 * n + *p - '0';
|
n = 16 * n + *p - '0';
|
||||||
else if (*p >= 'a' && *p <= 'f')
|
else if (*p >= 'a' && *p <= 'f')
|
||||||
n = 16 * n + *p - 'a' + 10;
|
n = 16 * n + *p - 'a' + 10;
|
||||||
|
@ -318,6 +357,8 @@ int hexstr(const uschar **pp) /* find and eval hex string at pp, return new p */
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#define isoctdigit(c) ((c) >= '0' && (c) <= '7') /* multiple use of arg */
|
#define isoctdigit(c) ((c) >= '0' && (c) <= '7') /* multiple use of arg */
|
||||||
|
|
||||||
int quoted(const uschar **pp) /* pick up next thing after a \\ */
|
int quoted(const uschar **pp) /* pick up next thing after a \\ */
|
||||||
|
@ -326,24 +367,28 @@ int quoted(const uschar **pp) /* pick up next thing after a \\ */
|
||||||
const uschar *p = *pp;
|
const uschar *p = *pp;
|
||||||
int c;
|
int c;
|
||||||
|
|
||||||
if ((c = *p++) == 't')
|
/* BUG: should advance by utf-8 char even if makes no sense */
|
||||||
|
|
||||||
|
if ((c = *p++) == 't') {
|
||||||
c = '\t';
|
c = '\t';
|
||||||
else if (c == 'n')
|
} else if (c == 'n') {
|
||||||
c = '\n';
|
c = '\n';
|
||||||
else if (c == 'f')
|
} else if (c == 'f') {
|
||||||
c = '\f';
|
c = '\f';
|
||||||
else if (c == 'r')
|
} else if (c == 'r') {
|
||||||
c = '\r';
|
c = '\r';
|
||||||
else if (c == 'b')
|
} else if (c == 'b') {
|
||||||
c = '\b';
|
c = '\b';
|
||||||
else if (c == 'v')
|
} else if (c == 'v') {
|
||||||
c = '\v';
|
c = '\v';
|
||||||
else if (c == 'a')
|
} else if (c == 'a') {
|
||||||
c = '\a';
|
c = '\a';
|
||||||
else if (c == '\\')
|
} else if (c == '\\') {
|
||||||
c = '\\';
|
c = '\\';
|
||||||
else if (c == 'x') { /* hexadecimal goo follows */
|
} else if (c == 'x') { /* 2 hex digits follow */
|
||||||
c = hexstr(&p); /* this adds a null if number is invalid */
|
c = hexstr(&p, 2); /* this adds a null if number is invalid */
|
||||||
|
} else if (c == 'u') { /* unicode char number up to 8 hex digits */
|
||||||
|
c = hexstr(&p, 8);
|
||||||
} else if (isoctdigit(c)) { /* \d \dd \ddd */
|
} else if (isoctdigit(c)) { /* \d \dd \ddd */
|
||||||
int n = c - '0';
|
int n = c - '0';
|
||||||
if (isoctdigit(*p)) {
|
if (isoctdigit(*p)) {
|
||||||
|
@ -358,50 +403,67 @@ int quoted(const uschar **pp) /* pick up next thing after a \\ */
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *cclenter(const char *argp) /* add a character class */
|
int *cclenter(const char *argp) /* add a character class */
|
||||||
{
|
{
|
||||||
int i, c, c2;
|
int i, c, c2;
|
||||||
const uschar *op, *p = (const uschar *) argp;
|
int n;
|
||||||
uschar *bp;
|
const uschar *p = (const uschar *) argp;
|
||||||
static uschar *buf = NULL;
|
int *bp, *retp;
|
||||||
|
static int *buf = NULL;
|
||||||
static int bufsz = 100;
|
static int bufsz = 100;
|
||||||
|
|
||||||
op = p;
|
if (buf == NULL && (buf = (int *) calloc(bufsz, sizeof(int))) == NULL)
|
||||||
if (buf == NULL && (buf = (uschar *) malloc(bufsz)) == NULL)
|
|
||||||
FATAL("out of space for character class [%.10s...] 1", p);
|
FATAL("out of space for character class [%.10s...] 1", p);
|
||||||
bp = buf;
|
bp = buf;
|
||||||
for (i = 0; (c = *p++) != 0; ) {
|
for (i = 0; *p != 0; ) {
|
||||||
|
n = u8_rune(&c, (const char *) p);
|
||||||
|
p += n;
|
||||||
if (c == '\\') {
|
if (c == '\\') {
|
||||||
c = quoted(&p);
|
c = quoted(&p);
|
||||||
} else if (c == '-' && i > 0 && bp[-1] != 0) {
|
} else if (c == '-' && i > 0 && bp[-1] != 0) {
|
||||||
if (*p != 0) {
|
if (*p != 0) {
|
||||||
c = bp[-1];
|
c = bp[-1];
|
||||||
c2 = *p++;
|
/* c2 = *p++; */
|
||||||
|
n = u8_rune(&c2, (const char *) p);
|
||||||
|
p += n;
|
||||||
if (c2 == '\\')
|
if (c2 == '\\')
|
||||||
c2 = quoted(&p);
|
c2 = quoted(&p); /* BUG: sets p, has to be u8 size */
|
||||||
if (c > c2) { /* empty; ignore */
|
if (c > c2) { /* empty; ignore */
|
||||||
bp--;
|
bp--;
|
||||||
i--;
|
i--;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
while (c < c2) {
|
while (c < c2) {
|
||||||
if (!adjbuf((char **) &buf, &bufsz, bp-buf+2, 100, (char **) &bp, "cclenter1"))
|
if (i >= bufsz) {
|
||||||
FATAL("out of space for character class [%.10s...] 2", p);
|
bufsz *= 2;
|
||||||
|
buf = (int *) realloc(buf, bufsz * sizeof(int));
|
||||||
|
if (buf == NULL)
|
||||||
|
FATAL("out of space for character class [%.10s...] 2", p);
|
||||||
|
bp = buf + i;
|
||||||
|
}
|
||||||
*bp++ = ++c;
|
*bp++ = ++c;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!adjbuf((char **) &buf, &bufsz, bp-buf+2, 100, (char **) &bp, "cclenter2"))
|
if (i >= bufsz) {
|
||||||
FATAL("out of space for character class [%.10s...] 3", p);
|
bufsz *= 2;
|
||||||
|
buf = (int *) realloc(buf, bufsz * sizeof(int));
|
||||||
|
if (buf == NULL)
|
||||||
|
FATAL("out of space for character class [%.10s...] 2", p);
|
||||||
|
bp = buf + i;
|
||||||
|
}
|
||||||
*bp++ = c;
|
*bp++ = c;
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
*bp = 0;
|
*bp = 0;
|
||||||
DPRINTF("cclenter: in = |%s|, out = |%s|\n", op, buf);
|
/* DPRINTF("cclenter: in = |%s|, out = |%s|\n", op, buf); BUG: can't print array of int */
|
||||||
xfree(op);
|
/* xfree(op); BUG: what are we freeing here? */
|
||||||
return (char *) tostring((char *) buf);
|
retp = (int *) calloc(bp-buf+1, sizeof(int));
|
||||||
|
for (i = 0; i < bp-buf+1; i++)
|
||||||
|
retp[i] = buf[i];
|
||||||
|
return retp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void overflo(const char *s)
|
void overflo(const char *s)
|
||||||
|
@ -468,7 +530,7 @@ int first(Node *p) /* collects initially active leaves of p into setvec */
|
||||||
setvec[lp] = 1;
|
setvec[lp] = 1;
|
||||||
setcnt++;
|
setcnt++;
|
||||||
}
|
}
|
||||||
if (type(p) == CCL && (*(char *) right(p)) == '\0')
|
if (type(p) == CCL && (*(int *) right(p)) == 0)
|
||||||
return(0); /* empty CCL */
|
return(0); /* empty CCL */
|
||||||
return(1);
|
return(1);
|
||||||
case PLUS:
|
case PLUS:
|
||||||
|
@ -524,9 +586,9 @@ void follow(Node *v) /* collects leaves that can follow v into setvec */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int member(int c, const char *sarg) /* is c in s? */
|
int member(int c, int *sarg) /* is c in s? */
|
||||||
{
|
{
|
||||||
const uschar *s = (const uschar *) sarg;
|
int *s = (int *) sarg;
|
||||||
|
|
||||||
while (*s)
|
while (*s)
|
||||||
if (c == *s++)
|
if (c == *s++)
|
||||||
|
@ -534,11 +596,113 @@ int member(int c, const char *sarg) /* is c in s? */
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void resize_gototab(fa *f, int state)
|
||||||
|
{
|
||||||
|
size_t new_size = f->gototab[state].allocated * 2;
|
||||||
|
gtte *p = (gtte *) realloc(f->gototab[state].entries, new_size * sizeof(gtte));
|
||||||
|
if (p == NULL)
|
||||||
|
overflo(__func__);
|
||||||
|
|
||||||
|
// need to initialized the new memory to zero
|
||||||
|
size_t orig_size = f->gototab[state].allocated; // 2nd half of new mem is this size
|
||||||
|
memset(p + orig_size, 0, orig_size * sizeof(gtte)); // clean it out
|
||||||
|
|
||||||
|
f->gototab[state].allocated = new_size; // update gototab info
|
||||||
|
f->gototab[state].entries = p;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int get_gototab(fa *f, int state, int ch) /* hide gototab implementation */
|
||||||
|
{
|
||||||
|
gtte key;
|
||||||
|
gtte *item;
|
||||||
|
|
||||||
|
key.ch = ch;
|
||||||
|
key.state = 0; /* irrelevant */
|
||||||
|
item = (gtte *) bsearch(& key, f->gototab[state].entries,
|
||||||
|
f->gototab[state].inuse, sizeof(gtte),
|
||||||
|
entry_cmp);
|
||||||
|
|
||||||
|
if (item == NULL)
|
||||||
|
return 0;
|
||||||
|
else
|
||||||
|
return item->state;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int entry_cmp(const void *l, const void *r)
|
||||||
|
{
|
||||||
|
const gtte *left, *right;
|
||||||
|
|
||||||
|
left = (const gtte *) l;
|
||||||
|
right = (const gtte *) r;
|
||||||
|
|
||||||
|
return left->ch - right->ch;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int set_gototab(fa *f, int state, int ch, int val) /* hide gototab implementation */
|
||||||
|
{
|
||||||
|
if (f->gototab[state].inuse == 0) {
|
||||||
|
f->gototab[state].entries[0].ch = ch;
|
||||||
|
f->gototab[state].entries[0].state = val;
|
||||||
|
f->gototab[state].inuse++;
|
||||||
|
return val;
|
||||||
|
} else if (ch > f->gototab[state].entries[f->gototab[state].inuse-1].ch) {
|
||||||
|
// not seen yet, insert and return
|
||||||
|
gtt *tab = & f->gototab[state];
|
||||||
|
if (tab->inuse + 1 >= tab->allocated)
|
||||||
|
resize_gototab(f, state);
|
||||||
|
|
||||||
|
f->gototab[state].entries[f->gototab[state].inuse-1].ch = ch;
|
||||||
|
f->gototab[state].entries[f->gototab[state].inuse-1].state = val;
|
||||||
|
f->gototab[state].inuse++;
|
||||||
|
return val;
|
||||||
|
} else {
|
||||||
|
// maybe we have it, maybe we don't
|
||||||
|
gtte key;
|
||||||
|
gtte *item;
|
||||||
|
|
||||||
|
key.ch = ch;
|
||||||
|
key.state = 0; /* irrelevant */
|
||||||
|
item = (gtte *) bsearch(& key, f->gototab[state].entries,
|
||||||
|
f->gototab[state].inuse, sizeof(gtte),
|
||||||
|
entry_cmp);
|
||||||
|
|
||||||
|
if (item != NULL) {
|
||||||
|
// we have it, update state and return
|
||||||
|
item->state = val;
|
||||||
|
return item->state;
|
||||||
|
}
|
||||||
|
// otherwise, fall through to insert and reallocate.
|
||||||
|
}
|
||||||
|
|
||||||
|
gtt *tab = & f->gototab[state];
|
||||||
|
if (tab->inuse + 1 >= tab->allocated)
|
||||||
|
resize_gototab(f, state);
|
||||||
|
++tab->inuse;
|
||||||
|
f->gototab[state].entries[tab->inuse].ch = ch;
|
||||||
|
f->gototab[state].entries[tab->inuse].state = val;
|
||||||
|
|
||||||
|
qsort(f->gototab[state].entries,
|
||||||
|
f->gototab[state].inuse, sizeof(gtte), entry_cmp);
|
||||||
|
|
||||||
|
return val; /* not used anywhere at the moment */
|
||||||
|
}
|
||||||
|
|
||||||
|
static void clear_gototab(fa *f, int state)
|
||||||
|
{
|
||||||
|
memset(f->gototab[state].entries, 0,
|
||||||
|
f->gototab[state].allocated * sizeof(gtte));
|
||||||
|
f->gototab[state].inuse = 0;
|
||||||
|
}
|
||||||
|
|
||||||
int match(fa *f, const char *p0) /* shortest match ? */
|
int match(fa *f, const char *p0) /* shortest match ? */
|
||||||
{
|
{
|
||||||
int s, ns;
|
int s, ns;
|
||||||
|
int n;
|
||||||
|
int rune;
|
||||||
const uschar *p = (const uschar *) p0;
|
const uschar *p = (const uschar *) p0;
|
||||||
|
|
||||||
|
/* return pmatch(f, p0); does it matter whether longest or shortest? */
|
||||||
|
|
||||||
s = f->initstat;
|
s = f->initstat;
|
||||||
assert (s < f->state_count);
|
assert (s < f->state_count);
|
||||||
|
|
||||||
|
@ -546,19 +710,25 @@ int match(fa *f, const char *p0) /* shortest match ? */
|
||||||
return(1);
|
return(1);
|
||||||
do {
|
do {
|
||||||
/* assert(*p < NCHARS); */
|
/* assert(*p < NCHARS); */
|
||||||
if ((ns = f->gototab[s][*p]) != 0)
|
n = u8_rune(&rune, (const char *) p);
|
||||||
|
if ((ns = get_gototab(f, s, rune)) != 0)
|
||||||
s = ns;
|
s = ns;
|
||||||
else
|
else
|
||||||
s = cgoto(f, s, *p);
|
s = cgoto(f, s, rune);
|
||||||
if (f->out[s])
|
if (f->out[s])
|
||||||
return(1);
|
return(1);
|
||||||
} while (*p++ != 0);
|
if (*p == 0)
|
||||||
|
break;
|
||||||
|
p += n;
|
||||||
|
} while (1); /* was *p++ != 0 */
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int pmatch(fa *f, const char *p0) /* longest match, for sub */
|
int pmatch(fa *f, const char *p0) /* longest match, for sub */
|
||||||
{
|
{
|
||||||
int s, ns;
|
int s, ns;
|
||||||
|
int n;
|
||||||
|
int rune;
|
||||||
const uschar *p = (const uschar *) p0;
|
const uschar *p = (const uschar *) p0;
|
||||||
const uschar *q;
|
const uschar *q;
|
||||||
|
|
||||||
|
@ -573,10 +743,11 @@ int pmatch(fa *f, const char *p0) /* longest match, for sub */
|
||||||
if (f->out[s]) /* final state */
|
if (f->out[s]) /* final state */
|
||||||
patlen = q-p;
|
patlen = q-p;
|
||||||
/* assert(*q < NCHARS); */
|
/* assert(*q < NCHARS); */
|
||||||
if ((ns = f->gototab[s][*q]) != 0)
|
n = u8_rune(&rune, (const char *) q);
|
||||||
|
if ((ns = get_gototab(f, s, rune)) != 0)
|
||||||
s = ns;
|
s = ns;
|
||||||
else
|
else
|
||||||
s = cgoto(f, s, *q);
|
s = cgoto(f, s, rune);
|
||||||
|
|
||||||
assert(s < f->state_count);
|
assert(s < f->state_count);
|
||||||
|
|
||||||
|
@ -588,7 +759,11 @@ int pmatch(fa *f, const char *p0) /* longest match, for sub */
|
||||||
else
|
else
|
||||||
goto nextin; /* no match */
|
goto nextin; /* no match */
|
||||||
}
|
}
|
||||||
} while (*q++ != 0);
|
if (*q == 0)
|
||||||
|
break;
|
||||||
|
q += n;
|
||||||
|
} while (1);
|
||||||
|
q++; /* was *q++ */
|
||||||
if (f->out[s])
|
if (f->out[s])
|
||||||
patlen = q-p-1; /* don't count $ */
|
patlen = q-p-1; /* don't count $ */
|
||||||
if (patlen >= 0) {
|
if (patlen >= 0) {
|
||||||
|
@ -597,13 +772,19 @@ int pmatch(fa *f, const char *p0) /* longest match, for sub */
|
||||||
}
|
}
|
||||||
nextin:
|
nextin:
|
||||||
s = 2;
|
s = 2;
|
||||||
} while (*p++);
|
if (*p == 0)
|
||||||
|
break;
|
||||||
|
n = u8_rune(&rune, (const char *) p);
|
||||||
|
p += n;
|
||||||
|
} while (1); /* was *p++ */
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int nematch(fa *f, const char *p0) /* non-empty match, for sub */
|
int nematch(fa *f, const char *p0) /* non-empty match, for sub */
|
||||||
{
|
{
|
||||||
int s, ns;
|
int s, ns;
|
||||||
|
int n;
|
||||||
|
int rune;
|
||||||
const uschar *p = (const uschar *) p0;
|
const uschar *p = (const uschar *) p0;
|
||||||
const uschar *q;
|
const uschar *q;
|
||||||
|
|
||||||
|
@ -618,10 +799,11 @@ int nematch(fa *f, const char *p0) /* non-empty match, for sub */
|
||||||
if (f->out[s]) /* final state */
|
if (f->out[s]) /* final state */
|
||||||
patlen = q-p;
|
patlen = q-p;
|
||||||
/* assert(*q < NCHARS); */
|
/* assert(*q < NCHARS); */
|
||||||
if ((ns = f->gototab[s][*q]) != 0)
|
n = u8_rune(&rune, (const char *) q);
|
||||||
|
if ((ns = get_gototab(f, s, rune)) != 0)
|
||||||
s = ns;
|
s = ns;
|
||||||
else
|
else
|
||||||
s = cgoto(f, s, *q);
|
s = cgoto(f, s, rune);
|
||||||
if (s == 1) { /* no transition */
|
if (s == 1) { /* no transition */
|
||||||
if (patlen > 0) {
|
if (patlen > 0) {
|
||||||
patbeg = (const char *) p;
|
patbeg = (const char *) p;
|
||||||
|
@ -629,7 +811,11 @@ int nematch(fa *f, const char *p0) /* non-empty match, for sub */
|
||||||
} else
|
} else
|
||||||
goto nnextin; /* no nonempty match */
|
goto nnextin; /* no nonempty match */
|
||||||
}
|
}
|
||||||
} while (*q++ != 0);
|
if (*q == 0)
|
||||||
|
break;
|
||||||
|
q += n;
|
||||||
|
} while (1);
|
||||||
|
q++;
|
||||||
if (f->out[s])
|
if (f->out[s])
|
||||||
patlen = q-p-1; /* don't count $ */
|
patlen = q-p-1; /* don't count $ */
|
||||||
if (patlen > 0 ) {
|
if (patlen > 0 ) {
|
||||||
|
@ -661,54 +847,84 @@ int nematch(fa *f, const char *p0) /* non-empty match, for sub */
|
||||||
|
|
||||||
bool fnematch(fa *pfa, FILE *f, char **pbuf, int *pbufsize, int quantum)
|
bool fnematch(fa *pfa, FILE *f, char **pbuf, int *pbufsize, int quantum)
|
||||||
{
|
{
|
||||||
char *buf = *pbuf;
|
char *i, *j, *k, *buf = *pbuf;
|
||||||
int bufsize = *pbufsize;
|
int bufsize = *pbufsize;
|
||||||
int c, i, j, k, ns, s;
|
int c, n, ns, s;
|
||||||
|
|
||||||
s = pfa->initstat;
|
s = pfa->initstat;
|
||||||
patlen = 0;
|
patlen = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* All indices relative to buf.
|
* buf <= i <= j <= k <= buf+bufsize
|
||||||
* i <= j <= k <= bufsize
|
|
||||||
*
|
*
|
||||||
* i: origin of active substring
|
* i: origin of active substring
|
||||||
* j: current character
|
* j: current character
|
||||||
* k: destination of next getc()
|
* k: destination of the next getc
|
||||||
*/
|
*/
|
||||||
i = -1, k = 0;
|
|
||||||
do {
|
|
||||||
j = i++;
|
|
||||||
do {
|
|
||||||
if (++j == k) {
|
|
||||||
if (k == bufsize)
|
|
||||||
if (!adjbuf((char **) &buf, &bufsize, bufsize+1, quantum, 0, "fnematch"))
|
|
||||||
FATAL("stream '%.30s...' too long", buf);
|
|
||||||
buf[k++] = (c = getc(f)) != EOF ? c : 0;
|
|
||||||
}
|
|
||||||
c = (uschar)buf[j];
|
|
||||||
/* assert(c < NCHARS); */
|
|
||||||
|
|
||||||
if ((ns = pfa->gototab[s][c]) != 0)
|
i = j = k = buf;
|
||||||
s = ns;
|
|
||||||
else
|
|
||||||
s = cgoto(pfa, s, c);
|
|
||||||
|
|
||||||
if (pfa->out[s]) { /* final state */
|
do {
|
||||||
patlen = j - i + 1;
|
/*
|
||||||
if (c == 0) /* don't count $ */
|
* Call u8_rune with at least awk_mb_cur_max ahead in
|
||||||
patlen--;
|
* the buffer until EOF interferes.
|
||||||
|
*/
|
||||||
|
if (k - j < awk_mb_cur_max) {
|
||||||
|
if (k + awk_mb_cur_max > buf + bufsize) {
|
||||||
|
char *obuf = buf;
|
||||||
|
adjbuf((char **) &buf, &bufsize,
|
||||||
|
bufsize + awk_mb_cur_max,
|
||||||
|
quantum, 0, "fnematch");
|
||||||
|
|
||||||
|
/* buf resized, maybe moved. update pointers */
|
||||||
|
*pbufsize = bufsize;
|
||||||
|
if (obuf != buf) {
|
||||||
|
i = buf + (i - obuf);
|
||||||
|
j = buf + (j - obuf);
|
||||||
|
k = buf + (k - obuf);
|
||||||
|
*pbuf = buf;
|
||||||
|
if (patlen)
|
||||||
|
patbeg = buf + (patbeg - obuf);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} while (buf[j] && s != 1);
|
for (n = awk_mb_cur_max ; n > 0; n--) {
|
||||||
|
*k++ = (c = getc(f)) != EOF ? c : 0;
|
||||||
|
if (c == EOF) {
|
||||||
|
if (ferror(f))
|
||||||
|
FATAL("fnematch: getc error");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
j += u8_rune(&c, j);
|
||||||
|
|
||||||
|
if ((ns = get_gototab(pfa, s, c)) != 0)
|
||||||
|
s = ns;
|
||||||
|
else
|
||||||
|
s = cgoto(pfa, s, c);
|
||||||
|
|
||||||
|
if (pfa->out[s]) { /* final state */
|
||||||
|
patbeg = i;
|
||||||
|
patlen = j - i;
|
||||||
|
if (c == 0) /* don't count $ */
|
||||||
|
patlen--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (c && s != 1)
|
||||||
|
continue; /* origin i still viable, next j */
|
||||||
|
if (patlen)
|
||||||
|
break; /* best match found */
|
||||||
|
|
||||||
|
/* no match at origin i, next i and start over */
|
||||||
|
i += u8_rune(&c, i);
|
||||||
|
if (c == 0)
|
||||||
|
break; /* no match */
|
||||||
|
j = i;
|
||||||
s = 2;
|
s = 2;
|
||||||
} while (buf[i] && !patlen);
|
} while (1);
|
||||||
|
|
||||||
/* adjbuf() may have relocated a resized buffer. Inform the world. */
|
|
||||||
*pbuf = buf;
|
|
||||||
*pbufsize = bufsize;
|
|
||||||
|
|
||||||
if (patlen) {
|
if (patlen) {
|
||||||
patbeg = (char *) buf + i;
|
|
||||||
/*
|
/*
|
||||||
* Under no circumstances is the last character fed to
|
* Under no circumstances is the last character fed to
|
||||||
* the automaton part of the match. It is EOF's nullbyte,
|
* the automaton part of the match. It is EOF's nullbyte,
|
||||||
|
@ -721,10 +937,10 @@ bool fnematch(fa *pfa, FILE *f, char **pbuf, int *pbufsize, int quantum)
|
||||||
* terminate the buffer.
|
* terminate the buffer.
|
||||||
*/
|
*/
|
||||||
do
|
do
|
||||||
if (buf[--k] && ungetc(buf[k], f) == EOF)
|
if (*--k && ungetc(*k, f) == EOF)
|
||||||
FATAL("unable to ungetc '%c'", buf[k]);
|
FATAL("unable to ungetc '%c'", *k);
|
||||||
while (k > i + patlen);
|
while (k > patbeg + patlen);
|
||||||
buf[k] = '\0';
|
*k = '\0';
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -797,7 +1013,7 @@ Node *primary(void)
|
||||||
rtok = relex();
|
rtok = relex();
|
||||||
if (rtok == ')') { /* special pleading for () */
|
if (rtok == ')') { /* special pleading for () */
|
||||||
rtok = relex();
|
rtok = relex();
|
||||||
return unary(op2(CCL, NIL, (Node *) tostring("")));
|
return unary(op2(CCL, NIL, (Node *) cclenter("")));
|
||||||
}
|
}
|
||||||
np = regexp();
|
np = regexp();
|
||||||
if (rtok == ')') {
|
if (rtok == ')') {
|
||||||
|
@ -820,7 +1036,7 @@ Node *concat(Node *np)
|
||||||
return (concat(op2(CAT, np, primary())));
|
return (concat(op2(CAT, np, primary())));
|
||||||
case EMPTYRE:
|
case EMPTYRE:
|
||||||
rtok = relex();
|
rtok = relex();
|
||||||
return (concat(op2(CAT, op2(CCL, NIL, (Node *) tostring("")),
|
return (concat(op2(CAT, op2(CCL, NIL, (Node *) cclenter("")),
|
||||||
primary())));
|
primary())));
|
||||||
}
|
}
|
||||||
return (np);
|
return (np);
|
||||||
|
@ -866,6 +1082,25 @@ Node *unary(Node *np)
|
||||||
* must be less than twice the size of their full name.
|
* must be less than twice the size of their full name.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/* Because isblank doesn't show up in any of the header files on any
|
||||||
|
* system i use, it's defined here. if some other locale has a richer
|
||||||
|
* definition of "blank", define HAS_ISBLANK and provide your own
|
||||||
|
* version.
|
||||||
|
* the parentheses here are an attempt to find a path through the maze
|
||||||
|
* of macro definition and/or function and/or version provided. thanks
|
||||||
|
* to nelson beebe for the suggestion; let's see if it works everywhere.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* #define HAS_ISBLANK */
|
||||||
|
#ifndef HAS_ISBLANK
|
||||||
|
|
||||||
|
int (xisblank)(int c)
|
||||||
|
{
|
||||||
|
return c==' ' || c=='\t';
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
static const struct charclass {
|
static const struct charclass {
|
||||||
const char *cc_name;
|
const char *cc_name;
|
||||||
int cc_namelen;
|
int cc_namelen;
|
||||||
|
@ -873,7 +1108,11 @@ static const struct charclass {
|
||||||
} charclasses[] = {
|
} charclasses[] = {
|
||||||
{ "alnum", 5, isalnum },
|
{ "alnum", 5, isalnum },
|
||||||
{ "alpha", 5, isalpha },
|
{ "alpha", 5, isalpha },
|
||||||
|
#ifndef HAS_ISBLANK
|
||||||
|
{ "blank", 5, xisblank },
|
||||||
|
#else
|
||||||
{ "blank", 5, isblank },
|
{ "blank", 5, isblank },
|
||||||
|
#endif
|
||||||
{ "cntrl", 5, iscntrl },
|
{ "cntrl", 5, iscntrl },
|
||||||
{ "digit", 5, isdigit },
|
{ "digit", 5, isdigit },
|
||||||
{ "graph", 5, isgraph },
|
{ "graph", 5, isgraph },
|
||||||
|
@ -1013,6 +1252,12 @@ int relex(void) /* lexical analyzer for reparse */
|
||||||
rescan:
|
rescan:
|
||||||
starttok = prestr;
|
starttok = prestr;
|
||||||
|
|
||||||
|
if ((n = u8_rune(&rlxval, (const char *) prestr)) > 1) {
|
||||||
|
prestr += n;
|
||||||
|
starttok = prestr;
|
||||||
|
return CHAR;
|
||||||
|
}
|
||||||
|
|
||||||
switch (c = *prestr++) {
|
switch (c = *prestr++) {
|
||||||
case '|': return OR;
|
case '|': return OR;
|
||||||
case '*': return STAR;
|
case '*': return STAR;
|
||||||
|
@ -1050,10 +1295,15 @@ rescan:
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
cflag = 0;
|
cflag = 0;
|
||||||
n = 2 * strlen((const char *) prestr)+1;
|
n = 5 * strlen((const char *) prestr)+1; /* BUG: was 2. what value? */
|
||||||
if (!adjbuf((char **) &buf, &bufsz, n, n, (char **) &bp, "relex1"))
|
if (!adjbuf((char **) &buf, &bufsz, n, n, (char **) &bp, "relex1"))
|
||||||
FATAL("out of space for reg expr %.10s...", lastre);
|
FATAL("out of space for reg expr %.10s...", lastre);
|
||||||
for (; ; ) {
|
for (; ; ) {
|
||||||
|
if ((n = u8_rune(&rlxval, (const char *) prestr)) > 1) {
|
||||||
|
for (i = 0; i < n; i++)
|
||||||
|
*bp++ = *prestr++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if ((c = *prestr++) == '\\') {
|
if ((c = *prestr++) == '\\') {
|
||||||
*bp++ = '\\';
|
*bp++ = '\\';
|
||||||
if ((c = *prestr++) == '\0')
|
if ((c = *prestr++) == '\0')
|
||||||
|
@ -1143,7 +1393,7 @@ rescan:
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case '{':
|
case '{':
|
||||||
if (isdigit(*(prestr))) {
|
if (isdigit((int) *(prestr))) {
|
||||||
num = 0; /* Process as a repetition */
|
num = 0; /* Process as a repetition */
|
||||||
n = -1; m = -1;
|
n = -1; m = -1;
|
||||||
commafound = false;
|
commafound = false;
|
||||||
|
@ -1213,7 +1463,6 @@ rescan:
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return 0; /* [jart] why wasn't this here? */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int cgoto(fa *f, int s, int c)
|
int cgoto(fa *f, int s, int c)
|
||||||
|
@ -1221,7 +1470,7 @@ int cgoto(fa *f, int s, int c)
|
||||||
int *p, *q;
|
int *p, *q;
|
||||||
int i, j, k;
|
int i, j, k;
|
||||||
|
|
||||||
assert(c == HAT || c < NCHARS);
|
/* assert(c == HAT || c < NCHARS); BUG: seg fault if disable test */
|
||||||
while (f->accept >= maxsetvec) { /* guessing here! */
|
while (f->accept >= maxsetvec) { /* guessing here! */
|
||||||
resizesetvec(__func__);
|
resizesetvec(__func__);
|
||||||
}
|
}
|
||||||
|
@ -1237,8 +1486,8 @@ int cgoto(fa *f, int s, int c)
|
||||||
|| (k == DOT && c != 0 && c != HAT)
|
|| (k == DOT && c != 0 && c != HAT)
|
||||||
|| (k == ALL && c != 0)
|
|| (k == ALL && c != 0)
|
||||||
|| (k == EMPTYRE && c != 0)
|
|| (k == EMPTYRE && c != 0)
|
||||||
|| (k == CCL && member(c, (char *) f->re[p[i]].lval.up))
|
|| (k == CCL && member(c, (int *) f->re[p[i]].lval.rp))
|
||||||
|| (k == NCCL && !member(c, (char *) f->re[p[i]].lval.up) && c != 0 && c != HAT)) {
|
|| (k == NCCL && !member(c, (int *) f->re[p[i]].lval.rp) && c != 0 && c != HAT)) {
|
||||||
q = f->re[p[i]].lfollow;
|
q = f->re[p[i]].lfollow;
|
||||||
for (j = 1; j <= *q; j++) {
|
for (j = 1; j <= *q; j++) {
|
||||||
if (q[j] >= maxsetvec) {
|
if (q[j] >= maxsetvec) {
|
||||||
|
@ -1270,7 +1519,7 @@ int cgoto(fa *f, int s, int c)
|
||||||
goto different;
|
goto different;
|
||||||
/* setvec is state i */
|
/* setvec is state i */
|
||||||
if (c != HAT)
|
if (c != HAT)
|
||||||
f->gototab[s][c] = i;
|
set_gototab(f, s, c, i);
|
||||||
return i;
|
return i;
|
||||||
different:;
|
different:;
|
||||||
}
|
}
|
||||||
|
@ -1278,14 +1527,13 @@ int cgoto(fa *f, int s, int c)
|
||||||
/* add tmpset to current set of states */
|
/* add tmpset to current set of states */
|
||||||
++(f->curstat);
|
++(f->curstat);
|
||||||
resize_state(f, f->curstat);
|
resize_state(f, f->curstat);
|
||||||
for (i = 0; i < NCHARS; i++)
|
clear_gototab(f, f->curstat);
|
||||||
f->gototab[f->curstat][i] = 0;
|
|
||||||
xfree(f->posns[f->curstat]);
|
xfree(f->posns[f->curstat]);
|
||||||
p = intalloc(setcnt + 1, __func__);
|
p = intalloc(setcnt + 1, __func__);
|
||||||
|
|
||||||
f->posns[f->curstat] = p;
|
f->posns[f->curstat] = p;
|
||||||
if (c != HAT)
|
if (c != HAT)
|
||||||
f->gototab[s][c] = f->curstat;
|
set_gototab(f, s, c, f->curstat);
|
||||||
for (i = 0; i <= setcnt; i++)
|
for (i = 0; i <= setcnt; i++)
|
||||||
p[i] = tmpset[i];
|
p[i] = tmpset[i];
|
||||||
if (setvec[f->accept])
|
if (setvec[f->accept])
|
||||||
|
@ -1303,7 +1551,8 @@ void freefa(fa *f) /* free a finite automaton */
|
||||||
if (f == NULL)
|
if (f == NULL)
|
||||||
return;
|
return;
|
||||||
for (i = 0; i < f->state_count; i++)
|
for (i = 0; i < f->state_count; i++)
|
||||||
xfree(f->gototab[i])
|
xfree(f->gototab[i].entries);
|
||||||
|
xfree(f->gototab);
|
||||||
for (i = 0; i <= f->curstat; i++)
|
for (i = 0; i <= f->curstat; i++)
|
||||||
xfree(f->posns[i]);
|
xfree(f->posns[i]);
|
||||||
for (i = 0; i <= f->accept; i++) {
|
for (i = 0; i <= f->accept; i++) {
|
||||||
|
|
129
third_party/awk/lex.c
vendored
129
third_party/awk/lex.c
vendored
|
@ -1,40 +1,35 @@
|
||||||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
/****************************************************************
|
||||||
│ vi: set noet ft=c ts=8 sw=8 fenc=utf-8 :vi │
|
Copyright (C) Lucent Technologies 1997
|
||||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
All Rights Reserved
|
||||||
│ │
|
|
||||||
│ Copyright (C) Lucent Technologies 1997 │
|
|
||||||
│ All Rights Reserved │
|
|
||||||
│ │
|
|
||||||
│ Permission to use, copy, modify, and distribute this software and │
|
|
||||||
│ its documentation for any purpose and without fee is hereby │
|
|
||||||
│ granted, provided that the above copyright notice appear in all │
|
|
||||||
│ copies and that both that the copyright notice and this │
|
|
||||||
│ permission notice and warranty disclaimer appear in supporting │
|
|
||||||
│ documentation, and that the name Lucent Technologies or any of │
|
|
||||||
│ its entities not be used in advertising or publicity pertaining │
|
|
||||||
│ to distribution of the software without specific, written prior │
|
|
||||||
│ permission. │
|
|
||||||
│ │
|
|
||||||
│ LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, │
|
|
||||||
│ INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. │
|
|
||||||
│ IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY │
|
|
||||||
│ SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES │
|
|
||||||
│ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER │
|
|
||||||
│ IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, │
|
|
||||||
│ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF │
|
|
||||||
│ THIS SOFTWARE. │
|
|
||||||
│ │
|
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
|
||||||
#include "libc/calls/calls.h"
|
|
||||||
#include "libc/fmt/conv.h"
|
|
||||||
#include "libc/mem/mem.h"
|
|
||||||
#include "libc/runtime/runtime.h"
|
|
||||||
#include "libc/stdio/stdio.h"
|
|
||||||
#include "libc/str/str.h"
|
|
||||||
#include "third_party/awk/awk.h"
|
|
||||||
#include "third_party/awk/awkgram.tab.h"
|
|
||||||
#include "third_party/gdtoa/gdtoa.h"
|
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and distribute this software and
|
||||||
|
its documentation for any purpose and without fee is hereby
|
||||||
|
granted, provided that the above copyright notice appear in all
|
||||||
|
copies and that both that the copyright notice and this
|
||||||
|
permission notice and warranty disclaimer appear in supporting
|
||||||
|
documentation, and that the name Lucent Technologies or any of
|
||||||
|
its entities not be used in advertising or publicity pertaining
|
||||||
|
to distribution of the software without specific, written prior
|
||||||
|
permission.
|
||||||
|
|
||||||
|
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||||
|
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
|
||||||
|
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
|
||||||
|
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||||
|
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
THIS SOFTWARE.
|
||||||
|
****************************************************************/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include "awk.h"
|
||||||
|
#include "awkgram.tab.h"
|
||||||
|
|
||||||
|
extern YYSTYPE yylval;
|
||||||
extern bool infunc;
|
extern bool infunc;
|
||||||
|
|
||||||
int lineno = 1;
|
int lineno = 1;
|
||||||
|
@ -373,6 +368,8 @@ int yylex(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern int runetochar(char *str, int c);
|
||||||
|
|
||||||
int string(void)
|
int string(void)
|
||||||
{
|
{
|
||||||
int c, n;
|
int c, n;
|
||||||
|
@ -420,20 +417,54 @@ int string(void)
|
||||||
*bp++ = n;
|
*bp++ = n;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'x': /* hex \x0-9a-fA-F + */
|
case 'x': /* hex \x0-9a-fA-F (exactly two) */
|
||||||
{ char xbuf[100], *px;
|
{
|
||||||
for (px = xbuf; (c = input()) != 0 && px-xbuf < 100-2; ) {
|
int i;
|
||||||
if (isdigit(c)
|
|
||||||
|| (c >= 'a' && c <= 'f')
|
if (!isxdigit(peek())) {
|
||||||
|| (c >= 'A' && c <= 'F'))
|
unput(c);
|
||||||
*px++ = c;
|
break;
|
||||||
else
|
}
|
||||||
break;
|
n = 0;
|
||||||
|
for (i = 0; i < 2; i++) {
|
||||||
|
c = input();
|
||||||
|
if (c == 0)
|
||||||
|
break;
|
||||||
|
if (isxdigit(c)) {
|
||||||
|
c = tolower(c);
|
||||||
|
n *= 16;
|
||||||
|
if (isdigit(c))
|
||||||
|
n += (c - '0');
|
||||||
|
else
|
||||||
|
n += 10 + (c - 'a');
|
||||||
|
} else {
|
||||||
|
unput(c);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i)
|
||||||
|
*bp++ = n;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 'u': /* utf \u0-9a-fA-F (1..8) */
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
n = 0;
|
||||||
|
for (i = 0; i < 8; i++) {
|
||||||
|
c = input();
|
||||||
|
if (!isxdigit(c) || c == 0)
|
||||||
|
break;
|
||||||
|
c = tolower(c);
|
||||||
|
n *= 16;
|
||||||
|
if (isdigit(c))
|
||||||
|
n += (c - '0');
|
||||||
|
else
|
||||||
|
n += 10 + (c - 'a');
|
||||||
}
|
}
|
||||||
*px = 0;
|
|
||||||
unput(c);
|
unput(c);
|
||||||
sscanf(xbuf, "%x", (unsigned int *) &n);
|
bp += runetochar(bp, n);
|
||||||
*bp++ = n;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -530,7 +561,7 @@ int regexpr(void)
|
||||||
char *bp;
|
char *bp;
|
||||||
|
|
||||||
if (buf == NULL && (buf = (char *) malloc(bufsz)) == NULL)
|
if (buf == NULL && (buf = (char *) malloc(bufsz)) == NULL)
|
||||||
FATAL("out of space for rex expr");
|
FATAL("out of space for reg expr");
|
||||||
bp = buf;
|
bp = buf;
|
||||||
for ( ; (c = input()) != '/' && c != 0; ) {
|
for ( ; (c = input()) != '/' && c != 0; ) {
|
||||||
if (!adjbuf(&buf, &bufsz, bp-buf+3, 500, &bp, "regexpr"))
|
if (!adjbuf(&buf, &bufsz, bp-buf+3, 500, &bp, "regexpr"))
|
||||||
|
|
223
third_party/awk/lib.c
vendored
223
third_party/awk/lib.c
vendored
|
@ -1,43 +1,43 @@
|
||||||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
/****************************************************************
|
||||||
│ vi: set noet ft=c ts=8 sw=8 fenc=utf-8 :vi │
|
Copyright (C) Lucent Technologies 1997
|
||||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
All Rights Reserved
|
||||||
│ │
|
|
||||||
│ Copyright (C) Lucent Technologies 1997 │
|
Permission to use, copy, modify, and distribute this software and
|
||||||
│ All Rights Reserved │
|
its documentation for any purpose and without fee is hereby
|
||||||
│ │
|
granted, provided that the above copyright notice appear in all
|
||||||
│ Permission to use, copy, modify, and distribute this software and │
|
copies and that both that the copyright notice and this
|
||||||
│ its documentation for any purpose and without fee is hereby │
|
permission notice and warranty disclaimer appear in supporting
|
||||||
│ granted, provided that the above copyright notice appear in all │
|
documentation, and that the name Lucent Technologies or any of
|
||||||
│ copies and that both that the copyright notice and this │
|
its entities not be used in advertising or publicity pertaining
|
||||||
│ permission notice and warranty disclaimer appear in supporting │
|
to distribution of the software without specific, written prior
|
||||||
│ documentation, and that the name Lucent Technologies or any of │
|
permission.
|
||||||
│ its entities not be used in advertising or publicity pertaining │
|
|
||||||
│ to distribution of the software without specific, written prior │
|
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||||
│ permission. │
|
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
|
||||||
│ │
|
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
|
||||||
│ LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, │
|
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
│ INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. │
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
|
||||||
│ IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY │
|
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||||
│ SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES │
|
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
│ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER │
|
THIS SOFTWARE.
|
||||||
│ IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, │
|
****************************************************************/
|
||||||
│ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF │
|
|
||||||
│ THIS SOFTWARE. │
|
|
||||||
│ │
|
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
|
||||||
#define DEBUG
|
#define DEBUG
|
||||||
#include "libc/calls/calls.h"
|
#include <stdio.h>
|
||||||
#include "libc/errno.h"
|
#include <string.h>
|
||||||
#include "libc/fmt/conv.h"
|
#include <strings.h>
|
||||||
#include "libc/limits.h"
|
#include <ctype.h>
|
||||||
#include "libc/math.h"
|
#include <errno.h>
|
||||||
#include "libc/mem/mem.h"
|
#include <stdlib.h>
|
||||||
#include "libc/runtime/runtime.h"
|
#include <stdarg.h>
|
||||||
#include "libc/str/str.h"
|
#include <limits.h>
|
||||||
#include "third_party/awk/awk.h"
|
#include <math.h>
|
||||||
|
#include "awk.h"
|
||||||
|
|
||||||
|
extern int u8_nextlen(const char *s);
|
||||||
|
|
||||||
char EMPTY[] = { '\0' };
|
char EMPTY[] = { '\0' };
|
||||||
static FILE *infile = NULL;
|
FILE *infile = NULL;
|
||||||
bool innew; /* true = infile has not been read by readrec */
|
bool innew; /* true = infile has not been read by readrec */
|
||||||
char *file = EMPTY;
|
char *file = EMPTY;
|
||||||
char *record;
|
char *record;
|
||||||
|
@ -152,11 +152,6 @@ int getrec(char **pbuf, int *pbufsize, bool isrecord) /* get next input record *
|
||||||
}
|
}
|
||||||
DPRINTF("RS=<%s>, FS=<%s>, ARGC=%g, FILENAME=%s\n",
|
DPRINTF("RS=<%s>, FS=<%s>, ARGC=%g, FILENAME=%s\n",
|
||||||
*RS, *FS, *ARGC, *FILENAME);
|
*RS, *FS, *ARGC, *FILENAME);
|
||||||
if (isrecord) {
|
|
||||||
donefld = false;
|
|
||||||
donerec = true;
|
|
||||||
savefs();
|
|
||||||
}
|
|
||||||
saveb0 = buf[0];
|
saveb0 = buf[0];
|
||||||
buf[0] = 0;
|
buf[0] = 0;
|
||||||
while (argno < *ARGC || infile == stdin) {
|
while (argno < *ARGC || infile == stdin) {
|
||||||
|
@ -196,6 +191,9 @@ int getrec(char **pbuf, int *pbufsize, bool isrecord) /* get next input record *
|
||||||
fldtab[0]->fval = result;
|
fldtab[0]->fval = result;
|
||||||
fldtab[0]->tval |= NUM;
|
fldtab[0]->tval |= NUM;
|
||||||
}
|
}
|
||||||
|
donefld = false;
|
||||||
|
donerec = true;
|
||||||
|
savefs();
|
||||||
}
|
}
|
||||||
setfval(nrloc, nrloc->fval+1);
|
setfval(nrloc, nrloc->fval+1);
|
||||||
setfval(fnrloc, fnrloc->fval+1);
|
setfval(fnrloc, fnrloc->fval+1);
|
||||||
|
@ -223,16 +221,22 @@ void nextfile(void)
|
||||||
argno++;
|
argno++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern int readcsvrec(char **pbuf, int *pbufsize, FILE *inf, bool newflag);
|
||||||
|
|
||||||
int readrec(char **pbuf, int *pbufsize, FILE *inf, bool newflag) /* read one record into buf */
|
int readrec(char **pbuf, int *pbufsize, FILE *inf, bool newflag) /* read one record into buf */
|
||||||
{
|
{
|
||||||
int sep, c, isrec;
|
int sep, c, isrec; // POTENTIAL BUG? isrec is a macro in awk.h
|
||||||
char *rr, *buf = *pbuf;
|
char *rr = *pbuf, *buf = *pbuf;
|
||||||
int bufsize = *pbufsize;
|
int bufsize = *pbufsize;
|
||||||
char *rs = getsval(rsloc);
|
char *rs = getsval(rsloc);
|
||||||
|
|
||||||
if (*rs && rs[1]) {
|
if (CSV) {
|
||||||
|
c = readcsvrec(pbuf, pbufsize, inf, newflag);
|
||||||
|
isrec = (c == EOF && rr == buf) ? false : true;
|
||||||
|
} else if (*rs && rs[1]) {
|
||||||
bool found;
|
bool found;
|
||||||
|
|
||||||
|
memset(buf, 0, bufsize);
|
||||||
fa *pfa = makedfa(rs, 1);
|
fa *pfa = makedfa(rs, 1);
|
||||||
if (newflag)
|
if (newflag)
|
||||||
found = fnematch(pfa, inf, &buf, &bufsize, recsize);
|
found = fnematch(pfa, inf, &buf, &bufsize, recsize);
|
||||||
|
@ -245,6 +249,7 @@ int readrec(char **pbuf, int *pbufsize, FILE *inf, bool newflag) /* read one rec
|
||||||
if (found)
|
if (found)
|
||||||
setptr(patbeg, '\0');
|
setptr(patbeg, '\0');
|
||||||
isrec = (found == 0 && *buf == '\0') ? false : true;
|
isrec = (found == 0 && *buf == '\0') ? false : true;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if ((sep = *rs) == 0) {
|
if ((sep = *rs) == 0) {
|
||||||
sep = '\n';
|
sep = '\n';
|
||||||
|
@ -282,6 +287,52 @@ int readrec(char **pbuf, int *pbufsize, FILE *inf, bool newflag) /* read one rec
|
||||||
return isrec;
|
return isrec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/*******************
|
||||||
|
* loose ends here:
|
||||||
|
* \r\n should become \n
|
||||||
|
* what about bare \r? Excel uses that for embedded newlines
|
||||||
|
* can't have "" in unquoted fields, according to RFC 4180
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
int readcsvrec(char **pbuf, int *pbufsize, FILE *inf, bool newflag) /* csv can have \n's */
|
||||||
|
{ /* so read a complete record that might be multiple lines */
|
||||||
|
int sep, c;
|
||||||
|
char *rr = *pbuf, *buf = *pbuf;
|
||||||
|
int bufsize = *pbufsize;
|
||||||
|
bool in_quote = false;
|
||||||
|
|
||||||
|
sep = '\n'; /* the only separator; have to skip over \n embedded in "..." */
|
||||||
|
rr = buf;
|
||||||
|
while ((c = getc(inf)) != EOF) {
|
||||||
|
if (c == sep) {
|
||||||
|
if (! in_quote)
|
||||||
|
break;
|
||||||
|
if (rr > buf && rr[-1] == '\r') // remove \r if was \r\n
|
||||||
|
rr--;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rr-buf+1 > bufsize)
|
||||||
|
if (!adjbuf(&buf, &bufsize, 1+rr-buf,
|
||||||
|
recsize, &rr, "readcsvrec 1"))
|
||||||
|
FATAL("input record `%.30s...' too long", buf);
|
||||||
|
*rr++ = c;
|
||||||
|
if (c == '"')
|
||||||
|
in_quote = ! in_quote;
|
||||||
|
}
|
||||||
|
if (c == '\n' && rr > buf && rr[-1] == '\r') // remove \r if was \r\n
|
||||||
|
rr--;
|
||||||
|
|
||||||
|
if (!adjbuf(&buf, &bufsize, 1+rr-buf, recsize, &rr, "readcsvrec 4"))
|
||||||
|
FATAL("input record `%.30s...' too long", buf);
|
||||||
|
*rr = 0;
|
||||||
|
*pbuf = buf;
|
||||||
|
*pbufsize = bufsize;
|
||||||
|
DPRINTF("readcsvrec saw <%s>, returns %d\n", buf, c);
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
char *getargv(int n) /* get ARGV[n] */
|
char *getargv(int n) /* get ARGV[n] */
|
||||||
{
|
{
|
||||||
Cell *x;
|
Cell *x;
|
||||||
|
@ -303,6 +354,9 @@ void setclvar(char *s) /* set var=value from s */
|
||||||
Cell *q;
|
Cell *q;
|
||||||
double result;
|
double result;
|
||||||
|
|
||||||
|
/* commit f3d9187d4e0f02294fb1b0e31152070506314e67 broke T.argv test */
|
||||||
|
/* I don't understand why it was changed. */
|
||||||
|
|
||||||
for (p=s; *p != '='; p++)
|
for (p=s; *p != '='; p++)
|
||||||
;
|
;
|
||||||
e = p;
|
e = p;
|
||||||
|
@ -315,6 +369,7 @@ void setclvar(char *s) /* set var=value from s */
|
||||||
q->tval |= NUM;
|
q->tval |= NUM;
|
||||||
}
|
}
|
||||||
DPRINTF("command line set %s to |%s|\n", s, p);
|
DPRINTF("command line set %s to |%s|\n", s, p);
|
||||||
|
free(p);
|
||||||
*e = '=';
|
*e = '=';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -344,9 +399,9 @@ void fldbld(void) /* create fields from current record */
|
||||||
i = 0; /* number of fields accumulated here */
|
i = 0; /* number of fields accumulated here */
|
||||||
if (inputFS == NULL) /* make sure we have a copy of FS */
|
if (inputFS == NULL) /* make sure we have a copy of FS */
|
||||||
savefs();
|
savefs();
|
||||||
if (strlen(inputFS) > 1) { /* it's a regular expression */
|
if (!CSV && strlen(inputFS) > 1) { /* it's a regular expression */
|
||||||
i = refldbld(r, inputFS);
|
i = refldbld(r, inputFS);
|
||||||
} else if ((sep = *inputFS) == ' ') { /* default whitespace */
|
} else if (!CSV && (sep = *inputFS) == ' ') { /* default whitespace */
|
||||||
for (i = 0; ; ) {
|
for (i = 0; ; ) {
|
||||||
while (*r == ' ' || *r == '\t' || *r == '\n')
|
while (*r == ' ' || *r == '\t' || *r == '\n')
|
||||||
r++;
|
r++;
|
||||||
|
@ -365,26 +420,58 @@ void fldbld(void) /* create fields from current record */
|
||||||
*fr++ = 0;
|
*fr++ = 0;
|
||||||
}
|
}
|
||||||
*fr = 0;
|
*fr = 0;
|
||||||
} else if ((sep = *inputFS) == 0) { /* new: FS="" => 1 char/field */
|
} else if (CSV) { /* CSV processing. no error handling */
|
||||||
for (i = 0; *r != '\0'; r += n) {
|
if (*r != 0) {
|
||||||
char buf[MB_LEN_MAX + 1];
|
for (;;) {
|
||||||
|
i++;
|
||||||
|
if (i > nfields)
|
||||||
|
growfldtab(i);
|
||||||
|
if (freeable(fldtab[i]))
|
||||||
|
xfree(fldtab[i]->sval);
|
||||||
|
fldtab[i]->sval = fr;
|
||||||
|
fldtab[i]->tval = FLD | STR | DONTFREE;
|
||||||
|
if (*r == '"' ) { /* start of "..." */
|
||||||
|
for (r++ ; *r != '\0'; ) {
|
||||||
|
if (*r == '"' && r[1] != '\0' && r[1] == '"') {
|
||||||
|
r += 2; /* doubled quote */
|
||||||
|
*fr++ = '"';
|
||||||
|
} else if (*r == '"' && (r[1] == '\0' || r[1] == ',')) {
|
||||||
|
r++; /* skip over closing quote */
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
*fr++ = *r++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*fr++ = 0;
|
||||||
|
} else { /* unquoted field */
|
||||||
|
while (*r != ',' && *r != '\0')
|
||||||
|
*fr++ = *r++;
|
||||||
|
*fr++ = 0;
|
||||||
|
}
|
||||||
|
if (*r++ == 0)
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*fr = 0;
|
||||||
|
} else if ((sep = *inputFS) == 0) { /* new: FS="" => 1 char/field */
|
||||||
|
for (i = 0; *r != '\0'; ) {
|
||||||
|
char buf[10];
|
||||||
i++;
|
i++;
|
||||||
if (i > nfields)
|
if (i > nfields)
|
||||||
growfldtab(i);
|
growfldtab(i);
|
||||||
if (freeable(fldtab[i]))
|
if (freeable(fldtab[i]))
|
||||||
xfree(fldtab[i]->sval);
|
xfree(fldtab[i]->sval);
|
||||||
n = mblen(r, MB_LEN_MAX);
|
n = u8_nextlen(r);
|
||||||
if (n < 0)
|
for (j = 0; j < n; j++)
|
||||||
n = 1;
|
buf[j] = *r++;
|
||||||
memcpy(buf, r, n);
|
buf[j] = '\0';
|
||||||
buf[n] = '\0';
|
|
||||||
fldtab[i]->sval = tostring(buf);
|
fldtab[i]->sval = tostring(buf);
|
||||||
fldtab[i]->tval = FLD | STR;
|
fldtab[i]->tval = FLD | STR;
|
||||||
}
|
}
|
||||||
*fr = 0;
|
*fr = 0;
|
||||||
} else if (*r != 0) { /* if 0, it's a null field */
|
} else if (*r != 0) { /* if 0, it's a null field */
|
||||||
/* subtlecase : if length(FS) == 1 && length(RS > 0)
|
/* subtle case: if length(FS) == 1 && length(RS > 0)
|
||||||
* \n is NOT a field separator (cf awk book 61,84).
|
* \n is NOT a field separator (cf awk book 61,84).
|
||||||
* this variable is tested in the inner while loop.
|
* this variable is tested in the inner while loop.
|
||||||
*/
|
*/
|
||||||
|
@ -587,11 +674,9 @@ void yyerror(const char *s)
|
||||||
SYNTAX("%s", s);
|
SYNTAX("%s", s);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern char *cmdname;
|
|
||||||
|
|
||||||
void SYNTAX(const char *fmt, ...)
|
void SYNTAX(const char *fmt, ...)
|
||||||
{
|
{
|
||||||
extern char *curfname;
|
extern char *cmdname, *curfname;
|
||||||
static int been_here = 0;
|
static int been_here = 0;
|
||||||
va_list varg;
|
va_list varg;
|
||||||
|
|
||||||
|
@ -641,6 +726,7 @@ void bcheck2(int n, int c1, int c2)
|
||||||
|
|
||||||
void FATAL(const char *fmt, ...)
|
void FATAL(const char *fmt, ...)
|
||||||
{
|
{
|
||||||
|
extern char *cmdname;
|
||||||
va_list varg;
|
va_list varg;
|
||||||
|
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
@ -656,6 +742,7 @@ void FATAL(const char *fmt, ...)
|
||||||
|
|
||||||
void WARNING(const char *fmt, ...)
|
void WARNING(const char *fmt, ...)
|
||||||
{
|
{
|
||||||
|
extern char *cmdname;
|
||||||
va_list varg;
|
va_list varg;
|
||||||
|
|
||||||
fflush(stdout);
|
fflush(stdout);
|
||||||
|
@ -758,10 +845,10 @@ int isclvar(const char *s) /* is s of form var=something ? */
|
||||||
{
|
{
|
||||||
const char *os = s;
|
const char *os = s;
|
||||||
|
|
||||||
if (!isalpha((uschar) *s) && *s != '_')
|
if (!isalpha((int) *s) && *s != '_')
|
||||||
return 0;
|
return 0;
|
||||||
for ( ; *s; s++)
|
for ( ; *s; s++)
|
||||||
if (!(isalnum((uschar) *s) || *s == '_'))
|
if (!(isalnum((int) *s) || *s == '_'))
|
||||||
break;
|
break;
|
||||||
return *s == '=' && s > os;
|
return *s == '=' && s > os;
|
||||||
}
|
}
|
||||||
|
@ -796,19 +883,19 @@ bool is_valid_number(const char *s, bool trailing_stuff_ok,
|
||||||
if (no_trailing)
|
if (no_trailing)
|
||||||
*no_trailing = false;
|
*no_trailing = false;
|
||||||
|
|
||||||
while (isspace(*s))
|
while (isspace((int) *s))
|
||||||
s++;
|
s++;
|
||||||
|
|
||||||
// no hex floating point, sorry
|
/* no hex floating point, sorry */
|
||||||
if (s[0] == '0' && tolower(s[1]) == 'x')
|
if (s[0] == '0' && tolower(s[1]) == 'x')
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// allow +nan, -nan, +inf, -inf, any other letter, no
|
/* allow +nan, -nan, +inf, -inf, any other letter, no */
|
||||||
if (s[0] == '+' || s[0] == '-') {
|
if (s[0] == '+' || s[0] == '-') {
|
||||||
is_nan = (strncasecmp(s+1, "nan", 3) == 0);
|
is_nan = (strncasecmp(s+1, "nan", 3) == 0);
|
||||||
is_inf = (strncasecmp(s+1, "inf", 3) == 0);
|
is_inf = (strncasecmp(s+1, "inf", 3) == 0);
|
||||||
if ((is_nan || is_inf)
|
if ((is_nan || is_inf)
|
||||||
&& (isspace(s[4]) || s[4] == '\0'))
|
&& (isspace((int) s[4]) || s[4] == '\0'))
|
||||||
goto convert;
|
goto convert;
|
||||||
else if (! isdigit(s[1]) && s[1] != '.')
|
else if (! isdigit(s[1]) && s[1] != '.')
|
||||||
return false;
|
return false;
|
||||||
|
@ -831,13 +918,13 @@ convert:
|
||||||
/*
|
/*
|
||||||
* check for trailing stuff
|
* check for trailing stuff
|
||||||
*/
|
*/
|
||||||
while (isspace(*ep))
|
while (isspace((int) *ep))
|
||||||
ep++;
|
ep++;
|
||||||
|
|
||||||
if (no_trailing != NULL)
|
if (no_trailing != NULL)
|
||||||
*no_trailing = (*ep == '\0');
|
*no_trailing = (*ep == '\0');
|
||||||
|
|
||||||
// return true if found the end, or trailing stuff is allowed
|
/* return true if found the end, or trailing stuff is allowed */
|
||||||
retval = *ep == '\0' || trailing_stuff_ok;
|
retval = *ep == '\0' || trailing_stuff_ok;
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
|
|
147
third_party/awk/main.c
vendored
147
third_party/awk/main.c
vendored
|
@ -1,46 +1,5 @@
|
||||||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
__notice(awk_license, "\
|
||||||
│ vi: set noet ft=c ts=8 sw=8 fenc=utf-8 :vi │
|
/****************************************************************\n\
|
||||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
|
||||||
│ │
|
|
||||||
│ Copyright (C) Lucent Technologies 1997 │
|
|
||||||
│ All Rights Reserved │
|
|
||||||
│ │
|
|
||||||
│ Permission to use, copy, modify, and distribute this software and │
|
|
||||||
│ its documentation for any purpose and without fee is hereby │
|
|
||||||
│ granted, provided that the above copyright notice appear in all │
|
|
||||||
│ copies and that both that the copyright notice and this │
|
|
||||||
│ permission notice and warranty disclaimer appear in supporting │
|
|
||||||
│ documentation, and that the name Lucent Technologies or any of │
|
|
||||||
│ its entities not be used in advertising or publicity pertaining │
|
|
||||||
│ to distribution of the software without specific, written prior │
|
|
||||||
│ permission. │
|
|
||||||
│ │
|
|
||||||
│ LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, │
|
|
||||||
│ INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. │
|
|
||||||
│ IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY │
|
|
||||||
│ SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES │
|
|
||||||
│ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER │
|
|
||||||
│ IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, │
|
|
||||||
│ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF │
|
|
||||||
│ THIS SOFTWARE. │
|
|
||||||
│ │
|
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
|
||||||
#define DEBUG
|
|
||||||
#include "libc/calls/calls.h"
|
|
||||||
#include "libc/calls/struct/sigaction.h"
|
|
||||||
#include "libc/calls/struct/siginfo.h"
|
|
||||||
#include "libc/mem/mem.h"
|
|
||||||
#include "libc/runtime/runtime.h"
|
|
||||||
#include "libc/stdio/rand.h"
|
|
||||||
#include "libc/str/locale.h"
|
|
||||||
#include "libc/str/str.h"
|
|
||||||
#include "libc/sysv/consts/sa.h"
|
|
||||||
#include "libc/sysv/consts/sicode.h"
|
|
||||||
#include "libc/sysv/consts/sig.h"
|
|
||||||
#include "third_party/awk/awk.h"
|
|
||||||
|
|
||||||
__notice(awk_notice, "\
|
|
||||||
The One True Awk\n\
|
|
||||||
Copyright (C) Lucent Technologies 1997\n\
|
Copyright (C) Lucent Technologies 1997\n\
|
||||||
All Rights Reserved\n\
|
All Rights Reserved\n\
|
||||||
\n\
|
\n\
|
||||||
|
@ -61,9 +20,21 @@ SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES\n\
|
||||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER\n\
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER\n\
|
||||||
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,\n\
|
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,\n\
|
||||||
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF\n\
|
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF\n\
|
||||||
THIS SOFTWARE.");
|
THIS SOFTWARE.\n\
|
||||||
|
****************************************************************/");
|
||||||
|
|
||||||
const char *version = "version 20220530";
|
const char *version = "version 20240311";
|
||||||
|
|
||||||
|
#define DEBUG
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
#include <locale.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <signal.h>
|
||||||
|
#include "awk.h"
|
||||||
|
|
||||||
|
extern char **environ;
|
||||||
extern int nfields;
|
extern int nfields;
|
||||||
|
|
||||||
int dbg = 0;
|
int dbg = 0;
|
||||||
|
@ -71,6 +42,7 @@ Awkfloat srand_seed = 1;
|
||||||
char *cmdname; /* gets argv[0] for error messages */
|
char *cmdname; /* gets argv[0] for error messages */
|
||||||
extern FILE *yyin; /* lex input file */
|
extern FILE *yyin; /* lex input file */
|
||||||
char *lexprog; /* points to program argument if it exists */
|
char *lexprog; /* points to program argument if it exists */
|
||||||
|
extern int errorflag; /* non-zero if any syntax errors; set by yyerror */
|
||||||
enum compile_states compile_time = ERROR_PRINTING;
|
enum compile_states compile_time = ERROR_PRINTING;
|
||||||
|
|
||||||
static char **pfile; /* program filenames from -f's */
|
static char **pfile; /* program filenames from -f's */
|
||||||
|
@ -78,23 +50,37 @@ static size_t maxpfile; /* max program filename */
|
||||||
static size_t npfile; /* number of filenames */
|
static size_t npfile; /* number of filenames */
|
||||||
static size_t curpfile; /* current filename */
|
static size_t curpfile; /* current filename */
|
||||||
|
|
||||||
|
bool CSV = false; /* true for csv input */
|
||||||
|
|
||||||
bool safe = false; /* true => "safe" mode */
|
bool safe = false; /* true => "safe" mode */
|
||||||
|
|
||||||
static wontreturn void fpecatch(int n, siginfo_t *si, void *uc)
|
size_t awk_mb_cur_max = 1;
|
||||||
|
|
||||||
|
static noreturn void fpecatch(int n
|
||||||
|
#ifdef SA_SIGINFO
|
||||||
|
, siginfo_t *si, void *uc
|
||||||
|
#endif
|
||||||
|
)
|
||||||
{
|
{
|
||||||
const char *emsg[10];
|
#ifdef SA_SIGINFOz
|
||||||
emsg[0] = "Unknown error";
|
static const char *emsg[] = {
|
||||||
emsg[FPE_INTDIV] = "Integer divide by zero";
|
[0] = "Unknown error",
|
||||||
emsg[FPE_INTOVF] = "Integer overflow";
|
[FPE_INTDIV] = "Integer divide by zero",
|
||||||
emsg[FPE_FLTDIV] = "Floating point divide by zero";
|
[FPE_INTOVF] = "Integer overflow",
|
||||||
emsg[FPE_FLTOVF] = "Floating point overflow";
|
[FPE_FLTDIV] = "Floating point divide by zero",
|
||||||
emsg[FPE_FLTUND] = "Floating point underflow";
|
[FPE_FLTOVF] = "Floating point overflow",
|
||||||
emsg[FPE_FLTRES] = "Floating point inexact result";
|
[FPE_FLTUND] = "Floating point underflow",
|
||||||
emsg[FPE_FLTINV] = "Invalid Floating point operation";
|
[FPE_FLTRES] = "Floating point inexact result",
|
||||||
emsg[FPE_FLTSUB] = "Subscript out of range";
|
[FPE_FLTINV] = "Invalid Floating point operation",
|
||||||
FATAL("floating point exception: %s",
|
[FPE_FLTSUB] = "Subscript out of range",
|
||||||
(size_t)si->si_code < sizeof(emsg) / sizeof(emsg[0]) &&
|
};
|
||||||
emsg[si->si_code] ? emsg[si->si_code] : emsg[0]);
|
#endif
|
||||||
|
FATAL("floating point exception"
|
||||||
|
#ifdef SA_SIGINFOz
|
||||||
|
": %s", (size_t)si->si_code < sizeof(emsg) / sizeof(emsg[0]) &&
|
||||||
|
emsg[si->si_code] ? emsg[si->si_code] : emsg[0]
|
||||||
|
#endif
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Can this work with recursive calls? I don't think so.
|
/* Can this work with recursive calls? I don't think so.
|
||||||
|
@ -129,30 +115,30 @@ getarg(int *argc, char ***argv, const char *msg)
|
||||||
int _awk(int argc, char *argv[])
|
int _awk(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
const char *fs = NULL;
|
const char *fs = NULL;
|
||||||
struct sigaction sa;
|
|
||||||
char *fn, *vn;
|
char *fn, *vn;
|
||||||
|
|
||||||
setlocale(LC_CTYPE, "");
|
setlocale(LC_CTYPE, "");
|
||||||
setlocale(LC_NUMERIC, "C"); /* for parsing cmdline & prog */
|
setlocale(LC_NUMERIC, "C"); /* for parsing cmdline & prog */
|
||||||
|
awk_mb_cur_max = MB_CUR_MAX;
|
||||||
cmdname = argv[0];
|
cmdname = argv[0];
|
||||||
|
|
||||||
if (pledge("stdio rpath wpath cpath proc exec", NULL) == -1) {
|
|
||||||
fprintf(stderr, "%s: pledge: incorrect arguments\n",
|
|
||||||
cmdname);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (argc == 1) {
|
if (argc == 1) {
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"usage: %s [-F fs] [-v var=value] [-f progfile | 'prog'] [file ...]\n",
|
"usage: %s [-F fs | --csv] [-v var=value] [-f progfile | 'prog'] [file ...]\n",
|
||||||
cmdname);
|
cmdname);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
#ifdef SA_SIGINFO
|
||||||
sa.sa_sigaction = fpecatch;
|
{
|
||||||
sa.sa_flags = SA_SIGINFO;
|
struct sigaction sa;
|
||||||
sigemptyset(&sa.sa_mask);
|
sa.sa_sigaction = fpecatch;
|
||||||
(void)sigaction(SIGFPE, &sa, NULL);
|
sa.sa_flags = SA_SIGINFO;
|
||||||
|
sigemptyset(&sa.sa_mask);
|
||||||
|
(void)sigaction(SIGFPE, &sa, NULL);
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
(void)signal(SIGFPE, fpecatch);
|
||||||
|
#endif
|
||||||
|
/*signal(SIGSEGV, segvcatch); experiment */
|
||||||
|
|
||||||
/* Set and keep track of the random seed */
|
/* Set and keep track of the random seed */
|
||||||
srand_seed = 1;
|
srand_seed = 1;
|
||||||
|
@ -170,6 +156,12 @@ int _awk(int argc, char *argv[])
|
||||||
argv++;
|
argv++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (strcmp(argv[1], "--csv") == 0) { /* turn on csv input processing */
|
||||||
|
CSV = true;
|
||||||
|
argc--;
|
||||||
|
argv++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
switch (argv[1][1]) {
|
switch (argv[1][1]) {
|
||||||
case 's':
|
case 's':
|
||||||
if (strcmp(argv[1], "-safe") == 0)
|
if (strcmp(argv[1], "-safe") == 0)
|
||||||
|
@ -208,6 +200,10 @@ int _awk(int argc, char *argv[])
|
||||||
argc--;
|
argc--;
|
||||||
argv++;
|
argv++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (CSV && (fs != NULL || lookup("FS", symtab) != NULL))
|
||||||
|
WARNING("danger: don't set FS when --csv is in effect");
|
||||||
|
|
||||||
/* argv[1] is now the first argument */
|
/* argv[1] is now the first argument */
|
||||||
if (npfile == 0) { /* no -f; first argument is program */
|
if (npfile == 0) { /* no -f; first argument is program */
|
||||||
if (argc <= 1) {
|
if (argc <= 1) {
|
||||||
|
@ -229,6 +225,11 @@ int _awk(int argc, char *argv[])
|
||||||
if (!safe)
|
if (!safe)
|
||||||
envinit(environ);
|
envinit(environ);
|
||||||
yyparse();
|
yyparse();
|
||||||
|
#if 0
|
||||||
|
// Doing this would comply with POSIX, but is not compatible with
|
||||||
|
// other awks and with what most users expect. So comment it out.
|
||||||
|
setlocale(LC_NUMERIC, ""); /* back to whatever it is locally */
|
||||||
|
#endif
|
||||||
if (fs)
|
if (fs)
|
||||||
*FS = qstring(fs, '\0');
|
*FS = qstring(fs, '\0');
|
||||||
DPRINTF("errorflag=%d\n", errorflag);
|
DPRINTF("errorflag=%d\n", errorflag);
|
||||||
|
|
66
third_party/awk/maketab.c
vendored
66
third_party/awk/maketab.c
vendored
|
@ -1,36 +1,26 @@
|
||||||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
/****************************************************************
|
||||||
│ vi: set noet ft=c ts=8 sw=8 fenc=utf-8 :vi │
|
Copyright (C) Lucent Technologies 1997
|
||||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
All Rights Reserved
|
||||||
│ │
|
|
||||||
│ Copyright (C) Lucent Technologies 1997 │
|
Permission to use, copy, modify, and distribute this software and
|
||||||
│ All Rights Reserved │
|
its documentation for any purpose and without fee is hereby
|
||||||
│ │
|
granted, provided that the above copyright notice appear in all
|
||||||
│ Permission to use, copy, modify, and distribute this software and │
|
copies and that both that the copyright notice and this
|
||||||
│ its documentation for any purpose and without fee is hereby │
|
permission notice and warranty disclaimer appear in supporting
|
||||||
│ granted, provided that the above copyright notice appear in all │
|
documentation, and that the name Lucent Technologies or any of
|
||||||
│ copies and that both that the copyright notice and this │
|
its entities not be used in advertising or publicity pertaining
|
||||||
│ permission notice and warranty disclaimer appear in supporting │
|
to distribution of the software without specific, written prior
|
||||||
│ documentation, and that the name Lucent Technologies or any of │
|
permission.
|
||||||
│ its entities not be used in advertising or publicity pertaining │
|
|
||||||
│ to distribution of the software without specific, written prior │
|
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||||
│ permission. │
|
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
|
||||||
│ │
|
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
|
||||||
│ LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, │
|
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
│ INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. │
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
|
||||||
│ IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY │
|
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||||
│ SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES │
|
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
│ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER │
|
THIS SOFTWARE.
|
||||||
│ IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, │
|
****************************************************************/
|
||||||
│ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF │
|
|
||||||
│ THIS SOFTWARE. │
|
|
||||||
│ │
|
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
|
||||||
#include "libc/mem/mem.h"
|
|
||||||
#include "libc/runtime/runtime.h"
|
|
||||||
#include "libc/stdio/stdio.h"
|
|
||||||
#include "libc/str/str.h"
|
|
||||||
#include "third_party/awk/awk.h"
|
|
||||||
#include "third_party/awk/awkgram.tab.h"
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* this program makes the table to link function names
|
* this program makes the table to link function names
|
||||||
|
@ -38,6 +28,12 @@
|
||||||
* it finds the indices in awkgram.tab.h, produced by bison.
|
* it finds the indices in awkgram.tab.h, produced by bison.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "awk.h"
|
||||||
|
#include "awkgram.tab.h"
|
||||||
|
|
||||||
struct xx
|
struct xx
|
||||||
{ int token;
|
{ int token;
|
||||||
const char *name;
|
const char *name;
|
||||||
|
@ -56,8 +52,8 @@ struct xx
|
||||||
{ ARRAY, "array", NULL },
|
{ ARRAY, "array", NULL },
|
||||||
{ INDIRECT, "indirect", "$(" },
|
{ INDIRECT, "indirect", "$(" },
|
||||||
{ SUBSTR, "substr", "substr" },
|
{ SUBSTR, "substr", "substr" },
|
||||||
{ SUB, "sub", "sub" },
|
{ SUB, "dosub", "sub" },
|
||||||
{ GSUB, "gsub", "gsub" },
|
{ GSUB, "dosub", "gsub" },
|
||||||
{ INDEX, "sindex", "sindex" },
|
{ INDEX, "sindex", "sindex" },
|
||||||
{ SPRINTF, "awksprintf", "sprintf " },
|
{ SPRINTF, "awksprintf", "sprintf " },
|
||||||
{ ADD, "arith", " + " },
|
{ ADD, "arith", " + " },
|
||||||
|
|
64
third_party/awk/parse.c
vendored
64
third_party/awk/parse.c
vendored
|
@ -1,37 +1,35 @@
|
||||||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
/****************************************************************
|
||||||
│ vi: set noet ft=c ts=8 sw=8 fenc=utf-8 :vi │
|
Copyright (C) Lucent Technologies 1997
|
||||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
All Rights Reserved
|
||||||
│ │
|
|
||||||
│ Copyright (C) Lucent Technologies 1997 │
|
|
||||||
│ All Rights Reserved │
|
|
||||||
│ │
|
|
||||||
│ Permission to use, copy, modify, and distribute this software and │
|
|
||||||
│ its documentation for any purpose and without fee is hereby │
|
|
||||||
│ granted, provided that the above copyright notice appear in all │
|
|
||||||
│ copies and that both that the copyright notice and this │
|
|
||||||
│ permission notice and warranty disclaimer appear in supporting │
|
|
||||||
│ documentation, and that the name Lucent Technologies or any of │
|
|
||||||
│ its entities not be used in advertising or publicity pertaining │
|
|
||||||
│ to distribution of the software without specific, written prior │
|
|
||||||
│ permission. │
|
|
||||||
│ │
|
|
||||||
│ LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, │
|
|
||||||
│ INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. │
|
|
||||||
│ IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY │
|
|
||||||
│ SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES │
|
|
||||||
│ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER │
|
|
||||||
│ IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, │
|
|
||||||
│ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF │
|
|
||||||
│ THIS SOFTWARE. │
|
|
||||||
│ │
|
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
|
||||||
#define DEBUG
|
|
||||||
#include "libc/mem/mem.h"
|
|
||||||
#include "libc/str/str.h"
|
|
||||||
#include "third_party/awk/awk.h"
|
|
||||||
#include "third_party/awk/awkgram.tab.h"
|
|
||||||
|
|
||||||
Node *nodealloc(int n)
|
Permission to use, copy, modify, and distribute this software and
|
||||||
|
its documentation for any purpose and without fee is hereby
|
||||||
|
granted, provided that the above copyright notice appear in all
|
||||||
|
copies and that both that the copyright notice and this
|
||||||
|
permission notice and warranty disclaimer appear in supporting
|
||||||
|
documentation, and that the name Lucent Technologies or any of
|
||||||
|
its entities not be used in advertising or publicity pertaining
|
||||||
|
to distribution of the software without specific, written prior
|
||||||
|
permission.
|
||||||
|
|
||||||
|
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||||
|
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
|
||||||
|
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
|
||||||
|
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||||
|
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
THIS SOFTWARE.
|
||||||
|
****************************************************************/
|
||||||
|
|
||||||
|
#define DEBUG
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include "awk.h"
|
||||||
|
#include "awkgram.tab.h"
|
||||||
|
|
||||||
|
Node *nodealloc(size_t n)
|
||||||
{
|
{
|
||||||
Node *x;
|
Node *x;
|
||||||
|
|
||||||
|
|
36
third_party/awk/proctab.c
vendored
36
third_party/awk/proctab.c
vendored
|
@ -1,32 +1,6 @@
|
||||||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
#include <stdio.h>
|
||||||
│ vi: set noet ft=c ts=8 sw=8 fenc=utf-8 :vi │
|
#include "awk.h"
|
||||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
#include "awkgram.tab.h"
|
||||||
│ │
|
|
||||||
│ Copyright (C) Lucent Technologies 1997 │
|
|
||||||
│ All Rights Reserved │
|
|
||||||
│ │
|
|
||||||
│ Permission to use, copy, modify, and distribute this software and │
|
|
||||||
│ its documentation for any purpose and without fee is hereby │
|
|
||||||
│ granted, provided that the above copyright notice appear in all │
|
|
||||||
│ copies and that both that the copyright notice and this │
|
|
||||||
│ permission notice and warranty disclaimer appear in supporting │
|
|
||||||
│ documentation, and that the name Lucent Technologies or any of │
|
|
||||||
│ its entities not be used in advertising or publicity pertaining │
|
|
||||||
│ to distribution of the software without specific, written prior │
|
|
||||||
│ permission. │
|
|
||||||
│ │
|
|
||||||
│ LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, │
|
|
||||||
│ INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. │
|
|
||||||
│ IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY │
|
|
||||||
│ SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES │
|
|
||||||
│ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER │
|
|
||||||
│ IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, │
|
|
||||||
│ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF │
|
|
||||||
│ THIS SOFTWARE. │
|
|
||||||
│ │
|
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
|
||||||
#include "third_party/awk/awk.h"
|
|
||||||
#include "third_party/awk/awkgram.tab.h"
|
|
||||||
|
|
||||||
static const char * const printname[95] = {
|
static const char * const printname[95] = {
|
||||||
"FIRSTTOKEN", /* 258 */
|
"FIRSTTOKEN", /* 258 */
|
||||||
|
@ -171,8 +145,8 @@ Cell *(*proctab[95])(Node **, int) = {
|
||||||
jump, /* EXIT */
|
jump, /* EXIT */
|
||||||
forstat, /* FOR */
|
forstat, /* FOR */
|
||||||
nullproc, /* FUNC */
|
nullproc, /* FUNC */
|
||||||
sub, /* SUB */
|
dosub, /* SUB */
|
||||||
gsub, /* GSUB */
|
dosub, /* GSUB */
|
||||||
ifstat, /* IF */
|
ifstat, /* IF */
|
||||||
sindex, /* INDEX */
|
sindex, /* INDEX */
|
||||||
nullproc, /* LSUBSTR */
|
nullproc, /* LSUBSTR */
|
||||||
|
|
204
third_party/awk/proto.h
vendored
Normal file
204
third_party/awk/proto.h
vendored
Normal file
|
@ -0,0 +1,204 @@
|
||||||
|
/****************************************************************
|
||||||
|
Copyright (C) Lucent Technologies 1997
|
||||||
|
All Rights Reserved
|
||||||
|
|
||||||
|
Permission to use, copy, modify, and distribute this software and
|
||||||
|
its documentation for any purpose and without fee is hereby
|
||||||
|
granted, provided that the above copyright notice appear in all
|
||||||
|
copies and that both that the copyright notice and this
|
||||||
|
permission notice and warranty disclaimer appear in supporting
|
||||||
|
documentation, and that the name Lucent Technologies or any of
|
||||||
|
its entities not be used in advertising or publicity pertaining
|
||||||
|
to distribution of the software without specific, written prior
|
||||||
|
permission.
|
||||||
|
|
||||||
|
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||||
|
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
|
||||||
|
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
|
||||||
|
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
|
||||||
|
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||||
|
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
|
THIS SOFTWARE.
|
||||||
|
****************************************************************/
|
||||||
|
|
||||||
|
extern int yywrap(void);
|
||||||
|
extern void setfname(Cell *);
|
||||||
|
extern int constnode(Node *);
|
||||||
|
extern char *strnode(Node *);
|
||||||
|
extern Node *notnull(Node *);
|
||||||
|
extern int yyparse(void);
|
||||||
|
|
||||||
|
extern int yylex(void);
|
||||||
|
extern void startreg(void);
|
||||||
|
extern int input(void);
|
||||||
|
extern void unput(int);
|
||||||
|
extern void unputstr(const char *);
|
||||||
|
extern int yylook(void);
|
||||||
|
extern int yyback(int *, int);
|
||||||
|
extern int yyinput(void);
|
||||||
|
|
||||||
|
extern fa *makedfa(const char *, bool);
|
||||||
|
extern fa *mkdfa(const char *, bool);
|
||||||
|
extern int makeinit(fa *, bool);
|
||||||
|
extern void penter(Node *);
|
||||||
|
extern void freetr(Node *);
|
||||||
|
extern int quoted(const uschar **);
|
||||||
|
extern int *cclenter(const char *);
|
||||||
|
extern noreturn void overflo(const char *);
|
||||||
|
extern void cfoll(fa *, Node *);
|
||||||
|
extern int first(Node *);
|
||||||
|
extern void follow(Node *);
|
||||||
|
extern int member(int, int *);
|
||||||
|
extern int match(fa *, const char *);
|
||||||
|
extern int pmatch(fa *, const char *);
|
||||||
|
extern int nematch(fa *, const char *);
|
||||||
|
extern bool fnematch(fa *, FILE *, char **, int *, int);
|
||||||
|
extern Node *reparse(const char *);
|
||||||
|
extern Node *regexp(void);
|
||||||
|
extern Node *primary(void);
|
||||||
|
extern Node *concat(Node *);
|
||||||
|
extern Node *alt(Node *);
|
||||||
|
extern Node *unary(Node *);
|
||||||
|
extern int relex(void);
|
||||||
|
extern int cgoto(fa *, int, int);
|
||||||
|
extern void freefa(fa *);
|
||||||
|
|
||||||
|
extern int pgetc(void);
|
||||||
|
extern char *cursource(void);
|
||||||
|
|
||||||
|
extern Node *nodealloc(size_t);
|
||||||
|
extern Node *exptostat(Node *);
|
||||||
|
extern Node *node1(int, Node *);
|
||||||
|
extern Node *node2(int, Node *, Node *);
|
||||||
|
extern Node *node3(int, Node *, Node *, Node *);
|
||||||
|
extern Node *node4(int, Node *, Node *, Node *, Node *);
|
||||||
|
extern Node *stat3(int, Node *, Node *, Node *);
|
||||||
|
extern Node *op2(int, Node *, Node *);
|
||||||
|
extern Node *op1(int, Node *);
|
||||||
|
extern Node *stat1(int, Node *);
|
||||||
|
extern Node *op3(int, Node *, Node *, Node *);
|
||||||
|
extern Node *op4(int, Node *, Node *, Node *, Node *);
|
||||||
|
extern Node *stat2(int, Node *, Node *);
|
||||||
|
extern Node *stat4(int, Node *, Node *, Node *, Node *);
|
||||||
|
extern Node *celltonode(Cell *, int);
|
||||||
|
extern Node *rectonode(void);
|
||||||
|
extern Node *makearr(Node *);
|
||||||
|
extern Node *pa2stat(Node *, Node *, Node *);
|
||||||
|
extern Node *linkum(Node *, Node *);
|
||||||
|
extern void defn(Cell *, Node *, Node *);
|
||||||
|
extern int isarg(const char *);
|
||||||
|
extern const char *tokname(int);
|
||||||
|
extern Cell *(*proctab[])(Node **, int);
|
||||||
|
extern int ptoi(void *);
|
||||||
|
extern Node *itonp(int);
|
||||||
|
|
||||||
|
extern void syminit(void);
|
||||||
|
extern void arginit(int, char **);
|
||||||
|
extern void envinit(char **);
|
||||||
|
extern Array *makesymtab(int);
|
||||||
|
extern void freesymtab(Cell *);
|
||||||
|
extern void freeelem(Cell *, const char *);
|
||||||
|
extern Cell *setsymtab(const char *, const char *, double, unsigned int, Array *);
|
||||||
|
extern int hash(const char *, int);
|
||||||
|
extern void rehash(Array *);
|
||||||
|
extern Cell *lookup(const char *, Array *);
|
||||||
|
extern double setfval(Cell *, double);
|
||||||
|
extern void funnyvar(Cell *, const char *);
|
||||||
|
extern char *setsval(Cell *, const char *);
|
||||||
|
extern double getfval(Cell *);
|
||||||
|
extern char *getsval(Cell *);
|
||||||
|
extern char *getpssval(Cell *); /* for print */
|
||||||
|
extern char *tostring(const char *);
|
||||||
|
extern char *tostringN(const char *, size_t);
|
||||||
|
extern char *qstring(const char *, int);
|
||||||
|
extern Cell *catstr(Cell *, Cell *);
|
||||||
|
|
||||||
|
extern void recinit(unsigned int);
|
||||||
|
extern void initgetrec(void);
|
||||||
|
extern void makefields(int, int);
|
||||||
|
extern void growfldtab(int n);
|
||||||
|
extern void savefs(void);
|
||||||
|
extern int getrec(char **, int *, bool);
|
||||||
|
extern void nextfile(void);
|
||||||
|
extern int readrec(char **buf, int *bufsize, FILE *inf, bool isnew);
|
||||||
|
extern char *getargv(int);
|
||||||
|
extern void setclvar(char *);
|
||||||
|
extern void fldbld(void);
|
||||||
|
extern void cleanfld(int, int);
|
||||||
|
extern void newfld(int);
|
||||||
|
extern void setlastfld(int);
|
||||||
|
extern int refldbld(const char *, const char *);
|
||||||
|
extern void recbld(void);
|
||||||
|
extern Cell *fieldadr(int);
|
||||||
|
extern void yyerror(const char *);
|
||||||
|
extern void bracecheck(void);
|
||||||
|
extern void bcheck2(int, int, int);
|
||||||
|
extern void SYNTAX(const char *, ...)
|
||||||
|
__attribute__((__format__(__printf__, 1, 2)));
|
||||||
|
extern noreturn void FATAL(const char *, ...)
|
||||||
|
__attribute__((__format__(__printf__, 1, 2)));
|
||||||
|
extern void WARNING(const char *, ...)
|
||||||
|
__attribute__((__format__(__printf__, 1, 2)));
|
||||||
|
extern void error(void);
|
||||||
|
extern void eprint(void);
|
||||||
|
extern void bclass(int);
|
||||||
|
extern double errcheck(double, const char *);
|
||||||
|
extern int isclvar(const char *);
|
||||||
|
extern bool is_valid_number(const char *s, bool trailing_stuff_ok,
|
||||||
|
bool *no_trailing, double *result);
|
||||||
|
#define is_number(s, val) is_valid_number(s, false, NULL, val)
|
||||||
|
|
||||||
|
extern int adjbuf(char **pb, int *sz, int min, int q, char **pbp, const char *what);
|
||||||
|
extern void run(Node *);
|
||||||
|
extern Cell *execute(Node *);
|
||||||
|
extern Cell *program(Node **, int);
|
||||||
|
extern Cell *call(Node **, int);
|
||||||
|
extern Cell *copycell(Cell *);
|
||||||
|
extern Cell *arg(Node **, int);
|
||||||
|
extern Cell *jump(Node **, int);
|
||||||
|
extern Cell *awkgetline(Node **, int);
|
||||||
|
extern Cell *getnf(Node **, int);
|
||||||
|
extern Cell *array(Node **, int);
|
||||||
|
extern Cell *awkdelete(Node **, int);
|
||||||
|
extern Cell *intest(Node **, int);
|
||||||
|
extern Cell *matchop(Node **, int);
|
||||||
|
extern Cell *boolop(Node **, int);
|
||||||
|
extern Cell *relop(Node **, int);
|
||||||
|
extern void tfree(Cell *);
|
||||||
|
extern Cell *gettemp(void);
|
||||||
|
extern Cell *field(Node **, int);
|
||||||
|
extern Cell *indirect(Node **, int);
|
||||||
|
extern Cell *substr(Node **, int);
|
||||||
|
extern Cell *sindex(Node **, int);
|
||||||
|
extern int format(char **, int *, const char *, Node *);
|
||||||
|
extern Cell *awksprintf(Node **, int);
|
||||||
|
extern Cell *awkprintf(Node **, int);
|
||||||
|
extern Cell *arith(Node **, int);
|
||||||
|
extern double ipow(double, int);
|
||||||
|
extern Cell *incrdecr(Node **, int);
|
||||||
|
extern Cell *assign(Node **, int);
|
||||||
|
extern Cell *cat(Node **, int);
|
||||||
|
extern Cell *pastat(Node **, int);
|
||||||
|
extern Cell *dopa2(Node **, int);
|
||||||
|
extern Cell *split(Node **, int);
|
||||||
|
extern Cell *condexpr(Node **, int);
|
||||||
|
extern Cell *ifstat(Node **, int);
|
||||||
|
extern Cell *whilestat(Node **, int);
|
||||||
|
extern Cell *dostat(Node **, int);
|
||||||
|
extern Cell *forstat(Node **, int);
|
||||||
|
extern Cell *instat(Node **, int);
|
||||||
|
extern Cell *bltin(Node **, int);
|
||||||
|
extern Cell *printstat(Node **, int);
|
||||||
|
extern Cell *nullproc(Node **, int);
|
||||||
|
extern FILE *redirect(int, Node *);
|
||||||
|
extern FILE *openfile(int, const char *, bool *);
|
||||||
|
extern const char *filename(FILE *);
|
||||||
|
extern Cell *closefile(Node **, int);
|
||||||
|
extern void closeall(void);
|
||||||
|
extern Cell *dosub(Node **, int);
|
||||||
|
|
||||||
|
extern FILE *popen(const char *, const char *);
|
||||||
|
extern int pclose(FILE *);
|
||||||
|
|
||||||
|
extern const char *flags2str(int flags);
|
980
third_party/awk/run.c
vendored
980
third_party/awk/run.c
vendored
File diff suppressed because it is too large
Load diff
75
third_party/awk/tran.c
vendored
75
third_party/awk/tran.c
vendored
|
@ -1,36 +1,34 @@
|
||||||
/*-*- mode:c;indent-tabs-mode:t;c-basic-offset:8;tab-width:8;coding:utf-8 -*-│
|
/****************************************************************
|
||||||
│ vi: set noet ft=c ts=8 sw=8 fenc=utf-8 :vi │
|
Copyright (C) Lucent Technologies 1997
|
||||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
All Rights Reserved
|
||||||
│ │
|
|
||||||
│ Copyright (C) Lucent Technologies 1997 │
|
Permission to use, copy, modify, and distribute this software and
|
||||||
│ All Rights Reserved │
|
its documentation for any purpose and without fee is hereby
|
||||||
│ │
|
granted, provided that the above copyright notice appear in all
|
||||||
│ Permission to use, copy, modify, and distribute this software and │
|
copies and that both that the copyright notice and this
|
||||||
│ its documentation for any purpose and without fee is hereby │
|
permission notice and warranty disclaimer appear in supporting
|
||||||
│ granted, provided that the above copyright notice appear in all │
|
documentation, and that the name Lucent Technologies or any of
|
||||||
│ copies and that both that the copyright notice and this │
|
its entities not be used in advertising or publicity pertaining
|
||||||
│ permission notice and warranty disclaimer appear in supporting │
|
to distribution of the software without specific, written prior
|
||||||
│ documentation, and that the name Lucent Technologies or any of │
|
permission.
|
||||||
│ its entities not be used in advertising or publicity pertaining │
|
|
||||||
│ to distribution of the software without specific, written prior │
|
LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||||
│ permission. │
|
INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS.
|
||||||
│ │
|
IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY
|
||||||
│ LUCENT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, │
|
SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||||
│ INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. │
|
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
|
||||||
│ IN NO EVENT SHALL LUCENT OR ANY OF ITS ENTITIES BE LIABLE FOR ANY │
|
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
|
||||||
│ SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES │
|
ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF
|
||||||
│ WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER │
|
THIS SOFTWARE.
|
||||||
│ IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, │
|
****************************************************************/
|
||||||
│ ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF │
|
|
||||||
│ THIS SOFTWARE. │
|
#define DEBUG
|
||||||
│ │
|
#include <stdio.h>
|
||||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
#include <math.h>
|
||||||
#define DEBUG
|
#include <ctype.h>
|
||||||
#include "libc/fmt/conv.h"
|
#include <string.h>
|
||||||
#include "libc/math.h"
|
#include <stdlib.h>
|
||||||
#include "libc/mem/mem.h"
|
#include "awk.h"
|
||||||
#include "libc/str/str.h"
|
|
||||||
#include "third_party/awk/awk.h"
|
|
||||||
|
|
||||||
#define FULLTAB 2 /* rehash when table gets this x full */
|
#define FULLTAB 2 /* rehash when table gets this x full */
|
||||||
#define GROWTAB 4 /* grow table by this factor */
|
#define GROWTAB 4 /* grow table by this factor */
|
||||||
|
@ -310,7 +308,7 @@ Awkfloat setfval(Cell *vp, Awkfloat f) /* set float val of a Cell */
|
||||||
} else if (&vp->fval == NF) {
|
} else if (&vp->fval == NF) {
|
||||||
donerec = false; /* mark $0 invalid */
|
donerec = false; /* mark $0 invalid */
|
||||||
setlastfld(f);
|
setlastfld(f);
|
||||||
DPRINTF("setting NF to %g\n", f);
|
DPRINTF("setfval: setting NF to %g\n", f);
|
||||||
} else if (isrec(vp)) {
|
} else if (isrec(vp)) {
|
||||||
donefld = false; /* mark $1... invalid */
|
donefld = false; /* mark $1... invalid */
|
||||||
donerec = true;
|
donerec = true;
|
||||||
|
@ -350,6 +348,10 @@ char *setsval(Cell *vp, const char *s) /* set string val of a Cell */
|
||||||
(void*)vp, NN(vp->nval), s, vp->tval, donerec, donefld);
|
(void*)vp, NN(vp->nval), s, vp->tval, donerec, donefld);
|
||||||
if ((vp->tval & (NUM | STR)) == 0)
|
if ((vp->tval & (NUM | STR)) == 0)
|
||||||
funnyvar(vp, "assign to");
|
funnyvar(vp, "assign to");
|
||||||
|
if (CSV && (vp == rsloc))
|
||||||
|
WARNING("danger: don't set RS when --csv is in effect");
|
||||||
|
if (CSV && (vp == fsloc))
|
||||||
|
WARNING("danger: don't set FS when --csv is in effect");
|
||||||
if (isfld(vp)) {
|
if (isfld(vp)) {
|
||||||
donerec = false; /* mark $0 invalid */
|
donerec = false; /* mark $0 invalid */
|
||||||
fldno = atoi(vp->nval);
|
fldno = atoi(vp->nval);
|
||||||
|
@ -377,7 +379,7 @@ char *setsval(Cell *vp, const char *s) /* set string val of a Cell */
|
||||||
donerec = false; /* mark $0 invalid */
|
donerec = false; /* mark $0 invalid */
|
||||||
f = getfval(vp);
|
f = getfval(vp);
|
||||||
setlastfld(f);
|
setlastfld(f);
|
||||||
DPRINTF("setting NF to %g\n", f);
|
DPRINTF("setsval: setting NF to %g\n", f);
|
||||||
}
|
}
|
||||||
|
|
||||||
return(vp->sval);
|
return(vp->sval);
|
||||||
|
@ -565,7 +567,6 @@ Cell *catstr(Cell *a, Cell *b) /* concatenate a and b */
|
||||||
|
|
||||||
char *qstring(const char *is, int delim) /* collect string up to next delim */
|
char *qstring(const char *is, int delim) /* collect string up to next delim */
|
||||||
{
|
{
|
||||||
const char *os = is;
|
|
||||||
int c, n;
|
int c, n;
|
||||||
const uschar *s = (const uschar *) is;
|
const uschar *s = (const uschar *) is;
|
||||||
uschar *buf, *bp;
|
uschar *buf, *bp;
|
||||||
|
@ -574,7 +575,7 @@ char *qstring(const char *is, int delim) /* collect string up to next delim */
|
||||||
FATAL( "out of space in qstring(%s)", s);
|
FATAL( "out of space in qstring(%s)", s);
|
||||||
for (bp = buf; (c = *s) != delim; s++) {
|
for (bp = buf; (c = *s) != delim; s++) {
|
||||||
if (c == '\n')
|
if (c == '\n')
|
||||||
SYNTAX( "newline in string %.20s...", os );
|
SYNTAX( "newline in string %.20s...", is );
|
||||||
else if (c != '\\')
|
else if (c != '\\')
|
||||||
*bp++ = c;
|
*bp++ = c;
|
||||||
else { /* \something */
|
else { /* \something */
|
||||||
|
|
Loading…
Reference in a new issue