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))))
|
||||
|
||||
THIRD_PARTY_AWK_CHECKS = \
|
||||
$(THIRD_PARTY_AWK_A).pkg \
|
||||
$(THIRD_PARTY_AWK_HDRS:%=o/$(MODE)/%.ok)
|
||||
$(THIRD_PARTY_AWK_A).pkg
|
||||
|
||||
$(THIRD_PARTY_AWK_A): \
|
||||
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
|
||||
|
||||
commit b92d8cecd132ce8e02a373e28dd42e6be34d3d59
|
||||
Author: ozan yigit <ozan.yigit@gmail.com>
|
||||
Date: Mon May 30 11:34:52 2022 -0400
|
||||
commit 2bab10b60b3f4d3bbefdcb60410655f317d1a452
|
||||
date Thu Mar 14 14:25:30 2024 +0200
|
||||
|
||||
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_
|
||||
#include "libc/assert.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/literal.h"
|
||||
#include "libc/stdio/stdio.h"
|
||||
COSMOPOLITAN_C_START_
|
||||
/****************************************************************
|
||||
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 <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#if __STDC_VERSION__ <= 199901L
|
||||
#define noreturn
|
||||
#else
|
||||
#include <stdnoreturn.h>
|
||||
#endif
|
||||
|
||||
typedef double Awkfloat;
|
||||
|
||||
|
@ -12,7 +37,7 @@ typedef double Awkfloat;
|
|||
|
||||
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
|
||||
* 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. */
|
||||
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 **FS;
|
||||
extern char **RS;
|
||||
|
@ -53,6 +80,8 @@ extern char **SUBSEP;
|
|||
extern Awkfloat *RSTART;
|
||||
extern Awkfloat *RLENGTH;
|
||||
|
||||
extern bool CSV; /* true for csv input */
|
||||
|
||||
extern char *record; /* points to $0 */
|
||||
extern int lineno; /* line number in awk program */
|
||||
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: */
|
||||
|
||||
#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. */
|
||||
#define HAT (NCHARS+2) /* matches ^ in regular expr */
|
||||
#define NSTATES 32
|
||||
|
@ -211,12 +241,24 @@ typedef struct rrow {
|
|||
int i;
|
||||
Node *np;
|
||||
uschar *up;
|
||||
int *rp; /* rune representation of char class */
|
||||
} lval; /* because Al stores a pointer in it! */
|
||||
int *lfollow;
|
||||
} 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 {
|
||||
unsigned int **gototab;
|
||||
gtt *gototab;
|
||||
uschar *out;
|
||||
uschar *restr;
|
||||
int **posns;
|
||||
|
@ -229,185 +271,5 @@ typedef struct fa {
|
|||
struct rrow re[1]; /* variable: actual size set by calling malloc */
|
||||
} 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);
|
||||
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_ */
|
||||
#include "proto.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_
|
||||
#define COSMOPOLITAN_THIRD_PARTY_AWK_AWKGRAM_TAB_H_
|
||||
#include "third_party/awk/awk.h"
|
||||
COSMOPOLITAN_C_START_
|
||||
#ifndef YY_YY_AWKGRAM_TAB_H_INCLUDED
|
||||
# define YY_YY_AWKGRAM_TAB_H_INCLUDED
|
||||
/* Debug traces. */
|
||||
#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;
|
||||
|
||||
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 │
|
||||
│ │
|
||||
│ 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/mem/mem.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "third_party/awk/awk.h"
|
||||
#include "third_party/awk/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.
|
||||
****************************************************************/
|
||||
|
||||
/* 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 type(v) (v)->nobj /* badly overloaded here */
|
||||
|
@ -80,6 +80,44 @@ int patlen;
|
|||
fa *fatab[NFA];
|
||||
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 *
|
||||
intalloc(size_t n, const char *f)
|
||||
{
|
||||
|
@ -105,7 +143,7 @@ resizesetvec(const char *f)
|
|||
static void
|
||||
resize_state(fa *f, int state)
|
||||
{
|
||||
unsigned int **p;
|
||||
gtt *p;
|
||||
uschar *p2;
|
||||
int **p3;
|
||||
int i, new_count;
|
||||
|
@ -115,7 +153,7 @@ resize_state(fa *f, int state)
|
|||
|
||||
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)
|
||||
goto out;
|
||||
f->gototab = p;
|
||||
|
@ -131,10 +169,12 @@ resize_state(fa *f, int state)
|
|||
f->posns = p3;
|
||||
|
||||
for (i = f->state_count; i < new_count; ++i) {
|
||||
f->gototab[i] = (unsigned int *) calloc(NCHARS, sizeof(**f->gototab));
|
||||
if (f->gototab[i] == NULL)
|
||||
f->gototab[i].entries = (gtte *) calloc(NCHARS, sizeof(gtte));
|
||||
if (f->gototab[i].entries == NULL)
|
||||
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->state_count = new_count;
|
||||
|
@ -230,8 +270,7 @@ int makeinit(fa *f, bool anchor)
|
|||
}
|
||||
if ((f->posns[2])[1] == f->accept)
|
||||
f->out[2] = 1;
|
||||
for (i = 0; i < NCHARS; i++)
|
||||
f->gototab[2][i] = 0;
|
||||
clear_gototab(f, 2);
|
||||
f->curstat = cgoto(f, 2, HAT);
|
||||
if (anchor) {
|
||||
*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 */
|
||||
/* 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) */
|
||||
const uschar *p;
|
||||
int n = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0, p = *pp; i < 2 && isxdigit(*p); i++, p++) {
|
||||
if (isdigit(*p))
|
||||
for (i = 0, p = *pp; i < max && isxdigit(*p); i++, p++) {
|
||||
if (isdigit((int) *p))
|
||||
n = 16 * n + *p - '0';
|
||||
else if (*p >= 'a' && *p <= 'f')
|
||||
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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#define isoctdigit(c) ((c) >= '0' && (c) <= '7') /* multiple use of arg */
|
||||
|
||||
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;
|
||||
int c;
|
||||
|
||||
if ((c = *p++) == 't')
|
||||
/* BUG: should advance by utf-8 char even if makes no sense */
|
||||
|
||||
if ((c = *p++) == 't') {
|
||||
c = '\t';
|
||||
else if (c == 'n')
|
||||
} else if (c == 'n') {
|
||||
c = '\n';
|
||||
else if (c == 'f')
|
||||
} else if (c == 'f') {
|
||||
c = '\f';
|
||||
else if (c == 'r')
|
||||
} else if (c == 'r') {
|
||||
c = '\r';
|
||||
else if (c == 'b')
|
||||
} else if (c == 'b') {
|
||||
c = '\b';
|
||||
else if (c == 'v')
|
||||
} else if (c == 'v') {
|
||||
c = '\v';
|
||||
else if (c == 'a')
|
||||
} else if (c == 'a') {
|
||||
c = '\a';
|
||||
else if (c == '\\')
|
||||
} else if (c == '\\') {
|
||||
c = '\\';
|
||||
else if (c == 'x') { /* hexadecimal goo follows */
|
||||
c = hexstr(&p); /* this adds a null if number is invalid */
|
||||
} else if (c == 'x') { /* 2 hex digits follow */
|
||||
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 */
|
||||
int n = c - '0';
|
||||
if (isoctdigit(*p)) {
|
||||
|
@ -358,50 +403,67 @@ int quoted(const uschar **pp) /* pick up next thing after a \\ */
|
|||
return c;
|
||||
}
|
||||
|
||||
char *cclenter(const char *argp) /* add a character class */
|
||||
int *cclenter(const char *argp) /* add a character class */
|
||||
{
|
||||
int i, c, c2;
|
||||
const uschar *op, *p = (const uschar *) argp;
|
||||
uschar *bp;
|
||||
static uschar *buf = NULL;
|
||||
int n;
|
||||
const uschar *p = (const uschar *) argp;
|
||||
int *bp, *retp;
|
||||
static int *buf = NULL;
|
||||
static int bufsz = 100;
|
||||
|
||||
op = p;
|
||||
if (buf == NULL && (buf = (uschar *) malloc(bufsz)) == NULL)
|
||||
if (buf == NULL && (buf = (int *) calloc(bufsz, sizeof(int))) == NULL)
|
||||
FATAL("out of space for character class [%.10s...] 1", p);
|
||||
bp = buf;
|
||||
for (i = 0; (c = *p++) != 0; ) {
|
||||
for (i = 0; *p != 0; ) {
|
||||
n = u8_rune(&c, (const char *) p);
|
||||
p += n;
|
||||
if (c == '\\') {
|
||||
c = quoted(&p);
|
||||
} else if (c == '-' && i > 0 && bp[-1] != 0) {
|
||||
if (*p != 0) {
|
||||
c = bp[-1];
|
||||
c2 = *p++;
|
||||
/* c2 = *p++; */
|
||||
n = u8_rune(&c2, (const char *) p);
|
||||
p += n;
|
||||
if (c2 == '\\')
|
||||
c2 = quoted(&p);
|
||||
c2 = quoted(&p); /* BUG: sets p, has to be u8 size */
|
||||
if (c > c2) { /* empty; ignore */
|
||||
bp--;
|
||||
i--;
|
||||
continue;
|
||||
}
|
||||
while (c < c2) {
|
||||
if (!adjbuf((char **) &buf, &bufsz, bp-buf+2, 100, (char **) &bp, "cclenter1"))
|
||||
FATAL("out of space for character class [%.10s...] 2", p);
|
||||
if (i >= bufsz) {
|
||||
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;
|
||||
i++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (!adjbuf((char **) &buf, &bufsz, bp-buf+2, 100, (char **) &bp, "cclenter2"))
|
||||
FATAL("out of space for character class [%.10s...] 3", p);
|
||||
if (i >= bufsz) {
|
||||
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;
|
||||
i++;
|
||||
}
|
||||
*bp = 0;
|
||||
DPRINTF("cclenter: in = |%s|, out = |%s|\n", op, buf);
|
||||
xfree(op);
|
||||
return (char *) tostring((char *) buf);
|
||||
/* DPRINTF("cclenter: in = |%s|, out = |%s|\n", op, buf); BUG: can't print array of int */
|
||||
/* xfree(op); BUG: what are we freeing here? */
|
||||
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)
|
||||
|
@ -468,7 +530,7 @@ int first(Node *p) /* collects initially active leaves of p into setvec */
|
|||
setvec[lp] = 1;
|
||||
setcnt++;
|
||||
}
|
||||
if (type(p) == CCL && (*(char *) right(p)) == '\0')
|
||||
if (type(p) == CCL && (*(int *) right(p)) == 0)
|
||||
return(0); /* empty CCL */
|
||||
return(1);
|
||||
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)
|
||||
if (c == *s++)
|
||||
|
@ -534,11 +596,113 @@ int member(int c, const char *sarg) /* is c in s? */
|
|||
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 s, ns;
|
||||
int n;
|
||||
int rune;
|
||||
const uschar *p = (const uschar *) p0;
|
||||
|
||||
/* return pmatch(f, p0); does it matter whether longest or shortest? */
|
||||
|
||||
s = f->initstat;
|
||||
assert (s < f->state_count);
|
||||
|
||||
|
@ -546,19 +710,25 @@ int match(fa *f, const char *p0) /* shortest match ? */
|
|||
return(1);
|
||||
do {
|
||||
/* 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;
|
||||
else
|
||||
s = cgoto(f, s, *p);
|
||||
s = cgoto(f, s, rune);
|
||||
if (f->out[s])
|
||||
return(1);
|
||||
} while (*p++ != 0);
|
||||
if (*p == 0)
|
||||
break;
|
||||
p += n;
|
||||
} while (1); /* was *p++ != 0 */
|
||||
return(0);
|
||||
}
|
||||
|
||||
int pmatch(fa *f, const char *p0) /* longest match, for sub */
|
||||
{
|
||||
int s, ns;
|
||||
int n;
|
||||
int rune;
|
||||
const uschar *p = (const uschar *) p0;
|
||||
const uschar *q;
|
||||
|
||||
|
@ -573,10 +743,11 @@ int pmatch(fa *f, const char *p0) /* longest match, for sub */
|
|||
if (f->out[s]) /* final state */
|
||||
patlen = q-p;
|
||||
/* 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;
|
||||
else
|
||||
s = cgoto(f, s, *q);
|
||||
s = cgoto(f, s, rune);
|
||||
|
||||
assert(s < f->state_count);
|
||||
|
||||
|
@ -588,7 +759,11 @@ int pmatch(fa *f, const char *p0) /* longest match, for sub */
|
|||
else
|
||||
goto nextin; /* no match */
|
||||
}
|
||||
} while (*q++ != 0);
|
||||
if (*q == 0)
|
||||
break;
|
||||
q += n;
|
||||
} while (1);
|
||||
q++; /* was *q++ */
|
||||
if (f->out[s])
|
||||
patlen = q-p-1; /* don't count $ */
|
||||
if (patlen >= 0) {
|
||||
|
@ -597,13 +772,19 @@ int pmatch(fa *f, const char *p0) /* longest match, for sub */
|
|||
}
|
||||
nextin:
|
||||
s = 2;
|
||||
} while (*p++);
|
||||
if (*p == 0)
|
||||
break;
|
||||
n = u8_rune(&rune, (const char *) p);
|
||||
p += n;
|
||||
} while (1); /* was *p++ */
|
||||
return (0);
|
||||
}
|
||||
|
||||
int nematch(fa *f, const char *p0) /* non-empty match, for sub */
|
||||
{
|
||||
int s, ns;
|
||||
int n;
|
||||
int rune;
|
||||
const uschar *p = (const uschar *) p0;
|
||||
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 */
|
||||
patlen = q-p;
|
||||
/* 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;
|
||||
else
|
||||
s = cgoto(f, s, *q);
|
||||
s = cgoto(f, s, rune);
|
||||
if (s == 1) { /* no transition */
|
||||
if (patlen > 0) {
|
||||
patbeg = (const char *) p;
|
||||
|
@ -629,7 +811,11 @@ int nematch(fa *f, const char *p0) /* non-empty match, for sub */
|
|||
} else
|
||||
goto nnextin; /* no nonempty match */
|
||||
}
|
||||
} while (*q++ != 0);
|
||||
if (*q == 0)
|
||||
break;
|
||||
q += n;
|
||||
} while (1);
|
||||
q++;
|
||||
if (f->out[s])
|
||||
patlen = q-p-1; /* don't count $ */
|
||||
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)
|
||||
{
|
||||
char *buf = *pbuf;
|
||||
char *i, *j, *k, *buf = *pbuf;
|
||||
int bufsize = *pbufsize;
|
||||
int c, i, j, k, ns, s;
|
||||
int c, n, ns, s;
|
||||
|
||||
s = pfa->initstat;
|
||||
patlen = 0;
|
||||
|
||||
/*
|
||||
* All indices relative to buf.
|
||||
* i <= j <= k <= bufsize
|
||||
* buf <= i <= j <= k <= buf+bufsize
|
||||
*
|
||||
* i: origin of active substring
|
||||
* 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)
|
||||
s = ns;
|
||||
else
|
||||
s = cgoto(pfa, s, c);
|
||||
i = j = k = buf;
|
||||
|
||||
if (pfa->out[s]) { /* final state */
|
||||
patlen = j - i + 1;
|
||||
if (c == 0) /* don't count $ */
|
||||
patlen--;
|
||||
do {
|
||||
/*
|
||||
* Call u8_rune with at least awk_mb_cur_max ahead in
|
||||
* 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;
|
||||
} while (buf[i] && !patlen);
|
||||
|
||||
/* adjbuf() may have relocated a resized buffer. Inform the world. */
|
||||
*pbuf = buf;
|
||||
*pbufsize = bufsize;
|
||||
} while (1);
|
||||
|
||||
if (patlen) {
|
||||
patbeg = (char *) buf + i;
|
||||
/*
|
||||
* Under no circumstances is the last character fed to
|
||||
* 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.
|
||||
*/
|
||||
do
|
||||
if (buf[--k] && ungetc(buf[k], f) == EOF)
|
||||
FATAL("unable to ungetc '%c'", buf[k]);
|
||||
while (k > i + patlen);
|
||||
buf[k] = '\0';
|
||||
if (*--k && ungetc(*k, f) == EOF)
|
||||
FATAL("unable to ungetc '%c'", *k);
|
||||
while (k > patbeg + patlen);
|
||||
*k = '\0';
|
||||
return true;
|
||||
}
|
||||
else
|
||||
|
@ -797,7 +1013,7 @@ Node *primary(void)
|
|||
rtok = relex();
|
||||
if (rtok == ')') { /* special pleading for () */
|
||||
rtok = relex();
|
||||
return unary(op2(CCL, NIL, (Node *) tostring("")));
|
||||
return unary(op2(CCL, NIL, (Node *) cclenter("")));
|
||||
}
|
||||
np = regexp();
|
||||
if (rtok == ')') {
|
||||
|
@ -820,7 +1036,7 @@ Node *concat(Node *np)
|
|||
return (concat(op2(CAT, np, primary())));
|
||||
case EMPTYRE:
|
||||
rtok = relex();
|
||||
return (concat(op2(CAT, op2(CCL, NIL, (Node *) tostring("")),
|
||||
return (concat(op2(CAT, op2(CCL, NIL, (Node *) cclenter("")),
|
||||
primary())));
|
||||
}
|
||||
return (np);
|
||||
|
@ -866,6 +1082,25 @@ Node *unary(Node *np)
|
|||
* 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 {
|
||||
const char *cc_name;
|
||||
int cc_namelen;
|
||||
|
@ -873,7 +1108,11 @@ static const struct charclass {
|
|||
} charclasses[] = {
|
||||
{ "alnum", 5, isalnum },
|
||||
{ "alpha", 5, isalpha },
|
||||
#ifndef HAS_ISBLANK
|
||||
{ "blank", 5, xisblank },
|
||||
#else
|
||||
{ "blank", 5, isblank },
|
||||
#endif
|
||||
{ "cntrl", 5, iscntrl },
|
||||
{ "digit", 5, isdigit },
|
||||
{ "graph", 5, isgraph },
|
||||
|
@ -1013,6 +1252,12 @@ int relex(void) /* lexical analyzer for reparse */
|
|||
rescan:
|
||||
starttok = prestr;
|
||||
|
||||
if ((n = u8_rune(&rlxval, (const char *) prestr)) > 1) {
|
||||
prestr += n;
|
||||
starttok = prestr;
|
||||
return CHAR;
|
||||
}
|
||||
|
||||
switch (c = *prestr++) {
|
||||
case '|': return OR;
|
||||
case '*': return STAR;
|
||||
|
@ -1050,10 +1295,15 @@ rescan:
|
|||
}
|
||||
else
|
||||
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"))
|
||||
FATAL("out of space for reg expr %.10s...", lastre);
|
||||
for (; ; ) {
|
||||
if ((n = u8_rune(&rlxval, (const char *) prestr)) > 1) {
|
||||
for (i = 0; i < n; i++)
|
||||
*bp++ = *prestr++;
|
||||
continue;
|
||||
}
|
||||
if ((c = *prestr++) == '\\') {
|
||||
*bp++ = '\\';
|
||||
if ((c = *prestr++) == '\0')
|
||||
|
@ -1143,7 +1393,7 @@ rescan:
|
|||
}
|
||||
break;
|
||||
case '{':
|
||||
if (isdigit(*(prestr))) {
|
||||
if (isdigit((int) *(prestr))) {
|
||||
num = 0; /* Process as a repetition */
|
||||
n = -1; m = -1;
|
||||
commafound = false;
|
||||
|
@ -1213,7 +1463,6 @@ rescan:
|
|||
}
|
||||
break;
|
||||
}
|
||||
return 0; /* [jart] why wasn't this here? */
|
||||
}
|
||||
|
||||
int cgoto(fa *f, int s, int c)
|
||||
|
@ -1221,7 +1470,7 @@ int cgoto(fa *f, int s, int c)
|
|||
int *p, *q;
|
||||
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! */
|
||||
resizesetvec(__func__);
|
||||
}
|
||||
|
@ -1237,8 +1486,8 @@ int cgoto(fa *f, int s, int c)
|
|||
|| (k == DOT && c != 0 && c != HAT)
|
||||
|| (k == ALL && c != 0)
|
||||
|| (k == EMPTYRE && c != 0)
|
||||
|| (k == CCL && member(c, (char *) f->re[p[i]].lval.up))
|
||||
|| (k == NCCL && !member(c, (char *) f->re[p[i]].lval.up) && c != 0 && c != HAT)) {
|
||||
|| (k == CCL && member(c, (int *) f->re[p[i]].lval.rp))
|
||||
|| (k == NCCL && !member(c, (int *) f->re[p[i]].lval.rp) && c != 0 && c != HAT)) {
|
||||
q = f->re[p[i]].lfollow;
|
||||
for (j = 1; j <= *q; j++) {
|
||||
if (q[j] >= maxsetvec) {
|
||||
|
@ -1270,7 +1519,7 @@ int cgoto(fa *f, int s, int c)
|
|||
goto different;
|
||||
/* setvec is state i */
|
||||
if (c != HAT)
|
||||
f->gototab[s][c] = i;
|
||||
set_gototab(f, s, c, i);
|
||||
return i;
|
||||
different:;
|
||||
}
|
||||
|
@ -1278,14 +1527,13 @@ int cgoto(fa *f, int s, int c)
|
|||
/* add tmpset to current set of states */
|
||||
++(f->curstat);
|
||||
resize_state(f, f->curstat);
|
||||
for (i = 0; i < NCHARS; i++)
|
||||
f->gototab[f->curstat][i] = 0;
|
||||
clear_gototab(f, f->curstat);
|
||||
xfree(f->posns[f->curstat]);
|
||||
p = intalloc(setcnt + 1, __func__);
|
||||
|
||||
f->posns[f->curstat] = p;
|
||||
if (c != HAT)
|
||||
f->gototab[s][c] = f->curstat;
|
||||
set_gototab(f, s, c, f->curstat);
|
||||
for (i = 0; i <= setcnt; i++)
|
||||
p[i] = tmpset[i];
|
||||
if (setvec[f->accept])
|
||||
|
@ -1303,7 +1551,8 @@ void freefa(fa *f) /* free a finite automaton */
|
|||
if (f == NULL)
|
||||
return;
|
||||
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++)
|
||||
xfree(f->posns[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 │
|
||||
│ │
|
||||
│ 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"
|
||||
/****************************************************************
|
||||
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 <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include "awk.h"
|
||||
#include "awkgram.tab.h"
|
||||
|
||||
extern YYSTYPE yylval;
|
||||
extern bool infunc;
|
||||
|
||||
int lineno = 1;
|
||||
|
@ -373,6 +368,8 @@ int yylex(void)
|
|||
}
|
||||
}
|
||||
|
||||
extern int runetochar(char *str, int c);
|
||||
|
||||
int string(void)
|
||||
{
|
||||
int c, n;
|
||||
|
@ -420,20 +417,54 @@ int string(void)
|
|||
*bp++ = n;
|
||||
break;
|
||||
|
||||
case 'x': /* hex \x0-9a-fA-F + */
|
||||
{ char xbuf[100], *px;
|
||||
for (px = xbuf; (c = input()) != 0 && px-xbuf < 100-2; ) {
|
||||
if (isdigit(c)
|
||||
|| (c >= 'a' && c <= 'f')
|
||||
|| (c >= 'A' && c <= 'F'))
|
||||
*px++ = c;
|
||||
else
|
||||
break;
|
||||
case 'x': /* hex \x0-9a-fA-F (exactly two) */
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!isxdigit(peek())) {
|
||||
unput(c);
|
||||
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);
|
||||
sscanf(xbuf, "%x", (unsigned int *) &n);
|
||||
*bp++ = n;
|
||||
bp += runetochar(bp, n);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -530,7 +561,7 @@ int regexpr(void)
|
|||
char *bp;
|
||||
|
||||
if (buf == NULL && (buf = (char *) malloc(bufsz)) == NULL)
|
||||
FATAL("out of space for rex expr");
|
||||
FATAL("out of space for reg expr");
|
||||
bp = buf;
|
||||
for ( ; (c = input()) != '/' && c != 0; ) {
|
||||
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 │
|
||||
│ │
|
||||
│ 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. │
|
||||
│ │
|
||||
╚─────────────────────────────────────────────────────────────────────────────*/
|
||||
/****************************************************************
|
||||
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/errno.h"
|
||||
#include "libc/fmt/conv.h"
|
||||
#include "libc/limits.h"
|
||||
#include "libc/math.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/runtime/runtime.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "third_party/awk/awk.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <strings.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <limits.h>
|
||||
#include <math.h>
|
||||
#include "awk.h"
|
||||
|
||||
extern int u8_nextlen(const char *s);
|
||||
|
||||
char EMPTY[] = { '\0' };
|
||||
static FILE *infile = NULL;
|
||||
FILE *infile = NULL;
|
||||
bool innew; /* true = infile has not been read by readrec */
|
||||
char *file = EMPTY;
|
||||
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",
|
||||
*RS, *FS, *ARGC, *FILENAME);
|
||||
if (isrecord) {
|
||||
donefld = false;
|
||||
donerec = true;
|
||||
savefs();
|
||||
}
|
||||
saveb0 = buf[0];
|
||||
buf[0] = 0;
|
||||
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]->tval |= NUM;
|
||||
}
|
||||
donefld = false;
|
||||
donerec = true;
|
||||
savefs();
|
||||
}
|
||||
setfval(nrloc, nrloc->fval+1);
|
||||
setfval(fnrloc, fnrloc->fval+1);
|
||||
|
@ -223,16 +221,22 @@ void nextfile(void)
|
|||
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 sep, c, isrec;
|
||||
char *rr, *buf = *pbuf;
|
||||
int sep, c, isrec; // POTENTIAL BUG? isrec is a macro in awk.h
|
||||
char *rr = *pbuf, *buf = *pbuf;
|
||||
int bufsize = *pbufsize;
|
||||
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;
|
||||
|
||||
memset(buf, 0, bufsize);
|
||||
fa *pfa = makedfa(rs, 1);
|
||||
if (newflag)
|
||||
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)
|
||||
setptr(patbeg, '\0');
|
||||
isrec = (found == 0 && *buf == '\0') ? false : true;
|
||||
|
||||
} else {
|
||||
if ((sep = *rs) == 0) {
|
||||
sep = '\n';
|
||||
|
@ -282,6 +287,52 @@ int readrec(char **pbuf, int *pbufsize, FILE *inf, bool newflag) /* read one rec
|
|||
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] */
|
||||
{
|
||||
Cell *x;
|
||||
|
@ -303,6 +354,9 @@ void setclvar(char *s) /* set var=value from s */
|
|||
Cell *q;
|
||||
double result;
|
||||
|
||||
/* commit f3d9187d4e0f02294fb1b0e31152070506314e67 broke T.argv test */
|
||||
/* I don't understand why it was changed. */
|
||||
|
||||
for (p=s; *p != '='; p++)
|
||||
;
|
||||
e = p;
|
||||
|
@ -315,6 +369,7 @@ void setclvar(char *s) /* set var=value from s */
|
|||
q->tval |= NUM;
|
||||
}
|
||||
DPRINTF("command line set %s to |%s|\n", s, p);
|
||||
free(p);
|
||||
*e = '=';
|
||||
}
|
||||
|
||||
|
@ -344,9 +399,9 @@ void fldbld(void) /* create fields from current record */
|
|||
i = 0; /* number of fields accumulated here */
|
||||
if (inputFS == NULL) /* make sure we have a copy of FS */
|
||||
savefs();
|
||||
if (strlen(inputFS) > 1) { /* it's a regular expression */
|
||||
if (!CSV && strlen(inputFS) > 1) { /* it's a regular expression */
|
||||
i = refldbld(r, inputFS);
|
||||
} else if ((sep = *inputFS) == ' ') { /* default whitespace */
|
||||
} else if (!CSV && (sep = *inputFS) == ' ') { /* default whitespace */
|
||||
for (i = 0; ; ) {
|
||||
while (*r == ' ' || *r == '\t' || *r == '\n')
|
||||
r++;
|
||||
|
@ -365,26 +420,58 @@ void fldbld(void) /* create fields from current record */
|
|||
*fr++ = 0;
|
||||
}
|
||||
*fr = 0;
|
||||
} else if ((sep = *inputFS) == 0) { /* new: FS="" => 1 char/field */
|
||||
for (i = 0; *r != '\0'; r += n) {
|
||||
char buf[MB_LEN_MAX + 1];
|
||||
|
||||
} else if (CSV) { /* CSV processing. no error handling */
|
||||
if (*r != 0) {
|
||||
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++;
|
||||
if (i > nfields)
|
||||
growfldtab(i);
|
||||
if (freeable(fldtab[i]))
|
||||
xfree(fldtab[i]->sval);
|
||||
n = mblen(r, MB_LEN_MAX);
|
||||
if (n < 0)
|
||||
n = 1;
|
||||
memcpy(buf, r, n);
|
||||
buf[n] = '\0';
|
||||
n = u8_nextlen(r);
|
||||
for (j = 0; j < n; j++)
|
||||
buf[j] = *r++;
|
||||
buf[j] = '\0';
|
||||
fldtab[i]->sval = tostring(buf);
|
||||
fldtab[i]->tval = FLD | STR;
|
||||
}
|
||||
*fr = 0;
|
||||
} 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).
|
||||
* this variable is tested in the inner while loop.
|
||||
*/
|
||||
|
@ -587,11 +674,9 @@ void yyerror(const char *s)
|
|||
SYNTAX("%s", s);
|
||||
}
|
||||
|
||||
extern char *cmdname;
|
||||
|
||||
void SYNTAX(const char *fmt, ...)
|
||||
{
|
||||
extern char *curfname;
|
||||
extern char *cmdname, *curfname;
|
||||
static int been_here = 0;
|
||||
va_list varg;
|
||||
|
||||
|
@ -641,6 +726,7 @@ void bcheck2(int n, int c1, int c2)
|
|||
|
||||
void FATAL(const char *fmt, ...)
|
||||
{
|
||||
extern char *cmdname;
|
||||
va_list varg;
|
||||
|
||||
fflush(stdout);
|
||||
|
@ -656,6 +742,7 @@ void FATAL(const char *fmt, ...)
|
|||
|
||||
void WARNING(const char *fmt, ...)
|
||||
{
|
||||
extern char *cmdname;
|
||||
va_list varg;
|
||||
|
||||
fflush(stdout);
|
||||
|
@ -758,10 +845,10 @@ int isclvar(const char *s) /* is s of form var=something ? */
|
|||
{
|
||||
const char *os = s;
|
||||
|
||||
if (!isalpha((uschar) *s) && *s != '_')
|
||||
if (!isalpha((int) *s) && *s != '_')
|
||||
return 0;
|
||||
for ( ; *s; s++)
|
||||
if (!(isalnum((uschar) *s) || *s == '_'))
|
||||
if (!(isalnum((int) *s) || *s == '_'))
|
||||
break;
|
||||
return *s == '=' && s > os;
|
||||
}
|
||||
|
@ -796,19 +883,19 @@ bool is_valid_number(const char *s, bool trailing_stuff_ok,
|
|||
if (no_trailing)
|
||||
*no_trailing = false;
|
||||
|
||||
while (isspace(*s))
|
||||
while (isspace((int) *s))
|
||||
s++;
|
||||
|
||||
// no hex floating point, sorry
|
||||
/* no hex floating point, sorry */
|
||||
if (s[0] == '0' && tolower(s[1]) == 'x')
|
||||
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] == '-') {
|
||||
is_nan = (strncasecmp(s+1, "nan", 3) == 0);
|
||||
is_inf = (strncasecmp(s+1, "inf", 3) == 0);
|
||||
if ((is_nan || is_inf)
|
||||
&& (isspace(s[4]) || s[4] == '\0'))
|
||||
&& (isspace((int) s[4]) || s[4] == '\0'))
|
||||
goto convert;
|
||||
else if (! isdigit(s[1]) && s[1] != '.')
|
||||
return false;
|
||||
|
@ -831,13 +918,13 @@ convert:
|
|||
/*
|
||||
* check for trailing stuff
|
||||
*/
|
||||
while (isspace(*ep))
|
||||
while (isspace((int) *ep))
|
||||
ep++;
|
||||
|
||||
if (no_trailing != NULL)
|
||||
*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;
|
||||
|
||||
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 -*-│
|
||||
│ vi: set noet ft=c ts=8 sw=8 fenc=utf-8 :vi │
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ 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\
|
||||
__notice(awk_license, "\
|
||||
/****************************************************************\n\
|
||||
Copyright (C) Lucent Technologies 1997\n\
|
||||
All Rights Reserved\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\
|
||||
IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,\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;
|
||||
|
||||
int dbg = 0;
|
||||
|
@ -71,6 +42,7 @@ Awkfloat srand_seed = 1;
|
|||
char *cmdname; /* gets argv[0] for error messages */
|
||||
extern FILE *yyin; /* lex input file */
|
||||
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;
|
||||
|
||||
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 curpfile; /* current filename */
|
||||
|
||||
bool CSV = false; /* true for csv input */
|
||||
|
||||
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];
|
||||
emsg[0] = "Unknown error";
|
||||
emsg[FPE_INTDIV] = "Integer divide by zero";
|
||||
emsg[FPE_INTOVF] = "Integer overflow";
|
||||
emsg[FPE_FLTDIV] = "Floating point divide by zero";
|
||||
emsg[FPE_FLTOVF] = "Floating point overflow";
|
||||
emsg[FPE_FLTUND] = "Floating point underflow";
|
||||
emsg[FPE_FLTRES] = "Floating point inexact result";
|
||||
emsg[FPE_FLTINV] = "Invalid Floating point operation";
|
||||
emsg[FPE_FLTSUB] = "Subscript out of range";
|
||||
FATAL("floating point exception: %s",
|
||||
(size_t)si->si_code < sizeof(emsg) / sizeof(emsg[0]) &&
|
||||
emsg[si->si_code] ? emsg[si->si_code] : emsg[0]);
|
||||
#ifdef SA_SIGINFOz
|
||||
static const char *emsg[] = {
|
||||
[0] = "Unknown error",
|
||||
[FPE_INTDIV] = "Integer divide by zero",
|
||||
[FPE_INTOVF] = "Integer overflow",
|
||||
[FPE_FLTDIV] = "Floating point divide by zero",
|
||||
[FPE_FLTOVF] = "Floating point overflow",
|
||||
[FPE_FLTUND] = "Floating point underflow",
|
||||
[FPE_FLTRES] = "Floating point inexact result",
|
||||
[FPE_FLTINV] = "Invalid Floating point operation",
|
||||
[FPE_FLTSUB] = "Subscript out of range",
|
||||
};
|
||||
#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.
|
||||
|
@ -129,30 +115,30 @@ getarg(int *argc, char ***argv, const char *msg)
|
|||
int _awk(int argc, char *argv[])
|
||||
{
|
||||
const char *fs = NULL;
|
||||
struct sigaction sa;
|
||||
char *fn, *vn;
|
||||
|
||||
setlocale(LC_CTYPE, "");
|
||||
setlocale(LC_NUMERIC, "C"); /* for parsing cmdline & prog */
|
||||
awk_mb_cur_max = MB_CUR_MAX;
|
||||
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) {
|
||||
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);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
sa.sa_sigaction = fpecatch;
|
||||
sa.sa_flags = SA_SIGINFO;
|
||||
sigemptyset(&sa.sa_mask);
|
||||
(void)sigaction(SIGFPE, &sa, NULL);
|
||||
#ifdef SA_SIGINFO
|
||||
{
|
||||
struct sigaction sa;
|
||||
sa.sa_sigaction = fpecatch;
|
||||
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 */
|
||||
srand_seed = 1;
|
||||
|
@ -170,6 +156,12 @@ int _awk(int argc, char *argv[])
|
|||
argv++;
|
||||
break;
|
||||
}
|
||||
if (strcmp(argv[1], "--csv") == 0) { /* turn on csv input processing */
|
||||
CSV = true;
|
||||
argc--;
|
||||
argv++;
|
||||
continue;
|
||||
}
|
||||
switch (argv[1][1]) {
|
||||
case 's':
|
||||
if (strcmp(argv[1], "-safe") == 0)
|
||||
|
@ -208,6 +200,10 @@ int _awk(int argc, char *argv[])
|
|||
argc--;
|
||||
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 */
|
||||
if (npfile == 0) { /* no -f; first argument is program */
|
||||
if (argc <= 1) {
|
||||
|
@ -229,6 +225,11 @@ int _awk(int argc, char *argv[])
|
|||
if (!safe)
|
||||
envinit(environ);
|
||||
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)
|
||||
*FS = qstring(fs, '\0');
|
||||
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 │
|
||||
│ │
|
||||
│ 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/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"
|
||||
/****************************************************************
|
||||
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.
|
||||
****************************************************************/
|
||||
|
||||
/*
|
||||
* this program makes the table to link function names
|
||||
|
@ -38,6 +28,12 @@
|
|||
* 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
|
||||
{ int token;
|
||||
const char *name;
|
||||
|
@ -56,8 +52,8 @@ struct xx
|
|||
{ ARRAY, "array", NULL },
|
||||
{ INDIRECT, "indirect", "$(" },
|
||||
{ SUBSTR, "substr", "substr" },
|
||||
{ SUB, "sub", "sub" },
|
||||
{ GSUB, "gsub", "gsub" },
|
||||
{ SUB, "dosub", "sub" },
|
||||
{ GSUB, "dosub", "gsub" },
|
||||
{ INDEX, "sindex", "sindex" },
|
||||
{ SPRINTF, "awksprintf", "sprintf " },
|
||||
{ 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 │
|
||||
│ │
|
||||
│ 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"
|
||||
/****************************************************************
|
||||
Copyright (C) Lucent Technologies 1997
|
||||
All Rights Reserved
|
||||
|
||||
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;
|
||||
|
||||
|
|
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 -*-│
|
||||
│ vi: set noet ft=c ts=8 sw=8 fenc=utf-8 :vi │
|
||||
╚──────────────────────────────────────────────────────────────────────────────╝
|
||||
│ │
|
||||
│ 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"
|
||||
#include <stdio.h>
|
||||
#include "awk.h"
|
||||
#include "awkgram.tab.h"
|
||||
|
||||
static const char * const printname[95] = {
|
||||
"FIRSTTOKEN", /* 258 */
|
||||
|
@ -171,8 +145,8 @@ Cell *(*proctab[95])(Node **, int) = {
|
|||
jump, /* EXIT */
|
||||
forstat, /* FOR */
|
||||
nullproc, /* FUNC */
|
||||
sub, /* SUB */
|
||||
gsub, /* GSUB */
|
||||
dosub, /* SUB */
|
||||
dosub, /* GSUB */
|
||||
ifstat, /* IF */
|
||||
sindex, /* INDEX */
|
||||
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 │
|
||||
│ │
|
||||
│ 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/fmt/conv.h"
|
||||
#include "libc/math.h"
|
||||
#include "libc/mem/mem.h"
|
||||
#include "libc/str/str.h"
|
||||
#include "third_party/awk/awk.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.
|
||||
****************************************************************/
|
||||
|
||||
#define DEBUG
|
||||
#include <stdio.h>
|
||||
#include <math.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include "awk.h"
|
||||
|
||||
#define FULLTAB 2 /* rehash when table gets this x full */
|
||||
#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) {
|
||||
donerec = false; /* mark $0 invalid */
|
||||
setlastfld(f);
|
||||
DPRINTF("setting NF to %g\n", f);
|
||||
DPRINTF("setfval: setting NF to %g\n", f);
|
||||
} else if (isrec(vp)) {
|
||||
donefld = false; /* mark $1... invalid */
|
||||
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);
|
||||
if ((vp->tval & (NUM | STR)) == 0)
|
||||
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)) {
|
||||
donerec = false; /* mark $0 invalid */
|
||||
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 */
|
||||
f = getfval(vp);
|
||||
setlastfld(f);
|
||||
DPRINTF("setting NF to %g\n", f);
|
||||
DPRINTF("setsval: setting NF to %g\n", f);
|
||||
}
|
||||
|
||||
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 */
|
||||
{
|
||||
const char *os = is;
|
||||
int c, n;
|
||||
const uschar *s = (const uschar *) is;
|
||||
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);
|
||||
for (bp = buf; (c = *s) != delim; s++) {
|
||||
if (c == '\n')
|
||||
SYNTAX( "newline in string %.20s...", os );
|
||||
SYNTAX( "newline in string %.20s...", is );
|
||||
else if (c != '\\')
|
||||
*bp++ = c;
|
||||
else { /* \something */
|
||||
|
|
Loading…
Reference in a new issue