4
0

wordsplit.c 53 KB

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