awk.c 99 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729273027312732273327342735273627372738273927402741274227432744274527462747274827492750275127522753275427552756275727582759276027612762276327642765276627672768276927702771277227732774277527762777277827792780278127822783278427852786278727882789279027912792279327942795279627972798279928002801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870287128722873287428752876287728782879288028812882288328842885288628872888288928902891289228932894289528962897289828992900290129022903290429052906290729082909291029112912291329142915291629172918291929202921292229232924292529262927292829292930293129322933293429352936293729382939294029412942294329442945294629472948294929502951295229532954295529562957295829592960296129622963296429652966296729682969297029712972297329742975297629772978297929802981298229832984298529862987298829892990299129922993299429952996299729982999300030013002300330043005300630073008300930103011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080308130823083308430853086308730883089309030913092309330943095309630973098309931003101310231033104310531063107310831093110311131123113311431153116311731183119312031213122312331243125312631273128312931303131313231333134313531363137313831393140314131423143314431453146314731483149315031513152315331543155315631573158315931603161316231633164316531663167316831693170317131723173317431753176317731783179318031813182318331843185318631873188318931903191319231933194319531963197319831993200320132023203320432053206320732083209321032113212321332143215321632173218321932203221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290329132923293329432953296329732983299330033013302330333043305330633073308330933103311331233133314331533163317331833193320332133223323332433253326332733283329333033313332333333343335333633373338333933403341334233433344334533463347334833493350335133523353335433553356335733583359336033613362336333643365336633673368336933703371337233733374337533763377337833793380338133823383338433853386338733883389339033913392339333943395339633973398339934003401340234033404340534063407340834093410341134123413341434153416341734183419342034213422342334243425342634273428342934303431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500350135023503350435053506350735083509351035113512351335143515351635173518351935203521352235233524352535263527352835293530353135323533353435353536353735383539354035413542354335443545354635473548354935503551355235533554355535563557355835593560356135623563356435653566356735683569357035713572357335743575357635773578357935803581358235833584358535863587358835893590359135923593359435953596359735983599360036013602360336043605360636073608360936103611361236133614361536163617361836193620362136223623362436253626362736283629363036313632363336343635363636373638363936403641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710371137123713371437153716371737183719372037213722372337243725372637273728372937303731373237333734373537363737373837393740374137423743374437453746374737483749375037513752375337543755375637573758375937603761376237633764376537663767376837693770377137723773377437753776377737783779378037813782378337843785378637873788378937903791379237933794379537963797379837993800380138023803380438053806380738083809381038113812381338143815381638173818381938203821382238233824382538263827382838293830383138323833383438353836383738383839384038413842384338443845384638473848384938503851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893
  1. /* vi: set sw=4 ts=4: */
  2. /*
  3. * awk implementation for busybox
  4. *
  5. * Copyright (C) 2002 by Dmitry Zakharov <dmit@crp.bank.gov.ua>
  6. *
  7. * Licensed under GPLv2 or later, see file LICENSE in this source tree.
  8. */
  9. //config:config AWK
  10. //config: bool "awk (24 kb)"
  11. //config: default y
  12. //config: help
  13. //config: Awk is used as a pattern scanning and processing language.
  14. //config:
  15. //config:config FEATURE_AWK_LIBM
  16. //config: bool "Enable math functions (requires libm)"
  17. //config: default y
  18. //config: depends on AWK
  19. //config: help
  20. //config: Enable math functions of the Awk programming language.
  21. //config: NOTE: This requires libm to be present for linking.
  22. //config:
  23. //config:config FEATURE_AWK_GNU_EXTENSIONS
  24. //config: bool "Enable a few GNU extensions"
  25. //config: default y
  26. //config: depends on AWK
  27. //config: help
  28. //config: Enable a few features from gawk:
  29. //config: * command line option -e AWK_PROGRAM
  30. //config: * simultaneous use of -f and -e on the command line.
  31. //config: This enables the use of awk library files.
  32. //config: Example: awk -f mylib.awk -e '{print myfunction($1);}' ...
  33. //applet:IF_AWK(APPLET_NOEXEC(awk, awk, BB_DIR_USR_BIN, BB_SUID_DROP, awk))
  34. //kbuild:lib-$(CONFIG_AWK) += awk.o
  35. //usage:#define awk_trivial_usage
  36. //usage: "[OPTIONS] [AWK_PROGRAM] [FILE]..."
  37. //usage:#define awk_full_usage "\n\n"
  38. //usage: " -v VAR=VAL Set variable"
  39. //usage: "\n -F SEP Use SEP as field separator"
  40. //usage: "\n -f/-E FILE Read program from FILE"
  41. //usage: IF_FEATURE_AWK_GNU_EXTENSIONS(
  42. //usage: "\n -e AWK_PROGRAM"
  43. //usage: )
  44. #include "libbb.h"
  45. #include "xregex.h"
  46. #include <math.h>
  47. /* This is a NOEXEC applet. Be very careful! */
  48. /* If you comment out one of these below, it will be #defined later
  49. * to perform debug printfs to stderr: */
  50. #define debug_printf_walker(...) do {} while (0)
  51. #define debug_printf_eval(...) do {} while (0)
  52. #define debug_printf_parse(...) do {} while (0)
  53. #ifndef debug_printf_walker
  54. # define debug_printf_walker(...) (fprintf(stderr, __VA_ARGS__))
  55. #endif
  56. #ifndef debug_printf_eval
  57. # define debug_printf_eval(...) (fprintf(stderr, __VA_ARGS__))
  58. #endif
  59. #ifndef debug_printf_parse
  60. # define debug_printf_parse(...) (fprintf(stderr, __VA_ARGS__))
  61. #else
  62. # define debug_parse_print_tc(...) ((void)0)
  63. #endif
  64. /* "+": stop on first non-option:
  65. * $ awk 'BEGIN { for(i=1; i<ARGC; ++i) { print i ": " ARGV[i] }}' -argz
  66. * 1: -argz
  67. */
  68. #define OPTSTR_AWK "+" \
  69. "F:v:f:" \
  70. IF_FEATURE_AWK_GNU_EXTENSIONS("e:E:") \
  71. "W:"
  72. enum {
  73. OPTBIT_F, /* define field separator */
  74. OPTBIT_v, /* define variable */
  75. OPTBIT_f, /* pull in awk program from file */
  76. IF_FEATURE_AWK_GNU_EXTENSIONS(OPTBIT_e,) /* -e AWK_PROGRAM */
  77. OPTBIT_W, /* -W ignored */
  78. OPT_F = 1 << OPTBIT_F,
  79. OPT_v = 1 << OPTBIT_v,
  80. OPT_f = 1 << OPTBIT_f,
  81. OPT_e = IF_FEATURE_AWK_GNU_EXTENSIONS((1 << OPTBIT_e)) + 0,
  82. OPT_W = 1 << OPTBIT_W
  83. };
  84. #define MAXVARFMT 240
  85. /* variable flags */
  86. #define VF_NUMBER 0x0001 /* 1 = primary type is number */
  87. #define VF_ARRAY 0x0002 /* 1 = it's an array */
  88. #define VF_CACHED 0x0100 /* 1 = num/str value has cached str/num eq */
  89. #define VF_USER 0x0200 /* 1 = user input (may be numeric string) */
  90. #define VF_SPECIAL 0x0400 /* 1 = requires extra handling when changed */
  91. #define VF_WALK 0x0800 /* 1 = variable has alloc'd x.walker list */
  92. #define VF_FSTR 0x1000 /* 1 = don't free() var::string (not malloced, or is owned by something else) */
  93. #define VF_CHILD 0x2000 /* 1 = function arg; x.parent points to source */
  94. #define VF_DIRTY 0x4000 /* 1 = variable was set explicitly */
  95. /* these flags are static, don't change them when value is changed */
  96. #define VF_DONTTOUCH (VF_ARRAY | VF_SPECIAL | VF_WALK | VF_CHILD | VF_DIRTY)
  97. typedef struct walker_list {
  98. char *end;
  99. char *cur;
  100. struct walker_list *prev;
  101. char wbuf[1];
  102. } walker_list;
  103. /* Variable */
  104. typedef struct var_s {
  105. unsigned type; /* flags */
  106. char *string;
  107. double number;
  108. union {
  109. int aidx; /* func arg idx (for compilation stage) */
  110. struct xhash_s *array; /* array ptr */
  111. struct var_s *parent; /* for func args, ptr to actual parameter */
  112. walker_list *walker; /* list of array elements (for..in) */
  113. } x;
  114. } var;
  115. /* Node chain (pattern-action chain, BEGIN, END, function bodies) */
  116. typedef struct chain_s {
  117. struct node_s *first;
  118. struct node_s *last;
  119. const char *programname;
  120. } chain;
  121. /* Function */
  122. typedef struct func_s {
  123. unsigned nargs;
  124. smallint defined;
  125. struct chain_s body;
  126. } func;
  127. /* I/O stream */
  128. typedef struct rstream_s {
  129. FILE *F;
  130. char *buffer;
  131. int adv;
  132. int size;
  133. int pos;
  134. smallint is_pipe;
  135. } rstream;
  136. typedef struct hash_item_s {
  137. union {
  138. struct var_s v; /* variable/array hash */
  139. struct rstream_s rs; /* redirect streams hash */
  140. struct func_s f; /* functions hash */
  141. } data;
  142. struct hash_item_s *next; /* next in chain */
  143. char name[1]; /* really it's longer */
  144. } hash_item;
  145. typedef struct xhash_s {
  146. unsigned nel; /* num of elements */
  147. unsigned csize; /* current hash size */
  148. unsigned nprime; /* next hash size in PRIMES[] */
  149. unsigned glen; /* summary length of item names */
  150. struct hash_item_s **items;
  151. } xhash;
  152. /* Tree node */
  153. typedef struct node_s {
  154. uint32_t info;
  155. unsigned lineno;
  156. union {
  157. struct node_s *n;
  158. var *v;
  159. int aidx;
  160. const char *new_progname;
  161. /* if TI_REGEXP node, points to regex_t[2] array (case sensitive and insensitive) */
  162. regex_t *re;
  163. } l;
  164. union {
  165. struct node_s *n;
  166. func *f;
  167. } r;
  168. union {
  169. struct node_s *n;
  170. } a;
  171. } node;
  172. typedef struct tsplitter_s {
  173. node n;
  174. regex_t re[2];
  175. } tsplitter;
  176. /* simple token classes */
  177. /* order and hex values are very important!!! See next_token() */
  178. #define TC_LPAREN (1 << 0) /* ( */
  179. #define TC_RPAREN (1 << 1) /* ) */
  180. #define TC_REGEXP (1 << 2) /* /.../ */
  181. #define TC_OUTRDR (1 << 3) /* | > >> */
  182. #define TC_UOPPOST (1 << 4) /* unary postfix operator ++ -- */
  183. #define TC_UOPPRE1 (1 << 5) /* unary prefix operator ++ -- $ */
  184. #define TC_BINOPX (1 << 6) /* two-opnd operator */
  185. #define TC_IN (1 << 7) /* 'in' */
  186. #define TC_COMMA (1 << 8) /* , */
  187. #define TC_PIPE (1 << 9) /* input redirection pipe | */
  188. #define TC_UOPPRE2 (1 << 10) /* unary prefix operator + - ! */
  189. #define TC_ARRTERM (1 << 11) /* ] */
  190. #define TC_LBRACE (1 << 12) /* { */
  191. #define TC_RBRACE (1 << 13) /* } */
  192. #define TC_SEMICOL (1 << 14) /* ; */
  193. #define TC_NEWLINE (1 << 15)
  194. #define TC_STATX (1 << 16) /* ctl statement (for, next...) */
  195. #define TC_WHILE (1 << 17) /* 'while' */
  196. #define TC_ELSE (1 << 18) /* 'else' */
  197. #define TC_BUILTIN (1 << 19)
  198. /* This costs ~50 bytes of code.
  199. * A separate class to support deprecated "length" form. If we don't need that
  200. * (i.e. if we demand that only "length()" with () is valid), then TC_LENGTH
  201. * can be merged with TC_BUILTIN:
  202. */
  203. #define TC_LENGTH (1 << 20) /* 'length' */
  204. #define TC_GETLINE (1 << 21) /* 'getline' */
  205. #define TC_FUNCDECL (1 << 22) /* 'function' 'func' */
  206. #define TC_BEGIN (1 << 23) /* 'BEGIN' */
  207. #define TC_END (1 << 24) /* 'END' */
  208. #define TC_EOF (1 << 25)
  209. #define TC_VARIABLE (1 << 26) /* name */
  210. #define TC_ARRAY (1 << 27) /* name[ */
  211. #define TC_FUNCTION (1 << 28) /* name( */
  212. #define TC_STRING (1 << 29) /* "..." */
  213. #define TC_NUMBER (1 << 30)
  214. #ifndef debug_parse_print_tc
  215. static void debug_parse_print_tc(uint32_t n)
  216. {
  217. if (n & TC_LPAREN ) debug_printf_parse(" LPAREN" );
  218. if (n & TC_RPAREN ) debug_printf_parse(" RPAREN" );
  219. if (n & TC_REGEXP ) debug_printf_parse(" REGEXP" );
  220. if (n & TC_OUTRDR ) debug_printf_parse(" OUTRDR" );
  221. if (n & TC_UOPPOST ) debug_printf_parse(" UOPPOST" );
  222. if (n & TC_UOPPRE1 ) debug_printf_parse(" UOPPRE1" );
  223. if (n & TC_BINOPX ) debug_printf_parse(" BINOPX" );
  224. if (n & TC_IN ) debug_printf_parse(" IN" );
  225. if (n & TC_COMMA ) debug_printf_parse(" COMMA" );
  226. if (n & TC_PIPE ) debug_printf_parse(" PIPE" );
  227. if (n & TC_UOPPRE2 ) debug_printf_parse(" UOPPRE2" );
  228. if (n & TC_ARRTERM ) debug_printf_parse(" ARRTERM" );
  229. if (n & TC_LBRACE ) debug_printf_parse(" LBRACE" );
  230. if (n & TC_RBRACE ) debug_printf_parse(" RBRACE" );
  231. if (n & TC_SEMICOL ) debug_printf_parse(" SEMICOL" );
  232. if (n & TC_NEWLINE ) debug_printf_parse(" NEWLINE" );
  233. if (n & TC_STATX ) debug_printf_parse(" STATX" );
  234. if (n & TC_WHILE ) debug_printf_parse(" WHILE" );
  235. if (n & TC_ELSE ) debug_printf_parse(" ELSE" );
  236. if (n & TC_BUILTIN ) debug_printf_parse(" BUILTIN" );
  237. if (n & TC_LENGTH ) debug_printf_parse(" LENGTH" );
  238. if (n & TC_GETLINE ) debug_printf_parse(" GETLINE" );
  239. if (n & TC_FUNCDECL) debug_printf_parse(" FUNCDECL");
  240. if (n & TC_BEGIN ) debug_printf_parse(" BEGIN" );
  241. if (n & TC_END ) debug_printf_parse(" END" );
  242. if (n & TC_EOF ) debug_printf_parse(" EOF" );
  243. if (n & TC_VARIABLE) debug_printf_parse(" VARIABLE");
  244. if (n & TC_ARRAY ) debug_printf_parse(" ARRAY" );
  245. if (n & TC_FUNCTION) debug_printf_parse(" FUNCTION");
  246. if (n & TC_STRING ) debug_printf_parse(" STRING" );
  247. if (n & TC_NUMBER ) debug_printf_parse(" NUMBER" );
  248. }
  249. #endif
  250. /* combined token classes ("token [class] sets") */
  251. #define TS_UOPPRE (TC_UOPPRE1 | TC_UOPPRE2)
  252. #define TS_BINOP (TC_BINOPX | TC_COMMA | TC_PIPE | TC_IN)
  253. //#define TS_UNARYOP (TS_UOPPRE | TC_UOPPOST)
  254. #define TS_OPERAND (TC_VARIABLE | TC_ARRAY | TC_FUNCTION \
  255. | TC_BUILTIN | TC_LENGTH | TC_GETLINE \
  256. | TC_LPAREN | TC_STRING | TC_NUMBER)
  257. #define TS_LVALUE (TC_VARIABLE | TC_ARRAY)
  258. #define TS_STATEMNT (TC_STATX | TC_WHILE)
  259. /* word tokens, cannot mean something else if not expected */
  260. #define TS_WORD (TC_IN | TS_STATEMNT | TC_ELSE \
  261. | TC_BUILTIN | TC_LENGTH | TC_GETLINE \
  262. | TC_FUNCDECL | TC_BEGIN | TC_END)
  263. /* discard newlines after these */
  264. #define TS_NOTERM (TS_BINOP | TC_COMMA | TC_LBRACE | TC_RBRACE \
  265. | TC_SEMICOL | TC_NEWLINE)
  266. /* what can expression begin with */
  267. #define TS_OPSEQ (TS_OPERAND | TS_UOPPRE | TC_REGEXP)
  268. /* what can group begin with */
  269. #define TS_GRPSEQ (TS_OPSEQ | TS_STATEMNT \
  270. | TC_SEMICOL | TC_NEWLINE | TC_LBRACE)
  271. /* if previous token class is CONCAT_L and next is CONCAT_R, concatenation */
  272. /* operator is inserted between them */
  273. #define TS_CONCAT_L (TC_VARIABLE | TC_ARRTERM | TC_RPAREN \
  274. | TC_STRING | TC_NUMBER | TC_UOPPOST \
  275. | TC_LENGTH)
  276. #define TS_CONCAT_R (TS_OPERAND | TS_UOPPRE)
  277. #define OF_RES1 0x010000 /* evaluate(left_node) */
  278. #define OF_RES2 0x020000 /* evaluate(right_node) */
  279. #define OF_STR1 0x040000 /* ...and use its string value */
  280. #define OF_STR2 0x080000 /* ...and use its string value */
  281. #define OF_NUM1 0x100000 /* ...and use its numeric value */
  282. #define OF_REQUIRED 0x200000 /* left_node must not be NULL */
  283. #define OF_CHECKED 0x400000 /* range pattern flip-flop bit */
  284. /* combined operator flags */
  285. #define xx 0
  286. #define xV OF_RES2
  287. #define xS (OF_RES2 | OF_STR2)
  288. #define Vx OF_RES1
  289. #define Rx OF_REQUIRED
  290. #define VV (OF_RES1 | OF_RES2)
  291. #define Nx (OF_RES1 | OF_NUM1)
  292. #define NV (OF_RES1 | OF_NUM1 | OF_RES2)
  293. #define Sx (OF_RES1 | OF_STR1)
  294. #define SV (OF_RES1 | OF_STR1 | OF_RES2)
  295. #define SS (OF_RES1 | OF_STR1 | OF_RES2 | OF_STR2)
  296. #define OPCLSMASK 0xFF00
  297. #define OPNMASK 0x007F
  298. /* operator precedence is the highest byte (even: r->l, odd: l->r grouping)
  299. * (for builtins the byte has a different meaning)
  300. */
  301. #undef P
  302. #undef PRIMASK
  303. #undef PRIMASK2
  304. #define PRIMASK 0x7F000000
  305. #define PRIMASK2 0x7E000000
  306. /* Smaller 'x' means _higher_ operator precedence */
  307. #define PRECEDENCE(x) (x << 24)
  308. #define P(x) PRECEDENCE(x)
  309. #define LOWEST_PRECEDENCE PRIMASK
  310. /* Operation classes */
  311. #define SHIFT_TIL_THIS 0x0600
  312. #define RECUR_FROM_THIS 0x1000
  313. enum {
  314. OC_DELETE = 0x0100, OC_EXEC = 0x0200, OC_NEWSOURCE = 0x0300,
  315. OC_PRINT = 0x0400, OC_PRINTF = 0x0500, OC_WALKINIT = 0x0600,
  316. OC_BR = 0x0700, OC_BREAK = 0x0800, OC_CONTINUE = 0x0900,
  317. OC_EXIT = 0x0a00, OC_NEXT = 0x0b00, OC_NEXTFILE = 0x0c00,
  318. OC_TEST = 0x0d00, OC_WALKNEXT = 0x0e00,
  319. OC_BINARY = 0x1000, OC_BUILTIN = 0x1100, OC_COLON = 0x1200,
  320. OC_COMMA = 0x1300, OC_COMPARE = 0x1400, OC_CONCAT = 0x1500,
  321. OC_FBLTIN = 0x1600, OC_FIELD = 0x1700, OC_FNARG = 0x1800,
  322. OC_FUNC = 0x1900, OC_GETLINE = 0x1a00, OC_IN = 0x1b00,
  323. OC_LAND = 0x1c00, OC_LOR = 0x1d00, OC_MATCH = 0x1e00,
  324. OC_MOVE = 0x1f00, OC_PGETLINE = 0x2000, OC_REGEXP = 0x2100,
  325. OC_REPLACE = 0x2200, OC_RETURN = 0x2300, OC_SPRINTF = 0x2400,
  326. OC_TERNARY = 0x2500, OC_UNARY = 0x2600, OC_VAR = 0x2700,
  327. OC_CONST = 0x2800, OC_DONE = 0x2900,
  328. ST_IF = 0x3000, ST_DO = 0x3100, ST_FOR = 0x3200,
  329. ST_WHILE = 0x3300
  330. };
  331. /* simple builtins */
  332. enum {
  333. F_in, F_rn, F_co, F_ex, F_lg, F_si, F_sq, F_sr,
  334. F_ti, F_le, F_sy, F_ff, F_cl
  335. };
  336. /* builtins */
  337. enum {
  338. B_a2, B_ix, B_ma, B_sp, B_ss, B_ti, B_mt, B_lo, B_up,
  339. B_ge, B_gs, B_su,
  340. B_an, B_co, B_ls, B_or, B_rs, B_xo,
  341. };
  342. /* tokens and their corresponding info values */
  343. #define NTC "\377" /* switch to next token class (tc<<1) */
  344. #define NTCC '\377'
  345. static const char tokenlist[] ALIGN1 =
  346. "\1(" NTC /* TC_LPAREN */
  347. "\1)" NTC /* TC_RPAREN */
  348. "\1/" NTC /* TC_REGEXP */
  349. "\2>>" "\1>" "\1|" NTC /* TC_OUTRDR */
  350. "\2++" "\2--" NTC /* TC_UOPPOST */
  351. "\2++" "\2--" "\1$" NTC /* TC_UOPPRE1 */
  352. "\2==" "\1=" "\2+=" "\2-=" /* TC_BINOPX */
  353. "\2*=" "\2/=" "\2%=" "\2^="
  354. "\1+" "\1-" "\3**=" "\2**"
  355. "\1/" "\1%" "\1^" "\1*"
  356. "\2!=" "\2>=" "\2<=" "\1>"
  357. "\1<" "\2!~" "\1~" "\2&&"
  358. "\2||" "\1?" "\1:" NTC
  359. "\2in" NTC /* TC_IN */
  360. "\1," NTC /* TC_COMMA */
  361. "\1|" NTC /* TC_PIPE */
  362. "\1+" "\1-" "\1!" NTC /* TC_UOPPRE2 */
  363. "\1]" NTC /* TC_ARRTERM */
  364. "\1{" NTC /* TC_LBRACE */
  365. "\1}" NTC /* TC_RBRACE */
  366. "\1;" NTC /* TC_SEMICOL */
  367. "\1\n" NTC /* TC_NEWLINE */
  368. "\2if" "\2do" "\3for" "\5break" /* TC_STATX */
  369. "\10continue" "\6delete" "\5print"
  370. "\6printf" "\4next" "\10nextfile"
  371. "\6return" "\4exit" NTC
  372. "\5while" NTC /* TC_WHILE */
  373. "\4else" NTC /* TC_ELSE */
  374. "\3and" "\5compl" "\6lshift" "\2or" /* TC_BUILTIN */
  375. "\6rshift" "\3xor"
  376. "\5close" "\6system" "\6fflush" "\5atan2"
  377. "\3cos" "\3exp" "\3int" "\3log"
  378. "\4rand" "\3sin" "\4sqrt" "\5srand"
  379. "\6gensub" "\4gsub" "\5index" /* "\6length" was here */
  380. "\5match" "\5split" "\7sprintf" "\3sub"
  381. "\6substr" "\7systime" "\10strftime" "\6mktime"
  382. "\7tolower" "\7toupper" NTC
  383. "\6length" NTC /* TC_LENGTH */
  384. "\7getline" NTC /* TC_GETLINE */
  385. "\4func" "\10function" NTC /* TC_FUNCDECL */
  386. "\5BEGIN" NTC /* TC_BEGIN */
  387. "\3END" /* TC_END */
  388. /* compiler adds trailing "\0" */
  389. ;
  390. static const uint32_t tokeninfo[] ALIGN4 = {
  391. 0, /* ( */
  392. 0, /* ) */
  393. #define TI_REGEXP OC_REGEXP
  394. TI_REGEXP, /* / */
  395. /* >> > | */
  396. xS|'a', xS|'w', xS|'|',
  397. /* ++ -- */
  398. OC_UNARY|xV|P(9)|'p', OC_UNARY|xV|P(9)|'m',
  399. #define TI_PREINC (OC_UNARY|xV|P(9)|'P')
  400. #define TI_PREDEC (OC_UNARY|xV|P(9)|'M')
  401. /* ++ -- $ */
  402. TI_PREINC, TI_PREDEC, OC_FIELD|xV|P(5),
  403. /* == = += -= */
  404. OC_COMPARE|VV|P(39)|5, OC_MOVE|VV|P(74), OC_REPLACE|NV|P(74)|'+', OC_REPLACE|NV|P(74)|'-',
  405. /* *= /= %= ^= (^ is exponentiation, NOT xor) */
  406. OC_REPLACE|NV|P(74)|'*', OC_REPLACE|NV|P(74)|'/', OC_REPLACE|NV|P(74)|'%', OC_REPLACE|NV|P(74)|'&',
  407. /* + - **= ** */
  408. OC_BINARY|NV|P(29)|'+', OC_BINARY|NV|P(29)|'-', OC_REPLACE|NV|P(74)|'&', OC_BINARY|NV|P(15)|'&',
  409. /* / % ^ * */
  410. OC_BINARY|NV|P(25)|'/', OC_BINARY|NV|P(25)|'%', OC_BINARY|NV|P(15)|'&', OC_BINARY|NV|P(25)|'*',
  411. /* != >= <= > */
  412. OC_COMPARE|VV|P(39)|4, OC_COMPARE|VV|P(39)|3, OC_COMPARE|VV|P(39)|0, OC_COMPARE|VV|P(39)|1,
  413. #define TI_LESS (OC_COMPARE|VV|P(39)|2)
  414. /* < !~ ~ && */
  415. TI_LESS, OC_MATCH|Sx|P(45)|'!', OC_MATCH|Sx|P(45)|'~', OC_LAND|Vx|P(55),
  416. #define TI_TERNARY (OC_TERNARY|Vx|P(64)|'?')
  417. #define TI_COLON (OC_COLON|xx|P(67)|':')
  418. /* || ? : */
  419. OC_LOR|Vx|P(59), TI_TERNARY, TI_COLON,
  420. #define TI_IN (OC_IN|SV|P(49))
  421. TI_IN,
  422. #define TI_COMMA (OC_COMMA|SS|P(80))
  423. TI_COMMA,
  424. #define TI_PGETLINE (OC_PGETLINE|SV|P(37))
  425. TI_PGETLINE, /* | */
  426. /* + - ! */
  427. OC_UNARY|xV|P(19)|'+', OC_UNARY|xV|P(19)|'-', OC_UNARY|xV|P(19)|'!',
  428. 0, /* ] */
  429. 0, /* { */
  430. 0, /* } */
  431. 0, /* ; */
  432. 0, /* \n */
  433. ST_IF, ST_DO, ST_FOR, OC_BREAK,
  434. OC_CONTINUE, OC_DELETE|Rx, OC_PRINT,
  435. OC_PRINTF, OC_NEXT, OC_NEXTFILE,
  436. OC_RETURN|Vx, OC_EXIT|Nx,
  437. ST_WHILE,
  438. 0, /* else */
  439. // OC_B's are builtins with enforced minimum number of arguments (two upper bits).
  440. // Highest byte bit pattern: nn s3s2s1 v3v2v1
  441. // nn - min. number of args, sN - resolve Nth arg to string, vN - resolve to var
  442. // OC_F's are builtins with zero or one argument.
  443. // |Rx| enforces that arg is present for: system, close, cos, sin, exp, int, log, sqrt
  444. // Check for no args is present in builtins' code (not in this table): rand, systime
  445. // Have one _optional_ arg: fflush, srand, length
  446. #define OC_B OC_BUILTIN
  447. #define OC_F OC_FBLTIN
  448. #define A1 P(0x40) /*one arg*/
  449. #define A2 P(0x80) /*two args*/
  450. #define A3 P(0xc0) /*three args*/
  451. #define __v P(1)
  452. #define _vv P(3)
  453. #define __s__v P(9)
  454. #define __s_vv P(0x0b)
  455. #define __svvv P(0x0f)
  456. #define _ss_vv P(0x1b)
  457. #define _s_vv_ P(0x16)
  458. #define ss_vv_ P(0x36)
  459. OC_B|B_an|_vv|A2, OC_B|B_co|__v|A1, OC_B|B_ls|_vv|A2, OC_B|B_or|_vv|A2, // and compl lshift or
  460. OC_B|B_rs|_vv|A2, OC_B|B_xo|_vv|A2, // rshift xor
  461. OC_F|F_cl|Sx|Rx, OC_F|F_sy|Sx|Rx, OC_F|F_ff|Sx, OC_B|B_a2|_vv|A2, // close system fflush atan2
  462. OC_F|F_co|Nx|Rx, OC_F|F_ex|Nx|Rx, OC_F|F_in|Nx|Rx, OC_F|F_lg|Nx|Rx, // cos exp int log
  463. OC_F|F_rn, OC_F|F_si|Nx|Rx, OC_F|F_sq|Nx|Rx, OC_F|F_sr|Nx, // rand sin sqrt srand
  464. OC_B|B_ge|_s_vv_|A3,OC_B|B_gs|ss_vv_|A2,OC_B|B_ix|_ss_vv|A2, // gensub gsub index /*length was here*/
  465. OC_B|B_ma|__s__v|A2,OC_B|B_sp|__s_vv|A2,OC_SPRINTF, OC_B|B_su|ss_vv_|A2,// match split sprintf sub
  466. OC_B|B_ss|__svvv|A2,OC_F|F_ti, OC_B|B_ti|__s_vv, OC_B|B_mt|__s_vv|A1,// substr systime strftime mktime
  467. OC_B|B_lo|__s__v|A1,OC_B|B_up|__s__v|A1, // tolower toupper
  468. OC_F|F_le|Sx, // length
  469. OC_GETLINE|SV, // getline
  470. 0, 0, // func function
  471. 0, // BEGIN
  472. 0 // END
  473. #undef A1
  474. #undef A2
  475. #undef A3
  476. #undef OC_B
  477. #undef OC_F
  478. };
  479. /* gawk 5.1.1 manpage says the precedence of comparisons and assignments are as follows:
  480. * ......
  481. * < > <= >= == !=
  482. * ~ !~
  483. * in
  484. * &&
  485. * ||
  486. * ?:
  487. * = += -= *= /= %= ^=
  488. * But there are some abnormalities:
  489. * awk 'BEGIN { print v=3==3,v }' - ok:
  490. * 1 1
  491. * awk 'BEGIN { print 3==v=3,v }' - wrong, (3==v)=3 is not a valid assignment:
  492. * 1 3
  493. * This also unexpectedly works: echo "foo" | awk '$1==$1="foo" {print $1}'
  494. * More than one comparison op fails to parse:
  495. * awk 'BEGIN { print 3==3==3 }' - syntax error (wrong, should work)
  496. * awk 'BEGIN { print 3==3!=3 }' - syntax error (wrong, should work)
  497. *
  498. * The ternary a?b:c works as follows in gawk: "a" can't be assignment
  499. * ("= has lower precedence than ?") but inside "b" or "c", assignment
  500. * is higher precedence:
  501. * awk 'BEGIN { u=v=w=1; print u=0?v=4:w=5; print u,v,w }'
  502. * 5
  503. * 5 1 5
  504. * This differs from C and shell's "test" rules for ?: which have implicit ()
  505. * around "b" in ?:, but not around "c" - they would barf on "w=5" above.
  506. * gawk allows nesting of ?: - this works:
  507. * u=0?v=4?5:6:w=7?8:9 means u=0?(v=4?5:6):(w=7?8:9)
  508. * bbox is buggy here, requires parens: "u=0?(v=4):(w=5)"
  509. */
  510. /* internal variable names and their initial values */
  511. /* asterisk marks SPECIAL vars; $ is just no-named Field0 */
  512. enum {
  513. CONVFMT, OFMT, FS, OFS,
  514. ORS, RS, RT, FILENAME,
  515. SUBSEP, F0, ARGIND, ARGC,
  516. ARGV, ERRNO, FNR, NR,
  517. NF, IGNORECASE, ENVIRON, NUM_INTERNAL_VARS
  518. };
  519. static const char vNames[] ALIGN1 =
  520. "CONVFMT\0" "OFMT\0" "FS\0*" "OFS\0"
  521. "ORS\0" "RS\0*" "RT\0" "FILENAME\0"
  522. "SUBSEP\0" "$\0*" "ARGIND\0" "ARGC\0"
  523. "ARGV\0" "ERRNO\0" "FNR\0" "NR\0"
  524. "NF\0*" "IGNORECASE\0*" "ENVIRON\0" "\0";
  525. static const char vValues[] ALIGN1 =
  526. "%.6g\0" "%.6g\0" " \0" " \0"
  527. "\n\0" "\n\0" "\0" "\0"
  528. "\034\0" "\0" "\377";
  529. #define str_percent_dot_6g vValues
  530. /* hash size may grow to these values */
  531. #define FIRST_PRIME 61
  532. static const uint16_t PRIMES[] ALIGN2 = { 251, 1021, 4093, 16381, 65521 };
  533. /* Globals. Split in two parts so that first one is addressed
  534. * with (mostly short) negative offsets.
  535. * NB: it's unsafe to put members of type "double"
  536. * into globals2 (gcc may fail to align them).
  537. */
  538. struct globals {
  539. double t_double;
  540. chain beginseq, mainseq, endseq;
  541. chain *seq;
  542. node *break_ptr, *continue_ptr;
  543. xhash *ahash; /* argument names, used only while parsing function bodies */
  544. xhash *fnhash; /* function names, used only in parsing stage */
  545. xhash *vhash; /* variables and arrays */
  546. //xhash *fdhash; /* file objects, used only in execution stage */
  547. //we are reusing ahash as fdhash, via define (see later)
  548. const char *g_progname;
  549. int g_lineno;
  550. int num_fields; /* number of existing $N's */
  551. unsigned num_alloc_fields; /* current size of Fields[] */
  552. /* NB: Fields[0] corresponds to $1, not to $0 */
  553. var *Fields;
  554. char *g_pos;
  555. char g_saved_ch;
  556. smallint got_program;
  557. smallint icase;
  558. smallint exiting;
  559. smallint nextrec;
  560. smallint nextfile;
  561. smallint is_f0_split;
  562. smallint t_rollback;
  563. /* former statics from various functions */
  564. smallint next_token__concat_inserted;
  565. uint32_t next_token__save_tclass;
  566. uint32_t next_token__save_info;
  567. };
  568. struct globals2 {
  569. uint32_t t_info; /* often used */
  570. uint32_t t_tclass;
  571. char *t_string;
  572. int t_lineno;
  573. var *intvar[NUM_INTERNAL_VARS]; /* often used */
  574. rstream iF;
  575. /* former statics from various functions */
  576. char *split_f0__fstrings;
  577. unsigned next_input_file__argind;
  578. smallint next_input_file__input_file_seen;
  579. smalluint exitcode;
  580. unsigned evaluate__seed;
  581. var *evaluate__fnargs;
  582. regex_t evaluate__sreg;
  583. var ptest__tmpvar;
  584. var awk_printf__tmpvar;
  585. var as_regex__tmpvar;
  586. var exit__tmpvar;
  587. var main__tmpvar;
  588. tsplitter exec_builtin__tspl;
  589. /* biggest and least used members go last */
  590. tsplitter fsplitter, rsplitter;
  591. char g_buf[MAXVARFMT + 1];
  592. };
  593. #define G1 (ptr_to_globals[-1])
  594. #define G (*(struct globals2 *)ptr_to_globals)
  595. /* For debug. nm --size-sort awk.o | grep -vi ' [tr] ' */
  596. //char G1size[sizeof(G1)]; // 0x70
  597. //char Gsize[sizeof(G)]; // 0x2f8
  598. /* Trying to keep most of members accessible with short offsets: */
  599. //char Gofs_seed[offsetof(struct globals2, evaluate__seed)]; // 0x7c
  600. #define t_double (G1.t_double )
  601. #define beginseq (G1.beginseq )
  602. #define mainseq (G1.mainseq )
  603. #define endseq (G1.endseq )
  604. #define seq (G1.seq )
  605. #define break_ptr (G1.break_ptr )
  606. #define continue_ptr (G1.continue_ptr)
  607. #define ahash (G1.ahash )
  608. #define fnhash (G1.fnhash )
  609. #define vhash (G1.vhash )
  610. #define fdhash ahash
  611. //^^^^^^^^^^^^^^^^^^ ahash is cleared after every function parsing,
  612. // and ends up empty after parsing phase. Thus, we can simply reuse it
  613. // for fdhash in execution stage.
  614. #define g_progname (G1.g_progname )
  615. #define g_lineno (G1.g_lineno )
  616. #define num_fields (G1.num_fields )
  617. #define num_alloc_fields (G1.num_alloc_fields)
  618. #define Fields (G1.Fields )
  619. #define g_pos (G1.g_pos )
  620. #define g_saved_ch (G1.g_saved_ch )
  621. #define got_program (G1.got_program )
  622. #define icase (G1.icase )
  623. #define exiting (G1.exiting )
  624. #define nextrec (G1.nextrec )
  625. #define nextfile (G1.nextfile )
  626. #define is_f0_split (G1.is_f0_split )
  627. #define t_rollback (G1.t_rollback )
  628. #define t_info (G.t_info )
  629. #define t_tclass (G.t_tclass )
  630. #define t_string (G.t_string )
  631. #define t_lineno (G.t_lineno )
  632. #define intvar (G.intvar )
  633. #define iF (G.iF )
  634. #define fsplitter (G.fsplitter )
  635. #define rsplitter (G.rsplitter )
  636. #define g_buf (G.g_buf )
  637. #define INIT_G() do { \
  638. SET_PTR_TO_GLOBALS((char*)xzalloc(sizeof(G1)+sizeof(G)) + sizeof(G1)); \
  639. t_tclass = TC_NEWLINE; \
  640. G.evaluate__seed = 1; \
  641. } while (0)
  642. static const char EMSG_UNEXP_EOS[] ALIGN1 = "Unexpected end of string";
  643. static const char EMSG_UNEXP_TOKEN[] ALIGN1 = "Unexpected token";
  644. static const char EMSG_DIV_BY_ZERO[] ALIGN1 = "Division by zero";
  645. static const char EMSG_INV_FMT[] ALIGN1 = "Invalid format specifier";
  646. static const char EMSG_TOO_FEW_ARGS[] ALIGN1 = "Too few arguments";
  647. static const char EMSG_NOT_ARRAY[] ALIGN1 = "Not an array";
  648. static const char EMSG_POSSIBLE_ERROR[] ALIGN1 = "Possible syntax error";
  649. static const char EMSG_UNDEF_FUNC[] ALIGN1 = "Call to undefined function";
  650. static const char EMSG_NO_MATH[] ALIGN1 = "Math support is not compiled in";
  651. static const char EMSG_NEGATIVE_FIELD[] ALIGN1 = "Access to negative field";
  652. static int awk_exit(void) NORETURN;
  653. static void syntax_error(const char *message) NORETURN;
  654. static void syntax_error(const char *message)
  655. {
  656. bb_error_msg_and_die("%s:%i: %s", g_progname, g_lineno, message);
  657. }
  658. /* ---- hash stuff ---- */
  659. static unsigned hashidx(const char *name)
  660. {
  661. unsigned idx = 0;
  662. while (*name)
  663. idx = *name++ + (idx << 6) - idx;
  664. return idx;
  665. }
  666. /* create new hash */
  667. static xhash *hash_init(void)
  668. {
  669. xhash *newhash;
  670. newhash = xzalloc(sizeof(*newhash));
  671. newhash->csize = FIRST_PRIME;
  672. newhash->items = xzalloc(FIRST_PRIME * sizeof(newhash->items[0]));
  673. return newhash;
  674. }
  675. static void hash_clear(xhash *hash)
  676. {
  677. unsigned i;
  678. hash_item *hi, *thi;
  679. for (i = 0; i < hash->csize; i++) {
  680. hi = hash->items[i];
  681. while (hi) {
  682. thi = hi;
  683. hi = hi->next;
  684. //FIXME: this assumes that it's a hash of *variables*:
  685. free(thi->data.v.string);
  686. free(thi);
  687. }
  688. hash->items[i] = NULL;
  689. }
  690. hash->glen = hash->nel = 0;
  691. }
  692. #if 0 //UNUSED
  693. static void hash_free(xhash *hash)
  694. {
  695. hash_clear(hash);
  696. free(hash->items);
  697. free(hash);
  698. }
  699. #endif
  700. /* find item in hash, return ptr to data, NULL if not found */
  701. static NOINLINE void *hash_search3(xhash *hash, const char *name, unsigned idx)
  702. {
  703. hash_item *hi;
  704. hi = hash->items[idx % hash->csize];
  705. while (hi) {
  706. if (strcmp(hi->name, name) == 0)
  707. return &hi->data;
  708. hi = hi->next;
  709. }
  710. return NULL;
  711. }
  712. static void *hash_search(xhash *hash, const char *name)
  713. {
  714. return hash_search3(hash, name, hashidx(name));
  715. }
  716. /* grow hash if it becomes too big */
  717. static void hash_rebuild(xhash *hash)
  718. {
  719. unsigned newsize, i, idx;
  720. hash_item **newitems, *hi, *thi;
  721. if (hash->nprime == ARRAY_SIZE(PRIMES))
  722. return;
  723. newsize = PRIMES[hash->nprime++];
  724. newitems = xzalloc(newsize * sizeof(newitems[0]));
  725. for (i = 0; i < hash->csize; i++) {
  726. hi = hash->items[i];
  727. while (hi) {
  728. thi = hi;
  729. hi = thi->next;
  730. idx = hashidx(thi->name) % newsize;
  731. thi->next = newitems[idx];
  732. newitems[idx] = thi;
  733. }
  734. }
  735. free(hash->items);
  736. hash->csize = newsize;
  737. hash->items = newitems;
  738. }
  739. /* find item in hash, add it if necessary. Return ptr to data */
  740. static void *hash_find(xhash *hash, const char *name)
  741. {
  742. hash_item *hi;
  743. unsigned idx;
  744. int l;
  745. idx = hashidx(name);
  746. hi = hash_search3(hash, name, idx);
  747. if (!hi) {
  748. if (++hash->nel > hash->csize * 8)
  749. hash_rebuild(hash);
  750. l = strlen(name) + 1;
  751. hi = xzalloc(sizeof(*hi) + l);
  752. strcpy(hi->name, name);
  753. idx = idx % hash->csize;
  754. hi->next = hash->items[idx];
  755. hash->items[idx] = hi;
  756. hash->glen += l;
  757. }
  758. return &hi->data;
  759. }
  760. #define findvar(hash, name) ((var*) hash_find((hash), (name)))
  761. #define newvar(name) ((var*) hash_find(vhash, (name)))
  762. #define newfile(name) ((rstream*)hash_find(fdhash, (name)))
  763. #define newfunc(name) ((func*) hash_find(fnhash, (name)))
  764. static void hash_remove(xhash *hash, const char *name)
  765. {
  766. hash_item *hi, **phi;
  767. phi = &hash->items[hashidx(name) % hash->csize];
  768. while (*phi) {
  769. hi = *phi;
  770. if (strcmp(hi->name, name) == 0) {
  771. hash->glen -= (strlen(name) + 1);
  772. hash->nel--;
  773. *phi = hi->next;
  774. free(hi);
  775. break;
  776. }
  777. phi = &hi->next;
  778. }
  779. }
  780. /* ------ some useful functions ------ */
  781. static char *skip_spaces(char *p)
  782. {
  783. for (;;) {
  784. if (*p == '\\' && p[1] == '\n') {
  785. p++;
  786. t_lineno++;
  787. } else if (*p != ' ' && *p != '\t') {
  788. break;
  789. }
  790. p++;
  791. }
  792. return p;
  793. }
  794. /* returns old *s, advances *s past word and terminating NUL */
  795. static char *nextword(char **s)
  796. {
  797. char *p = *s;
  798. char *q = p;
  799. while (*q++ != '\0')
  800. continue;
  801. *s = q;
  802. return p;
  803. }
  804. static char nextchar(char **s)
  805. {
  806. char c, *pps;
  807. again:
  808. c = *(*s)++;
  809. pps = *s;
  810. if (c == '\\')
  811. c = bb_process_escape_sequence((const char**)s);
  812. /* Example awk statement:
  813. * s = "abc\"def"
  814. * we must treat \" as "
  815. */
  816. if (c == '\\' && *s == pps) { /* unrecognized \z? */
  817. c = *(*s); /* yes, fetch z */
  818. if (c) { /* advance unless z = NUL */
  819. (*s)++;
  820. if (c == '\n') /* \<newline>? eat it */
  821. goto again;
  822. }
  823. }
  824. return c;
  825. }
  826. /* TODO: merge with strcpy_and_process_escape_sequences()?
  827. */
  828. static void unescape_string_in_place(char *s1)
  829. {
  830. char *s = s1;
  831. while ((*s1 = nextchar(&s)) != '\0')
  832. s1++;
  833. }
  834. static ALWAYS_INLINE int isalnum_(int c)
  835. {
  836. return (isalnum(c) || c == '_');
  837. }
  838. static double my_strtod(char **pp)
  839. {
  840. char *cp = *pp;
  841. return strtod(cp, pp);
  842. }
  843. #if ENABLE_DESKTOP
  844. static double my_strtod_or_hexoct(char **pp)
  845. {
  846. char *cp = *pp;
  847. if (cp[0] == '0') {
  848. /* Might be hex or octal integer: 0x123abc or 07777 */
  849. char c = (cp[1] | 0x20);
  850. if (c == 'x' || isdigit(cp[1])) {
  851. unsigned long long ull = strtoull(cp, pp, 0);
  852. if (c == 'x')
  853. return ull;
  854. c = **pp;
  855. if (!isdigit(c) && c != '.')
  856. return ull;
  857. /* else: it may be a floating number. Examples:
  858. * 009.123 (*pp points to '9')
  859. * 000.123 (*pp points to '.')
  860. * fall through to strtod.
  861. */
  862. }
  863. }
  864. return strtod(cp, pp);
  865. }
  866. #else
  867. # define my_strtod_or_hexoct(p) my_strtod(p)
  868. #endif
  869. /* -------- working with variables (set/get/copy/etc) -------- */
  870. static const char *fmt_num(const char *format, double n)
  871. {
  872. if (n == (long long)n) {
  873. snprintf(g_buf, MAXVARFMT, "%lld", (long long)n);
  874. } else {
  875. const char *s = format;
  876. char c;
  877. do { c = *s; } while (c && *++s);
  878. if (strchr("diouxX", c)) {
  879. snprintf(g_buf, MAXVARFMT, format, (int)n);
  880. } else if (strchr("eEfFgGaA", c)) {
  881. snprintf(g_buf, MAXVARFMT, format, n);
  882. } else {
  883. syntax_error(EMSG_INV_FMT);
  884. }
  885. }
  886. return g_buf;
  887. }
  888. static xhash *iamarray(var *a)
  889. {
  890. while (a->type & VF_CHILD)
  891. a = a->x.parent;
  892. if (!(a->type & VF_ARRAY)) {
  893. a->type |= VF_ARRAY;
  894. a->x.array = hash_init();
  895. }
  896. return a->x.array;
  897. }
  898. #define clear_array(array) hash_clear(array)
  899. /* clear a variable */
  900. static var *clrvar(var *v)
  901. {
  902. if (!(v->type & VF_FSTR))
  903. free(v->string);
  904. v->type &= VF_DONTTOUCH;
  905. v->type |= VF_DIRTY;
  906. v->string = NULL;
  907. return v;
  908. }
  909. static void handle_special(var *);
  910. /* assign string value to variable */
  911. static var *setvar_p(var *v, char *value)
  912. {
  913. clrvar(v);
  914. v->string = value;
  915. handle_special(v);
  916. return v;
  917. }
  918. /* same as setvar_p but make a copy of string */
  919. static var *setvar_s(var *v, const char *value)
  920. {
  921. return setvar_p(v, (value && *value) ? xstrdup(value) : NULL);
  922. }
  923. static var *setvar_sn(var *v, const char *value, int len)
  924. {
  925. return setvar_p(v, (value && *value && len > 0) ? xstrndup(value, len) : NULL);
  926. }
  927. /* same as setvar_s but sets USER flag */
  928. static var *setvar_u(var *v, const char *value)
  929. {
  930. v = setvar_s(v, value);
  931. v->type |= VF_USER;
  932. return v;
  933. }
  934. /* set array element to user string */
  935. static void setari_u(var *a, int idx, const char *s)
  936. {
  937. var *v;
  938. v = findvar(iamarray(a), itoa(idx));
  939. setvar_u(v, s);
  940. }
  941. /* assign numeric value to variable */
  942. static var *setvar_i(var *v, double value)
  943. {
  944. clrvar(v);
  945. v->type |= VF_NUMBER;
  946. v->number = value;
  947. handle_special(v);
  948. return v;
  949. }
  950. static void setvar_ERRNO(void)
  951. {
  952. setvar_i(intvar[ERRNO], errno);
  953. }
  954. static const char *getvar_s(var *v)
  955. {
  956. /* if v is numeric and has no cached string, convert it to string */
  957. if ((v->type & (VF_NUMBER | VF_CACHED)) == VF_NUMBER) {
  958. const char *convfmt = str_percent_dot_6g; /* "%.6g" */
  959. /* Get CONVFMT, unless we already recursed on it:
  960. * someone might try to cause stack overflow by setting
  961. * CONVFMT=9 (a numeric, not string, value)
  962. */
  963. if (v != intvar[CONVFMT])
  964. convfmt = getvar_s(intvar[CONVFMT]);
  965. /* Convert the value */
  966. v->string = xstrdup(fmt_num(convfmt, v->number));
  967. v->type |= VF_CACHED;
  968. }
  969. return (v->string == NULL) ? "" : v->string;
  970. }
  971. static double getvar_i(var *v)
  972. {
  973. char *s;
  974. if ((v->type & (VF_NUMBER | VF_CACHED)) == 0) {
  975. v->number = 0;
  976. s = v->string;
  977. if (s && *s) {
  978. debug_printf_eval("getvar_i: '%s'->", s);
  979. v->number = my_strtod(&s);
  980. /* ^^^ hex/oct NOT allowed here! */
  981. debug_printf_eval("%f (s:'%s')\n", v->number, s);
  982. if (v->type & VF_USER) {
  983. //TODO: skip_spaces() also skips backslash+newline, is it intended here?
  984. s = skip_spaces(s);
  985. if (*s != '\0')
  986. v->type &= ~VF_USER;
  987. }
  988. } else {
  989. debug_printf_eval("getvar_i: '%s'->zero\n", s);
  990. v->type &= ~VF_USER;
  991. }
  992. v->type |= VF_CACHED;
  993. }
  994. debug_printf_eval("getvar_i: %f\n", v->number);
  995. return v->number;
  996. }
  997. /* Used for operands of bitwise ops */
  998. static unsigned long getvar_i_int(var *v)
  999. {
  1000. double d = getvar_i(v);
  1001. /* Casting doubles to longs is undefined for values outside
  1002. * of target type range. Try to widen it as much as possible */
  1003. if (d >= 0)
  1004. return (unsigned long)d;
  1005. /* Why? Think about d == -4294967295.0 (assuming 32bit longs) */
  1006. return - (long) (unsigned long) (-d);
  1007. }
  1008. static var *copyvar(var *dest, const var *src)
  1009. {
  1010. if (dest != src) {
  1011. clrvar(dest);
  1012. dest->type |= (src->type & ~(VF_DONTTOUCH | VF_FSTR));
  1013. debug_printf_eval("copyvar: number:%f string:'%s'\n", src->number, src->string);
  1014. dest->number = src->number;
  1015. if (src->string)
  1016. dest->string = xstrdup(src->string);
  1017. }
  1018. handle_special(dest);
  1019. return dest;
  1020. }
  1021. static var *incvar(var *v)
  1022. {
  1023. return setvar_i(v, getvar_i(v) + 1.0);
  1024. }
  1025. /* return true if v is number or numeric string */
  1026. static int is_numeric(var *v)
  1027. {
  1028. getvar_i(v);
  1029. return ((v->type ^ VF_DIRTY) & (VF_NUMBER | VF_USER | VF_DIRTY));
  1030. }
  1031. /* return 1 when value of v corresponds to true, 0 otherwise */
  1032. static int istrue(var *v)
  1033. {
  1034. if (is_numeric(v))
  1035. return (v->number != 0);
  1036. return (v->string && v->string[0]);
  1037. }
  1038. /* ------- awk program text parsing ------- */
  1039. /* Parse next token pointed by global pos, place results into global t_XYZ variables.
  1040. * If token isn't expected, print error message and die.
  1041. * Return token class (also store it in t_tclass).
  1042. */
  1043. static uint32_t next_token(uint32_t expected)
  1044. {
  1045. #define concat_inserted (G1.next_token__concat_inserted)
  1046. #define save_tclass (G1.next_token__save_tclass)
  1047. #define save_info (G1.next_token__save_info)
  1048. char *p;
  1049. const char *tl;
  1050. const uint32_t *ti;
  1051. uint32_t tc, last_token_class;
  1052. last_token_class = t_tclass; /* t_tclass is initialized to TC_NEWLINE */
  1053. debug_printf_parse("%s() expected(%x):", __func__, expected);
  1054. debug_parse_print_tc(expected);
  1055. debug_printf_parse("\n");
  1056. if (t_rollback) {
  1057. debug_printf_parse("%s: using rolled-back token\n", __func__);
  1058. t_rollback = FALSE;
  1059. } else if (concat_inserted) {
  1060. debug_printf_parse("%s: using concat-inserted token\n", __func__);
  1061. concat_inserted = FALSE;
  1062. t_tclass = save_tclass;
  1063. t_info = save_info;
  1064. } else {
  1065. p = g_pos;
  1066. if (g_saved_ch != '\0') {
  1067. *p = g_saved_ch;
  1068. g_saved_ch = '\0';
  1069. }
  1070. readnext:
  1071. p = skip_spaces(p);
  1072. g_lineno = t_lineno;
  1073. if (*p == '#')
  1074. while (*p != '\n' && *p != '\0')
  1075. p++;
  1076. if (*p == '\0') {
  1077. tc = TC_EOF;
  1078. debug_printf_parse("%s: token found: TC_EOF\n", __func__);
  1079. } else if (*p == '"') {
  1080. /* it's a string */
  1081. char *s = t_string = ++p;
  1082. while (*p != '"') {
  1083. char *pp;
  1084. if (*p == '\0' || *p == '\n')
  1085. syntax_error(EMSG_UNEXP_EOS);
  1086. pp = p;
  1087. *s++ = nextchar(&pp);
  1088. p = pp;
  1089. }
  1090. p++;
  1091. *s = '\0';
  1092. tc = TC_STRING;
  1093. debug_printf_parse("%s: token found:'%s' TC_STRING\n", __func__, t_string);
  1094. } else if ((expected & TC_REGEXP) && *p == '/') {
  1095. /* it's regexp */
  1096. char *s = t_string = ++p;
  1097. while (*p != '/') {
  1098. if (*p == '\0' || *p == '\n')
  1099. syntax_error(EMSG_UNEXP_EOS);
  1100. *s = *p++;
  1101. if (*s++ == '\\') {
  1102. char *pp = p;
  1103. s[-1] = bb_process_escape_sequence((const char **)&pp);
  1104. if (*p == '\\')
  1105. *s++ = '\\';
  1106. if (pp == p)
  1107. *s++ = *p++;
  1108. else
  1109. p = pp;
  1110. }
  1111. }
  1112. p++;
  1113. *s = '\0';
  1114. tc = TC_REGEXP;
  1115. debug_printf_parse("%s: token found:'%s' TC_REGEXP\n", __func__, t_string);
  1116. } else if (*p == '.' || isdigit(*p)) {
  1117. /* it's a number */
  1118. char *pp = p;
  1119. t_double = my_strtod_or_hexoct(&pp);
  1120. /* ^^^ awk only allows hex/oct consts in _program_, not in _input_ */
  1121. p = pp;
  1122. if (*p == '.')
  1123. syntax_error(EMSG_UNEXP_TOKEN);
  1124. tc = TC_NUMBER;
  1125. debug_printf_parse("%s: token found:%f TC_NUMBER\n", __func__, t_double);
  1126. } else {
  1127. char *end_of_name;
  1128. if (*p == '\n')
  1129. t_lineno++;
  1130. /* search for something known */
  1131. tl = tokenlist;
  1132. tc = 0x00000001;
  1133. ti = tokeninfo;
  1134. while (*tl) {
  1135. int l = (unsigned char) *tl++;
  1136. if (l == (unsigned char) NTCC) {
  1137. tc <<= 1;
  1138. continue;
  1139. }
  1140. /* if token class is expected,
  1141. * token matches,
  1142. * and it's not a longer word,
  1143. */
  1144. if ((tc & (expected | TS_WORD | TC_NEWLINE))
  1145. && strncmp(p, tl, l) == 0
  1146. && !((tc & TS_WORD) && isalnum_(p[l]))
  1147. ) {
  1148. /* then this is what we are looking for */
  1149. t_info = *ti;
  1150. debug_printf_parse("%s: token found:'%.*s' t_info:%x\n", __func__, l, p, t_info);
  1151. p += l;
  1152. goto token_found;
  1153. }
  1154. ti++;
  1155. tl += l;
  1156. }
  1157. /* not a known token */
  1158. /* is it a name? (var/array/function) */
  1159. if (!isalnum_(*p))
  1160. syntax_error(EMSG_UNEXP_TOKEN); /* no */
  1161. /* yes */
  1162. t_string = p;
  1163. while (isalnum_(*p))
  1164. p++;
  1165. end_of_name = p;
  1166. if (last_token_class == TC_FUNCDECL)
  1167. /* eat space in "function FUNC (...) {...}" declaration */
  1168. p = skip_spaces(p);
  1169. else if (expected & TC_ARRAY) {
  1170. /* eat space between array name and [ */
  1171. char *s = skip_spaces(p);
  1172. if (*s == '[') /* array ref, not just a name? */
  1173. p = s;
  1174. }
  1175. /* else: do NOT consume whitespace after variable name!
  1176. * gawk allows definition "function FUNC (p) {...}" - note space,
  1177. * but disallows the call "FUNC (p)" because it isn't one -
  1178. * expression "v (a)" should NOT be parsed as TC_FUNCTION:
  1179. * it is a valid concatenation if "v" is a variable,
  1180. * not a function name (and type of name is not known at parse time).
  1181. */
  1182. if (*p == '(') {
  1183. p++;
  1184. tc = TC_FUNCTION;
  1185. debug_printf_parse("%s: token found:'%s' TC_FUNCTION\n", __func__, t_string);
  1186. } else if (*p == '[') {
  1187. p++;
  1188. tc = TC_ARRAY;
  1189. debug_printf_parse("%s: token found:'%s' TC_ARRAY\n", __func__, t_string);
  1190. } else {
  1191. tc = TC_VARIABLE;
  1192. debug_printf_parse("%s: token found:'%s' TC_VARIABLE\n", __func__, t_string);
  1193. if (end_of_name == p) {
  1194. /* there is no space for trailing NUL in t_string!
  1195. * We need to save the char we are going to NUL.
  1196. * (we'll use it in future call to next_token())
  1197. */
  1198. g_saved_ch = *end_of_name;
  1199. // especially pathological example is V="abc"; V.2 - it's V concatenated to .2
  1200. // (it evaluates to "abc0.2"). Because of this case, we can't simply cache
  1201. // '.' and analyze it later: we also have to *store it back* in next
  1202. // next_token(), in order to give my_strtod() the undamaged ".2" string.
  1203. }
  1204. }
  1205. *end_of_name = '\0'; /* terminate t_string */
  1206. }
  1207. token_found:
  1208. g_pos = p;
  1209. /* skipping newlines in some cases */
  1210. if ((last_token_class & TS_NOTERM) && (tc & TC_NEWLINE))
  1211. goto readnext;
  1212. /* insert concatenation operator when needed */
  1213. debug_printf_parse("%s: concat_inserted if all nonzero: %x %x %x %x\n", __func__,
  1214. (last_token_class & TS_CONCAT_L), (tc & TS_CONCAT_R), (expected & TS_BINOP),
  1215. !(last_token_class == TC_LENGTH && tc == TC_LPAREN));
  1216. if ((last_token_class & TS_CONCAT_L) && (tc & TS_CONCAT_R) && (expected & TS_BINOP)
  1217. && !(last_token_class == TC_LENGTH && tc == TC_LPAREN) /* but not for "length(..." */
  1218. ) {
  1219. concat_inserted = TRUE;
  1220. save_tclass = tc;
  1221. save_info = t_info;
  1222. tc = TC_BINOPX;
  1223. t_info = OC_CONCAT | SS | PRECEDENCE(35);
  1224. }
  1225. t_tclass = tc;
  1226. debug_printf_parse("%s: t_tclass=tc=%x\n", __func__, tc);
  1227. }
  1228. /* Are we ready for this? */
  1229. if (!(t_tclass & expected)) {
  1230. syntax_error((last_token_class & (TC_NEWLINE | TC_EOF)) ?
  1231. EMSG_UNEXP_EOS : EMSG_UNEXP_TOKEN);
  1232. }
  1233. debug_printf_parse("%s: returning, t_double:%f t_tclass:", __func__, t_double);
  1234. debug_parse_print_tc(t_tclass);
  1235. debug_printf_parse("\n");
  1236. return t_tclass;
  1237. #undef concat_inserted
  1238. #undef save_tclass
  1239. #undef save_info
  1240. }
  1241. static ALWAYS_INLINE void rollback_token(void)
  1242. {
  1243. t_rollback = TRUE;
  1244. }
  1245. static node *new_node(uint32_t info)
  1246. {
  1247. node *n;
  1248. n = xzalloc(sizeof(node));
  1249. n->info = info;
  1250. n->lineno = g_lineno;
  1251. return n;
  1252. }
  1253. static void mk_re_node(const char *s, node *n, regex_t *re)
  1254. {
  1255. n->info = TI_REGEXP;
  1256. n->l.re = re;
  1257. xregcomp(re, s, REG_EXTENDED);
  1258. xregcomp(re + 1, s, REG_EXTENDED | REG_ICASE);
  1259. }
  1260. static node *parse_expr(uint32_t);
  1261. static node *parse_lrparen_list(void)
  1262. {
  1263. next_token(TC_LPAREN);
  1264. return parse_expr(TC_RPAREN);
  1265. }
  1266. /* Parse expression terminated by given token, return ptr
  1267. * to built subtree. Terminator is eaten by parse_expr */
  1268. static node *parse_expr(uint32_t term_tc)
  1269. {
  1270. node sn;
  1271. node *cn = &sn;
  1272. node *getline_node;
  1273. uint32_t tc, expected_tc;
  1274. debug_printf_parse("%s() term_tc(%x):", __func__, term_tc);
  1275. debug_parse_print_tc(term_tc);
  1276. debug_printf_parse("\n");
  1277. sn.info = LOWEST_PRECEDENCE;
  1278. sn.r.n = sn.a.n = getline_node = NULL;
  1279. expected_tc = TS_OPERAND | TS_UOPPRE | TC_REGEXP | term_tc;
  1280. while (!((tc = next_token(expected_tc)) & term_tc)) {
  1281. node *vn;
  1282. if (getline_node && (t_info == TI_LESS)) {
  1283. /* Attach input redirection (<) to getline node */
  1284. debug_printf_parse("%s: input redir\n", __func__);
  1285. cn = getline_node->l.n = new_node(OC_CONCAT | SS | PRECEDENCE(37));
  1286. cn->a.n = getline_node;
  1287. expected_tc = TS_OPERAND | TS_UOPPRE;
  1288. getline_node = NULL;
  1289. continue;
  1290. }
  1291. if (tc & (TS_BINOP | TC_UOPPOST)) {
  1292. debug_printf_parse("%s: TS_BINOP | TC_UOPPOST tc:%x\n", __func__, tc);
  1293. /* for binary and postfix-unary operators, jump back over
  1294. * previous operators with higher precedence */
  1295. vn = cn;
  1296. while (((t_info & PRIMASK) > (vn->a.n->info & PRIMASK2))
  1297. || (t_info == vn->info && t_info == TI_COLON)
  1298. ) {
  1299. vn = vn->a.n;
  1300. if (!vn->a.n) syntax_error(EMSG_UNEXP_TOKEN);
  1301. }
  1302. if (t_info == TI_TERNARY) /* "?" token */
  1303. //TODO: why?
  1304. t_info += PRECEDENCE(6);
  1305. cn = vn->a.n->r.n = new_node(t_info);
  1306. cn->a.n = vn->a.n;
  1307. if (tc & TS_BINOP) {
  1308. cn->l.n = vn;
  1309. /* Prevent:
  1310. * awk 'BEGIN { "qwe" = 1 }'
  1311. * awk 'BEGIN { 7 *= 7 }'
  1312. * awk 'BEGIN { length("qwe") = 1 }'
  1313. * awk 'BEGIN { (1+1) += 3 }'
  1314. */
  1315. /* Assignment? (including *= and friends) */
  1316. if (((t_info & OPCLSMASK) == OC_MOVE)
  1317. || ((t_info & OPCLSMASK) == OC_REPLACE)
  1318. ) {
  1319. debug_printf_parse("%s: MOVE/REPLACE vn->info:%08x\n", __func__, vn->info);
  1320. /* Left side is a (variable or array element)
  1321. * or function argument
  1322. * or $FIELD ?
  1323. */
  1324. if ((vn->info & OPCLSMASK) != OC_VAR
  1325. && (vn->info & OPCLSMASK) != OC_FNARG
  1326. && (vn->info & OPCLSMASK) != OC_FIELD
  1327. ) {
  1328. syntax_error(EMSG_UNEXP_TOKEN); /* no. bad */
  1329. }
  1330. }
  1331. expected_tc = TS_OPERAND | TS_UOPPRE | TC_REGEXP;
  1332. if (t_info == TI_PGETLINE) { /* "|" token */
  1333. next_token(TC_GETLINE); /* must be folowed by "getline" */
  1334. /* give maximum precedence to this pipe */
  1335. cn->info &= ~PRIMASK; /* sets PRECEDENCE(0) */
  1336. expected_tc = TS_OPERAND | TS_UOPPRE | TS_BINOP | term_tc;
  1337. }
  1338. } else {
  1339. /* It was an unary postfix operator */
  1340. cn->r.n = vn;
  1341. expected_tc = TS_OPERAND | TS_UOPPRE | TS_BINOP | term_tc;
  1342. }
  1343. vn->a.n = cn;
  1344. continue;
  1345. }
  1346. /* It wasn't a binary or postfix-unary operator */
  1347. debug_printf_parse("%s: other, t_info:%x\n", __func__, t_info);
  1348. /* for operands and prefix-unary operators, attach them
  1349. * to last node */
  1350. vn = cn;
  1351. cn = vn->r.n = new_node(t_info);
  1352. cn->a.n = vn;
  1353. expected_tc = TS_OPERAND | TS_UOPPRE | TC_REGEXP;
  1354. if (t_info == TI_PREINC || t_info == TI_PREDEC)
  1355. expected_tc = TS_LVALUE | TC_UOPPRE1;
  1356. if (!(tc & (TS_OPERAND | TC_REGEXP)))
  1357. continue;
  1358. debug_printf_parse("%s: TS_OPERAND | TC_REGEXP\n", __func__);
  1359. expected_tc = TS_UOPPRE | TC_UOPPOST | TS_BINOP | TS_OPERAND | term_tc;
  1360. /* one should be very careful with switch on tclass -
  1361. * only simple tclasses should be used (TC_xyz, not TS_xyz) */
  1362. switch (tc) {
  1363. var *v;
  1364. case TC_VARIABLE:
  1365. case TC_ARRAY:
  1366. debug_printf_parse("%s: TC_VARIABLE | TC_ARRAY\n", __func__);
  1367. cn->info = OC_VAR;
  1368. v = hash_search(ahash, t_string);
  1369. if (v != NULL) {
  1370. cn->info = OC_FNARG;
  1371. cn->l.aidx = v->x.aidx;
  1372. } else {
  1373. cn->l.v = newvar(t_string);
  1374. }
  1375. if (tc & TC_ARRAY) {
  1376. cn->info |= xS;
  1377. cn->r.n = parse_expr(TC_ARRTERM);
  1378. }
  1379. break;
  1380. case TC_NUMBER:
  1381. case TC_STRING:
  1382. debug_printf_parse("%s: TC_NUMBER | TC_STRING\n", __func__);
  1383. cn->info = OC_CONST;
  1384. v = cn->l.v = xzalloc(sizeof(var));
  1385. if (tc & TC_NUMBER) {
  1386. setvar_i(v, t_double);
  1387. } else {
  1388. setvar_s(v, t_string);
  1389. }
  1390. expected_tc &= ~TC_UOPPOST; /* NUM++, "str"++ not allowed */
  1391. break;
  1392. case TC_REGEXP:
  1393. debug_printf_parse("%s: TC_REGEXP\n", __func__);
  1394. mk_re_node(t_string, cn, xzalloc(sizeof(regex_t)*2));
  1395. break;
  1396. case TC_FUNCTION:
  1397. debug_printf_parse("%s: TC_FUNCTION\n", __func__);
  1398. cn->info = OC_FUNC;
  1399. cn->r.f = newfunc(t_string);
  1400. cn->l.n = parse_expr(TC_RPAREN);
  1401. break;
  1402. case TC_LPAREN:
  1403. debug_printf_parse("%s: TC_LPAREN\n", __func__);
  1404. cn = vn->r.n = parse_expr(TC_RPAREN);
  1405. if (!cn)
  1406. syntax_error("Empty sequence");
  1407. cn->a.n = vn;
  1408. break;
  1409. case TC_GETLINE:
  1410. /* "getline" is a function, not a statement.
  1411. * Works in gawk:
  1412. * r = ["SHELL CMD" | ] getline [VAR] [<"FILE"]
  1413. * if (getline <"FILE" < 0) print "Can't read FILE"
  1414. * while ("SHELL CMD" | getline > 0) ...
  1415. * Returns: 1 successful read, 0 EOF, -1 error (sets ERRNO)
  1416. */
  1417. debug_printf_parse("%s: TC_GETLINE\n", __func__);
  1418. getline_node = cn;
  1419. expected_tc = TS_OPERAND | TS_UOPPRE | TS_BINOP | term_tc;
  1420. break;
  1421. case TC_BUILTIN:
  1422. debug_printf_parse("%s: TC_BUILTIN\n", __func__);
  1423. cn->l.n = parse_lrparen_list();
  1424. break;
  1425. case TC_LENGTH:
  1426. debug_printf_parse("%s: TC_LENGTH\n", __func__);
  1427. tc = next_token(TC_LPAREN /* length(...) */
  1428. | TC_SEMICOL /* length; */
  1429. | TC_NEWLINE /* length<newline> */
  1430. | TC_RBRACE /* length } */
  1431. | TC_BINOPX /* length <op> NUM */
  1432. | TC_COMMA /* print length, 1 */
  1433. );
  1434. if (tc != TC_LPAREN)
  1435. rollback_token();
  1436. else {
  1437. /* It was a "(" token. Handle just like TC_BUILTIN */
  1438. cn->l.n = parse_expr(TC_RPAREN);
  1439. }
  1440. break;
  1441. }
  1442. } /* while() */
  1443. debug_printf_parse("%s() returns %p\n", __func__, sn.r.n);
  1444. return sn.r.n;
  1445. }
  1446. /* add node to chain. Return ptr to alloc'd node */
  1447. static node *chain_node(uint32_t info)
  1448. {
  1449. node *n;
  1450. if (!seq->first)
  1451. seq->first = seq->last = new_node(0);
  1452. if (seq->programname != g_progname) {
  1453. seq->programname = g_progname;
  1454. n = chain_node(OC_NEWSOURCE);
  1455. n->l.new_progname = g_progname;
  1456. }
  1457. n = seq->last;
  1458. n->info = info;
  1459. seq->last = n->a.n = new_node(OC_DONE);
  1460. return n;
  1461. }
  1462. static void chain_expr(uint32_t info)
  1463. {
  1464. node *n;
  1465. n = chain_node(info);
  1466. n->l.n = parse_expr(TC_SEMICOL | TC_NEWLINE | TC_RBRACE);
  1467. if ((info & OF_REQUIRED) && !n->l.n)
  1468. syntax_error(EMSG_TOO_FEW_ARGS);
  1469. if (t_tclass & TC_RBRACE)
  1470. rollback_token();
  1471. }
  1472. static void chain_group(void);
  1473. static node *chain_loop(node *nn)
  1474. {
  1475. node *n, *n2, *save_brk, *save_cont;
  1476. save_brk = break_ptr;
  1477. save_cont = continue_ptr;
  1478. n = chain_node(OC_BR | Vx);
  1479. continue_ptr = new_node(OC_EXEC);
  1480. break_ptr = new_node(OC_EXEC);
  1481. chain_group();
  1482. n2 = chain_node(OC_EXEC | Vx);
  1483. n2->l.n = nn;
  1484. n2->a.n = n;
  1485. continue_ptr->a.n = n2;
  1486. break_ptr->a.n = n->r.n = seq->last;
  1487. continue_ptr = save_cont;
  1488. break_ptr = save_brk;
  1489. return n;
  1490. }
  1491. static void chain_until_rbrace(void)
  1492. {
  1493. uint32_t tc;
  1494. while ((tc = next_token(TS_GRPSEQ | TC_RBRACE)) != TC_RBRACE) {
  1495. debug_printf_parse("%s: !TC_RBRACE\n", __func__);
  1496. if (tc == TC_NEWLINE)
  1497. continue;
  1498. rollback_token();
  1499. chain_group();
  1500. }
  1501. debug_printf_parse("%s: TC_RBRACE\n", __func__);
  1502. }
  1503. /* parse group and attach it to chain */
  1504. static void chain_group(void)
  1505. {
  1506. uint32_t tc;
  1507. node *n, *n2, *n3;
  1508. do {
  1509. tc = next_token(TS_GRPSEQ);
  1510. } while (tc == TC_NEWLINE);
  1511. if (tc == TC_LBRACE) {
  1512. debug_printf_parse("%s: TC_LBRACE\n", __func__);
  1513. chain_until_rbrace();
  1514. return;
  1515. }
  1516. if (tc & (TS_OPSEQ | TC_SEMICOL)) {
  1517. debug_printf_parse("%s: TS_OPSEQ | TC_SEMICOL\n", __func__);
  1518. rollback_token();
  1519. chain_expr(OC_EXEC | Vx);
  1520. return;
  1521. }
  1522. /* TS_STATEMNT */
  1523. debug_printf_parse("%s: TS_STATEMNT(?)\n", __func__);
  1524. switch (t_info & OPCLSMASK) {
  1525. case ST_IF:
  1526. debug_printf_parse("%s: ST_IF\n", __func__);
  1527. n = chain_node(OC_BR | Vx);
  1528. n->l.n = parse_lrparen_list();
  1529. chain_group();
  1530. n2 = chain_node(OC_EXEC);
  1531. n->r.n = seq->last;
  1532. if (next_token(TS_GRPSEQ | TC_RBRACE | TC_ELSE) == TC_ELSE) {
  1533. chain_group();
  1534. n2->a.n = seq->last;
  1535. } else {
  1536. rollback_token();
  1537. }
  1538. break;
  1539. case ST_WHILE:
  1540. debug_printf_parse("%s: ST_WHILE\n", __func__);
  1541. n2 = parse_lrparen_list();
  1542. n = chain_loop(NULL);
  1543. n->l.n = n2;
  1544. break;
  1545. case ST_DO:
  1546. debug_printf_parse("%s: ST_DO\n", __func__);
  1547. n2 = chain_node(OC_EXEC);
  1548. n = chain_loop(NULL);
  1549. n2->a.n = n->a.n;
  1550. next_token(TC_WHILE);
  1551. n->l.n = parse_lrparen_list();
  1552. break;
  1553. case ST_FOR:
  1554. debug_printf_parse("%s: ST_FOR\n", __func__);
  1555. next_token(TC_LPAREN);
  1556. n2 = parse_expr(TC_SEMICOL | TC_RPAREN);
  1557. if (t_tclass & TC_RPAREN) { /* for (I in ARRAY) */
  1558. if (!n2 || n2->info != TI_IN)
  1559. syntax_error(EMSG_UNEXP_TOKEN);
  1560. n = chain_node(OC_WALKINIT | VV);
  1561. n->l.n = n2->l.n;
  1562. n->r.n = n2->r.n;
  1563. n = chain_loop(NULL);
  1564. n->info = OC_WALKNEXT | Vx;
  1565. n->l.n = n2->l.n;
  1566. } else { /* for (;;) */
  1567. n = chain_node(OC_EXEC | Vx);
  1568. n->l.n = n2;
  1569. n2 = parse_expr(TC_SEMICOL);
  1570. n3 = parse_expr(TC_RPAREN);
  1571. n = chain_loop(n3);
  1572. n->l.n = n2;
  1573. if (!n2)
  1574. n->info = OC_EXEC;
  1575. }
  1576. break;
  1577. case OC_PRINT:
  1578. case OC_PRINTF:
  1579. debug_printf_parse("%s: OC_PRINT[F]\n", __func__);
  1580. n = chain_node(t_info);
  1581. n->l.n = parse_expr(TC_SEMICOL | TC_NEWLINE | TC_OUTRDR | TC_RBRACE);
  1582. if (t_tclass & TC_OUTRDR) {
  1583. n->info |= t_info;
  1584. n->r.n = parse_expr(TC_SEMICOL | TC_NEWLINE | TC_RBRACE);
  1585. }
  1586. if (t_tclass & TC_RBRACE)
  1587. rollback_token();
  1588. break;
  1589. case OC_BREAK:
  1590. debug_printf_parse("%s: OC_BREAK\n", __func__);
  1591. n = chain_node(OC_EXEC);
  1592. if (!break_ptr)
  1593. syntax_error("'break' not in a loop");
  1594. n->a.n = break_ptr;
  1595. chain_expr(t_info);
  1596. break;
  1597. case OC_CONTINUE:
  1598. debug_printf_parse("%s: OC_CONTINUE\n", __func__);
  1599. n = chain_node(OC_EXEC);
  1600. if (!continue_ptr)
  1601. syntax_error("'continue' not in a loop");
  1602. n->a.n = continue_ptr;
  1603. chain_expr(t_info);
  1604. break;
  1605. /* delete, next, nextfile, return, exit */
  1606. default:
  1607. debug_printf_parse("%s: default\n", __func__);
  1608. chain_expr(t_info);
  1609. }
  1610. }
  1611. static void parse_program(char *p)
  1612. {
  1613. debug_printf_parse("%s()\n", __func__);
  1614. g_pos = p;
  1615. t_lineno = 1;
  1616. for (;;) {
  1617. uint32_t tclass;
  1618. tclass = next_token(TS_OPSEQ | TC_LBRACE | TC_BEGIN | TC_END | TC_FUNCDECL
  1619. | TC_EOF | TC_NEWLINE /* but not TC_SEMICOL */);
  1620. got_tok:
  1621. if (tclass == TC_EOF) {
  1622. debug_printf_parse("%s: TC_EOF\n", __func__);
  1623. break;
  1624. }
  1625. if (tclass == TC_NEWLINE) {
  1626. debug_printf_parse("%s: TC_NEWLINE\n", __func__);
  1627. continue;
  1628. }
  1629. if (tclass == TC_BEGIN) {
  1630. debug_printf_parse("%s: TC_BEGIN\n", __func__);
  1631. seq = &beginseq;
  1632. /* ensure there is no newline between BEGIN and { */
  1633. next_token(TC_LBRACE);
  1634. chain_until_rbrace();
  1635. goto next_tok;
  1636. }
  1637. if (tclass == TC_END) {
  1638. debug_printf_parse("%s: TC_END\n", __func__);
  1639. seq = &endseq;
  1640. /* ensure there is no newline between END and { */
  1641. next_token(TC_LBRACE);
  1642. chain_until_rbrace();
  1643. goto next_tok;
  1644. }
  1645. if (tclass == TC_FUNCDECL) {
  1646. func *f;
  1647. debug_printf_parse("%s: TC_FUNCDECL\n", __func__);
  1648. next_token(TC_FUNCTION);
  1649. f = newfunc(t_string);
  1650. if (f->defined)
  1651. syntax_error("Duplicate function");
  1652. f->defined = 1;
  1653. //f->body.first = NULL; - already is
  1654. //f->nargs = 0; - already is
  1655. /* func arg list: comma sep list of args, and a close paren */
  1656. for (;;) {
  1657. var *v;
  1658. if (next_token(TC_VARIABLE | TC_RPAREN) == TC_RPAREN) {
  1659. if (f->nargs == 0)
  1660. break; /* func() is ok */
  1661. /* func(a,) is not ok */
  1662. syntax_error(EMSG_UNEXP_TOKEN);
  1663. }
  1664. v = findvar(ahash, t_string);
  1665. v->x.aidx = f->nargs++;
  1666. /* Arg followed either by end of arg list or 1 comma */
  1667. if (next_token(TC_COMMA | TC_RPAREN) == TC_RPAREN)
  1668. break;
  1669. /* it was a comma, we ate it */
  1670. }
  1671. seq = &f->body;
  1672. /* ensure there is { after "func F(...)" - but newlines are allowed */
  1673. while (next_token(TC_LBRACE | TC_NEWLINE) == TC_NEWLINE)
  1674. continue;
  1675. chain_until_rbrace();
  1676. hash_clear(ahash);
  1677. goto next_tok;
  1678. }
  1679. seq = &mainseq;
  1680. if (tclass & TS_OPSEQ) {
  1681. node *cn;
  1682. debug_printf_parse("%s: TS_OPSEQ\n", __func__);
  1683. rollback_token();
  1684. cn = chain_node(OC_TEST);
  1685. cn->l.n = parse_expr(TC_SEMICOL | TC_NEWLINE | TC_EOF | TC_LBRACE);
  1686. if (t_tclass == TC_LBRACE) {
  1687. debug_printf_parse("%s: TC_LBRACE\n", __func__);
  1688. chain_until_rbrace();
  1689. } else {
  1690. /* no action, assume default "{ print }" */
  1691. debug_printf_parse("%s: !TC_LBRACE\n", __func__);
  1692. chain_node(OC_PRINT);
  1693. }
  1694. cn->r.n = mainseq.last;
  1695. goto next_tok;
  1696. }
  1697. /* tclass == TC_LBRACE */
  1698. debug_printf_parse("%s: TC_LBRACE(?)\n", __func__);
  1699. chain_until_rbrace();
  1700. next_tok:
  1701. /* Same as next_token() at the top of the loop, + TC_SEMICOL */
  1702. tclass = next_token(TS_OPSEQ | TC_LBRACE | TC_BEGIN | TC_END | TC_FUNCDECL
  1703. | TC_EOF | TC_NEWLINE | TC_SEMICOL);
  1704. /* gawk allows many newlines, but does not allow more than one semicolon:
  1705. * BEGIN {...}<newline>;<newline>;
  1706. * would complain "each rule must have a pattern or an action part".
  1707. * Same message for
  1708. * ; BEGIN {...}
  1709. */
  1710. if (tclass != TC_SEMICOL)
  1711. goto got_tok; /* use this token */
  1712. /* else: loop back - ate the semicolon, get and use _next_ token */
  1713. } /* for (;;) */
  1714. }
  1715. /* -------- program execution part -------- */
  1716. /* temporary variables allocator */
  1717. static var *nvalloc(int sz)
  1718. {
  1719. return xzalloc(sz * sizeof(var));
  1720. }
  1721. static void nvfree(var *v, int sz)
  1722. {
  1723. var *p = v;
  1724. while (--sz >= 0) {
  1725. if ((p->type & (VF_ARRAY | VF_CHILD)) == VF_ARRAY) {
  1726. clear_array(iamarray(p));
  1727. free(p->x.array->items);
  1728. free(p->x.array);
  1729. }
  1730. if (p->type & VF_WALK) {
  1731. walker_list *n;
  1732. walker_list *w = p->x.walker;
  1733. debug_printf_walker("nvfree: freeing walker @%p\n", &p->x.walker);
  1734. p->x.walker = NULL;
  1735. while (w) {
  1736. n = w->prev;
  1737. debug_printf_walker(" free(%p)\n", w);
  1738. free(w);
  1739. w = n;
  1740. }
  1741. }
  1742. clrvar(p);
  1743. p++;
  1744. }
  1745. free(v);
  1746. }
  1747. static node *mk_splitter(const char *s, tsplitter *spl)
  1748. {
  1749. regex_t *re;
  1750. node *n;
  1751. re = spl->re;
  1752. n = &spl->n;
  1753. if (n->info == TI_REGEXP) {
  1754. regfree(re);
  1755. regfree(re + 1);
  1756. }
  1757. if (s[0] && s[1]) { /* strlen(s) > 1 */
  1758. mk_re_node(s, n, re);
  1759. } else {
  1760. n->info = (uint32_t) s[0];
  1761. }
  1762. return n;
  1763. }
  1764. static var *evaluate(node *, var *);
  1765. /* Use node as a regular expression. Supplied with node ptr and regex_t
  1766. * storage space. Return ptr to regex (if result points to preg, it should
  1767. * be later regfree'd manually).
  1768. */
  1769. static regex_t *as_regex(node *op, regex_t *preg)
  1770. {
  1771. int cflags;
  1772. const char *s;
  1773. if (op->info == TI_REGEXP) {
  1774. return &op->l.re[icase];
  1775. }
  1776. //tmpvar = nvalloc(1);
  1777. #define TMPVAR (&G.as_regex__tmpvar)
  1778. // We use a single "static" tmpvar (instead of on-stack or malloced one)
  1779. // to decrease memory consumption in deeply-recursive awk programs.
  1780. // The rule to work safely is to never call evaluate() while our static
  1781. // TMPVAR's value is still needed.
  1782. s = getvar_s(evaluate(op, TMPVAR));
  1783. cflags = icase ? REG_EXTENDED | REG_ICASE : REG_EXTENDED;
  1784. /* Testcase where REG_EXTENDED fails (unpaired '{'):
  1785. * echo Hi | awk 'gsub("@(samp|code|file)\{","");'
  1786. * gawk 3.1.5 eats this. We revert to ~REG_EXTENDED
  1787. * (maybe gsub is not supposed to use REG_EXTENDED?).
  1788. */
  1789. if (regcomp(preg, s, cflags)) {
  1790. cflags &= ~REG_EXTENDED;
  1791. xregcomp(preg, s, cflags);
  1792. }
  1793. //nvfree(tmpvar, 1);
  1794. #undef TMPVAR
  1795. return preg;
  1796. }
  1797. /* gradually increasing buffer.
  1798. * note that we reallocate even if n == old_size,
  1799. * and thus there is at least one extra allocated byte.
  1800. */
  1801. static char* qrealloc(char *b, int n, int *size)
  1802. {
  1803. if (!b || n >= *size) {
  1804. *size = n + (n>>1) + 80;
  1805. b = xrealloc(b, *size);
  1806. }
  1807. return b;
  1808. }
  1809. /* resize field storage space */
  1810. static void fsrealloc(int size)
  1811. {
  1812. int i, newsize;
  1813. if ((unsigned)size >= num_alloc_fields) {
  1814. /* Sanity cap, easier than catering for over/underflows */
  1815. if ((unsigned)size > 0xffffff)
  1816. bb_die_memory_exhausted();
  1817. i = num_alloc_fields;
  1818. num_alloc_fields = size + 16;
  1819. newsize = num_alloc_fields * sizeof(Fields[0]);
  1820. debug_printf_eval("fsrealloc: xrealloc(%p, %u)\n", Fields, newsize);
  1821. Fields = xrealloc(Fields, newsize);
  1822. debug_printf_eval("fsrealloc: Fields=%p..%p\n", Fields, (char*)Fields + newsize - 1);
  1823. /* ^^^ did Fields[] move? debug aid for L.v getting "upstaged" by R.v in evaluate() */
  1824. for (; i < num_alloc_fields; i++) {
  1825. Fields[i].type = VF_SPECIAL | VF_DIRTY;
  1826. Fields[i].string = NULL;
  1827. }
  1828. }
  1829. /* if size < num_fields, clear extra field variables */
  1830. for (i = size; i < num_fields; i++) {
  1831. clrvar(Fields + i);
  1832. }
  1833. num_fields = size;
  1834. }
  1835. static int regexec1_nonempty(const regex_t *preg, const char *s, regmatch_t pmatch[])
  1836. {
  1837. int r = regexec(preg, s, 1, pmatch, 0);
  1838. if (r == 0 && pmatch[0].rm_eo == 0) {
  1839. /* For example, happens when FS can match
  1840. * an empty string (awk -F ' *'). Logically,
  1841. * this should split into one-char fields.
  1842. * However, gawk 5.0.1 searches for first
  1843. * _non-empty_ separator string match:
  1844. */
  1845. size_t ofs = 0;
  1846. do {
  1847. ofs++;
  1848. if (!s[ofs])
  1849. return REG_NOMATCH;
  1850. regexec(preg, s + ofs, 1, pmatch, 0);
  1851. } while (pmatch[0].rm_eo == 0);
  1852. pmatch[0].rm_so += ofs;
  1853. pmatch[0].rm_eo += ofs;
  1854. }
  1855. return r;
  1856. }
  1857. static int awk_split(const char *s, node *spl, char **slist)
  1858. {
  1859. int n;
  1860. char c[4];
  1861. char *s1;
  1862. /* in worst case, each char would be a separate field */
  1863. *slist = s1 = xzalloc(strlen(s) * 2 + 3);
  1864. strcpy(s1, s);
  1865. c[0] = c[1] = (char)spl->info;
  1866. c[2] = c[3] = '\0';
  1867. if (*getvar_s(intvar[RS]) == '\0')
  1868. c[2] = '\n';
  1869. n = 0;
  1870. if (spl->info == TI_REGEXP) { /* regex split */
  1871. if (!*s)
  1872. return n; /* "": zero fields */
  1873. n++; /* at least one field will be there */
  1874. do {
  1875. int l;
  1876. regmatch_t pmatch[1];
  1877. l = strcspn(s, c+2); /* len till next NUL or \n */
  1878. if (regexec1_nonempty(&spl->l.re[icase], s, pmatch) == 0
  1879. && pmatch[0].rm_so <= l
  1880. ) {
  1881. /* if (pmatch[0].rm_eo == 0) ... - impossible */
  1882. l = pmatch[0].rm_so;
  1883. n++; /* we saw yet another delimiter */
  1884. } else {
  1885. pmatch[0].rm_eo = l;
  1886. if (s[l])
  1887. pmatch[0].rm_eo++;
  1888. }
  1889. s1 = mempcpy(s1, s, l);
  1890. *s1++ = '\0';
  1891. s += pmatch[0].rm_eo;
  1892. } while (*s);
  1893. /* echo a-- | awk -F-- '{ print NF, length($NF), $NF }'
  1894. * should print "2 0 ":
  1895. */
  1896. *s1 = '\0';
  1897. return n;
  1898. }
  1899. if (c[0] == '\0') { /* null split */
  1900. while (*s) {
  1901. *s1++ = *s++;
  1902. *s1++ = '\0';
  1903. n++;
  1904. }
  1905. return n;
  1906. }
  1907. if (c[0] != ' ') { /* single-character split */
  1908. if (icase) {
  1909. c[0] = toupper(c[0]);
  1910. c[1] = tolower(c[1]);
  1911. }
  1912. if (*s1)
  1913. n++;
  1914. while ((s1 = strpbrk(s1, c)) != NULL) {
  1915. *s1++ = '\0';
  1916. n++;
  1917. }
  1918. return n;
  1919. }
  1920. /* space split: "In the special case that FS is a single space,
  1921. * fields are separated by runs of spaces and/or tabs and/or newlines"
  1922. */
  1923. while (*s) {
  1924. /* s = skip_whitespace(s); -- WRONG (also skips \v \f \r) */
  1925. while (*s == ' ' || *s == '\t' || *s == '\n')
  1926. s++;
  1927. if (!*s)
  1928. break;
  1929. n++;
  1930. while (*s && !(*s == ' ' || *s == '\t' || *s == '\n'))
  1931. *s1++ = *s++;
  1932. *s1++ = '\0';
  1933. }
  1934. return n;
  1935. }
  1936. static void split_f0(void)
  1937. {
  1938. /* static char *fstrings; */
  1939. #define fstrings (G.split_f0__fstrings)
  1940. int i, n;
  1941. char *s;
  1942. if (is_f0_split)
  1943. return;
  1944. is_f0_split = TRUE;
  1945. free(fstrings);
  1946. fsrealloc(0);
  1947. n = awk_split(getvar_s(intvar[F0]), &fsplitter.n, &fstrings);
  1948. fsrealloc(n);
  1949. s = fstrings;
  1950. for (i = 0; i < n; i++) {
  1951. Fields[i].string = nextword(&s);
  1952. Fields[i].type |= (VF_FSTR | VF_USER | VF_DIRTY);
  1953. }
  1954. /* set NF manually to avoid side effects */
  1955. clrvar(intvar[NF]);
  1956. intvar[NF]->type = VF_NUMBER | VF_SPECIAL;
  1957. intvar[NF]->number = num_fields;
  1958. #undef fstrings
  1959. }
  1960. /* perform additional actions when some internal variables changed */
  1961. static void handle_special(var *v)
  1962. {
  1963. int n;
  1964. char *b;
  1965. const char *sep, *s;
  1966. int sl, l, len, i, bsize;
  1967. if (!(v->type & VF_SPECIAL))
  1968. return;
  1969. if (v == intvar[NF]) {
  1970. n = (int)getvar_i(v);
  1971. if (n < 0)
  1972. syntax_error("NF set to negative value");
  1973. fsrealloc(n);
  1974. /* recalculate $0 */
  1975. sep = getvar_s(intvar[OFS]);
  1976. sl = strlen(sep);
  1977. b = NULL;
  1978. len = 0;
  1979. for (i = 0; i < n; i++) {
  1980. s = getvar_s(&Fields[i]);
  1981. l = strlen(s);
  1982. if (b) {
  1983. memcpy(b+len, sep, sl);
  1984. len += sl;
  1985. }
  1986. b = qrealloc(b, len+l+sl, &bsize);
  1987. memcpy(b+len, s, l);
  1988. len += l;
  1989. }
  1990. if (b)
  1991. b[len] = '\0';
  1992. setvar_p(intvar[F0], b);
  1993. is_f0_split = TRUE;
  1994. } else if (v == intvar[F0]) {
  1995. is_f0_split = FALSE;
  1996. } else if (v == intvar[FS]) {
  1997. /*
  1998. * The POSIX-2008 standard says that changing FS should have no effect on the
  1999. * current input line, but only on the next one. The language is:
  2000. *
  2001. * > Before the first reference to a field in the record is evaluated, the record
  2002. * > shall be split into fields, according to the rules in Regular Expressions,
  2003. * > using the value of FS that was current at the time the record was read.
  2004. *
  2005. * So, split up current line before assignment to FS:
  2006. */
  2007. split_f0();
  2008. mk_splitter(getvar_s(v), &fsplitter);
  2009. } else if (v == intvar[RS]) {
  2010. mk_splitter(getvar_s(v), &rsplitter);
  2011. } else if (v == intvar[IGNORECASE]) {
  2012. icase = istrue(v);
  2013. } else { /* $n */
  2014. n = getvar_i(intvar[NF]);
  2015. setvar_i(intvar[NF], n > v-Fields ? n : v-Fields+1);
  2016. /* right here v is invalid. Just to note... */
  2017. }
  2018. }
  2019. /* step through func/builtin/etc arguments */
  2020. static node *nextarg(node **pn)
  2021. {
  2022. node *n;
  2023. n = *pn;
  2024. if (n && n->info == TI_COMMA) {
  2025. *pn = n->r.n;
  2026. n = n->l.n;
  2027. } else {
  2028. *pn = NULL;
  2029. }
  2030. return n;
  2031. }
  2032. static void hashwalk_init(var *v, xhash *array)
  2033. {
  2034. hash_item *hi;
  2035. unsigned i;
  2036. walker_list *w;
  2037. walker_list *prev_walker;
  2038. if (v->type & VF_WALK) {
  2039. prev_walker = v->x.walker;
  2040. } else {
  2041. v->type |= VF_WALK;
  2042. prev_walker = NULL;
  2043. }
  2044. debug_printf_walker("hashwalk_init: prev_walker:%p\n", prev_walker);
  2045. w = v->x.walker = xzalloc(sizeof(*w) + array->glen + 1); /* why + 1? */
  2046. debug_printf_walker(" walker@%p=%p\n", &v->x.walker, w);
  2047. w->cur = w->end = w->wbuf;
  2048. w->prev = prev_walker;
  2049. for (i = 0; i < array->csize; i++) {
  2050. hi = array->items[i];
  2051. while (hi) {
  2052. w->end = stpcpy(w->end, hi->name) + 1;
  2053. hi = hi->next;
  2054. }
  2055. }
  2056. }
  2057. static int hashwalk_next(var *v)
  2058. {
  2059. walker_list *w = v->x.walker;
  2060. if (w->cur >= w->end) {
  2061. walker_list *prev_walker = w->prev;
  2062. debug_printf_walker("end of iteration, free(walker@%p:%p), prev_walker:%p\n", &v->x.walker, w, prev_walker);
  2063. free(w);
  2064. v->x.walker = prev_walker;
  2065. return FALSE;
  2066. }
  2067. setvar_s(v, nextword(&w->cur));
  2068. return TRUE;
  2069. }
  2070. /* evaluate node, return 1 when result is true, 0 otherwise */
  2071. static int ptest(node *pattern)
  2072. {
  2073. // We use a single "static" tmpvar (instead of on-stack or malloced one)
  2074. // to decrease memory consumption in deeply-recursive awk programs.
  2075. // The rule to work safely is to never call evaluate() while our static
  2076. // TMPVAR's value is still needed.
  2077. return istrue(evaluate(pattern, &G.ptest__tmpvar));
  2078. }
  2079. /* read next record from stream rsm into a variable v */
  2080. static int awk_getline(rstream *rsm, var *v)
  2081. {
  2082. char *b;
  2083. regmatch_t pmatch[1];
  2084. int p, pp;
  2085. int fd, so, eo, retval, rp;
  2086. char *m, *s;
  2087. debug_printf_eval("entered %s()\n", __func__);
  2088. /* we're using our own buffer since we need access to accumulating
  2089. * characters
  2090. */
  2091. fd = fileno(rsm->F);
  2092. m = rsm->buffer;
  2093. if (!m)
  2094. m = qrealloc(m, 256, &rsm->size);
  2095. p = rsm->pos;
  2096. rp = 0;
  2097. pp = 0;
  2098. do {
  2099. b = m + rsm->adv;
  2100. so = eo = p;
  2101. retval = 1;
  2102. if (p > 0) {
  2103. char c = (char) rsplitter.n.info;
  2104. if (rsplitter.n.info == TI_REGEXP) {
  2105. if (regexec(&rsplitter.n.l.re[icase],
  2106. b, 1, pmatch, 0) == 0
  2107. ) {
  2108. so = pmatch[0].rm_so;
  2109. eo = pmatch[0].rm_eo;
  2110. if (b[eo] != '\0')
  2111. break;
  2112. }
  2113. } else if (c != '\0') {
  2114. s = strchr(b+pp, c);
  2115. if (!s)
  2116. s = memchr(b+pp, '\0', p - pp);
  2117. if (s) {
  2118. so = eo = s-b;
  2119. eo++;
  2120. break;
  2121. }
  2122. } else {
  2123. while (b[rp] == '\n')
  2124. rp++;
  2125. s = strstr(b+rp, "\n\n");
  2126. if (s) {
  2127. so = eo = s-b;
  2128. while (b[eo] == '\n')
  2129. eo++;
  2130. if (b[eo] != '\0')
  2131. break;
  2132. }
  2133. }
  2134. }
  2135. if (rsm->adv > 0) {
  2136. memmove(m, m+rsm->adv, p+1);
  2137. b = m;
  2138. rsm->adv = 0;
  2139. }
  2140. b = m = qrealloc(m, p+128, &rsm->size);
  2141. pp = p;
  2142. p += safe_read(fd, b+p, rsm->size - p - 1);
  2143. if (p < pp) {
  2144. p = 0;
  2145. retval = 0;
  2146. setvar_ERRNO();
  2147. }
  2148. b[p] = '\0';
  2149. } while (p > pp);
  2150. if (p == 0) {
  2151. retval--;
  2152. } else {
  2153. setvar_sn(v, b+rp, so-rp);
  2154. v->type |= VF_USER;
  2155. setvar_sn(intvar[RT], b+so, eo-so);
  2156. }
  2157. rsm->buffer = m;
  2158. rsm->adv += eo;
  2159. rsm->pos = p - eo;
  2160. debug_printf_eval("returning from %s(): %d\n", __func__, retval);
  2161. return retval;
  2162. }
  2163. /* formatted output into an allocated buffer, return ptr to buffer */
  2164. #if !ENABLE_FEATURE_AWK_GNU_EXTENSIONS
  2165. # define awk_printf(a, b) awk_printf(a)
  2166. #endif
  2167. static char *awk_printf(node *n, size_t *len)
  2168. {
  2169. char *b;
  2170. char *fmt, *f;
  2171. size_t i;
  2172. //tmpvar = nvalloc(1);
  2173. #define TMPVAR (&G.awk_printf__tmpvar)
  2174. // We use a single "static" tmpvar (instead of on-stack or malloced one)
  2175. // to decrease memory consumption in deeply-recursive awk programs.
  2176. // The rule to work safely is to never call evaluate() while our static
  2177. // TMPVAR's value is still needed.
  2178. fmt = f = xstrdup(getvar_s(evaluate(nextarg(&n), TMPVAR)));
  2179. // ^^^^^^^^^ here we immediately strdup() the value, so the later call
  2180. // to evaluate() potentially recursing into another awk_printf() can't
  2181. // mangle the value.
  2182. b = NULL;
  2183. i = 0;
  2184. while (1) { /* "print one format spec" loop */
  2185. char *s;
  2186. char c;
  2187. char sv;
  2188. var *arg;
  2189. size_t slen;
  2190. /* Find end of the next format spec, or end of line */
  2191. s = f;
  2192. while (1) {
  2193. c = *f;
  2194. if (!c) /* no percent chars found at all */
  2195. goto nul;
  2196. f++;
  2197. if (c == '%')
  2198. break;
  2199. }
  2200. /* we are past % in "....%..." */
  2201. c = *f;
  2202. if (!c) /* "....%" */
  2203. goto nul;
  2204. if (c == '%') { /* "....%%...." */
  2205. slen = f - s;
  2206. s = xstrndup(s, slen);
  2207. f++;
  2208. goto append; /* print "....%" part verbatim */
  2209. }
  2210. while (1) {
  2211. if (isalpha(c))
  2212. break;
  2213. if (c == '*') /* gawk supports %*d and %*.*f, we don't... */
  2214. syntax_error("%*x formats are not supported");
  2215. c = *++f;
  2216. if (!c) { /* "....%...." and no letter found after % */
  2217. /* Example: awk 'BEGIN { printf "^^^%^^^\n"; }' */
  2218. nul:
  2219. slen = f - s;
  2220. goto tail; /* print remaining string, exit loop */
  2221. }
  2222. }
  2223. /* we are at A in "....%...A..." */
  2224. arg = evaluate(nextarg(&n), TMPVAR);
  2225. /* Result can be arbitrarily long. Example:
  2226. * printf "%99999s", "BOOM"
  2227. */
  2228. sv = *++f;
  2229. *f = '\0';
  2230. if (c == 'c') {
  2231. char cc = is_numeric(arg) ? getvar_i(arg) : *getvar_s(arg);
  2232. char *r = xasprintf(s, cc ? cc : '^' /* else strlen will be wrong */);
  2233. slen = strlen(r);
  2234. if (cc == '\0') /* if cc is NUL, re-format the string with it */
  2235. sprintf(r, s, cc);
  2236. s = r;
  2237. } else {
  2238. if (c == 's') {
  2239. s = xasprintf(s, getvar_s(arg));
  2240. } else {
  2241. double d = getvar_i(arg);
  2242. if (strchr("diouxX", c)) {
  2243. //TODO: make it wider here (%x -> %llx etc)?
  2244. //Can even print the value into a temp string with %.0f,
  2245. //then replace diouxX with s and print that string.
  2246. //This will correctly print even very large numbers,
  2247. //but some replacements are not equivalent:
  2248. //%09d -> %09s: breaks zero-padding;
  2249. //%+d -> %+s: won't prepend +; etc
  2250. s = xasprintf(s, (int)d);
  2251. } else if (strchr("eEfFgGaA", c)) {
  2252. s = xasprintf(s, d);
  2253. } else {
  2254. /* gawk 5.1.1 printf("%W") prints "%W", does not error out */
  2255. s = xstrndup(s, f - s);
  2256. }
  2257. }
  2258. slen = strlen(s);
  2259. }
  2260. *f = sv;
  2261. append:
  2262. if (i == 0) {
  2263. b = s;
  2264. i = slen;
  2265. continue;
  2266. }
  2267. tail:
  2268. b = xrealloc(b, i + slen + 1);
  2269. strcpy(b + i, s);
  2270. i += slen;
  2271. if (!c) /* s is NOT allocated and this is the last part of string? */
  2272. break;
  2273. free(s);
  2274. }
  2275. free(fmt);
  2276. //nvfree(tmpvar, 1);
  2277. #undef TMPVAR
  2278. #if ENABLE_FEATURE_AWK_GNU_EXTENSIONS
  2279. if (len)
  2280. *len = i;
  2281. #endif
  2282. return b;
  2283. }
  2284. /* Common substitution routine.
  2285. * Replace (nm)'th substring of (src) that matches (rn) with (repl),
  2286. * store result into (dest), return number of substitutions.
  2287. * If nm = 0, replace all matches.
  2288. * If src or dst is NULL, use $0.
  2289. * If subexp != 0, enable subexpression matching (\0-\9).
  2290. */
  2291. static int awk_sub(node *rn, const char *repl, int nm, var *src, var *dest /*,int subexp*/)
  2292. {
  2293. char *resbuf;
  2294. const char *sp;
  2295. int match_no, residx, replen, resbufsize;
  2296. int regexec_flags;
  2297. regmatch_t pmatch[10];
  2298. regex_t sreg, *regex;
  2299. /* True only if called to implement gensub(): */
  2300. int subexp = (src != dest);
  2301. #if defined(REG_STARTEND)
  2302. const char *src_string;
  2303. size_t src_strlen;
  2304. regexec_flags = REG_STARTEND;
  2305. #else
  2306. regexec_flags = 0;
  2307. #endif
  2308. resbuf = NULL;
  2309. residx = 0;
  2310. match_no = 0;
  2311. regex = as_regex(rn, &sreg);
  2312. sp = getvar_s(src ? src : intvar[F0]);
  2313. #if defined(REG_STARTEND)
  2314. src_string = sp;
  2315. src_strlen = strlen(src_string);
  2316. #endif
  2317. replen = strlen(repl);
  2318. for (;;) {
  2319. int so, eo;
  2320. #if defined(REG_STARTEND)
  2321. // REG_STARTEND: "This flag is a BSD extension, not present in POSIX"
  2322. size_t start_ofs = sp - src_string;
  2323. pmatch[0].rm_so = start_ofs;
  2324. pmatch[0].rm_eo = src_strlen;
  2325. if (regexec(regex, src_string, 10, pmatch, regexec_flags) != 0)
  2326. break;
  2327. eo = pmatch[0].rm_eo - start_ofs;
  2328. so = pmatch[0].rm_so - start_ofs;
  2329. #else
  2330. // BUG:
  2331. // gsub(/\<b*/,"") on "abc" matches empty string at "a...",
  2332. // advances sp one char (see "Empty match" comment later) to "bc"
  2333. // ... and erroneously matches "b" even though it is NOT at the word start.
  2334. enum { start_ofs = 0 };
  2335. if (regexec(regex, sp, 10, pmatch, regexec_flags) != 0)
  2336. break;
  2337. so = pmatch[0].rm_so;
  2338. eo = pmatch[0].rm_eo;
  2339. #endif
  2340. //bb_error_msg("match %u: [%u,%u] '%s'%p", match_no+1, so, eo, sp,sp);
  2341. resbuf = qrealloc(resbuf, residx + eo + replen, &resbufsize);
  2342. memcpy(resbuf + residx, sp, eo);
  2343. residx += eo;
  2344. if (++match_no >= nm) {
  2345. const char *s;
  2346. int bslash;
  2347. /* replace */
  2348. residx -= (eo - so);
  2349. bslash = 0;
  2350. for (s = repl; *s; s++) {
  2351. char c = *s;
  2352. if (c == '\\' && s[1]) {
  2353. bslash ^= 1;
  2354. if (bslash)
  2355. continue;
  2356. }
  2357. if ((!bslash && c == '&')
  2358. || (subexp && bslash && c >= '0' && c <= '9')
  2359. ) {
  2360. int n, j = 0;
  2361. if (c != '&') {
  2362. j = c - '0';
  2363. }
  2364. n = pmatch[j].rm_eo - pmatch[j].rm_so;
  2365. resbuf = qrealloc(resbuf, residx + replen + n, &resbufsize);
  2366. memcpy(resbuf + residx, sp + pmatch[j].rm_so - start_ofs, n);
  2367. residx += n;
  2368. } else
  2369. resbuf[residx++] = c;
  2370. bslash = 0;
  2371. }
  2372. }
  2373. sp += eo;
  2374. if (match_no == nm)
  2375. break;
  2376. if (eo == so) {
  2377. /* Empty match (e.g. "b*" will match anywhere).
  2378. * Advance by one char. */
  2379. /* Subtle: this is safe only because
  2380. * qrealloc allocated at least one extra byte */
  2381. resbuf[residx] = *sp;
  2382. if (*sp == '\0')
  2383. goto ret;
  2384. sp++;
  2385. residx++;
  2386. }
  2387. regexec_flags |= REG_NOTBOL;
  2388. }
  2389. resbuf = qrealloc(resbuf, residx + strlen(sp), &resbufsize);
  2390. strcpy(resbuf + residx, sp);
  2391. ret:
  2392. //bb_error_msg("end sp:'%s'%p", sp,sp);
  2393. setvar_p(dest ? dest : intvar[F0], resbuf);
  2394. if (regex == &sreg)
  2395. regfree(regex);
  2396. return match_no;
  2397. }
  2398. static NOINLINE int do_mktime(const char *ds)
  2399. {
  2400. struct tm then;
  2401. int count;
  2402. /*memset(&then, 0, sizeof(then)); - not needed */
  2403. then.tm_isdst = -1; /* default is unknown */
  2404. /* manpage of mktime says these fields are ints,
  2405. * so we can sscanf stuff directly into them */
  2406. count = sscanf(ds, "%u %u %u %u %u %u %d",
  2407. &then.tm_year, &then.tm_mon, &then.tm_mday,
  2408. &then.tm_hour, &then.tm_min, &then.tm_sec,
  2409. &then.tm_isdst);
  2410. if (count < 6
  2411. || (unsigned)then.tm_mon < 1
  2412. || (unsigned)then.tm_year < 1900
  2413. ) {
  2414. return -1;
  2415. }
  2416. then.tm_mon -= 1;
  2417. then.tm_year -= 1900;
  2418. return mktime(&then);
  2419. }
  2420. /* Reduce stack usage in exec_builtin() by keeping match() code separate */
  2421. static NOINLINE var *do_match(node *an1, const char *as0)
  2422. {
  2423. regmatch_t pmatch[1];
  2424. regex_t sreg, *re;
  2425. int n, start, len;
  2426. re = as_regex(an1, &sreg);
  2427. n = regexec(re, as0, 1, pmatch, 0);
  2428. if (re == &sreg)
  2429. regfree(re);
  2430. start = 0;
  2431. len = -1;
  2432. if (n == 0) {
  2433. start = pmatch[0].rm_so + 1;
  2434. len = pmatch[0].rm_eo - pmatch[0].rm_so;
  2435. }
  2436. setvar_i(newvar("RLENGTH"), len);
  2437. return setvar_i(newvar("RSTART"), start);
  2438. }
  2439. /* Reduce stack usage in evaluate() by keeping builtins' code separate */
  2440. static NOINLINE var *exec_builtin(node *op, var *res)
  2441. {
  2442. #define tspl (G.exec_builtin__tspl)
  2443. var *tmpvars;
  2444. node *an[4];
  2445. var *av[4];
  2446. const char *as[4];
  2447. node *spl;
  2448. uint32_t isr, info;
  2449. int nargs;
  2450. time_t tt;
  2451. int i, l, ll, n;
  2452. tmpvars = nvalloc(4);
  2453. #define TMPVAR0 (tmpvars)
  2454. #define TMPVAR1 (tmpvars + 1)
  2455. #define TMPVAR2 (tmpvars + 2)
  2456. #define TMPVAR3 (tmpvars + 3)
  2457. #define TMPVAR(i) (tmpvars + (i))
  2458. isr = info = op->info;
  2459. op = op->l.n;
  2460. av[2] = av[3] = NULL;
  2461. for (i = 0; i < 4 && op; i++) {
  2462. an[i] = nextarg(&op);
  2463. if (isr & 0x09000000) {
  2464. av[i] = evaluate(an[i], TMPVAR(i));
  2465. if (isr & 0x08000000)
  2466. as[i] = getvar_s(av[i]);
  2467. }
  2468. isr >>= 1;
  2469. }
  2470. nargs = i;
  2471. if ((uint32_t)nargs < (info >> 30))
  2472. syntax_error(EMSG_TOO_FEW_ARGS);
  2473. info &= OPNMASK;
  2474. switch (info) {
  2475. case B_a2:
  2476. if (ENABLE_FEATURE_AWK_LIBM)
  2477. setvar_i(res, atan2(getvar_i(av[0]), getvar_i(av[1])));
  2478. else
  2479. syntax_error(EMSG_NO_MATH);
  2480. break;
  2481. case B_sp: {
  2482. char *s, *s1;
  2483. if (nargs > 2) {
  2484. spl = (an[2]->info == TI_REGEXP) ? an[2]
  2485. : mk_splitter(getvar_s(evaluate(an[2], TMPVAR2)), &tspl);
  2486. } else {
  2487. spl = &fsplitter.n;
  2488. }
  2489. n = awk_split(as[0], spl, &s);
  2490. s1 = s;
  2491. clear_array(iamarray(av[1]));
  2492. for (i = 1; i <= n; i++)
  2493. setari_u(av[1], i, nextword(&s));
  2494. free(s1);
  2495. setvar_i(res, n);
  2496. break;
  2497. }
  2498. case B_ss: {
  2499. l = strlen(as[0]);
  2500. i = getvar_i(av[1]) - 1;
  2501. if (i > l)
  2502. i = l;
  2503. if (i < 0)
  2504. i = 0;
  2505. n = (nargs > 2) ? getvar_i(av[2]) : l-i;
  2506. if (n < 0)
  2507. n = 0;
  2508. setvar_sn(res, as[0]+i, n);
  2509. break;
  2510. }
  2511. /* Bitwise ops must assume that operands are unsigned. GNU Awk 3.1.5:
  2512. * awk '{ print or(-1,1) }' gives "4.29497e+09", not "-2.xxxe+09" */
  2513. case B_an:
  2514. setvar_i(res, getvar_i_int(av[0]) & getvar_i_int(av[1]));
  2515. break;
  2516. case B_co:
  2517. setvar_i(res, ~getvar_i_int(av[0]));
  2518. break;
  2519. case B_ls:
  2520. setvar_i(res, getvar_i_int(av[0]) << getvar_i_int(av[1]));
  2521. break;
  2522. case B_or:
  2523. setvar_i(res, getvar_i_int(av[0]) | getvar_i_int(av[1]));
  2524. break;
  2525. case B_rs:
  2526. setvar_i(res, getvar_i_int(av[0]) >> getvar_i_int(av[1]));
  2527. break;
  2528. case B_xo:
  2529. setvar_i(res, getvar_i_int(av[0]) ^ getvar_i_int(av[1]));
  2530. break;
  2531. case B_lo:
  2532. case B_up: {
  2533. char *s, *s1;
  2534. s1 = s = xstrdup(as[0]);
  2535. while (*s1) {
  2536. //*s1 = (info == B_up) ? toupper(*s1) : tolower(*s1);
  2537. if ((unsigned char)((*s1 | 0x20) - 'a') <= ('z' - 'a'))
  2538. *s1 = (info == B_up) ? (*s1 & 0xdf) : (*s1 | 0x20);
  2539. s1++;
  2540. }
  2541. setvar_p(res, s);
  2542. break;
  2543. }
  2544. case B_ix:
  2545. n = 0;
  2546. ll = strlen(as[1]);
  2547. l = strlen(as[0]) - ll;
  2548. if (ll > 0 && l >= 0) {
  2549. if (!icase) {
  2550. char *s = strstr(as[0], as[1]);
  2551. if (s)
  2552. n = (s - as[0]) + 1;
  2553. } else {
  2554. /* this piece of code is terribly slow and
  2555. * really should be rewritten
  2556. */
  2557. for (i = 0; i <= l; i++) {
  2558. if (strncasecmp(as[0]+i, as[1], ll) == 0) {
  2559. n = i+1;
  2560. break;
  2561. }
  2562. }
  2563. }
  2564. }
  2565. setvar_i(res, n);
  2566. break;
  2567. case B_ti:
  2568. if (nargs > 1)
  2569. tt = getvar_i(av[1]);
  2570. else
  2571. time(&tt);
  2572. i = strftime(g_buf, MAXVARFMT,
  2573. ((nargs > 0) ? as[0] : "%a %b %d %H:%M:%S %Z %Y"),
  2574. localtime(&tt));
  2575. setvar_sn(res, g_buf, i);
  2576. break;
  2577. case B_mt:
  2578. setvar_i(res, do_mktime(as[0]));
  2579. break;
  2580. case B_ma:
  2581. res = do_match(an[1], as[0]);
  2582. break;
  2583. case B_ge: /* gensub(regex, repl, matchnum, string) */
  2584. awk_sub(an[0], as[1], /*matchnum:*/getvar_i(av[2]), /*src:*/av[3], /*dst:*/res/*, TRUE*/);
  2585. break;
  2586. case B_gs: /* gsub(regex, repl, string) */
  2587. setvar_i(res, awk_sub(an[0], as[1], /*matchnum:all*/0, /*src:*/av[2], /*dst:*/av[2]/*, FALSE*/));
  2588. break;
  2589. case B_su: /* sub(regex, repl, string) */
  2590. setvar_i(res, awk_sub(an[0], as[1], /*matchnum:first*/1, /*src:*/av[2], /*dst:*/av[2]/*, FALSE*/));
  2591. break;
  2592. }
  2593. nvfree(tmpvars, 4);
  2594. #undef TMPVAR0
  2595. #undef TMPVAR1
  2596. #undef TMPVAR2
  2597. #undef TMPVAR3
  2598. #undef TMPVAR
  2599. return res;
  2600. #undef tspl
  2601. }
  2602. /* if expr looks like "var=value", perform assignment and return 1,
  2603. * otherwise return 0 */
  2604. static int try_to_assign(const char *expr)
  2605. {
  2606. char *exprc, *val;
  2607. val = (char*)endofname(expr);
  2608. if (val == (char*)expr || *val != '=') {
  2609. return FALSE;
  2610. }
  2611. exprc = xstrdup(expr);
  2612. val = exprc + (val - expr);
  2613. *val++ = '\0';
  2614. unescape_string_in_place(val);
  2615. setvar_u(newvar(exprc), val);
  2616. free(exprc);
  2617. return TRUE;
  2618. }
  2619. /* switch to next input file */
  2620. static int next_input_file(void)
  2621. {
  2622. #define input_file_seen (G.next_input_file__input_file_seen)
  2623. #define argind (G.next_input_file__argind)
  2624. const char *fname;
  2625. if (iF.F) {
  2626. fclose(iF.F);
  2627. iF.F = NULL;
  2628. iF.pos = iF.adv = 0;
  2629. }
  2630. for (;;) {
  2631. /* GNU Awk 5.1.1 does not _read_ ARGIND (but does read ARGC).
  2632. * It only sets ARGIND to 1, 2, 3... for every command-line filename
  2633. * (VAR=VAL params cause a gap in numbering).
  2634. * If there are none and stdin is used, then ARGIND is not modified:
  2635. * if it is set by e.g. 'BEGIN { ARGIND="foo" }', that value will
  2636. * still be there.
  2637. */
  2638. argind++;
  2639. if (argind >= getvar_i(intvar[ARGC])) {
  2640. if (input_file_seen)
  2641. return FALSE;
  2642. fname = "-";
  2643. iF.F = stdin;
  2644. break;
  2645. }
  2646. fname = getvar_s(findvar(iamarray(intvar[ARGV]), utoa(argind)));
  2647. if (fname && *fname) {
  2648. if (got_program != 2) { /* there was no -E option */
  2649. /* "If a filename on the command line has the form
  2650. * var=val it is treated as a variable assignment"
  2651. */
  2652. if (try_to_assign(fname))
  2653. continue;
  2654. }
  2655. iF.F = xfopen_stdin(fname);
  2656. setvar_i(intvar[ARGIND], argind);
  2657. break;
  2658. }
  2659. }
  2660. setvar_s(intvar[FILENAME], fname);
  2661. input_file_seen = TRUE;
  2662. return TRUE;
  2663. #undef argind
  2664. #undef input_file_seen
  2665. }
  2666. /*
  2667. * Evaluate node - the heart of the program. Supplied with subtree
  2668. * and "res" variable to assign the result to if we evaluate an expression.
  2669. * If node refers to e.g. a variable or a field, no assignment happens.
  2670. * Return ptr to the result (which may or may not be the "res" variable!)
  2671. */
  2672. #define XC(n) ((n) >> 8)
  2673. static var *evaluate(node *op, var *res)
  2674. {
  2675. /* This procedure is recursive so we should count every byte */
  2676. #define fnargs (G.evaluate__fnargs)
  2677. /* seed is initialized to 1 */
  2678. #define seed (G.evaluate__seed)
  2679. #define sreg (G.evaluate__sreg)
  2680. var *tmpvars;
  2681. if (!op)
  2682. return setvar_s(res, NULL);
  2683. debug_printf_eval("entered %s()\n", __func__);
  2684. tmpvars = nvalloc(2);
  2685. #define TMPVAR0 (tmpvars)
  2686. #define TMPVAR1 (tmpvars + 1)
  2687. while (op) {
  2688. struct {
  2689. var *v;
  2690. const char *s;
  2691. } L = L; /* for compiler */
  2692. struct {
  2693. var *v;
  2694. const char *s;
  2695. } R = R;
  2696. double L_d = L_d;
  2697. uint32_t opinfo;
  2698. int opn;
  2699. node *op1;
  2700. var *old_Fields_ptr;
  2701. opinfo = op->info;
  2702. opn = (opinfo & OPNMASK);
  2703. g_lineno = op->lineno;
  2704. op1 = op->l.n;
  2705. debug_printf_eval("opinfo:%08x opn:%08x\n", opinfo, opn);
  2706. /* execute inevitable things */
  2707. old_Fields_ptr = NULL;
  2708. if (opinfo & OF_RES1) {
  2709. if ((opinfo & OF_REQUIRED) && !op1)
  2710. syntax_error(EMSG_TOO_FEW_ARGS);
  2711. L.v = evaluate(op1, TMPVAR0);
  2712. /* Does L.v point to $n variable? */
  2713. if ((size_t)(L.v - Fields) < num_alloc_fields) {
  2714. /* yes, remember where Fields[] is */
  2715. old_Fields_ptr = Fields;
  2716. }
  2717. if (opinfo & OF_NUM1) {
  2718. L_d = getvar_i(L.v);
  2719. debug_printf_eval("L_d:%f\n", L_d);
  2720. }
  2721. }
  2722. /* NB: if both L and R are $NNNs, and right one is large,
  2723. * then at this pint L.v points to Fields[NNN1], second
  2724. * evaluate() below reallocates and moves (!) Fields[],
  2725. * R.v points to Fields[NNN2] but L.v now points to freed mem!
  2726. * (Seen trying to evaluate "$444 $44444")
  2727. */
  2728. if (opinfo & OF_RES2) {
  2729. R.v = evaluate(op->r.n, TMPVAR1);
  2730. /* Seen in $5=$$5=$0:
  2731. * Evaluation of R.v ($$5=$0 expression)
  2732. * made L.v ($5) invalid. It's detected here.
  2733. */
  2734. if (old_Fields_ptr) {
  2735. //if (old_Fields_ptr != Fields)
  2736. // debug_printf_eval("L.v moved\n");
  2737. L.v = Fields + (L.v - old_Fields_ptr);
  2738. }
  2739. if (opinfo & OF_STR2) {
  2740. R.s = getvar_s(R.v);
  2741. debug_printf_eval("R.s:'%s'\n", R.s);
  2742. }
  2743. }
  2744. /* Get L.s _after_ R.v is evaluated: it may have realloc'd L.v
  2745. * so we must get the string after "old_Fields_ptr" correction
  2746. * above. Testcase: x = (v = "abc", gsub("b", "X", v));
  2747. */
  2748. if (opinfo & OF_RES1) {
  2749. if (opinfo & OF_STR1) {
  2750. L.s = getvar_s(L.v);
  2751. debug_printf_eval("L.s:'%s'\n", L.s);
  2752. }
  2753. }
  2754. debug_printf_eval("switch(0x%x)\n", XC(opinfo & OPCLSMASK));
  2755. switch (XC(opinfo & OPCLSMASK)) {
  2756. /* -- iterative node type -- */
  2757. /* test pattern */
  2758. case XC( OC_TEST ):
  2759. debug_printf_eval("TEST\n");
  2760. if (op1->info == TI_COMMA) {
  2761. /* it's range pattern */
  2762. if ((opinfo & OF_CHECKED) || ptest(op1->l.n)) {
  2763. op->info |= OF_CHECKED;
  2764. if (ptest(op1->r.n))
  2765. op->info &= ~OF_CHECKED;
  2766. op = op->a.n;
  2767. } else {
  2768. op = op->r.n;
  2769. }
  2770. } else {
  2771. op = ptest(op1) ? op->a.n : op->r.n;
  2772. }
  2773. break;
  2774. /* just evaluate an expression, also used as unconditional jump */
  2775. case XC( OC_EXEC ):
  2776. debug_printf_eval("EXEC\n");
  2777. break;
  2778. /* branch, used in if-else and various loops */
  2779. case XC( OC_BR ):
  2780. debug_printf_eval("BR\n");
  2781. op = istrue(L.v) ? op->a.n : op->r.n;
  2782. break;
  2783. /* initialize for-in loop */
  2784. case XC( OC_WALKINIT ):
  2785. debug_printf_eval("WALKINIT\n");
  2786. hashwalk_init(L.v, iamarray(R.v));
  2787. break;
  2788. /* get next array item */
  2789. case XC( OC_WALKNEXT ):
  2790. debug_printf_eval("WALKNEXT\n");
  2791. op = hashwalk_next(L.v) ? op->a.n : op->r.n;
  2792. break;
  2793. case XC( OC_PRINT ):
  2794. debug_printf_eval("PRINT /\n");
  2795. case XC( OC_PRINTF ):
  2796. debug_printf_eval("PRINTF\n");
  2797. {
  2798. FILE *F = stdout;
  2799. if (op->r.n) {
  2800. rstream *rsm = newfile(R.s);
  2801. if (!rsm->F) {
  2802. if (opn == '|') {
  2803. rsm->F = popen(R.s, "w");
  2804. if (rsm->F == NULL)
  2805. bb_simple_perror_msg_and_die("popen");
  2806. rsm->is_pipe = 1;
  2807. } else {
  2808. rsm->F = xfopen(R.s, opn=='w' ? "w" : "a");
  2809. }
  2810. }
  2811. F = rsm->F;
  2812. }
  2813. /* Can't just check 'opinfo == OC_PRINT' here, parser ORs
  2814. * additional bits to opinfos of print/printf with redirects
  2815. */
  2816. if ((opinfo & OPCLSMASK) == OC_PRINT) {
  2817. if (!op1) {
  2818. fputs(getvar_s(intvar[F0]), F);
  2819. } else {
  2820. for (;;) {
  2821. var *v = evaluate(nextarg(&op1), TMPVAR0);
  2822. if (v->type & VF_NUMBER) {
  2823. fputs(fmt_num(getvar_s(intvar[OFMT]), getvar_i(v)),
  2824. F);
  2825. } else {
  2826. fputs(getvar_s(v), F);
  2827. }
  2828. if (!op1)
  2829. break;
  2830. fputs(getvar_s(intvar[OFS]), F);
  2831. }
  2832. }
  2833. fputs(getvar_s(intvar[ORS]), F);
  2834. } else { /* PRINTF */
  2835. IF_FEATURE_AWK_GNU_EXTENSIONS(size_t len;)
  2836. char *s = awk_printf(op1, &len);
  2837. #if ENABLE_FEATURE_AWK_GNU_EXTENSIONS
  2838. fwrite(s, len, 1, F);
  2839. #else
  2840. fputs(s, F);
  2841. #endif
  2842. free(s);
  2843. }
  2844. fflush(F);
  2845. break;
  2846. }
  2847. case XC( OC_DELETE ):
  2848. debug_printf_eval("DELETE\n");
  2849. {
  2850. /* "delete" is special:
  2851. * "delete array[var--]" must evaluate index expr only once.
  2852. */
  2853. uint32_t info = op1->info & OPCLSMASK;
  2854. var *v;
  2855. if (info == OC_VAR) {
  2856. v = op1->l.v;
  2857. } else if (info == OC_FNARG) {
  2858. v = &fnargs[op1->l.aidx];
  2859. } else {
  2860. syntax_error(EMSG_NOT_ARRAY);
  2861. }
  2862. if (op1->r.n) { /* array ref? */
  2863. const char *s;
  2864. s = getvar_s(evaluate(op1->r.n, TMPVAR0));
  2865. hash_remove(iamarray(v), s);
  2866. } else {
  2867. clear_array(iamarray(v));
  2868. }
  2869. break;
  2870. }
  2871. case XC( OC_NEWSOURCE ):
  2872. debug_printf_eval("NEWSOURCE\n");
  2873. g_progname = op->l.new_progname;
  2874. break;
  2875. case XC( OC_RETURN ):
  2876. debug_printf_eval("RETURN\n");
  2877. copyvar(res, L.v);
  2878. break;
  2879. case XC( OC_NEXTFILE ):
  2880. debug_printf_eval("NEXTFILE\n");
  2881. nextfile = TRUE;
  2882. case XC( OC_NEXT ):
  2883. debug_printf_eval("NEXT\n");
  2884. nextrec = TRUE;
  2885. case XC( OC_DONE ):
  2886. debug_printf_eval("DONE\n");
  2887. clrvar(res);
  2888. break;
  2889. case XC( OC_EXIT ):
  2890. debug_printf_eval("EXIT\n");
  2891. if (op1)
  2892. G.exitcode = (int)L_d;
  2893. awk_exit();
  2894. /* -- recursive node type -- */
  2895. case XC( OC_CONST ):
  2896. debug_printf_eval("CONST ");
  2897. case XC( OC_VAR ):
  2898. debug_printf_eval("VAR\n");
  2899. L.v = op->l.v;
  2900. if (L.v == intvar[NF])
  2901. split_f0();
  2902. goto v_cont;
  2903. case XC( OC_FNARG ):
  2904. debug_printf_eval("FNARG[%d]\n", op->l.aidx);
  2905. L.v = &fnargs[op->l.aidx];
  2906. v_cont:
  2907. res = op->r.n ? findvar(iamarray(L.v), R.s) : L.v;
  2908. break;
  2909. case XC( OC_IN ):
  2910. debug_printf_eval("IN\n");
  2911. setvar_i(res, hash_search(iamarray(R.v), L.s) ? 1 : 0);
  2912. break;
  2913. case XC( OC_REGEXP ):
  2914. debug_printf_eval("REGEXP\n");
  2915. op1 = op;
  2916. L.s = getvar_s(intvar[F0]);
  2917. goto re_cont;
  2918. case XC( OC_MATCH ):
  2919. debug_printf_eval("MATCH\n");
  2920. op1 = op->r.n;
  2921. re_cont:
  2922. {
  2923. regex_t *re = as_regex(op1, &sreg);
  2924. int i = regexec(re, L.s, 0, NULL, 0);
  2925. if (re == &sreg)
  2926. regfree(re);
  2927. setvar_i(res, (i == 0) ^ (opn == '!'));
  2928. }
  2929. break;
  2930. case XC( OC_MOVE ):
  2931. debug_printf_eval("MOVE\n");
  2932. /* make sure that we never return a temp var */
  2933. if (L.v == TMPVAR0)
  2934. L.v = res;
  2935. /* if source is a temporary string, just relink it to dest */
  2936. if (R.v == TMPVAR1
  2937. && !(R.v->type & VF_NUMBER)
  2938. /* Why check !NUMBER? if R.v is a number but has cached R.v->string,
  2939. * L.v ends up a string, which is wrong */
  2940. /*&& R.v->string - always not NULL (right?) */
  2941. ) {
  2942. res = setvar_p(L.v, R.v->string); /* avoids strdup */
  2943. R.v->string = NULL;
  2944. } else {
  2945. res = copyvar(L.v, R.v);
  2946. }
  2947. break;
  2948. case XC( OC_TERNARY ):
  2949. debug_printf_eval("TERNARY\n");
  2950. if (op->r.n->info != TI_COLON)
  2951. syntax_error(EMSG_POSSIBLE_ERROR);
  2952. res = evaluate(istrue(L.v) ? op->r.n->l.n : op->r.n->r.n, res);
  2953. break;
  2954. case XC( OC_FUNC ): {
  2955. var *argvars, *sv_fnargs;
  2956. const char *sv_progname;
  2957. int nargs, i;
  2958. debug_printf_eval("FUNC\n");
  2959. if (!op->r.f->defined)
  2960. syntax_error(EMSG_UNDEF_FUNC);
  2961. /* The body might be empty, still has to eval the args */
  2962. nargs = op->r.f->nargs;
  2963. argvars = nvalloc(nargs);
  2964. i = 0;
  2965. while (op1) {
  2966. var *arg = evaluate(nextarg(&op1), TMPVAR0);
  2967. if (i == nargs) {
  2968. /* call with more arguments than function takes.
  2969. * (gawk warns: "warning: function 'f' called with more arguments than declared").
  2970. * They are still evaluated, but discarded: */
  2971. clrvar(arg);
  2972. continue;
  2973. }
  2974. copyvar(&argvars[i], arg);
  2975. argvars[i].type |= VF_CHILD;
  2976. argvars[i].x.parent = arg;
  2977. i++;
  2978. }
  2979. sv_fnargs = fnargs;
  2980. sv_progname = g_progname;
  2981. fnargs = argvars;
  2982. res = evaluate(op->r.f->body.first, res);
  2983. nvfree(argvars, nargs);
  2984. g_progname = sv_progname;
  2985. fnargs = sv_fnargs;
  2986. break;
  2987. }
  2988. case XC( OC_GETLINE ):
  2989. debug_printf_eval("GETLINE /\n");
  2990. case XC( OC_PGETLINE ):
  2991. debug_printf_eval("PGETLINE\n");
  2992. {
  2993. rstream *rsm;
  2994. int i;
  2995. if (op1) {
  2996. rsm = newfile(L.s);
  2997. if (!rsm->F) {
  2998. /* NB: can't use "opinfo == TI_PGETLINE", would break "cmd" | getline */
  2999. if ((opinfo & OPCLSMASK) == OC_PGETLINE) {
  3000. rsm->F = popen(L.s, "r");
  3001. rsm->is_pipe = TRUE;
  3002. } else {
  3003. rsm->F = fopen_for_read(L.s); /* not xfopen! */
  3004. }
  3005. }
  3006. } else {
  3007. if (!iF.F)
  3008. next_input_file();
  3009. rsm = &iF;
  3010. }
  3011. if (!rsm->F) {
  3012. setvar_ERRNO();
  3013. setvar_i(res, -1);
  3014. break;
  3015. }
  3016. if (!op->r.n)
  3017. R.v = intvar[F0];
  3018. i = awk_getline(rsm, R.v);
  3019. if (i > 0 && !op1) {
  3020. incvar(intvar[FNR]);
  3021. incvar(intvar[NR]);
  3022. }
  3023. setvar_i(res, i);
  3024. break;
  3025. }
  3026. /* simple builtins */
  3027. case XC( OC_FBLTIN ): {
  3028. double R_d = R_d; /* for compiler */
  3029. debug_printf_eval("FBLTIN\n");
  3030. if (op1 && op1->info == TI_COMMA)
  3031. /* Simple builtins take one arg maximum */
  3032. syntax_error("Too many arguments");
  3033. switch (opn) {
  3034. case F_in:
  3035. R_d = (long long)L_d;
  3036. break;
  3037. case F_rn: /*rand*/
  3038. if (op1)
  3039. syntax_error("Too many arguments");
  3040. {
  3041. #if RAND_MAX >= 0x7fffffff
  3042. uint32_t u = ((uint32_t)rand() << 16) ^ rand();
  3043. uint64_t v = ((uint64_t)rand() << 32) | u;
  3044. /* the above shift+or is optimized out on 32-bit arches */
  3045. # if RAND_MAX > 0x7fffffff
  3046. v &= 0x7fffffffffffffffULL;
  3047. # endif
  3048. R_d = (double)v / 0x8000000000000000ULL;
  3049. #else
  3050. # error Not implemented for this value of RAND_MAX
  3051. #endif
  3052. break;
  3053. }
  3054. case F_co:
  3055. if (ENABLE_FEATURE_AWK_LIBM) {
  3056. R_d = cos(L_d);
  3057. break;
  3058. }
  3059. case F_ex:
  3060. if (ENABLE_FEATURE_AWK_LIBM) {
  3061. R_d = exp(L_d);
  3062. break;
  3063. }
  3064. case F_lg:
  3065. if (ENABLE_FEATURE_AWK_LIBM) {
  3066. R_d = log(L_d);
  3067. break;
  3068. }
  3069. case F_si:
  3070. if (ENABLE_FEATURE_AWK_LIBM) {
  3071. R_d = sin(L_d);
  3072. break;
  3073. }
  3074. case F_sq:
  3075. if (ENABLE_FEATURE_AWK_LIBM) {
  3076. R_d = sqrt(L_d);
  3077. break;
  3078. }
  3079. syntax_error(EMSG_NO_MATH);
  3080. break;
  3081. case F_sr:
  3082. R_d = (double)seed;
  3083. seed = op1 ? (unsigned)L_d : (unsigned)time(NULL);
  3084. srand(seed);
  3085. break;
  3086. case F_ti: /*systime*/
  3087. if (op1)
  3088. syntax_error("Too many arguments");
  3089. R_d = time(NULL);
  3090. break;
  3091. case F_le:
  3092. debug_printf_eval("length: L.s:'%s'\n", L.s);
  3093. if (!op1) {
  3094. L.s = getvar_s(intvar[F0]);
  3095. debug_printf_eval("length: L.s='%s'\n", L.s);
  3096. }
  3097. else if (L.v->type & VF_ARRAY) {
  3098. R_d = L.v->x.array->nel;
  3099. debug_printf_eval("length: array_len:%d\n", L.v->x.array->nel);
  3100. break;
  3101. }
  3102. R_d = strlen(L.s);
  3103. break;
  3104. case F_sy:
  3105. fflush_all();
  3106. R_d = (ENABLE_FEATURE_ALLOW_EXEC && L.s && *L.s)
  3107. ? (system(L.s) >> 8) : 0;
  3108. break;
  3109. case F_ff:
  3110. if (!op1) {
  3111. fflush(stdout);
  3112. } else if (L.s && *L.s) {
  3113. rstream *rsm = newfile(L.s);
  3114. fflush(rsm->F);
  3115. } else {
  3116. fflush_all();
  3117. }
  3118. break;
  3119. case F_cl: {
  3120. rstream *rsm;
  3121. int err = 0;
  3122. rsm = (rstream *)hash_search(fdhash, L.s);
  3123. debug_printf_eval("OC_FBLTIN close: op1:%p s:'%s' rsm:%p\n", op1, L.s, rsm);
  3124. if (rsm) {
  3125. debug_printf_eval("OC_FBLTIN F_cl "
  3126. "rsm->is_pipe:%d, ->F:%p\n",
  3127. rsm->is_pipe, rsm->F);
  3128. /* Can be NULL if open failed. Example:
  3129. * getline line <"doesnt_exist";
  3130. * close("doesnt_exist"); <--- here rsm->F is NULL
  3131. */
  3132. if (rsm->F)
  3133. err = rsm->is_pipe ? pclose(rsm->F) : fclose(rsm->F);
  3134. free(rsm->buffer);
  3135. hash_remove(fdhash, L.s);
  3136. } else {
  3137. err = -1;
  3138. /* gawk 'BEGIN { print close(""); print ERRNO }'
  3139. * -1
  3140. * close of redirection that was never opened
  3141. */
  3142. errno = ENOENT;
  3143. }
  3144. if (err)
  3145. setvar_ERRNO();
  3146. R_d = (double)err;
  3147. break;
  3148. }
  3149. } /* switch */
  3150. setvar_i(res, R_d);
  3151. break;
  3152. }
  3153. case XC( OC_BUILTIN ):
  3154. debug_printf_eval("BUILTIN\n");
  3155. res = exec_builtin(op, res);
  3156. break;
  3157. case XC( OC_SPRINTF ):
  3158. debug_printf_eval("SPRINTF\n");
  3159. setvar_p(res, awk_printf(op1, NULL));
  3160. break;
  3161. case XC( OC_UNARY ):
  3162. debug_printf_eval("UNARY\n");
  3163. {
  3164. double Ld, R_d;
  3165. Ld = R_d = getvar_i(R.v);
  3166. switch (opn) {
  3167. case 'P':
  3168. Ld = ++R_d;
  3169. goto r_op_change;
  3170. case 'p':
  3171. R_d++;
  3172. goto r_op_change;
  3173. case 'M':
  3174. Ld = --R_d;
  3175. goto r_op_change;
  3176. case 'm':
  3177. R_d--;
  3178. r_op_change:
  3179. setvar_i(R.v, R_d);
  3180. break;
  3181. case '!':
  3182. Ld = !istrue(R.v);
  3183. break;
  3184. case '-':
  3185. Ld = -R_d;
  3186. break;
  3187. }
  3188. setvar_i(res, Ld);
  3189. break;
  3190. }
  3191. case XC( OC_FIELD ):
  3192. debug_printf_eval("FIELD\n");
  3193. {
  3194. int i = (int)getvar_i(R.v);
  3195. if (i < 0)
  3196. syntax_error(EMSG_NEGATIVE_FIELD);
  3197. if (i == 0) {
  3198. res = intvar[F0];
  3199. } else {
  3200. split_f0();
  3201. if (i > num_fields)
  3202. fsrealloc(i);
  3203. res = &Fields[i - 1];
  3204. }
  3205. break;
  3206. }
  3207. /* concatenation (" ") and index joining (",") */
  3208. case XC( OC_CONCAT ):
  3209. debug_printf_eval("CONCAT /\n");
  3210. case XC( OC_COMMA ): {
  3211. const char *sep = "";
  3212. debug_printf_eval("COMMA\n");
  3213. if (opinfo == TI_COMMA)
  3214. sep = getvar_s(intvar[SUBSEP]);
  3215. setvar_p(res, xasprintf("%s%s%s", L.s, sep, R.s));
  3216. break;
  3217. }
  3218. case XC( OC_LAND ):
  3219. debug_printf_eval("LAND\n");
  3220. setvar_i(res, istrue(L.v) ? ptest(op->r.n) : 0);
  3221. break;
  3222. case XC( OC_LOR ):
  3223. debug_printf_eval("LOR\n");
  3224. setvar_i(res, istrue(L.v) ? 1 : ptest(op->r.n));
  3225. break;
  3226. case XC( OC_BINARY ):
  3227. debug_printf_eval("BINARY /\n");
  3228. case XC( OC_REPLACE ):
  3229. debug_printf_eval("REPLACE\n");
  3230. {
  3231. double R_d = getvar_i(R.v);
  3232. debug_printf_eval("R_d:%f opn:%c\n", R_d, opn);
  3233. switch (opn) {
  3234. case '+':
  3235. L_d += R_d;
  3236. break;
  3237. case '-':
  3238. L_d -= R_d;
  3239. break;
  3240. case '*':
  3241. L_d *= R_d;
  3242. break;
  3243. case '/':
  3244. if (R_d == 0)
  3245. syntax_error(EMSG_DIV_BY_ZERO);
  3246. L_d /= R_d;
  3247. break;
  3248. case '&':
  3249. if (ENABLE_FEATURE_AWK_LIBM)
  3250. L_d = pow(L_d, R_d);
  3251. else
  3252. syntax_error(EMSG_NO_MATH);
  3253. break;
  3254. case '%':
  3255. if (R_d == 0)
  3256. syntax_error(EMSG_DIV_BY_ZERO);
  3257. L_d -= (long long)(L_d / R_d) * R_d;
  3258. break;
  3259. }
  3260. debug_printf_eval("BINARY/REPLACE result:%f\n", L_d);
  3261. res = setvar_i(((opinfo & OPCLSMASK) == OC_BINARY) ? res : L.v, L_d);
  3262. break;
  3263. }
  3264. case XC( OC_COMPARE ): {
  3265. int i = i; /* for compiler */
  3266. double Ld;
  3267. debug_printf_eval("COMPARE\n");
  3268. if (is_numeric(L.v) && is_numeric(R.v)) {
  3269. Ld = getvar_i(L.v) - getvar_i(R.v);
  3270. } else {
  3271. const char *l = getvar_s(L.v);
  3272. const char *r = getvar_s(R.v);
  3273. Ld = icase ? strcasecmp(l, r) : strcmp(l, r);
  3274. }
  3275. switch (opn & 0xfe) {
  3276. case 0:
  3277. i = (Ld > 0);
  3278. break;
  3279. case 2:
  3280. i = (Ld >= 0);
  3281. break;
  3282. case 4:
  3283. i = (Ld == 0);
  3284. break;
  3285. }
  3286. debug_printf_eval("COMPARE result: %d\n", (i == 0) ^ (opn & 1));
  3287. setvar_i(res, (i == 0) ^ (opn & 1));
  3288. break;
  3289. }
  3290. default:
  3291. syntax_error(EMSG_POSSIBLE_ERROR);
  3292. } /* switch */
  3293. if ((opinfo & OPCLSMASK) <= SHIFT_TIL_THIS)
  3294. op = op->a.n;
  3295. if ((opinfo & OPCLSMASK) >= RECUR_FROM_THIS)
  3296. break;
  3297. if (nextrec)
  3298. break;
  3299. } /* while (op) */
  3300. nvfree(tmpvars, 2);
  3301. #undef TMPVAR0
  3302. #undef TMPVAR1
  3303. debug_printf_eval("returning from %s(): %p\n", __func__, res);
  3304. return res;
  3305. #undef fnargs
  3306. #undef seed
  3307. #undef sreg
  3308. }
  3309. static int awk_exit(void)
  3310. {
  3311. unsigned i;
  3312. if (!exiting) {
  3313. exiting = TRUE;
  3314. nextrec = FALSE;
  3315. evaluate(endseq.first, &G.exit__tmpvar);
  3316. }
  3317. /* waiting for children */
  3318. for (i = 0; i < fdhash->csize; i++) {
  3319. hash_item *hi;
  3320. hi = fdhash->items[i];
  3321. while (hi) {
  3322. if (hi->data.rs.F && hi->data.rs.is_pipe)
  3323. pclose(hi->data.rs.F);
  3324. hi = hi->next;
  3325. }
  3326. }
  3327. exit(G.exitcode);
  3328. }
  3329. int awk_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
  3330. int awk_main(int argc UNUSED_PARAM, char **argv)
  3331. {
  3332. int ch;
  3333. int i;
  3334. INIT_G();
  3335. /* Undo busybox.c, or else strtod may eat ','! This breaks parsing:
  3336. * $1,$2 == '$1,' '$2', NOT '$1' ',' '$2' */
  3337. if (ENABLE_LOCALE_SUPPORT)
  3338. setlocale(LC_NUMERIC, "C");
  3339. /* initialize variables */
  3340. vhash = hash_init();
  3341. {
  3342. char *vnames = (char *)vNames; /* cheat */
  3343. char *vvalues = (char *)vValues;
  3344. for (i = 0; *vnames; i++) {
  3345. var *v;
  3346. intvar[i] = v = newvar(nextword(&vnames));
  3347. if (*vvalues != '\377')
  3348. setvar_s(v, nextword(&vvalues));
  3349. else
  3350. setvar_i(v, 0);
  3351. if (*vnames == '*') {
  3352. v->type |= VF_SPECIAL;
  3353. vnames++;
  3354. }
  3355. }
  3356. }
  3357. handle_special(intvar[FS]);
  3358. handle_special(intvar[RS]);
  3359. /* Huh, people report that sometimes environ is NULL. Oh well. */
  3360. if (environ) {
  3361. char **envp;
  3362. for (envp = environ; *envp; envp++) {
  3363. /* environ is writable, thus we don't strdup it needlessly */
  3364. char *s = *envp;
  3365. char *s1 = strchr(s, '=');
  3366. if (s1) {
  3367. *s1 = '\0';
  3368. /* Both findvar and setvar_u take const char*
  3369. * as 2nd arg -> environment is not trashed */
  3370. setvar_u(findvar(iamarray(intvar[ENVIRON]), s), s1 + 1);
  3371. *s1 = '=';
  3372. }
  3373. }
  3374. }
  3375. fnhash = hash_init();
  3376. ahash = hash_init();
  3377. /* Cannot use getopt32: need to preserve order of -e / -f / -E / -i */
  3378. while ((ch = getopt(argc, argv, OPTSTR_AWK)) >= 0) {
  3379. switch (ch) {
  3380. case 'F':
  3381. unescape_string_in_place(optarg);
  3382. setvar_s(intvar[FS], optarg);
  3383. break;
  3384. case 'v':
  3385. if (!try_to_assign(optarg))
  3386. bb_show_usage();
  3387. break;
  3388. //TODO: implement -i LIBRARY, it is easy-ish
  3389. case 'E':
  3390. case 'f': {
  3391. int fd;
  3392. char *s;
  3393. g_progname = optarg;
  3394. fd = xopen_stdin(g_progname);
  3395. s = xmalloc_read(fd, NULL); /* it's NUL-terminated */
  3396. if (!s)
  3397. bb_perror_msg_and_die("read error from '%s'", g_progname);
  3398. close(fd);
  3399. parse_program(s);
  3400. free(s);
  3401. got_program = 1;
  3402. if (ch == 'E') {
  3403. got_program = 2;
  3404. goto stop_option_parsing;
  3405. }
  3406. break;
  3407. }
  3408. #if ENABLE_FEATURE_AWK_GNU_EXTENSIONS
  3409. case 'e':
  3410. g_progname = "cmd. line";
  3411. parse_program(optarg);
  3412. got_program = 1;
  3413. break;
  3414. #endif
  3415. case 'W':
  3416. bb_simple_error_msg("warning: option -W is ignored");
  3417. break;
  3418. default:
  3419. //bb_error_msg("ch:%d", ch);
  3420. bb_show_usage();
  3421. }
  3422. }
  3423. stop_option_parsing:
  3424. argv += optind;
  3425. //argc -= optind;
  3426. if (!got_program) {
  3427. if (!*argv)
  3428. bb_show_usage();
  3429. g_progname = "cmd. line";
  3430. parse_program(*argv++);
  3431. }
  3432. /* Free unused parse structures */
  3433. //hash_free(fnhash); // ~250 bytes when empty, used only for function names
  3434. //^^^^^^^^^^^^^^^^^ does not work, hash_clear() inside SEGVs
  3435. // (IOW: hash_clear() assumes it's a hash of variables. fnhash is not).
  3436. free(fnhash->items);
  3437. free(fnhash);
  3438. fnhash = NULL; // debug
  3439. //hash_free(ahash); // empty after parsing, will reuse as fdhash instead of freeing
  3440. /* Parsing done, on to executing */
  3441. /* fill in ARGV array */
  3442. setari_u(intvar[ARGV], 0, "awk");
  3443. i = 0;
  3444. while (*argv)
  3445. setari_u(intvar[ARGV], ++i, *argv++);
  3446. setvar_i(intvar[ARGC], i + 1);
  3447. //fdhash = ahash; // done via define
  3448. newfile("/dev/stdin")->F = stdin;
  3449. newfile("/dev/stdout")->F = stdout;
  3450. newfile("/dev/stderr")->F = stderr;
  3451. evaluate(beginseq.first, &G.main__tmpvar);
  3452. if (!mainseq.first && !endseq.first)
  3453. awk_exit();
  3454. /* input file could already be opened in BEGIN block */
  3455. if (!iF.F)
  3456. goto next_file; /* no, it wasn't, go try opening */
  3457. /* Iterate over input files */
  3458. for (;;) {
  3459. nextfile = FALSE;
  3460. setvar_i(intvar[FNR], 0);
  3461. while ((i = awk_getline(&iF, intvar[F0])) > 0) {
  3462. nextrec = FALSE;
  3463. incvar(intvar[NR]);
  3464. incvar(intvar[FNR]);
  3465. evaluate(mainseq.first, &G.main__tmpvar);
  3466. if (nextfile)
  3467. break;
  3468. }
  3469. if (i < 0)
  3470. syntax_error(strerror(errno));
  3471. next_file:
  3472. if (!next_input_file())
  3473. break;
  3474. }
  3475. awk_exit();
  3476. /*return 0;*/
  3477. }