wordsplit.c 54 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562
  1. /* wordsplit - a word splitter
  2. Copyright (C) 2009-2018 Sergey Poznyakoff
  3. This program is free software; you can redistribute it and/or modify it
  4. under the terms of the GNU General Public License as published by the
  5. Free Software Foundation; either version 3 of the License, or (at your
  6. option) any later version.
  7. This program is distributed in the hope that it will be useful,
  8. but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  10. GNU General Public License for more details.
  11. You should have received a copy of the GNU General Public License along
  12. with this program. If not, see <http://www.gnu.org/licenses/>. */
  13. #ifdef HAVE_CONFIG_H
  14. # include <config.h>
  15. #endif
  16. #include <errno.h>
  17. #include <ctype.h>
  18. #include <unistd.h>
  19. #include <stdlib.h>
  20. #include <string.h>
  21. #include <stdio.h>
  22. #include <stdarg.h>
  23. #include <pwd.h>
  24. #include <glob.h>
  25. #if ENABLE_NLS
  26. # include <gettext.h>
  27. #else
  28. # define gettext(msgid) msgid
  29. #endif
  30. #define _(msgid) gettext (msgid)
  31. #define N_(msgid) msgid
  32. #ifndef FALLTHROUGH
  33. # if __GNUC__ < 7
  34. # define FALLTHROUGH ((void) 0)
  35. # else
  36. # define FALLTHROUGH __attribute__ ((__fallthrough__))
  37. # endif
  38. #endif
  39. #include <wordsplit.h>
  40. #define ISWS(c) ((c)==' '||(c)=='\t'||(c)=='\n')
  41. #define ISDELIM(ws,c) \
  42. (strchr ((ws)->ws_delim, (c)) != NULL)
  43. #define ISPUNCT(c) (strchr("!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~",(c))!=NULL)
  44. #define ISUPPER(c) ('A' <= ((unsigned) (c)) && ((unsigned) (c)) <= 'Z')
  45. #define ISLOWER(c) ('a' <= ((unsigned) (c)) && ((unsigned) (c)) <= 'z')
  46. #define ISALPHA(c) (ISUPPER(c) || ISLOWER(c))
  47. #define ISDIGIT(c) ('0' <= ((unsigned) (c)) && ((unsigned) (c)) <= '9')
  48. #define ISXDIGIT(c) (strchr("abcdefABCDEF", c)!=NULL)
  49. #define ISALNUM(c) (ISALPHA(c) || ISDIGIT(c))
  50. #define ISPRINT(c) (' ' <= ((unsigned) (c)) && ((unsigned) (c)) <= 127)
  51. #define ISVARBEG(c) (ISALPHA(c) || c == '_')
  52. #define ISVARCHR(c) (ISALNUM(c) || c == '_')
  53. #define WSP_RETURN_DELIMS(wsp) \
  54. ((wsp)->ws_flags & WRDSF_RETURN_DELIMS || ((wsp)->ws_options & WRDSO_MAXWORDS))
  55. #define ALLOC_INIT 128
  56. #define ALLOC_INCR 128
  57. static void
  58. _wsplt_alloc_die (struct wordsplit *wsp)
  59. {
  60. wsp->ws_error ("%s", _("memory exhausted"));
  61. abort ();
  62. }
  63. static void __WORDSPLIT_ATTRIBUTE_FORMAT ((__printf__, 1, 2))
  64. _wsplt_error (const char *fmt, ...)
  65. {
  66. va_list ap;
  67. va_start (ap, fmt);
  68. vfprintf (stderr, fmt, ap);
  69. va_end (ap);
  70. fputc ('\n', stderr);
  71. }
  72. static void wordsplit_free_nodes (struct wordsplit *);
  73. static int
  74. _wsplt_seterr (struct wordsplit *wsp, int ec)
  75. {
  76. wsp->ws_errno = ec;
  77. if (wsp->ws_flags & WRDSF_SHOWERR)
  78. wordsplit_perror (wsp);
  79. return ec;
  80. }
  81. static int
  82. _wsplt_nomem (struct wordsplit *wsp)
  83. {
  84. errno = ENOMEM;
  85. wsp->ws_errno = WRDSE_NOSPACE;
  86. if (wsp->ws_flags & WRDSF_ENOMEMABRT)
  87. wsp->ws_alloc_die (wsp);
  88. if (wsp->ws_flags & WRDSF_SHOWERR)
  89. wordsplit_perror (wsp);
  90. if (!(wsp->ws_flags & WRDSF_REUSE))
  91. wordsplit_free (wsp);
  92. wordsplit_free_nodes (wsp);
  93. return wsp->ws_errno;
  94. }
  95. static int wordsplit_run (const char *command, size_t length,
  96. struct wordsplit *wsp,
  97. unsigned flags, int lvl);
  98. static int wordsplit_init (struct wordsplit *wsp, const char *input, size_t len,
  99. unsigned flags);
  100. static int wordsplit_process_list (struct wordsplit *wsp, size_t start);
  101. static int wordsplit_finish (struct wordsplit *wsp);
  102. static int
  103. _wsplt_subsplit (struct wordsplit *wsp, struct wordsplit *wss,
  104. char const *str, int len,
  105. unsigned flags, int finalize)
  106. {
  107. int rc;
  108. wss->ws_delim = wsp->ws_delim;
  109. wss->ws_debug = wsp->ws_debug;
  110. wss->ws_error = wsp->ws_error;
  111. wss->ws_alloc_die = wsp->ws_alloc_die;
  112. if (!(flags & WRDSF_NOVAR))
  113. {
  114. wss->ws_env = wsp->ws_env;
  115. wss->ws_getvar = wsp->ws_getvar;
  116. flags |= wsp->ws_flags & (WRDSF_ENV | WRDSF_ENV_KV | WRDSF_GETVAR);
  117. }
  118. if (!(flags & WRDSF_NOCMD))
  119. {
  120. wss->ws_command = wsp->ws_command;
  121. }
  122. if ((flags & (WRDSF_NOVAR|WRDSF_NOCMD)) != (WRDSF_NOVAR|WRDSF_NOCMD))
  123. {
  124. wss->ws_closure = wsp->ws_closure;
  125. flags |= wsp->ws_flags & WRDSF_CLOSURE;
  126. }
  127. wss->ws_options = wsp->ws_options;
  128. flags |= WRDSF_DELIM
  129. | WRDSF_ALLOC_DIE
  130. | WRDSF_ERROR
  131. | WRDSF_DEBUG
  132. | (wsp->ws_flags & (WRDSF_SHOWDBG | WRDSF_SHOWERR | WRDSF_OPTIONS));
  133. rc = wordsplit_init (wss, str, len, flags);
  134. if (rc)
  135. return rc;
  136. wss->ws_lvl = wsp->ws_lvl + 1;
  137. rc = wordsplit_process_list (wss, 0);
  138. if (rc)
  139. {
  140. wordsplit_free_nodes (wss);
  141. return rc;
  142. }
  143. if (finalize)
  144. {
  145. rc = wordsplit_finish (wss);
  146. wordsplit_free_nodes (wss);
  147. }
  148. return rc;
  149. }
  150. static void
  151. _wsplt_seterr_sub (struct wordsplit *wsp, struct wordsplit *wss)
  152. {
  153. if (wsp->ws_errno == WRDSE_USERERR)
  154. free (wsp->ws_usererr);
  155. wsp->ws_errno = wss->ws_errno;
  156. if (wss->ws_errno == WRDSE_USERERR)
  157. {
  158. wsp->ws_usererr = wss->ws_usererr;
  159. wss->ws_errno = WRDSE_EOF;
  160. wss->ws_usererr = NULL;
  161. }
  162. }
  163. static void
  164. wordsplit_init0 (struct wordsplit *wsp)
  165. {
  166. if (wsp->ws_flags & WRDSF_REUSE)
  167. {
  168. if (!(wsp->ws_flags & WRDSF_APPEND))
  169. wordsplit_free_words (wsp);
  170. wordsplit_clearerr (wsp);
  171. }
  172. else
  173. {
  174. wsp->ws_wordv = NULL;
  175. wsp->ws_wordc = 0;
  176. wsp->ws_wordn = 0;
  177. }
  178. wsp->ws_errno = 0;
  179. }
  180. char wordsplit_c_escape_tab[] = "\\\\\"\"a\ab\bf\fn\nr\rt\tv\v";
  181. static int
  182. wordsplit_init (struct wordsplit *wsp, const char *input, size_t len,
  183. unsigned flags)
  184. {
  185. wsp->ws_flags = flags;
  186. if (!(wsp->ws_flags & WRDSF_ALLOC_DIE))
  187. wsp->ws_alloc_die = _wsplt_alloc_die;
  188. if (!(wsp->ws_flags & WRDSF_ERROR))
  189. wsp->ws_error = _wsplt_error;
  190. if (!(wsp->ws_flags & WRDSF_NOVAR))
  191. {
  192. /* These will be initialized on first variable assignment */
  193. wsp->ws_envidx = wsp->ws_envsiz = 0;
  194. wsp->ws_envbuf = NULL;
  195. }
  196. if (!(wsp->ws_flags & WRDSF_NOCMD))
  197. {
  198. if (!wsp->ws_command)
  199. {
  200. _wsplt_seterr (wsp, WRDSE_USAGE);
  201. errno = EINVAL;
  202. return wsp->ws_errno;
  203. }
  204. }
  205. if (wsp->ws_flags & WRDSF_SHOWDBG)
  206. {
  207. if (!(wsp->ws_flags & WRDSF_DEBUG))
  208. {
  209. if (wsp->ws_flags & WRDSF_ERROR)
  210. wsp->ws_debug = wsp->ws_error;
  211. else if (wsp->ws_flags & WRDSF_SHOWERR)
  212. wsp->ws_debug = _wsplt_error;
  213. else
  214. wsp->ws_flags &= ~WRDSF_SHOWDBG;
  215. }
  216. }
  217. wsp->ws_input = input;
  218. wsp->ws_len = len;
  219. if (!(wsp->ws_flags & WRDSF_DOOFFS))
  220. wsp->ws_offs = 0;
  221. if (!(wsp->ws_flags & WRDSF_DELIM))
  222. wsp->ws_delim = " \t\n";
  223. if (!(wsp->ws_flags & WRDSF_COMMENT))
  224. wsp->ws_comment = NULL;
  225. if (!(wsp->ws_flags & WRDSF_CLOSURE))
  226. wsp->ws_closure = NULL;
  227. if (!(wsp->ws_flags & WRDSF_OPTIONS))
  228. wsp->ws_options = 0;
  229. if (wsp->ws_flags & WRDSF_ESCAPE)
  230. {
  231. if (!wsp->ws_escape[WRDSX_WORD])
  232. wsp->ws_escape[WRDSX_WORD] = "";
  233. if (!wsp->ws_escape[WRDSX_QUOTE])
  234. wsp->ws_escape[WRDSX_QUOTE] = "";
  235. }
  236. else
  237. {
  238. if (wsp->ws_flags & WRDSF_CESCAPES)
  239. {
  240. wsp->ws_escape[WRDSX_WORD] = wordsplit_c_escape_tab;
  241. wsp->ws_escape[WRDSX_QUOTE] = wordsplit_c_escape_tab;
  242. wsp->ws_options |= WRDSO_OESC_QUOTE | WRDSO_OESC_WORD
  243. | WRDSO_XESC_QUOTE | WRDSO_XESC_WORD;
  244. }
  245. else
  246. {
  247. wsp->ws_escape[WRDSX_WORD] = "";
  248. wsp->ws_escape[WRDSX_QUOTE] = "\\\\\"\"";
  249. wsp->ws_options |= WRDSO_BSKEEP_QUOTE;
  250. }
  251. }
  252. wsp->ws_endp = 0;
  253. wsp->ws_wordi = 0;
  254. if (wsp->ws_flags & WRDSF_REUSE)
  255. wordsplit_free_nodes (wsp);
  256. wsp->ws_head = wsp->ws_tail = NULL;
  257. wordsplit_init0 (wsp);
  258. return 0;
  259. }
  260. static int
  261. alloc_space (struct wordsplit *wsp, size_t count)
  262. {
  263. size_t offs = (wsp->ws_flags & WRDSF_DOOFFS) ? wsp->ws_offs : 0;
  264. char **ptr;
  265. size_t newalloc;
  266. if (wsp->ws_wordv == NULL)
  267. {
  268. newalloc = offs + count > ALLOC_INIT ? count : ALLOC_INIT;
  269. ptr = calloc (newalloc, sizeof (ptr[0]));
  270. }
  271. else if (wsp->ws_wordn < offs + wsp->ws_wordc + count)
  272. {
  273. newalloc = offs + wsp->ws_wordc +
  274. (count > ALLOC_INCR ? count : ALLOC_INCR);
  275. ptr = realloc (wsp->ws_wordv, newalloc * sizeof (ptr[0]));
  276. }
  277. else
  278. return 0;
  279. if (ptr)
  280. {
  281. wsp->ws_wordn = newalloc;
  282. wsp->ws_wordv = ptr;
  283. }
  284. else
  285. return _wsplt_nomem (wsp);
  286. return 0;
  287. }
  288. /* Node state flags */
  289. #define _WSNF_NULL 0x01 /* null node (a noop) */
  290. #define _WSNF_WORD 0x02 /* node contains word in v.word */
  291. #define _WSNF_QUOTE 0x04 /* text is quoted */
  292. #define _WSNF_NOEXPAND 0x08 /* text is not subject to expansion */
  293. #define _WSNF_JOIN 0x10 /* node must be joined with the next node */
  294. #define _WSNF_SEXP 0x20 /* is a sed expression */
  295. #define _WSNF_DELIM 0x40 /* node is a delimiter */
  296. #define _WSNF_EMPTYOK 0x0100 /* special flag indicating that
  297. wordsplit_add_segm must add the
  298. segment even if it is empty */
  299. struct wordsplit_node
  300. {
  301. struct wordsplit_node *prev; /* Previous element */
  302. struct wordsplit_node *next; /* Next element */
  303. unsigned flags; /* Node flags */
  304. union
  305. {
  306. struct
  307. {
  308. size_t beg; /* Start of word in ws_input */
  309. size_t end; /* End of word in ws_input */
  310. } segm;
  311. char *word;
  312. } v;
  313. };
  314. static const char *
  315. wsnode_flagstr (unsigned flags)
  316. {
  317. static char retbuf[7];
  318. char *p = retbuf;
  319. if (flags & _WSNF_WORD)
  320. *p++ = 'w';
  321. else if (flags & _WSNF_NULL)
  322. *p++ = 'n';
  323. else
  324. *p++ = '-';
  325. if (flags & _WSNF_QUOTE)
  326. *p++ = 'q';
  327. else
  328. *p++ = '-';
  329. if (flags & _WSNF_NOEXPAND)
  330. *p++ = 'E';
  331. else
  332. *p++ = '-';
  333. if (flags & _WSNF_JOIN)
  334. *p++ = 'j';
  335. else
  336. *p++ = '-';
  337. if (flags & _WSNF_SEXP)
  338. *p++ = 's';
  339. else
  340. *p++ = '-';
  341. if (flags & _WSNF_DELIM)
  342. *p++ = 'd';
  343. else
  344. *p++ = '-';
  345. *p = 0;
  346. return retbuf;
  347. }
  348. static const char *
  349. wsnode_ptr (struct wordsplit *wsp, struct wordsplit_node *p)
  350. {
  351. if (p->flags & _WSNF_NULL)
  352. return "";
  353. else if (p->flags & _WSNF_WORD)
  354. return p->v.word;
  355. else
  356. return wsp->ws_input + p->v.segm.beg;
  357. }
  358. static size_t
  359. wsnode_len (struct wordsplit_node *p)
  360. {
  361. if (p->flags & _WSNF_NULL)
  362. return 0;
  363. else if (p->flags & _WSNF_WORD)
  364. return strlen (p->v.word);
  365. else
  366. return p->v.segm.end - p->v.segm.beg;
  367. }
  368. static int
  369. wsnode_new (struct wordsplit *wsp, struct wordsplit_node **pnode)
  370. {
  371. struct wordsplit_node *node = calloc (1, sizeof (*node));
  372. if (!node)
  373. return _wsplt_nomem (wsp);
  374. *pnode = node;
  375. return 0;
  376. }
  377. static void
  378. wsnode_free (struct wordsplit_node *p)
  379. {
  380. if (p->flags & _WSNF_WORD)
  381. free (p->v.word);
  382. free (p);
  383. }
  384. static void
  385. wsnode_append (struct wordsplit *wsp, struct wordsplit_node *node)
  386. {
  387. node->next = NULL;
  388. node->prev = wsp->ws_tail;
  389. if (wsp->ws_tail)
  390. wsp->ws_tail->next = node;
  391. else
  392. wsp->ws_head = node;
  393. wsp->ws_tail = node;
  394. }
  395. static void
  396. wsnode_remove (struct wordsplit *wsp, struct wordsplit_node *node)
  397. {
  398. struct wordsplit_node *p;
  399. p = node->prev;
  400. if (p)
  401. {
  402. p->next = node->next;
  403. if (!node->next)
  404. p->flags &= ~_WSNF_JOIN;
  405. }
  406. else
  407. wsp->ws_head = node->next;
  408. p = node->next;
  409. if (p)
  410. p->prev = node->prev;
  411. else
  412. wsp->ws_tail = node->prev;
  413. node->next = node->prev = NULL;
  414. }
  415. static struct wordsplit_node *
  416. wsnode_tail (struct wordsplit_node *p)
  417. {
  418. while (p && p->next)
  419. p = p->next;
  420. return p;
  421. }
  422. static void
  423. wsnode_insert (struct wordsplit *wsp, struct wordsplit_node *node,
  424. struct wordsplit_node *anchor, int before)
  425. {
  426. if (!wsp->ws_head)
  427. {
  428. node->next = node->prev = NULL;
  429. wsp->ws_head = wsp->ws_tail = node;
  430. }
  431. else if (before)
  432. {
  433. if (anchor->prev)
  434. wsnode_insert (wsp, node, anchor->prev, 0);
  435. else
  436. {
  437. struct wordsplit_node *tail = wsnode_tail (node);
  438. node->prev = NULL;
  439. tail->next = anchor;
  440. anchor->prev = tail;
  441. wsp->ws_head = node;
  442. }
  443. }
  444. else
  445. {
  446. struct wordsplit_node *p;
  447. struct wordsplit_node *tail = wsnode_tail (node);
  448. p = anchor->next;
  449. if (p)
  450. p->prev = tail;
  451. else
  452. wsp->ws_tail = tail;
  453. tail->next = p;
  454. node->prev = anchor;
  455. anchor->next = node;
  456. }
  457. }
  458. static int
  459. wordsplit_add_segm (struct wordsplit *wsp, size_t beg, size_t end, int flg)
  460. {
  461. struct wordsplit_node *node;
  462. int rc;
  463. if (end == beg && !(flg & _WSNF_EMPTYOK))
  464. return 0;
  465. rc = wsnode_new (wsp, &node);
  466. if (rc)
  467. return rc;
  468. node->flags = flg & ~(_WSNF_WORD | _WSNF_EMPTYOK);
  469. node->v.segm.beg = beg;
  470. node->v.segm.end = end;
  471. wsnode_append (wsp, node);
  472. return 0;
  473. }
  474. static void
  475. wordsplit_free_nodes (struct wordsplit *wsp)
  476. {
  477. struct wordsplit_node *p;
  478. for (p = wsp->ws_head; p;)
  479. {
  480. struct wordsplit_node *next = p->next;
  481. wsnode_free (p);
  482. p = next;
  483. }
  484. wsp->ws_head = wsp->ws_tail = NULL;
  485. }
  486. static void
  487. wordsplit_dump_nodes (struct wordsplit *wsp)
  488. {
  489. struct wordsplit_node *p;
  490. int n = 0;
  491. for (p = wsp->ws_head, n = 0; p; p = p->next, n++)
  492. {
  493. if (p->flags & _WSNF_WORD)
  494. wsp->ws_debug ("(%02d) %4d: %p: %#04x (%s):%s;",
  495. wsp->ws_lvl,
  496. n, p, p->flags, wsnode_flagstr (p->flags), p->v.word);
  497. else
  498. wsp->ws_debug ("(%02d) %4d: %p: %#04x (%s):%.*s;",
  499. wsp->ws_lvl,
  500. n, p, p->flags, wsnode_flagstr (p->flags),
  501. (int) (p->v.segm.end - p->v.segm.beg),
  502. wsp->ws_input + p->v.segm.beg);
  503. }
  504. }
  505. static int
  506. coalesce_segment (struct wordsplit *wsp, struct wordsplit_node *node)
  507. {
  508. struct wordsplit_node *p, *end;
  509. size_t len = 0;
  510. char *buf, *cur;
  511. int stop;
  512. if (!(node->flags & _WSNF_JOIN))
  513. return 0;
  514. for (p = node; p && (p->flags & _WSNF_JOIN); p = p->next)
  515. {
  516. len += wsnode_len (p);
  517. }
  518. if (p)
  519. len += wsnode_len (p);
  520. end = p;
  521. buf = malloc (len + 1);
  522. if (!buf)
  523. return _wsplt_nomem (wsp);
  524. cur = buf;
  525. p = node;
  526. for (stop = 0; !stop;)
  527. {
  528. struct wordsplit_node *next = p->next;
  529. const char *str = wsnode_ptr (wsp, p);
  530. size_t slen = wsnode_len (p);
  531. memcpy (cur, str, slen);
  532. cur += slen;
  533. if (p != node)
  534. {
  535. node->flags |= p->flags & _WSNF_QUOTE;
  536. wsnode_remove (wsp, p);
  537. stop = p == end;
  538. wsnode_free (p);
  539. }
  540. p = next;
  541. }
  542. *cur = 0;
  543. node->flags &= ~_WSNF_JOIN;
  544. if (node->flags & _WSNF_WORD)
  545. free (node->v.word);
  546. else
  547. node->flags |= _WSNF_WORD;
  548. node->v.word = buf;
  549. return 0;
  550. }
  551. static void wordsplit_string_unquote_copy (struct wordsplit *ws, int inquote,
  552. char *dst, const char *src,
  553. size_t n);
  554. static int
  555. wsnode_quoteremoval (struct wordsplit *wsp)
  556. {
  557. struct wordsplit_node *p;
  558. for (p = wsp->ws_head; p; p = p->next)
  559. {
  560. const char *str = wsnode_ptr (wsp, p);
  561. size_t slen = wsnode_len (p);
  562. int unquote;
  563. if (wsp->ws_flags & WRDSF_QUOTE)
  564. unquote = !(p->flags & _WSNF_NOEXPAND);
  565. else
  566. unquote = 0;
  567. if (unquote)
  568. {
  569. if (!(p->flags & _WSNF_WORD))
  570. {
  571. char *newstr = malloc (slen + 1);
  572. if (!newstr)
  573. return _wsplt_nomem (wsp);
  574. memcpy (newstr, str, slen);
  575. newstr[slen] = 0;
  576. p->v.word = newstr;
  577. p->flags |= _WSNF_WORD;
  578. }
  579. wordsplit_string_unquote_copy (wsp, p->flags & _WSNF_QUOTE,
  580. p->v.word, str, slen);
  581. }
  582. }
  583. return 0;
  584. }
  585. static int
  586. wsnode_coalesce (struct wordsplit *wsp)
  587. {
  588. struct wordsplit_node *p;
  589. for (p = wsp->ws_head; p; p = p->next)
  590. {
  591. if (p->flags & _WSNF_JOIN)
  592. if (coalesce_segment (wsp, p))
  593. return 1;
  594. }
  595. return 0;
  596. }
  597. static int
  598. wsnode_tail_coalesce (struct wordsplit *wsp, struct wordsplit_node *p)
  599. {
  600. if (p->next)
  601. {
  602. struct wordsplit_node *np = p;
  603. while (np && np->next)
  604. {
  605. np->flags |= _WSNF_JOIN;
  606. np = np->next;
  607. }
  608. if (coalesce_segment (wsp, p))
  609. return 1;
  610. }
  611. return 0;
  612. }
  613. static size_t skip_delim (struct wordsplit *wsp);
  614. static int
  615. wordsplit_finish (struct wordsplit *wsp)
  616. {
  617. struct wordsplit_node *p;
  618. size_t n;
  619. int delim;
  620. /* Postprocess delimiters. It would be rather simple, if it weren't for
  621. the incremental operation.
  622. Nodes of type _WSNF_DELIM get inserted to the node list if either
  623. WRDSF_RETURN_DELIMS flag or WRDSO_MAXWORDS option is set.
  624. The following cases should be distinguished:
  625. 1. If both WRDSF_SQUEEZE_DELIMS and WRDSF_RETURN_DELIMS are set, compress
  626. any runs of similar delimiter nodes to a single node. The nodes are
  627. 'similar' if they point to the same delimiter character.
  628. If WRDSO_MAXWORDS option is set, stop compressing when
  629. ws_wordi + 1 == ws_maxwords, and coalesce the rest of nodes into
  630. a single last node.
  631. 2. If WRDSO_MAXWORDS option is set, but WRDSF_RETURN_DELIMS is not,
  632. remove any delimiter nodes. Stop operation when
  633. ws_wordi + 1 == ws_maxwords, and coalesce the rest of nodes into
  634. a single last node.
  635. 3. If incremental operation is in progress, restart the loop any time
  636. a delimiter node is about to be returned, unless WRDSF_RETURN_DELIMS
  637. is set.
  638. */
  639. again:
  640. delim = 0; /* Delimiter being processed (if any) */
  641. n = 0; /* Number of words processed so far */
  642. p = wsp->ws_head; /* Current node */
  643. while (p)
  644. {
  645. struct wordsplit_node *next = p->next;
  646. if (p->flags & _WSNF_DELIM)
  647. {
  648. if (wsp->ws_flags & WRDSF_RETURN_DELIMS)
  649. {
  650. if (wsp->ws_flags & WRDSF_SQUEEZE_DELIMS)
  651. {
  652. char const *s = wsnode_ptr (wsp, p);
  653. if (delim)
  654. {
  655. if (delim == *s)
  656. {
  657. wsnode_remove (wsp, p);
  658. p = next;
  659. continue;
  660. }
  661. else
  662. {
  663. delim = 0;
  664. n++; /* Count this node; it will be returned */
  665. }
  666. }
  667. else
  668. {
  669. delim = *s;
  670. p = next;
  671. continue;
  672. }
  673. }
  674. }
  675. else if (wsp->ws_options & WRDSO_MAXWORDS)
  676. {
  677. wsnode_remove (wsp, p);
  678. p = next;
  679. continue;
  680. }
  681. }
  682. else
  683. {
  684. if (delim)
  685. {
  686. /* Last node was a delimiter or a compressed run of delimiters;
  687. Count it, and clear the delimiter marker */
  688. n++;
  689. delim = 0;
  690. }
  691. if (wsp->ws_options & WRDSO_MAXWORDS)
  692. {
  693. if (wsp->ws_wordi + n + 1 == wsp->ws_maxwords)
  694. break;
  695. }
  696. }
  697. n++;
  698. if (wsp->ws_flags & WRDSF_INCREMENTAL)
  699. p = NULL; /* Break the loop */
  700. else
  701. p = next;
  702. }
  703. if (p)
  704. {
  705. /* We're here if WRDSO_MAXWORDS is in effect and wsp->ws_maxwords
  706. words have already been collected. Reconstruct a single final
  707. node from the remaining nodes. */
  708. if (wsnode_tail_coalesce (wsp, p))
  709. return wsp->ws_errno;
  710. n++;
  711. }
  712. if (n == 0 && (wsp->ws_flags & WRDSF_INCREMENTAL))
  713. {
  714. /* The loop above have eliminated all nodes. Restart the
  715. processing, if there's any input left. */
  716. if (wsp->ws_endp < wsp->ws_len)
  717. {
  718. int rc;
  719. if (wsp->ws_flags & WRDSF_SHOWDBG)
  720. wsp->ws_debug (_("Restarting"));
  721. rc = wordsplit_process_list (wsp, skip_delim (wsp));
  722. if (rc)
  723. return rc;
  724. }
  725. else
  726. {
  727. wsp->ws_error = WRDSE_EOF;
  728. return WRDSE_EOF;
  729. }
  730. goto again;
  731. }
  732. if (alloc_space (wsp, n + 1))
  733. return wsp->ws_errno;
  734. while (wsp->ws_head)
  735. {
  736. const char *str = wsnode_ptr (wsp, wsp->ws_head);
  737. size_t slen = wsnode_len (wsp->ws_head);
  738. char *newstr = malloc (slen + 1);
  739. /* Assign newstr first, even if it is NULL. This way
  740. wordsplit_free will work even if we return
  741. nomem later. */
  742. wsp->ws_wordv[wsp->ws_offs + wsp->ws_wordc] = newstr;
  743. if (!newstr)
  744. return _wsplt_nomem (wsp);
  745. memcpy (newstr, str, slen);
  746. newstr[slen] = 0;
  747. wsnode_remove (wsp, wsp->ws_head);
  748. wsp->ws_wordc++;
  749. wsp->ws_wordi++;
  750. if (wsp->ws_flags & WRDSF_INCREMENTAL)
  751. break;
  752. }
  753. wsp->ws_wordv[wsp->ws_offs + wsp->ws_wordc] = NULL;
  754. return 0;
  755. }
  756. int
  757. wordsplit_append (wordsplit_t *wsp, int argc, char **argv)
  758. {
  759. int rc;
  760. size_t i;
  761. rc = alloc_space (wsp, wsp->ws_wordc + argc + 1);
  762. if (rc)
  763. return rc;
  764. for (i = 0; i < argc; i++)
  765. {
  766. char *newstr = strdup (argv[i]);
  767. if (!newstr)
  768. {
  769. while (i > 0)
  770. {
  771. free (wsp->ws_wordv[wsp->ws_offs + wsp->ws_wordc + i - 1]);
  772. wsp->ws_wordv[wsp->ws_offs + wsp->ws_wordc + i - 1] = NULL;
  773. i--;
  774. }
  775. return _wsplt_nomem (wsp);
  776. }
  777. wsp->ws_wordv[wsp->ws_offs + wsp->ws_wordc + i] = newstr;
  778. }
  779. wsp->ws_wordc += i;
  780. wsp->ws_wordv[wsp->ws_offs + wsp->ws_wordc] = NULL;
  781. return 0;
  782. }
  783. /* Variable expansion */
  784. static int
  785. node_split_prefix (struct wordsplit *wsp,
  786. struct wordsplit_node **ptail,
  787. struct wordsplit_node *node,
  788. size_t beg, size_t len, int flg)
  789. {
  790. struct wordsplit_node *newnode;
  791. if (len == 0)
  792. return 0;
  793. if (wsnode_new (wsp, &newnode))
  794. return 1;
  795. wsnode_insert (wsp, newnode, *ptail, 0);
  796. if (node->flags & _WSNF_WORD)
  797. {
  798. const char *str = wsnode_ptr (wsp, node);
  799. char *newstr = malloc (len + 1);
  800. if (!newstr)
  801. return _wsplt_nomem (wsp);
  802. memcpy (newstr, str + beg, len);
  803. newstr[len] = 0;
  804. newnode->flags = _WSNF_WORD;
  805. newnode->v.word = newstr;
  806. }
  807. else
  808. {
  809. newnode->v.segm.beg = node->v.segm.beg + beg;
  810. newnode->v.segm.end = newnode->v.segm.beg + len;
  811. }
  812. newnode->flags |= flg;
  813. *ptail = newnode;
  814. return 0;
  815. }
  816. static int
  817. find_closing_paren (const char *str, size_t i, size_t len, size_t *poff,
  818. char const *paren)
  819. {
  820. enum { st_init, st_squote, st_dquote } state = st_init;
  821. size_t level = 1;
  822. for (; i < len; i++)
  823. {
  824. switch (state)
  825. {
  826. case st_init:
  827. switch (str[i])
  828. {
  829. default:
  830. if (str[i] == paren[0])
  831. {
  832. level++;
  833. break;
  834. }
  835. else if (str[i] == paren[1])
  836. {
  837. if (--level == 0)
  838. {
  839. *poff = i;
  840. return 0;
  841. }
  842. break;
  843. }
  844. break;
  845. case '"':
  846. state = st_dquote;
  847. break;
  848. case '\'':
  849. state = st_squote;
  850. break;
  851. }
  852. break;
  853. case st_squote:
  854. if (str[i] == '\'')
  855. state = st_init;
  856. break;
  857. case st_dquote:
  858. if (str[i] == '\\')
  859. i++;
  860. else if (str[i] == '"')
  861. state = st_init;
  862. break;
  863. }
  864. }
  865. return 1;
  866. }
  867. static int
  868. wordsplit_find_env (struct wordsplit *wsp, const char *name, size_t len,
  869. char const **ret)
  870. {
  871. size_t i;
  872. if (!(wsp->ws_flags & WRDSF_ENV))
  873. return WRDSE_UNDEF;
  874. if (wsp->ws_flags & WRDSF_ENV_KV)
  875. {
  876. /* A key-value pair environment */
  877. for (i = 0; wsp->ws_env[i]; i++)
  878. {
  879. size_t elen = strlen (wsp->ws_env[i]);
  880. if (elen == len && memcmp (wsp->ws_env[i], name, elen) == 0)
  881. {
  882. *ret = wsp->ws_env[i + 1];
  883. return WRDSE_OK;
  884. }
  885. /* Skip the value. Break the loop if it is NULL. */
  886. i++;
  887. if (wsp->ws_env[i] == NULL)
  888. break;
  889. }
  890. }
  891. else if (wsp->ws_env)
  892. {
  893. /* Usual (A=B) environment. */
  894. for (i = 0; wsp->ws_env[i]; i++)
  895. {
  896. size_t j;
  897. const char *var = wsp->ws_env[i];
  898. for (j = 0; j < len; j++)
  899. if (name[j] != var[j])
  900. break;
  901. if (j == len && var[j] == '=')
  902. {
  903. *ret = var + j + 1;
  904. return WRDSE_OK;
  905. }
  906. }
  907. }
  908. return WRDSE_UNDEF;
  909. }
  910. static int
  911. wsplt_assign_var (struct wordsplit *wsp, const char *name, size_t namelen,
  912. char *value)
  913. {
  914. int n = (wsp->ws_flags & WRDSF_ENV_KV) ? 2 : 1;
  915. char *v;
  916. if (wsp->ws_envidx + n >= wsp->ws_envsiz)
  917. {
  918. size_t sz;
  919. char **newenv;
  920. if (!wsp->ws_envbuf)
  921. {
  922. if (wsp->ws_flags & WRDSF_ENV)
  923. {
  924. size_t i = 0, j;
  925. if (wsp->ws_env)
  926. {
  927. for (; wsp->ws_env[i]; i++)
  928. ;
  929. }
  930. sz = i + n + 1;
  931. newenv = calloc (sz, sizeof(newenv[0]));
  932. if (!newenv)
  933. return _wsplt_nomem (wsp);
  934. for (j = 0; j < i; j++)
  935. {
  936. newenv[j] = strdup (wsp->ws_env[j]);
  937. if (!newenv[j])
  938. {
  939. for (; j > 1; j--)
  940. free (newenv[j-1]);
  941. free (newenv[j-1]);
  942. free (newenv);
  943. return _wsplt_nomem (wsp);
  944. }
  945. }
  946. newenv[j] = NULL;
  947. wsp->ws_envbuf = newenv;
  948. wsp->ws_envidx = i;
  949. wsp->ws_envsiz = sz;
  950. wsp->ws_env = (const char**) wsp->ws_envbuf;
  951. }
  952. else
  953. {
  954. newenv = calloc (WORDSPLIT_ENV_INIT, sizeof(newenv[0]));
  955. if (!newenv)
  956. return _wsplt_nomem (wsp);
  957. wsp->ws_envbuf = newenv;
  958. wsp->ws_envidx = 0;
  959. wsp->ws_envsiz = WORDSPLIT_ENV_INIT;
  960. wsp->ws_env = (const char**) wsp->ws_envbuf;
  961. wsp->ws_flags |= WRDSF_ENV;
  962. }
  963. }
  964. else
  965. {
  966. wsp->ws_envsiz *= 2;
  967. newenv = realloc (wsp->ws_envbuf,
  968. wsp->ws_envsiz * sizeof (wsp->ws_envbuf[0]));
  969. if (!newenv)
  970. return _wsplt_nomem (wsp);
  971. wsp->ws_envbuf = newenv;
  972. wsp->ws_env = (const char**) wsp->ws_envbuf;
  973. }
  974. }
  975. if (wsp->ws_flags & WRDSF_ENV_KV)
  976. {
  977. /* A key-value pair environment */
  978. char *p = malloc (namelen + 1);
  979. if (!p)
  980. return _wsplt_nomem (wsp);
  981. memcpy (p, name, namelen);
  982. p[namelen] = 0;
  983. v = strdup (value);
  984. if (!v)
  985. {
  986. free (p);
  987. return _wsplt_nomem (wsp);
  988. }
  989. wsp->ws_env[wsp->ws_envidx++] = p;
  990. wsp->ws_env[wsp->ws_envidx++] = v;
  991. }
  992. else
  993. {
  994. v = malloc (namelen + strlen(value) + 2);
  995. if (!v)
  996. return _wsplt_nomem (wsp);
  997. memcpy (v, name, namelen);
  998. v[namelen++] = '=';
  999. strcpy(v + namelen, value);
  1000. wsp->ws_env[wsp->ws_envidx++] = v;
  1001. }
  1002. wsp->ws_env[wsp->ws_envidx++] = NULL;
  1003. return WRDSE_OK;
  1004. }
  1005. static int
  1006. expvar (struct wordsplit *wsp, const char *str, size_t len,
  1007. struct wordsplit_node **ptail, const char **pend, unsigned flg)
  1008. {
  1009. size_t i = 0;
  1010. const char *defstr = NULL;
  1011. char *value;
  1012. const char *vptr;
  1013. struct wordsplit_node *newnode;
  1014. const char *start = str - 1;
  1015. int rc;
  1016. struct wordsplit ws;
  1017. if (ISVARBEG (str[0]))
  1018. {
  1019. for (i = 1; i < len; i++)
  1020. if (!ISVARCHR (str[i]))
  1021. break;
  1022. *pend = str + i - 1;
  1023. }
  1024. else if (str[0] == '{')
  1025. {
  1026. str++;
  1027. len--;
  1028. for (i = 1; i < len; i++)
  1029. {
  1030. if (str[i] == ':')
  1031. {
  1032. size_t j;
  1033. defstr = str + i + 1;
  1034. if (find_closing_paren (str, i + 1, len, &j, "{}"))
  1035. return _wsplt_seterr (wsp, WRDSE_CBRACE);
  1036. *pend = str + j;
  1037. break;
  1038. }
  1039. else if (str[i] == '}')
  1040. {
  1041. defstr = NULL;
  1042. *pend = str + i;
  1043. break;
  1044. }
  1045. else if (strchr ("-+?=", str[i]))
  1046. {
  1047. size_t j;
  1048. defstr = str + i;
  1049. if (find_closing_paren (str, i, len, &j, "{}"))
  1050. return _wsplt_seterr (wsp, WRDSE_CBRACE);
  1051. *pend = str + j;
  1052. break;
  1053. }
  1054. }
  1055. if (i == len)
  1056. return _wsplt_seterr (wsp, WRDSE_CBRACE);
  1057. }
  1058. else
  1059. {
  1060. if (wsnode_new (wsp, &newnode))
  1061. return 1;
  1062. wsnode_insert (wsp, newnode, *ptail, 0);
  1063. *ptail = newnode;
  1064. newnode->flags = _WSNF_WORD | flg;
  1065. newnode->v.word = malloc (3);
  1066. if (!newnode->v.word)
  1067. return _wsplt_nomem (wsp);
  1068. newnode->v.word[0] = '$';
  1069. newnode->v.word[1] = str[0];
  1070. newnode->v.word[2] = 0;
  1071. *pend = str;
  1072. return 0;
  1073. }
  1074. /* Actually expand the variable */
  1075. /* str - start of the variable name
  1076. i - its length
  1077. defstr - default replacement str */
  1078. if (defstr && strchr("-+?=", defstr[0]) == 0)
  1079. {
  1080. rc = WRDSE_UNDEF;
  1081. defstr = NULL;
  1082. }
  1083. else
  1084. {
  1085. rc = wordsplit_find_env (wsp, str, i, &vptr);
  1086. if (rc == WRDSE_OK)
  1087. {
  1088. if (vptr)
  1089. {
  1090. value = strdup (vptr);
  1091. if (!value)
  1092. rc = WRDSE_NOSPACE;
  1093. }
  1094. else
  1095. rc = WRDSE_UNDEF;
  1096. }
  1097. else if (wsp->ws_flags & WRDSF_GETVAR)
  1098. rc = wsp->ws_getvar (&value, str, i, wsp->ws_closure);
  1099. else
  1100. rc = WRDSE_UNDEF;
  1101. if (rc == WRDSE_OK
  1102. && (!value || value[0] == 0)
  1103. && defstr && defstr[-1] == ':')
  1104. {
  1105. free (value);
  1106. rc = WRDSE_UNDEF;
  1107. }
  1108. }
  1109. switch (rc)
  1110. {
  1111. case WRDSE_OK:
  1112. if (defstr && *defstr == '+')
  1113. {
  1114. size_t size = *pend - ++defstr;
  1115. rc = _wsplt_subsplit (wsp, &ws, defstr, size,
  1116. WRDSF_NOSPLIT | WRDSF_WS | WRDSF_QUOTE |
  1117. (wsp->ws_flags &
  1118. (WRDSF_NOVAR | WRDSF_NOCMD)), 1);
  1119. if (rc)
  1120. return rc;
  1121. free (value);
  1122. value = ws.ws_wordv[0];
  1123. ws.ws_wordv[0] = NULL;
  1124. wordsplit_free (&ws);
  1125. }
  1126. break;
  1127. case WRDSE_UNDEF:
  1128. if (defstr)
  1129. {
  1130. size_t size;
  1131. if (*defstr == '-' || *defstr == '=')
  1132. {
  1133. size = *pend - ++defstr;
  1134. rc = _wsplt_subsplit (wsp, &ws, defstr, size,
  1135. WRDSF_NOSPLIT | WRDSF_WS | WRDSF_QUOTE |
  1136. (wsp->ws_flags &
  1137. (WRDSF_NOVAR | WRDSF_NOCMD)),
  1138. 1);
  1139. if (rc)
  1140. return rc;
  1141. value = ws.ws_wordv[0];
  1142. ws.ws_wordv[0] = NULL;
  1143. wordsplit_free (&ws);
  1144. if (defstr[-1] == '=')
  1145. wsplt_assign_var (wsp, str, i, value);
  1146. }
  1147. else
  1148. {
  1149. if (*defstr == '?')
  1150. {
  1151. size = *pend - ++defstr;
  1152. if (size == 0)
  1153. wsp->ws_error (_("%.*s: variable null or not set"),
  1154. (int) i, str);
  1155. else
  1156. {
  1157. rc = _wsplt_subsplit (wsp, &ws, defstr, size,
  1158. WRDSF_NOSPLIT | WRDSF_WS |
  1159. WRDSF_QUOTE |
  1160. (wsp->ws_flags &
  1161. (WRDSF_NOVAR | WRDSF_NOCMD)),
  1162. 1);
  1163. if (rc == 0)
  1164. wsp->ws_error ("%.*s: %s",
  1165. (int) i, str, ws.ws_wordv[0]);
  1166. else
  1167. wsp->ws_error ("%.*s: %.*s",
  1168. (int) i, str, (int) size, defstr);
  1169. wordsplit_free (&ws);
  1170. }
  1171. }
  1172. value = NULL;
  1173. }
  1174. }
  1175. else if (wsp->ws_flags & WRDSF_UNDEF)
  1176. {
  1177. _wsplt_seterr (wsp, WRDSE_UNDEF);
  1178. return 1;
  1179. }
  1180. else
  1181. {
  1182. if (wsp->ws_flags & WRDSF_WARNUNDEF)
  1183. wsp->ws_error (_("warning: undefined variable `%.*s'"),
  1184. (int) i, str);
  1185. if (wsp->ws_flags & WRDSF_KEEPUNDEF)
  1186. value = NULL;
  1187. else
  1188. {
  1189. value = strdup ("");
  1190. if (!value)
  1191. return _wsplt_nomem (wsp);
  1192. }
  1193. }
  1194. break;
  1195. case WRDSE_NOSPACE:
  1196. return _wsplt_nomem (wsp);
  1197. case WRDSE_USERERR:
  1198. if (wsp->ws_errno == WRDSE_USERERR)
  1199. free (wsp->ws_usererr);
  1200. wsp->ws_usererr = value;
  1201. FALLTHROUGH;
  1202. default:
  1203. _wsplt_seterr (wsp, rc);
  1204. return 1;
  1205. }
  1206. if (value)
  1207. {
  1208. if (flg & _WSNF_QUOTE)
  1209. {
  1210. if (wsnode_new (wsp, &newnode))
  1211. {
  1212. free (value);
  1213. return 1;
  1214. }
  1215. wsnode_insert (wsp, newnode, *ptail, 0);
  1216. *ptail = newnode;
  1217. newnode->flags = _WSNF_WORD | _WSNF_NOEXPAND | flg;
  1218. newnode->v.word = value;
  1219. }
  1220. else if (*value == 0)
  1221. {
  1222. free (value);
  1223. /* Empty string is a special case */
  1224. if (wsnode_new (wsp, &newnode))
  1225. return 1;
  1226. wsnode_insert (wsp, newnode, *ptail, 0);
  1227. *ptail = newnode;
  1228. newnode->flags = _WSNF_NULL;
  1229. }
  1230. else
  1231. {
  1232. struct wordsplit ws;
  1233. int rc;
  1234. rc = _wsplt_subsplit (wsp, &ws, value, strlen (value),
  1235. WRDSF_NOVAR | WRDSF_NOCMD |
  1236. WRDSF_QUOTE
  1237. | (WSP_RETURN_DELIMS (wsp) ? WRDSF_RETURN_DELIMS : 0) ,
  1238. 0);
  1239. free (value);
  1240. if (rc)
  1241. {
  1242. _wsplt_seterr_sub (wsp, &ws);
  1243. wordsplit_free (&ws);
  1244. return 1;
  1245. }
  1246. wsnode_insert (wsp, ws.ws_head, *ptail, 0);
  1247. *ptail = ws.ws_tail;
  1248. ws.ws_head = ws.ws_tail = NULL;
  1249. wordsplit_free (&ws);
  1250. }
  1251. }
  1252. else if (wsp->ws_flags & WRDSF_KEEPUNDEF)
  1253. {
  1254. size_t size = *pend - start + 1;
  1255. if (wsnode_new (wsp, &newnode))
  1256. return 1;
  1257. wsnode_insert (wsp, newnode, *ptail, 0);
  1258. *ptail = newnode;
  1259. newnode->flags = _WSNF_WORD | _WSNF_NOEXPAND | flg;
  1260. newnode->v.word = malloc (size + 1);
  1261. if (!newnode->v.word)
  1262. return _wsplt_nomem (wsp);
  1263. memcpy (newnode->v.word, start, size);
  1264. newnode->v.word[size] = 0;
  1265. }
  1266. else
  1267. {
  1268. if (wsnode_new (wsp, &newnode))
  1269. return 1;
  1270. wsnode_insert (wsp, newnode, *ptail, 0);
  1271. *ptail = newnode;
  1272. newnode->flags = _WSNF_NULL;
  1273. }
  1274. return 0;
  1275. }
  1276. static int
  1277. begin_var_p (int c)
  1278. {
  1279. return c == '{' || ISVARBEG (c);
  1280. }
  1281. static int
  1282. node_expand (struct wordsplit *wsp, struct wordsplit_node *node,
  1283. int (*beg_p) (int),
  1284. int (*ws_exp_fn) (struct wordsplit *wsp,
  1285. const char *str, size_t len,
  1286. struct wordsplit_node **ptail,
  1287. const char **pend,
  1288. unsigned flg))
  1289. {
  1290. const char *str = wsnode_ptr (wsp, node);
  1291. size_t slen = wsnode_len (node);
  1292. const char *end = str + slen;
  1293. const char *p;
  1294. size_t off = 0;
  1295. struct wordsplit_node *tail = node;
  1296. for (p = str; p < end; p++)
  1297. {
  1298. if (*p == '\\')
  1299. {
  1300. p++;
  1301. continue;
  1302. }
  1303. if (*p == '$' && beg_p (p[1]))
  1304. {
  1305. size_t n = p - str;
  1306. if (tail != node)
  1307. tail->flags |= _WSNF_JOIN;
  1308. if (node_split_prefix (wsp, &tail, node, off, n, _WSNF_JOIN))
  1309. return 1;
  1310. p++;
  1311. if (ws_exp_fn (wsp, p, slen - n, &tail, &p,
  1312. node->flags & (_WSNF_JOIN | _WSNF_QUOTE)))
  1313. return 1;
  1314. off += p - str + 1;
  1315. str = p + 1;
  1316. }
  1317. }
  1318. if (p > str)
  1319. {
  1320. if (tail != node)
  1321. tail->flags |= _WSNF_JOIN;
  1322. if (node_split_prefix (wsp, &tail, node, off, p - str,
  1323. node->flags & (_WSNF_JOIN|_WSNF_QUOTE)))
  1324. return 1;
  1325. }
  1326. if (tail != node)
  1327. {
  1328. wsnode_remove (wsp, node);
  1329. wsnode_free (node);
  1330. }
  1331. return 0;
  1332. }
  1333. /* Remove NULL nodes from the list */
  1334. static void
  1335. wsnode_nullelim (struct wordsplit *wsp)
  1336. {
  1337. struct wordsplit_node *p;
  1338. for (p = wsp->ws_head; p;)
  1339. {
  1340. struct wordsplit_node *next = p->next;
  1341. if (p->flags & _WSNF_DELIM && p->prev)
  1342. p->prev->flags &= ~_WSNF_JOIN;
  1343. if (p->flags & _WSNF_NULL)
  1344. {
  1345. wsnode_remove (wsp, p);
  1346. wsnode_free (p);
  1347. }
  1348. p = next;
  1349. }
  1350. }
  1351. static int
  1352. wordsplit_varexp (struct wordsplit *wsp)
  1353. {
  1354. struct wordsplit_node *p;
  1355. for (p = wsp->ws_head; p;)
  1356. {
  1357. struct wordsplit_node *next = p->next;
  1358. if (!(p->flags & (_WSNF_NOEXPAND|_WSNF_DELIM)))
  1359. if (node_expand (wsp, p, begin_var_p, expvar))
  1360. return 1;
  1361. p = next;
  1362. }
  1363. wsnode_nullelim (wsp);
  1364. return 0;
  1365. }
  1366. static int
  1367. begin_cmd_p (int c)
  1368. {
  1369. return c == '(';
  1370. }
  1371. static int
  1372. expcmd (struct wordsplit *wsp, const char *str, size_t len,
  1373. struct wordsplit_node **ptail, const char **pend, unsigned flg)
  1374. {
  1375. int rc;
  1376. size_t j;
  1377. char *value;
  1378. struct wordsplit_node *newnode;
  1379. str++;
  1380. len--;
  1381. if (find_closing_paren (str, 0, len, &j, "()"))
  1382. {
  1383. _wsplt_seterr (wsp, WRDSE_PAREN);
  1384. return 1;
  1385. }
  1386. *pend = str + j;
  1387. if (wsp->ws_options & WRDSO_ARGV)
  1388. {
  1389. struct wordsplit ws;
  1390. rc = _wsplt_subsplit (wsp, &ws, str, j, WRDSF_WS | WRDSF_QUOTE, 1);
  1391. if (rc)
  1392. {
  1393. _wsplt_seterr_sub (wsp, &ws);
  1394. wordsplit_free (&ws);
  1395. return 1;
  1396. }
  1397. rc = wsp->ws_command (&value, str, j, ws.ws_wordv, wsp->ws_closure);
  1398. wordsplit_free (&ws);
  1399. }
  1400. else
  1401. rc = wsp->ws_command (&value, str, j, NULL, wsp->ws_closure);
  1402. if (rc == WRDSE_NOSPACE)
  1403. return _wsplt_nomem (wsp);
  1404. else if (rc)
  1405. {
  1406. if (rc == WRDSE_USERERR)
  1407. {
  1408. if (wsp->ws_errno == WRDSE_USERERR)
  1409. free (wsp->ws_usererr);
  1410. wsp->ws_usererr = value;
  1411. }
  1412. _wsplt_seterr (wsp, rc);
  1413. return 1;
  1414. }
  1415. if (value)
  1416. {
  1417. if (flg & _WSNF_QUOTE)
  1418. {
  1419. if (wsnode_new (wsp, &newnode))
  1420. return 1;
  1421. wsnode_insert (wsp, newnode, *ptail, 0);
  1422. *ptail = newnode;
  1423. newnode->flags = _WSNF_WORD | _WSNF_NOEXPAND | flg;
  1424. newnode->v.word = value;
  1425. }
  1426. else if (*value == 0)
  1427. {
  1428. free (value);
  1429. /* Empty string is a special case */
  1430. if (wsnode_new (wsp, &newnode))
  1431. return 1;
  1432. wsnode_insert (wsp, newnode, *ptail, 0);
  1433. *ptail = newnode;
  1434. newnode->flags = _WSNF_NULL;
  1435. }
  1436. else
  1437. {
  1438. struct wordsplit ws;
  1439. int rc;
  1440. rc = _wsplt_subsplit (wsp, &ws, value, strlen (value),
  1441. WRDSF_NOVAR | WRDSF_NOCMD
  1442. | WRDSF_WS | WRDSF_QUOTE
  1443. | (WSP_RETURN_DELIMS (wsp) ? WRDSF_RETURN_DELIMS : 0),
  1444. 0);
  1445. free (value);
  1446. if (rc)
  1447. {
  1448. _wsplt_seterr_sub (wsp, &ws);
  1449. wordsplit_free (&ws);
  1450. return 1;
  1451. }
  1452. wsnode_insert (wsp, ws.ws_head, *ptail, 0);
  1453. *ptail = ws.ws_tail;
  1454. ws.ws_head = ws.ws_tail = NULL;
  1455. wordsplit_free (&ws);
  1456. }
  1457. }
  1458. else
  1459. {
  1460. if (wsnode_new (wsp, &newnode))
  1461. return 1;
  1462. wsnode_insert (wsp, newnode, *ptail, 0);
  1463. *ptail = newnode;
  1464. newnode->flags = _WSNF_NULL;
  1465. }
  1466. return 0;
  1467. }
  1468. static int
  1469. wordsplit_cmdexp (struct wordsplit *wsp)
  1470. {
  1471. struct wordsplit_node *p;
  1472. for (p = wsp->ws_head; p;)
  1473. {
  1474. struct wordsplit_node *next = p->next;
  1475. if (!(p->flags & _WSNF_NOEXPAND))
  1476. if (node_expand (wsp, p, begin_cmd_p, expcmd))
  1477. return 1;
  1478. p = next;
  1479. }
  1480. wsnode_nullelim (wsp);
  1481. return 0;
  1482. }
  1483. /* Strip off any leading and trailing whitespace. This function is called
  1484. right after the initial scanning, therefore it assumes that every
  1485. node in the list is a text reference node. */
  1486. static int
  1487. wordsplit_trimws (struct wordsplit *wsp)
  1488. {
  1489. struct wordsplit_node *p;
  1490. for (p = wsp->ws_head; p; p = p->next)
  1491. {
  1492. size_t n;
  1493. if (!(p->flags & _WSNF_QUOTE))
  1494. {
  1495. /* Skip leading whitespace: */
  1496. for (n = p->v.segm.beg; n < p->v.segm.end && ISWS (wsp->ws_input[n]);
  1497. n++)
  1498. ;
  1499. p->v.segm.beg = n;
  1500. }
  1501. while (p->next && (p->flags & _WSNF_JOIN))
  1502. p = p->next;
  1503. if (p->flags & _WSNF_QUOTE)
  1504. continue;
  1505. /* Trim trailing whitespace */
  1506. for (n = p->v.segm.end;
  1507. n > p->v.segm.beg && ISWS (wsp->ws_input[n - 1]); n--);
  1508. p->v.segm.end = n;
  1509. if (p->v.segm.beg == p->v.segm.end)
  1510. p->flags |= _WSNF_NULL;
  1511. }
  1512. wsnode_nullelim (wsp);
  1513. return 0;
  1514. }
  1515. static int
  1516. wordsplit_tildexpand (struct wordsplit *wsp)
  1517. {
  1518. struct wordsplit_node *p;
  1519. char *uname = NULL;
  1520. size_t usize = 0;
  1521. for (p = wsp->ws_head; p; p = p->next)
  1522. {
  1523. const char *str;
  1524. if (p->flags & _WSNF_QUOTE)
  1525. continue;
  1526. str = wsnode_ptr (wsp, p);
  1527. if (str[0] == '~')
  1528. {
  1529. size_t i, size, dlen;
  1530. size_t slen = wsnode_len (p);
  1531. struct passwd *pw;
  1532. char *newstr;
  1533. for (i = 1; i < slen && str[i] != '/'; i++)
  1534. ;
  1535. if (i == slen)
  1536. continue;
  1537. if (i > 1)
  1538. {
  1539. if (i > usize)
  1540. {
  1541. char *p = realloc (uname, i);
  1542. if (!p)
  1543. {
  1544. free (uname);
  1545. return _wsplt_nomem (wsp);
  1546. }
  1547. uname = p;
  1548. usize = i;
  1549. }
  1550. --i;
  1551. memcpy (uname, str + 1, i);
  1552. uname[i] = 0;
  1553. pw = getpwnam (uname);
  1554. }
  1555. else
  1556. pw = getpwuid (getuid ());
  1557. if (!pw)
  1558. continue;
  1559. dlen = strlen (pw->pw_dir);
  1560. size = slen - i + dlen;
  1561. newstr = malloc (size);
  1562. if (!newstr)
  1563. {
  1564. free (uname);
  1565. return _wsplt_nomem (wsp);
  1566. }
  1567. --size;
  1568. memcpy (newstr, pw->pw_dir, dlen);
  1569. memcpy (newstr + dlen, str + i + 1, slen - i - 1);
  1570. newstr[size] = 0;
  1571. if (p->flags & _WSNF_WORD)
  1572. free (p->v.word);
  1573. p->v.word = newstr;
  1574. p->flags |= _WSNF_WORD;
  1575. }
  1576. }
  1577. free (uname);
  1578. return 0;
  1579. }
  1580. static int
  1581. isglob (const char *s, int l)
  1582. {
  1583. while (l--)
  1584. {
  1585. if (strchr ("*?[", *s++))
  1586. return 1;
  1587. }
  1588. return 0;
  1589. }
  1590. static int
  1591. wordsplit_pathexpand (struct wordsplit *wsp)
  1592. {
  1593. struct wordsplit_node *p, *next;
  1594. size_t slen;
  1595. int flags = 0;
  1596. #ifdef GLOB_PERIOD
  1597. if (wsp->ws_options & WRDSO_DOTGLOB)
  1598. flags = GLOB_PERIOD;
  1599. #endif
  1600. for (p = wsp->ws_head; p; p = next)
  1601. {
  1602. const char *str;
  1603. next = p->next;
  1604. if (p->flags & _WSNF_QUOTE)
  1605. continue;
  1606. str = wsnode_ptr (wsp, p);
  1607. slen = wsnode_len (p);
  1608. if (isglob (str, slen))
  1609. {
  1610. int i;
  1611. glob_t g;
  1612. struct wordsplit_node *prev;
  1613. char *pattern;
  1614. pattern = malloc (slen + 1);
  1615. if (!pattern)
  1616. return _wsplt_nomem (wsp);
  1617. memcpy (pattern, str, slen);
  1618. pattern[slen] = 0;
  1619. switch (glob (pattern, flags, NULL, &g))
  1620. {
  1621. case 0:
  1622. free (pattern);
  1623. break;
  1624. case GLOB_NOSPACE:
  1625. free (pattern);
  1626. return _wsplt_nomem (wsp);
  1627. case GLOB_NOMATCH:
  1628. if (wsp->ws_options & WRDSO_NULLGLOB)
  1629. {
  1630. wsnode_remove (wsp, p);
  1631. wsnode_free (p);
  1632. }
  1633. else if (wsp->ws_options & WRDSO_FAILGLOB)
  1634. {
  1635. char buf[128];
  1636. if (wsp->ws_errno == WRDSE_USERERR)
  1637. free (wsp->ws_usererr);
  1638. snprintf (buf, sizeof (buf), _("no files match pattern %s"),
  1639. pattern);
  1640. free (pattern);
  1641. wsp->ws_usererr = strdup (buf);
  1642. if (!wsp->ws_usererr)
  1643. return _wsplt_nomem (wsp);
  1644. else
  1645. return _wsplt_seterr (wsp, WRDSE_USERERR);
  1646. }
  1647. free (pattern);
  1648. continue;
  1649. default:
  1650. free (pattern);
  1651. return _wsplt_seterr (wsp, WRDSE_GLOBERR);
  1652. }
  1653. prev = p;
  1654. for (i = 0; i < g.gl_pathc; i++)
  1655. {
  1656. struct wordsplit_node *newnode;
  1657. char *newstr;
  1658. if (wsnode_new (wsp, &newnode))
  1659. return 1;
  1660. newstr = strdup (g.gl_pathv[i]);
  1661. if (!newstr)
  1662. {
  1663. wsnode_free (newnode);
  1664. return _wsplt_nomem (wsp);
  1665. }
  1666. newnode->v.word = newstr;
  1667. newnode->flags |= _WSNF_WORD|_WSNF_QUOTE;
  1668. wsnode_insert (wsp, newnode, prev, 0);
  1669. prev = newnode;
  1670. }
  1671. globfree (&g);
  1672. wsnode_remove (wsp, p);
  1673. wsnode_free (p);
  1674. }
  1675. }
  1676. return 0;
  1677. }
  1678. static int
  1679. skip_sed_expr (const char *command, size_t i, size_t len)
  1680. {
  1681. int state;
  1682. do
  1683. {
  1684. int delim;
  1685. if (command[i] == ';')
  1686. i++;
  1687. if (!(command[i] == 's' && i + 3 < len && ISPUNCT (command[i + 1])))
  1688. break;
  1689. delim = command[++i];
  1690. state = 1;
  1691. for (i++; i < len; i++)
  1692. {
  1693. if (state == 3)
  1694. {
  1695. if (command[i] == delim || !ISALNUM (command[i]))
  1696. break;
  1697. }
  1698. else if (command[i] == '\\')
  1699. i++;
  1700. else if (command[i] == delim)
  1701. state++;
  1702. }
  1703. }
  1704. while (state == 3 && i < len && command[i] == ';');
  1705. return i;
  1706. }
  1707. /* wsp->ws_endp points to a delimiter character. If RETURN_DELIMS
  1708. is true, return its value, otherwise return the index past it. */
  1709. static inline size_t
  1710. skip_delim_internal (struct wordsplit *wsp, int return_delims)
  1711. {
  1712. return return_delims ? wsp->ws_endp : wsp->ws_endp + 1;
  1713. }
  1714. static inline size_t
  1715. skip_delim (struct wordsplit *wsp)
  1716. {
  1717. return skip_delim_internal (wsp, WSP_RETURN_DELIMS (wsp));
  1718. }
  1719. static inline size_t
  1720. skip_delim_real (struct wordsplit *wsp)
  1721. {
  1722. return skip_delim_internal (wsp, wsp->ws_flags & WRDSF_RETURN_DELIMS);
  1723. }
  1724. #define _WRDS_EOF 0
  1725. #define _WRDS_OK 1
  1726. #define _WRDS_ERR 2
  1727. static int
  1728. scan_qstring (struct wordsplit *wsp, size_t start, size_t *end)
  1729. {
  1730. size_t j;
  1731. const char *command = wsp->ws_input;
  1732. size_t len = wsp->ws_len;
  1733. char q = command[start];
  1734. for (j = start + 1; j < len && command[j] != q; j++)
  1735. if (q == '"' && command[j] == '\\')
  1736. j++;
  1737. if (j < len && command[j] == q)
  1738. {
  1739. unsigned flags = _WSNF_QUOTE | _WSNF_EMPTYOK;
  1740. if (q == '\'')
  1741. flags |= _WSNF_NOEXPAND;
  1742. if (wordsplit_add_segm (wsp, start + 1, j, flags))
  1743. return _WRDS_ERR;
  1744. *end = j;
  1745. }
  1746. else
  1747. {
  1748. wsp->ws_endp = start;
  1749. _wsplt_seterr (wsp, WRDSE_QUOTE);
  1750. return _WRDS_ERR;
  1751. }
  1752. return 0;
  1753. }
  1754. static int
  1755. scan_word (struct wordsplit *wsp, size_t start, int consume_all)
  1756. {
  1757. size_t len = wsp->ws_len;
  1758. const char *command = wsp->ws_input;
  1759. const char *comment = wsp->ws_comment;
  1760. int join = 0;
  1761. unsigned flags = 0;
  1762. struct wordsplit_node *np = wsp->ws_tail;
  1763. size_t i = start;
  1764. if (i >= len)
  1765. {
  1766. wsp->ws_errno = WRDSE_EOF;
  1767. return _WRDS_EOF;
  1768. }
  1769. start = i;
  1770. if (wsp->ws_flags & WRDSF_SED_EXPR
  1771. && command[i] == 's' && i + 3 < len && ISPUNCT (command[i + 1]))
  1772. {
  1773. flags = _WSNF_SEXP;
  1774. i = skip_sed_expr (command, i, len);
  1775. }
  1776. else if (consume_all || !ISDELIM (wsp, command[i]))
  1777. {
  1778. while (i < len)
  1779. {
  1780. if (comment && strchr (comment, command[i]) != NULL)
  1781. {
  1782. size_t j;
  1783. for (j = i + 1; j < len && command[j] != '\n'; j++)
  1784. ;
  1785. if (wordsplit_add_segm (wsp, start, i, 0))
  1786. return _WRDS_ERR;
  1787. wsp->ws_endp = j;
  1788. return _WRDS_OK;
  1789. }
  1790. if (wsp->ws_flags & WRDSF_QUOTE)
  1791. {
  1792. if (command[i] == '\\')
  1793. {
  1794. if (++i == len)
  1795. break;
  1796. i++;
  1797. continue;
  1798. }
  1799. if (((wsp->ws_flags & WRDSF_SQUOTE) && command[i] == '\'') ||
  1800. ((wsp->ws_flags & WRDSF_DQUOTE) && command[i] == '"'))
  1801. {
  1802. if (join && wsp->ws_tail)
  1803. wsp->ws_tail->flags |= _WSNF_JOIN;
  1804. if (wordsplit_add_segm (wsp, start, i, _WSNF_JOIN))
  1805. return _WRDS_ERR;
  1806. if (scan_qstring (wsp, i, &i))
  1807. return _WRDS_ERR;
  1808. start = i + 1;
  1809. join = 1;
  1810. }
  1811. }
  1812. if (command[i] == '$')
  1813. {
  1814. if (!(wsp->ws_flags & WRDSF_NOVAR)
  1815. && command[i+1] == '{'
  1816. && find_closing_paren (command, i + 2, len, &i, "{}") == 0)
  1817. continue;
  1818. if (!(wsp->ws_flags & WRDSF_NOCMD)
  1819. && command[i+1] == '('
  1820. && find_closing_paren (command, i + 2, len, &i, "()") == 0)
  1821. continue;
  1822. }
  1823. if (!consume_all && ISDELIM (wsp, command[i]))
  1824. break;
  1825. else
  1826. i++;
  1827. }
  1828. }
  1829. else if (WSP_RETURN_DELIMS (wsp))
  1830. {
  1831. i++;
  1832. flags |= _WSNF_DELIM;
  1833. }
  1834. else if (!(wsp->ws_flags & WRDSF_SQUEEZE_DELIMS))
  1835. flags |= _WSNF_EMPTYOK;
  1836. if (join && i > start && wsp->ws_tail)
  1837. wsp->ws_tail->flags |= _WSNF_JOIN;
  1838. if (wordsplit_add_segm (wsp, start, i, flags))
  1839. return _WRDS_ERR;
  1840. wsp->ws_endp = i;
  1841. if (wsp->ws_flags & WRDSF_INCREMENTAL)
  1842. return _WRDS_EOF;
  1843. if (consume_all)
  1844. {
  1845. if (!np)
  1846. np = wsp->ws_head;
  1847. while (np)
  1848. {
  1849. np->flags |= _WSNF_QUOTE;
  1850. np = np->next;
  1851. }
  1852. }
  1853. return _WRDS_OK;
  1854. }
  1855. #define to_num(c) \
  1856. (ISDIGIT(c) ? c - '0' : (ISXDIGIT(c) ? toupper(c) - 'A' + 10 : 255 ))
  1857. static int
  1858. xtonum (int *pval, const char *src, int base, int cnt)
  1859. {
  1860. int i, val;
  1861. for (i = 0, val = 0; i < cnt; i++, src++)
  1862. {
  1863. int n = *(unsigned char *) src;
  1864. if (n > 127 || (n = to_num (n)) >= base)
  1865. break;
  1866. val = val * base + n;
  1867. }
  1868. *pval = val;
  1869. return i;
  1870. }
  1871. size_t
  1872. wordsplit_c_quoted_length (const char *str, int quote_hex, int *quote)
  1873. {
  1874. size_t len = 0;
  1875. *quote = 0;
  1876. for (; *str; str++)
  1877. {
  1878. if (strchr (" \"", *str))
  1879. *quote = 1;
  1880. if (*str == ' ')
  1881. len++;
  1882. else if (*str == '"')
  1883. len += 2;
  1884. else if (*str != '\t' && *str != '\\' && ISPRINT (*str))
  1885. len++;
  1886. else if (quote_hex)
  1887. len += 3;
  1888. else
  1889. {
  1890. if (wordsplit_c_quote_char (*str))
  1891. len += 2;
  1892. else
  1893. len += 4;
  1894. }
  1895. }
  1896. return len;
  1897. }
  1898. static int
  1899. wsplt_unquote_char (const char *transtab, int c)
  1900. {
  1901. while (*transtab && transtab[1])
  1902. {
  1903. if (*transtab++ == c)
  1904. return *transtab;
  1905. ++transtab;
  1906. }
  1907. return 0;
  1908. }
  1909. static int
  1910. wsplt_quote_char (const char *transtab, int c)
  1911. {
  1912. for (; *transtab && transtab[1]; transtab += 2)
  1913. {
  1914. if (transtab[1] == c)
  1915. return *transtab;
  1916. }
  1917. return 0;
  1918. }
  1919. int
  1920. wordsplit_c_unquote_char (int c)
  1921. {
  1922. return wsplt_unquote_char (wordsplit_c_escape_tab, c);
  1923. }
  1924. int
  1925. wordsplit_c_quote_char (int c)
  1926. {
  1927. return wsplt_quote_char (wordsplit_c_escape_tab, c);
  1928. }
  1929. void
  1930. wordsplit_string_unquote_copy (struct wordsplit *ws, int inquote,
  1931. char *dst, const char *src, size_t n)
  1932. {
  1933. int i = 0;
  1934. int c;
  1935. inquote = !!inquote;
  1936. while (i < n)
  1937. {
  1938. if (src[i] == '\\')
  1939. {
  1940. ++i;
  1941. if (WRDSO_ESC_TEST (ws, inquote, WRDSO_XESC)
  1942. && (src[i] == 'x' || src[i] == 'X'))
  1943. {
  1944. if (n - i < 2)
  1945. {
  1946. *dst++ = '\\';
  1947. *dst++ = src[i++];
  1948. }
  1949. else
  1950. {
  1951. int off = xtonum (&c, src + i + 1,
  1952. 16, 2);
  1953. if (off == 0)
  1954. {
  1955. *dst++ = '\\';
  1956. *dst++ = src[i++];
  1957. }
  1958. else
  1959. {
  1960. *dst++ = c;
  1961. i += off + 1;
  1962. }
  1963. }
  1964. }
  1965. else if (WRDSO_ESC_TEST (ws, inquote, WRDSO_OESC)
  1966. && (unsigned char) src[i] < 128 && ISDIGIT (src[i]))
  1967. {
  1968. if (n - i < 1)
  1969. {
  1970. *dst++ = '\\';
  1971. *dst++ = src[i++];
  1972. }
  1973. else
  1974. {
  1975. int off = xtonum (&c, src + i, 8, 3);
  1976. if (off == 0)
  1977. {
  1978. *dst++ = '\\';
  1979. *dst++ = src[i++];
  1980. }
  1981. else
  1982. {
  1983. *dst++ = c;
  1984. i += off;
  1985. }
  1986. }
  1987. }
  1988. else if ((c = wsplt_unquote_char (ws->ws_escape[inquote], src[i])))
  1989. {
  1990. *dst++ = c;
  1991. ++i;
  1992. }
  1993. else
  1994. {
  1995. if (WRDSO_ESC_TEST (ws, inquote, WRDSO_BSKEEP))
  1996. *dst++ = '\\';
  1997. *dst++ = src[i++];
  1998. }
  1999. }
  2000. else
  2001. *dst++ = src[i++];
  2002. }
  2003. *dst = 0;
  2004. }
  2005. void
  2006. wordsplit_c_quote_copy (char *dst, const char *src, int quote_hex)
  2007. {
  2008. for (; *src; src++)
  2009. {
  2010. if (*src == '"')
  2011. {
  2012. *dst++ = '\\';
  2013. *dst++ = *src;
  2014. }
  2015. else if (*src != '\t' && *src != '\\' && ISPRINT (*src))
  2016. *dst++ = *src;
  2017. else
  2018. {
  2019. char tmp[4];
  2020. if (quote_hex)
  2021. {
  2022. snprintf (tmp, sizeof tmp, "%%%02X", *(unsigned char *) src);
  2023. memcpy (dst, tmp, 3);
  2024. dst += 3;
  2025. }
  2026. else
  2027. {
  2028. int c = wordsplit_c_quote_char (*src);
  2029. *dst++ = '\\';
  2030. if (c)
  2031. *dst++ = c;
  2032. else
  2033. {
  2034. snprintf (tmp, sizeof tmp, "%03o", *(unsigned char *) src);
  2035. memcpy (dst, tmp, 3);
  2036. dst += 3;
  2037. }
  2038. }
  2039. }
  2040. }
  2041. }
  2042. /* This structure describes a single expansion phase */
  2043. struct exptab
  2044. {
  2045. char const *descr; /* Textual description (for debugging) */
  2046. int flag; /* WRDSF_ bit that controls this phase */
  2047. int opt; /* Entry-specific options (see EXPOPT_ flags below */
  2048. int (*expansion) (struct wordsplit *wsp); /* expansion function */
  2049. };
  2050. /* The following options control expansions: */
  2051. /* Normally the exptab entry is run if its flag bit is set in struct
  2052. wordsplit. The EXPOPT_NEG option negates this test so that expansion
  2053. is performed if its associated flag bit is not set in struct wordsplit. */
  2054. #define EXPOPT_NEG 0x01
  2055. /* All bits in flag must be set in order for entry to match */
  2056. #define EXPORT_ALLOF 0x02
  2057. /* Coalesce the input list before running the expansion. */
  2058. #define EXPOPT_COALESCE 0x04
  2059. static struct exptab exptab[] = {
  2060. { N_("WS trimming"), WRDSF_WS, 0,
  2061. wordsplit_trimws },
  2062. { N_("command substitution"), WRDSF_NOCMD, EXPOPT_NEG|EXPOPT_COALESCE,
  2063. wordsplit_cmdexp },
  2064. { N_("coalesce list"), 0, EXPOPT_NEG|EXPOPT_COALESCE,
  2065. NULL },
  2066. { N_("tilde expansion"), WRDSF_PATHEXPAND, 0,
  2067. wordsplit_tildexpand },
  2068. { N_("variable expansion"), WRDSF_NOVAR, EXPOPT_NEG,
  2069. wordsplit_varexp },
  2070. { N_("quote removal"), 0, EXPOPT_NEG,
  2071. wsnode_quoteremoval },
  2072. { N_("coalesce list"), 0, EXPOPT_NEG|EXPOPT_COALESCE,
  2073. NULL },
  2074. { N_("path expansion"), WRDSF_PATHEXPAND, 0,
  2075. wordsplit_pathexpand },
  2076. { NULL }
  2077. };
  2078. static inline int
  2079. exptab_matches(struct exptab *p, struct wordsplit *wsp)
  2080. {
  2081. int result;
  2082. result = (wsp->ws_flags & p->flag);
  2083. if (p->opt & EXPORT_ALLOF)
  2084. result = result == p->flag;
  2085. if (p->opt & EXPOPT_NEG)
  2086. result = !result;
  2087. return result;
  2088. }
  2089. static int
  2090. wordsplit_process_list (struct wordsplit *wsp, size_t start)
  2091. {
  2092. struct exptab *p;
  2093. if (wsp->ws_flags & WRDSF_SHOWDBG)
  2094. wsp->ws_debug (_("(%02d) Input:%.*s;"),
  2095. wsp->ws_lvl, (int) wsp->ws_len, wsp->ws_input);
  2096. if ((wsp->ws_flags & WRDSF_NOSPLIT)
  2097. || ((wsp->ws_options & WRDSO_MAXWORDS)
  2098. && wsp->ws_wordi + 1 == wsp->ws_maxwords))
  2099. {
  2100. /* Treat entire input as a single word */
  2101. if (scan_word (wsp, start, 1) == _WRDS_ERR)
  2102. return wsp->ws_errno;
  2103. }
  2104. else
  2105. {
  2106. int rc;
  2107. while ((rc = scan_word (wsp, start, 0)) == _WRDS_OK)
  2108. start = skip_delim (wsp);
  2109. /* Make sure tail element is not joinable */
  2110. if (wsp->ws_tail)
  2111. wsp->ws_tail->flags &= ~_WSNF_JOIN;
  2112. if (rc == _WRDS_ERR)
  2113. return wsp->ws_errno;
  2114. }
  2115. if (wsp->ws_flags & WRDSF_SHOWDBG)
  2116. {
  2117. wsp->ws_debug ("(%02d) %s", wsp->ws_lvl, _("Initial list:"));
  2118. wordsplit_dump_nodes (wsp);
  2119. }
  2120. for (p = exptab; p->descr; p++)
  2121. {
  2122. if (exptab_matches(p, wsp))
  2123. {
  2124. if (p->opt & EXPOPT_COALESCE)
  2125. {
  2126. if (wsnode_coalesce (wsp))
  2127. break;
  2128. if (wsp->ws_flags & WRDSF_SHOWDBG)
  2129. {
  2130. wsp->ws_debug ("(%02d) %s", wsp->ws_lvl,
  2131. _("Coalesced list:"));
  2132. wordsplit_dump_nodes (wsp);
  2133. }
  2134. }
  2135. if (p->expansion)
  2136. {
  2137. if (p->expansion (wsp))
  2138. break;
  2139. if (wsp->ws_flags & WRDSF_SHOWDBG)
  2140. {
  2141. wsp->ws_debug ("(%02d) %s", wsp->ws_lvl, _(p->descr));
  2142. wordsplit_dump_nodes (wsp);
  2143. }
  2144. }
  2145. }
  2146. }
  2147. return wsp->ws_errno;
  2148. }
  2149. static int
  2150. wordsplit_run (const char *command, size_t length, struct wordsplit *wsp,
  2151. unsigned flags, int lvl)
  2152. {
  2153. int rc;
  2154. size_t start;
  2155. if (!command)
  2156. {
  2157. if (!(flags & WRDSF_INCREMENTAL))
  2158. return _wsplt_seterr (wsp, WRDSE_USAGE);
  2159. if (wsp->ws_head)
  2160. return wordsplit_finish (wsp);
  2161. start = skip_delim_real (wsp);
  2162. if (wsp->ws_endp == wsp->ws_len)
  2163. return _wsplt_seterr (wsp, WRDSE_NOINPUT);
  2164. wsp->ws_flags |= WRDSF_REUSE;
  2165. wordsplit_init0 (wsp);
  2166. }
  2167. else
  2168. {
  2169. start = 0;
  2170. rc = wordsplit_init (wsp, command, length, flags);
  2171. if (rc)
  2172. return rc;
  2173. wsp->ws_lvl = lvl;
  2174. }
  2175. rc = wordsplit_process_list (wsp, start);
  2176. if (rc)
  2177. return rc;
  2178. return wordsplit_finish (wsp);
  2179. }
  2180. int
  2181. wordsplit_len (const char *command, size_t length, struct wordsplit *wsp,
  2182. unsigned flags)
  2183. {
  2184. return wordsplit_run (command, length, wsp, flags, 0);
  2185. }
  2186. int
  2187. wordsplit (const char *command, struct wordsplit *ws, unsigned flags)
  2188. {
  2189. return wordsplit_len (command, command ? strlen (command) : 0, ws, flags);
  2190. }
  2191. void
  2192. wordsplit_free_words (struct wordsplit *ws)
  2193. {
  2194. size_t i;
  2195. for (i = 0; i < ws->ws_wordc; i++)
  2196. {
  2197. char *p = ws->ws_wordv[ws->ws_offs + i];
  2198. if (p)
  2199. {
  2200. free (p);
  2201. ws->ws_wordv[ws->ws_offs + i] = NULL;
  2202. }
  2203. }
  2204. ws->ws_wordc = 0;
  2205. }
  2206. void
  2207. wordsplit_free_envbuf (struct wordsplit *ws)
  2208. {
  2209. if (ws->ws_flags & WRDSF_NOCMD)
  2210. return;
  2211. if (ws->ws_envbuf)
  2212. {
  2213. size_t i;
  2214. for (i = 0; ws->ws_envbuf[i]; i++)
  2215. free (ws->ws_envbuf[i]);
  2216. free (ws->ws_envbuf);
  2217. ws->ws_envidx = ws->ws_envsiz = 0;
  2218. ws->ws_envbuf = NULL;
  2219. }
  2220. }
  2221. void
  2222. wordsplit_clearerr (struct wordsplit *ws)
  2223. {
  2224. if (ws->ws_errno == WRDSE_USERERR)
  2225. free (ws->ws_usererr);
  2226. ws->ws_usererr = NULL;
  2227. ws->ws_errno = WRDSE_OK;
  2228. }
  2229. void
  2230. wordsplit_free (struct wordsplit *ws)
  2231. {
  2232. wordsplit_free_nodes (ws);
  2233. wordsplit_free_words (ws);
  2234. free (ws->ws_wordv);
  2235. ws->ws_wordv = NULL;
  2236. wordsplit_free_envbuf (ws);
  2237. }
  2238. int
  2239. wordsplit_get_words (struct wordsplit *ws, size_t *wordc, char ***wordv)
  2240. {
  2241. char **p = realloc (ws->ws_wordv,
  2242. (ws->ws_wordc + 1) * sizeof (ws->ws_wordv[0]));
  2243. if (!p)
  2244. return -1;
  2245. *wordv = p;
  2246. *wordc = ws->ws_wordc;
  2247. ws->ws_wordv = NULL;
  2248. ws->ws_wordc = 0;
  2249. ws->ws_wordn = 0;
  2250. return 0;
  2251. }
  2252. const char *_wordsplit_errstr[] = {
  2253. N_("no error"),
  2254. N_("missing closing quote"),
  2255. N_("memory exhausted"),
  2256. N_("invalid wordsplit usage"),
  2257. N_("unbalanced curly brace"),
  2258. N_("undefined variable"),
  2259. N_("input exhausted"),
  2260. N_("unbalanced parenthesis"),
  2261. N_("globbing error")
  2262. };
  2263. int _wordsplit_nerrs =
  2264. sizeof (_wordsplit_errstr) / sizeof (_wordsplit_errstr[0]);
  2265. const char *
  2266. wordsplit_strerror (struct wordsplit *ws)
  2267. {
  2268. if (ws->ws_errno == WRDSE_USERERR)
  2269. return ws->ws_usererr;
  2270. if (ws->ws_errno < _wordsplit_nerrs)
  2271. return _wordsplit_errstr[ws->ws_errno];
  2272. return N_("unknown error");
  2273. }
  2274. void
  2275. wordsplit_perror (struct wordsplit *wsp)
  2276. {
  2277. switch (wsp->ws_errno)
  2278. {
  2279. case WRDSE_QUOTE:
  2280. wsp->ws_error (_("missing closing %c (start near #%lu)"),
  2281. wsp->ws_input[wsp->ws_endp],
  2282. (unsigned long) wsp->ws_endp);
  2283. break;
  2284. default:
  2285. wsp->ws_error ("%s", wordsplit_strerror (wsp));
  2286. }
  2287. }