]>
git.ipfire.org Git - thirdparty/glibc.git/blob - posix/wordexp.c
1 /* POSIX.2 wordexp implementation.
2 Copyright (C) 1997 Free Software Foundation, Inc.
3 This file is part of the GNU C Library.
4 Contributed by Tim Waugh <tim@cyberelk.demon.co.uk>.
6 The GNU C Library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Library General Public License as
8 published by the Free Software Foundation; either version 2 of the
9 License, or (at your option) any later version.
11 The GNU C Library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Library General Public License for more details.
16 You should have received a copy of the GNU Library General Public
17 License along with the GNU C Library; see the file COPYING.LIB. If not,
18 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
19 Boston, MA 02111-1307, USA. */
25 #include <sys/types.h>
30 #include <sys/types.h>
37 #include <sys/param.h>
43 * This is a recursive-descent-style word expansion routine.
46 /* Some forward declarations */
47 static int parse_dollars (char **word
, size_t *word_length
, size_t *max_length
,
48 const char *words
, size_t *offset
, int flags
,
50 static int parse_backtick (char **word
, size_t *word_length
,
51 size_t *max_length
, const char *words
,
52 size_t *offset
, int flags
, wordexp_t
*pwordexp
);
53 static int eval_expr (char *expr
, int *result
);
55 /* The w_*() functions manipulate word lists. */
60 w_addchar (char *buffer
, size_t *actlen
, size_t *maxlen
, char ch
)
61 /* (lengths exclude trailing zero) */
63 /* Add a character to the buffer, allocating room for it if needed.
66 if (*actlen
== *maxlen
)
68 char *old_buffer
= buffer
;
69 assert (buffer
== NULL
|| *maxlen
!= 0);
71 buffer
= realloc (buffer
, 1 + *maxlen
);
80 buffer
[++(*actlen
)] = '\0';
87 w_addstr (char *buffer
, size_t *actlen
, size_t *maxlen
, const char *str
)
88 /* (lengths exclude trailing zero) */
90 /* Add a string to the buffer, allocating room for it if needed.
94 assert (str
!= NULL
); /* w_addstr only called from this file */
97 if (*actlen
+ len
> *maxlen
)
99 char *old_buffer
= buffer
;
100 assert (buffer
== NULL
|| *maxlen
!= 0);
101 *maxlen
+= MAX (2 * len
, W_CHUNK
);
102 buffer
= realloc (old_buffer
, 1 + *maxlen
);
110 memcpy (&buffer
[*actlen
], str
, len
);
112 buffer
[*actlen
] = '\0';
119 w_addword (wordexp_t
*pwordexp
, char *word
)
121 /* Add a word to the wordlist */
124 num_p
= 2 + pwordexp
->we_wordc
+ pwordexp
->we_offs
;
125 pwordexp
->we_wordv
= realloc (pwordexp
->we_wordv
, sizeof (char *) * num_p
);
126 if (pwordexp
->we_wordv
!= NULL
)
128 pwordexp
->we_wordv
[pwordexp
->we_wordc
++] = word
;
129 pwordexp
->we_wordv
[pwordexp
->we_wordc
] = NULL
;
136 /* The parse_*() functions should leave *offset being the offset in 'words'
137 * to the last character processed.
141 parse_backslash (char **word
, size_t *word_length
, size_t *max_length
,
142 const char *words
, size_t *offset
)
144 /* We are poised _at_ a backslash, not in quotes */
146 switch (words
[1 + *offset
])
149 /* Backslash is last character of input words */
157 *word
= w_addchar (*word
, word_length
, max_length
, words
[1 + *offset
]);
169 parse_qtd_backslash (char **word
, size_t *word_length
, size_t *max_length
,
170 const char *words
, size_t *offset
)
172 /* We are poised _at_ a backslash, inside quotes */
174 switch (words
[1 + *offset
])
177 /* Backslash is last character of input words */
188 *word
= w_addchar (*word
, word_length
, max_length
, words
[1 + *offset
]);
196 *word
= w_addchar (*word
, word_length
, max_length
, words
[*offset
]);
198 *word
= w_addchar (*word
, word_length
, max_length
, words
[1 + *offset
]);
211 parse_tilde (char **word
, size_t *word_length
, size_t *max_length
,
212 const char *words
, size_t *offset
, size_t wordc
)
214 /* We are poised _at_ a tilde */
217 if (*word_length
!= 0)
219 if (!((*word
)[*word_length
- 1] == '=' && wordc
== 0))
221 if (!((*word
)[*word_length
- 1] == ':' &&
222 strchr (*word
, '=') && wordc
== 0))
224 *word
= w_addchar (*word
, word_length
, max_length
, '~');
225 return *word
? 0 : WRDE_NOSPACE
;
230 for (i
= 1 + *offset
; words
[i
]; i
++)
232 if (words
[i
] == ':' || words
[i
] == '/' || words
[i
] == ' ' ||
233 words
[i
] == '\t' || words
[i
] == 0 )
236 if (words
[i
] == '\\')
238 *word
= w_addchar (*word
, word_length
, max_length
, '~');
239 return *word
? 0 : WRDE_NOSPACE
;
243 if (i
== 1 + *offset
)
245 /* Tilde appears on its own */
247 struct passwd pwd
, *tpwd
;
249 char* buffer
= __alloca (buflen
);
254 while ((result
= __getpwuid_r (uid
, &pwd
, buffer
, buflen
, &tpwd
)) != 0
258 buffer
= __alloca (buflen
);
261 if (result
== 0 && pwd
.pw_dir
!= NULL
)
263 *word
= w_addstr (*word
, word_length
, max_length
, pwd
.pw_dir
);
269 *word
= w_addchar (*word
, word_length
, max_length
, '~');
276 /* Look up user name in database to get home directory */
277 char *user
= __strndup (&words
[1 + *offset
], i
- *offset
);
278 struct passwd pwd
, *tpwd
;
280 char* buffer
= __alloca (buflen
);
283 while ((result
= __getpwnam_r (user
, &pwd
, buffer
, buflen
, &tpwd
)) != 0
287 buffer
= __alloca (buflen
);
290 if (result
== 0 && pwd
.pw_dir
)
291 *word
= w_addstr (*word
, word_length
, max_length
, pwd
.pw_dir
);
294 /* (invalid login name) */
295 *word
= w_addchar (*word
, word_length
, max_length
, '~');
297 *word
= w_addstr (*word
, word_length
, max_length
, user
);
302 return *word
? 0 : WRDE_NOSPACE
;
306 parse_glob (char **word
, size_t *word_length
, size_t *max_length
,
307 const char *words
, size_t *offset
, int flags
,
308 wordexp_t
*pwordexp
, char *ifs
)
310 /* We are poised just after a '*' or a '{'. */
316 for (; words
[*offset
]; (*offset
)++)
317 switch (words
[*offset
])
324 error
= parse_dollars (word
, word_length
, max_length
, words
, offset
,
332 if (ifs
== NULL
|| strchr (ifs
, words
[*offset
]) == NULL
)
334 *word
= w_addchar (*word
, word_length
, max_length
, words
[*offset
]);
344 error
= glob (*word
, GLOB_NOCHECK
, NULL
, &globbuf
);
348 /* We can only run into memory problems. */
349 assert (error
== GLOB_NOSPACE
);
356 /* No field splitting allowed */
357 *word_length
= strlen (globbuf
.gl_pathv
[0]);
358 *word
= realloc (*word
, 1 + *word_length
);
362 strcpy (*word
, globbuf
.gl_pathv
[0]);
364 for (match
= 1; match
< globbuf
.gl_pathc
&& *word
!= NULL
; ++match
)
366 *word
= w_addchar (*word
, word_length
, max_length
, ' ');
368 *word
= w_addstr (*word
, word_length
, max_length
,
369 globbuf
.gl_pathv
[match
]);
372 /* Re-parse white space on return */
375 return *word
? 0 : WRDE_NOSPACE
;
383 matching_word
= malloc (1 + strlen (globbuf
.gl_pathv
[0]));
384 if (matching_word
== NULL
)
387 strcpy (matching_word
, globbuf
.gl_pathv
[0]);
388 if (w_addword (pwordexp
, matching_word
) == WRDE_NOSPACE
)
391 for (match
= 1; match
< globbuf
.gl_pathc
; ++match
)
393 matching_word
= __strdup (globbuf
.gl_pathv
[match
]);
394 if (matching_word
== NULL
)
397 if (w_addword (pwordexp
, matching_word
) == WRDE_NOSPACE
)
403 /* Re-parse white space on return */
413 parse_squote (char **word
, size_t *word_length
, size_t *max_length
,
414 const char *words
, size_t *offset
)
416 /* We are poised just after a single quote */
417 for (; words
[*offset
]; ++(*offset
))
419 if (words
[*offset
] != '\'')
421 *word
= w_addchar (*word
, word_length
, max_length
, words
[*offset
]);
428 /* Unterminated string */
432 /* Functions to evaluate an arithmetic expression */
434 eval_expr_val (char **expr
, int *result
)
439 /* Skip white space */
440 for (digit
= *expr
; digit
&& *digit
&& isspace (*digit
); ++digit
);
446 /* Scan for closing paren */
447 for (++digit
; **expr
&& **expr
!= ')'; ++(*expr
));
455 if (eval_expr (digit
, result
))
460 case '+': /* Positive value */
464 case '-': /* Negative value */
470 if (!isdigit (*digit
))
475 for (; *digit
&& isdigit (*digit
); ++digit
)
476 *result
= (*result
* 10) + (*digit
- '0');
484 eval_expr_multdiv (char **expr
, int *result
)
489 if (eval_expr_val (expr
, result
))
494 /* Skip white space */
495 for (; *expr
&& **expr
&& isspace (**expr
); ++(*expr
));
500 if ((eval_expr_val (expr
, &arg
)) != 0)
505 else if (**expr
== '/')
508 if ((eval_expr_val (expr
, &arg
)) != 0)
520 eval_expr (char *expr
, int *result
)
525 if ((eval_expr_multdiv (&expr
, result
)) != 0)
530 /* Skip white space */
531 for (; expr
&& *expr
&& isspace (*expr
); ++expr
);
536 if ((eval_expr_multdiv (&expr
, &arg
)) != 0)
541 else if (*expr
== '-')
544 if ((eval_expr_multdiv (&expr
, &arg
)) != 0)
556 parse_arith (char **word
, size_t *word_length
, size_t *max_length
,
557 const char *words
, size_t *offset
, int flags
, int bracket
)
559 /* We are poised just after "$((" or "$[" */
562 size_t expr_length
= 0;
563 size_t expr_maxlen
= 0;
566 for (; words
[*offset
]; ++(*offset
))
568 switch (words
[*offset
])
571 error
= parse_dollars (&expr
, &expr_length
, &expr_maxlen
,
572 words
, offset
, flags
, NULL
);
573 /* The NULL here is to tell parse_dollars not to
585 error
= parse_backtick (&expr
, &expr_length
, &expr_maxlen
,
586 words
, offset
, flags
, NULL
);
587 /* The NULL here is to tell parse_backtick not to
598 error
= parse_qtd_backslash (&expr
, &expr_length
, &expr_maxlen
,
605 /* I think that a backslash within an
606 * arithmetic expansion is bound to
607 * cause an error sooner or later anyway though.
612 if (--paren_depth
== 0)
617 if (bracket
|| words
[1 + *offset
] != ')')
624 eval_expr (expr
, &numresult
) != 0)
627 result
= __alloca (100);
628 __snprintf (result
, 100, "%d", numresult
);
629 *word
= w_addstr (*word
, word_length
, max_length
, result
);
631 return *word
? 0 : WRDE_NOSPACE
;
633 expr
= w_addchar (expr
, &expr_length
, &expr_maxlen
, words
[*offset
]);
640 if (bracket
&& paren_depth
== 1)
646 if (*expr
&& eval_expr (expr
, &numresult
) != 0)
649 result
= __alloca (100);
650 __snprintf (result
, 100, "%d", numresult
);
651 *word
= w_addstr (*word
, word_length
, max_length
, result
);
653 return *word
? 0 : WRDE_NOSPACE
;
669 expr
= w_addchar (expr
, &expr_length
, &expr_maxlen
, words
[*offset
]);
680 /* Function to execute a command and retrieve the results */
681 /* pwordexp contains NULL if field-splitting is forbidden */
683 exec_comm (char *comm
, char **word
, size_t *word_length
, size_t *max_length
,
684 int flags
, wordexp_t
*pwordexp
)
694 * 0 until first non-(whitespace-ifs)
696 * 2 after non-(whitespace-ifs)
699 /* Don't fork() unless necessary */
707 if ((pid
= fork ()) < 0)
716 /* Redirect input and output */
719 /* Close stderr if we have to */
720 if ((flags
& WRDE_SHOWERR
) == 0)
723 execl (_PATH_BSHELL
, _PATH_BSHELL
, "-c", comm
, NULL
);
732 buffer
= __alloca (bufsize
);
735 { /* Quoted - no field splitting */
739 if ((buflen
= read (fildes
[0], buffer
, bufsize
)) < 1)
741 if (waitpid (pid
, NULL
, WNOHANG
) == 0)
743 if ((buflen
= read (fildes
[0], buffer
, bufsize
)) < 1)
747 for (i
= 0; i
< buflen
; ++i
)
749 *word
= w_addchar (*word
, word_length
, max_length
, buffer
[i
]);
762 /* Not quoted - split fields.
763 * NB. This isn't done properly yet.
767 if ((buflen
= read (fildes
[0], buffer
, bufsize
)) < 1)
769 if (waitpid (pid
, NULL
, WNOHANG
) == 0)
771 if ((read (fildes
[0], buffer
, bufsize
)) < 1)
775 for (i
= 0; i
< buflen
; ++i
)
777 /* What if these aren't field separators? FIX */
778 if (buffer
[i
] == ' ' || buffer
[i
] == '\t' || buffer
[i
] == '\n')
788 if (w_addword (pwordexp
, *word
) == WRDE_NOSPACE
)
799 *word
= w_addchar (*word
, word_length
, max_length
, buffer
[i
]);
813 parse_comm (char **word
, size_t *word_length
, size_t *max_length
,
814 const char *words
, size_t *offset
, int flags
, wordexp_t
*pwordexp
)
816 /* We are poised just after "$(" */
819 size_t comm_length
= 0;
820 size_t comm_maxlen
= 0;
823 for (; words
[*offset
]; ++(*offset
))
825 switch (words
[*offset
])
828 if (--paren_depth
== 0)
830 /* Go -- give script to the shell */
831 error
= exec_comm (comm
, word
, word_length
, max_length
, flags
,
837 /* This is just part of the script */
838 comm
= w_addchar (comm
, &comm_length
, &comm_maxlen
, words
[*offset
]);
847 comm
= w_addchar (comm
, &comm_length
, &comm_maxlen
, words
[*offset
]);
861 parse_param (char **word
, size_t *word_length
, size_t *max_length
,
862 const char *words
, size_t *offset
, int flags
, wordexp_t
*pwordexp
)
864 /* We are poised just after "$" */
865 size_t start
= *offset
;
866 size_t env_length
= 0;
867 size_t env_maxlen
= 0;
868 size_t pat_length
= 0;
869 size_t pat_maxlen
= 0;
871 char *pattern
= NULL
;
880 for (; words
[*offset
]; ++(*offset
))
882 switch (words
[*offset
])
885 if (action
|| prefix
|| suffix
)
888 pattern
= w_addchar (pattern
, &pat_length
, &pat_maxlen
,
896 if (*offset
== start
)
898 /* Otherwise evaluate */
899 /* (and re-parse this character) */
904 if (words
[start
] != '{')
909 if (action
|| prefix
|| suffix
)
913 pattern
= w_addchar (pattern
, &pat_length
, &pat_maxlen
,
927 if (words
[start
] == '{')
929 /* At the start? (ie. 'string length') */
930 if (*offset
== start
+ 1)
933 /* Separating variable name from prefix pattern? */
934 if (words
[*offset
] == '#')
936 if (prefix
< 2 && !suffix
)
944 if (suffix
< 2 && !prefix
)
951 /* Must be part of prefix/suffix pattern. */
952 pattern
= w_addchar (pattern
, &pat_length
, &pat_maxlen
,
959 /* Otherwise evaluate */
960 /* (and re-parse this character) */
972 if (action
|| prefix
|| suffix
)
974 pattern
= w_addchar (pattern
, &pat_length
, &pat_maxlen
,
982 if ((words
[1 + *offset
] == '-') || (words
[1 + *offset
] == '=') ||
983 (words
[1 + *offset
] == '?') || (words
[1 + *offset
] == '+'))
1004 if (action
|| prefix
|| suffix
)
1006 pattern
= w_addchar (pattern
, &pat_length
, &pat_maxlen
,
1008 if (pattern
== NULL
)
1011 return WRDE_NOSPACE
;
1017 action
= words
[*offset
];
1021 if (action
|| prefix
|| suffix
)
1023 error
= parse_qtd_backslash (word
, word_length
, max_length
,
1030 error
= WRDE_SYNTAX
;
1038 if (action
|| prefix
|| suffix
)
1040 pattern
= w_addchar (pattern
, &pat_length
, &pat_maxlen
,
1042 if (pattern
== NULL
)
1048 if ((words
[start
] == '{') || isalpha (words
[*offset
]))
1050 env
= w_addchar (env
, &env_length
, &env_maxlen
, words
[*offset
]);
1062 /* End of input string */
1066 if (words
[start
] == '{' && words
[*offset
] != '}')
1075 *offset
= start
- 1;
1076 *word
= w_addchar (*word
, word_length
, max_length
, '$');
1079 return *word
? 0 : WRDE_NOSPACE
;
1082 value
= getenv (env
);
1084 if (action
|| prefix
|| suffix
)
1089 /* For the time being, pattern is ignored */
1090 printf ("Pattern: %s\nPrefix: %d\nSuffix: %d\n", pattern
, prefix
, suffix
);
1094 if (value
&& *value
)
1097 if (!colon_seen
&& value
)
1099 /* Substitute NULL */
1106 fprintf (stderr
, "%s: ", env
);
1110 /* Expand 'pattern' and write it to stderr */
1113 error
= wordexp (pattern
, &we
, flags
);
1119 for (i
= 0; i
< we
.we_wordc
; ++i
)
1121 fprintf (stderr
, "%s%s", i
? " " : "", we
.we_wordv
[i
]);
1124 fprintf (stderr
, "\n");
1125 error
= WRDE_BADVAL
;
1134 fprintf (stderr
, "parameter null or not set\n");
1140 printf ("warning: parameter substitution does not yet support \"%s%c\"\n", colon_seen
?":":"", action
);
1149 /* Variable not defined */
1150 if (flags
& WRDE_UNDEF
)
1156 if (pwordexp
== NULL
)
1157 /* Quoted - no field split */
1158 *word
= w_addstr (*word
, word_length
, max_length
, value
);
1160 /* Should field-split here - FIX */
1161 *word
= w_addstr (*word
, word_length
, max_length
, value
);
1163 return *word
? 0 : WRDE_NOSPACE
;
1172 return WRDE_NOSPACE
;
1176 parse_dollars (char **word
, size_t *word_length
, size_t *max_length
,
1177 const char *words
, size_t *offset
, int flags
,
1178 wordexp_t
*pwordexp
)
1180 /* We are poised _at_ "$" */
1181 switch (words
[1 + *offset
])
1186 *word
= w_addchar (*word
, word_length
, max_length
, '$');
1187 return *word
? 0 : WRDE_NOSPACE
;
1190 if (words
[2 + *offset
] == '(')
1193 /* Call parse_arith -- 0 is for "no brackets" */
1194 return parse_arith (word
, word_length
, max_length
, words
, offset
,
1198 if (flags
& WRDE_NOCMD
)
1202 return parse_comm (word
, word_length
, max_length
, words
, offset
, flags
,
1207 /* Call parse_arith -- 1 is for "brackets" */
1208 return parse_arith (word
, word_length
, max_length
, words
, offset
, flags
,
1213 ++(*offset
); /* parse_param needs to know if "{" is there */
1214 return parse_param (word
, word_length
, max_length
, words
, offset
, flags
,
1220 parse_backtick (char **word
, size_t *word_length
, size_t *max_length
,
1221 const char *words
, size_t *offset
, int flags
,
1222 wordexp_t
*pwordexp
)
1224 /* We are poised just after "`" */
1226 size_t comm_length
= 0;
1227 size_t comm_maxlen
= 0;
1231 for (; words
[*offset
]; ++(*offset
))
1233 switch (words
[*offset
])
1236 /* Go -- give the script to the shell */
1237 error
= exec_comm (comm
, word
, word_length
, max_length
, flags
,
1245 error
= parse_qtd_backslash (&comm
, &comm_length
, &comm_maxlen
,
1258 error
= parse_backslash (&comm
, &comm_length
, &comm_maxlen
, words
,
1270 squoting
= 1 - squoting
;
1272 comm
= w_addchar (comm
, &comm_length
, &comm_maxlen
, words
[*offset
]);
1274 return WRDE_NOSPACE
;
1284 parse_dquote (char **word
, size_t *word_length
, size_t *max_length
,
1285 const char *words
, size_t *offset
, int flags
)
1287 /* We are poised just after a double-quote */
1290 for (; words
[*offset
]; ++(*offset
))
1292 switch (words
[*offset
])
1298 error
= parse_dollars (word
, word_length
, max_length
, words
, offset
,
1300 /* The NULL here is to tell parse_dollars not to
1309 if (flags
& WRDE_NOCMD
)
1313 error
= parse_backtick (word
, word_length
, max_length
, words
,
1314 offset
, flags
, NULL
);
1315 /* The NULL here is to tell parse_backtick not to
1324 error
= parse_qtd_backslash (word
, word_length
, max_length
, words
,
1333 *word
= w_addchar (*word
, word_length
, max_length
, words
[*offset
]);
1335 return WRDE_NOSPACE
;
1339 /* Unterminated string */
1344 * wordfree() is to be called after pwordexp is finished with.
1348 wordfree (wordexp_t
*pwordexp
)
1351 /* wordexp can set pwordexp to NULL */
1352 if (pwordexp
&& pwordexp
->we_wordv
)
1354 char **wordv
= pwordexp
->we_wordv
;
1356 for (wordv
+= pwordexp
->we_offs
; *wordv
; ++wordv
)
1359 free (pwordexp
->we_wordv
);
1360 pwordexp
->we_wordv
= NULL
;
1369 wordexp (const char *words
, wordexp_t
*pwordexp
, int flags
)
1371 size_t wordv_offset
;
1372 size_t words_offset
;
1373 size_t word_length
= 0;
1374 size_t max_length
= 0;
1379 char **old_wordv
= pwordexp
->we_wordv
;
1380 size_t old_wordc
= pwordexp
->we_wordc
;
1382 if (flags
& WRDE_REUSE
)
1383 /* Minimal implementation of WRDE_REUSE for now */
1384 wordfree (pwordexp
);
1386 if (flags
& WRDE_DOOFFS
)
1388 pwordexp
->we_wordv
= calloc (1 + pwordexp
->we_offs
, sizeof (char *));
1389 if (pwordexp
->we_wordv
== NULL
)
1390 return WRDE_NOSPACE
;
1394 pwordexp
->we_wordv
= calloc (1, sizeof (char *));
1395 if (pwordexp
->we_wordv
== NULL
)
1396 return WRDE_NOSPACE
;
1398 pwordexp
->we_offs
= 0;
1401 if ((flags
& WRDE_APPEND
) == 0)
1402 pwordexp
->we_wordc
= 0;
1404 wordv_offset
= pwordexp
->we_offs
+ pwordexp
->we_wordc
;
1406 /* Find out what the field separators are.
1407 * There are two types: whitespace and non-whitespace.
1409 ifs
= getenv ("IFS");
1412 ifs
= strcpy (ifs_white
, " \t\n");
1416 char *whch
= ifs_white
;
1418 while (*ifsch
!= '\0')
1419 if ((*ifsch
== ' ') || (*ifsch
== '\t') || (*ifsch
== '\n'))
1421 /* White space IFS. See first whether it is already in our
1423 char *runp
= ifs_white
;
1425 while (runp
< whch
&& *runp
!= '\0' && *runp
!= *ifsch
)
1434 for (words_offset
= 0 ; words
[words_offset
] ; ++words_offset
)
1435 switch (words
[words_offset
])
1447 wordfree (pwordexp
);
1448 pwordexp
->we_wordc
= 0;
1449 pwordexp
->we_wordv
= old_wordv
;
1450 return WRDE_BADCHAR
;
1453 error
= parse_backslash (&word
, &word_length
, &max_length
, words
,
1462 error
= parse_dollars (&word
, &word_length
, &max_length
, words
,
1463 &words_offset
, flags
, pwordexp
);
1471 if (flags
& WRDE_NOCMD
)
1475 error
= parse_backtick (&word
, &word_length
, &max_length
, words
,
1476 &words_offset
, flags
, pwordexp
);
1485 error
= parse_dquote (&word
, &word_length
, &max_length
, words
,
1486 &words_offset
, flags
);
1495 error
= parse_squote (&word
, &word_length
, &max_length
, words
,
1504 error
= parse_tilde (&word
, &word_length
, &max_length
, words
,
1505 &words_offset
, pwordexp
->we_wordc
);
1514 error
= parse_glob (&word
, &word_length
, &max_length
, words
,
1515 &words_offset
, flags
, pwordexp
, ifs
);
1523 /* Is it a field separator? */
1524 if (strchr (ifs
, words
[words_offset
]) == NULL
)
1526 /* "Ordinary" character -- add it to word */
1528 word
= w_addchar (word
, &word_length
, &max_length
,
1529 words
[words_offset
]);
1532 error
= WRDE_NOSPACE
;
1539 /* Field separator */
1540 if (strchr (ifs_white
, words
[words_offset
]))
1542 /* It's a whitespace IFS char. Ignore it at the beginning
1543 of a line and ignore multiple instances. */
1544 if (!word
|| !*word
)
1547 if (w_addword (pwordexp
, word
) == WRDE_NOSPACE
)
1549 error
= WRDE_NOSPACE
;
1558 /* It's a non-whitespace IFS char */
1560 /* Multiple non-whitespace IFS chars are treated as one;
1565 if (w_addword (pwordexp
, word
) == WRDE_NOSPACE
)
1567 error
= WRDE_NOSPACE
;
1579 /* There was a field separator at the end */
1583 /* There was no field separator at the end */
1584 return w_addword (pwordexp
, word
);
1588 free memory used, set we_wordc and wd_wordv back to what they were.
1593 wordfree (pwordexp
);
1594 pwordexp
->we_wordv
= old_wordv
;
1595 pwordexp
->we_wordc
= old_wordc
;