Extract one token from a string.
49{
50 if (!dest || !tok)
51 return -1;
52
53 char ch;
54 char qc = '\0';
55 char *pc = NULL;
56
58
60 while ((ch = *tok->
dptr))
61 {
62 if (qc == '\0')
63 {
65 break;
67 break;
69 break;
71 break;
73 break;
75 break;
77 break;
79 break;
80 }
81
83
84 if (ch == qc)
85 {
86 qc = 0;
87 }
88 else if (!qc && ((ch ==
'\'') || (ch ==
'"')) && !(flags &
TOKEN_QUOTE))
89 {
90 qc = ch;
91 }
92 else if ((ch == '\\') && (qc != '\''))
93 {
94 if (tok->
dptr[0] ==
'\0')
95 return -1;
96 switch (ch = *tok->
dptr++)
97 {
98 case 'c':
99 case 'C':
100 if (tok->
dptr[0] ==
'\0')
101 return -1;
104 break;
105 case 'e':
107 break;
108 case 'f':
110 break;
111 case 'n':
113 break;
114 case 'r':
116 break;
117 case 't':
119 break;
120 default:
122 {
125 }
126 else
127 {
129 }
130 }
131 }
133 {
134 if (tok->
dptr[0] ==
'\0')
135 return -1;
137 if (ch == '^')
138 {
140 }
141 else if (ch == '[')
142 {
144 }
146 {
148 }
149 else
150 {
153 }
154 }
155 else if ((ch == '`') && (!qc || (qc == '"')))
156 {
157 FILE *fp = NULL;
158 pid_t pid;
159
161 do
162 {
163 pc = strpbrk(pc, "\\`");
164 if (pc)
165 {
166
167 if (*pc == '\\')
168 {
169 if (*(pc + 1))
170 pc += 2;
171 else
172 pc = NULL;
173 }
174 }
175 } while (pc && (pc[0] != '`'));
176 if (!pc)
177 {
179 return -1;
180 }
182 *pc = '\0';
184 {
185
189 }
190 else
191 {
193 }
194 *pc = '`';
196 if (pid < 0)
197 {
200 return -1;
201 }
202
204
205
206 char *expn = NULL;
207 size_t expn_len = 0;
211 if (rc != 0)
212 {
215 }
217
218
219
220
221
222 if (expn)
223 {
224 if (qc)
225 {
227 }
228 else
229 {
236 }
238 }
239 }
240 else if ((ch == '$') && (!qc || (qc == '"')) &&
242 {
243 const char *env = NULL;
244 char *var = NULL;
245
246 if (tok->
dptr[0] ==
'{')
247 {
248 pc = strchr(tok->
dptr,
'}');
249 if (pc)
250 {
253
255 {
261 }
262 }
263 }
264 else
265 {
267 ;
268
271 }
272 if (var)
273 {
276
278 {
280 }
282 {
284 }
285 else
286 {
289 }
292 }
293 }
294 else
295 {
297 }
298 }
299
301 return 0;
302}
void buf_seek(struct Buffer *buf, size_t offset)
Set current read/write position to offset from beginning.
void buf_reset(struct Buffer *buf)
Reset an existing Buffer.
size_t buf_addch(struct Buffer *buf, char c)
Add a single character to a Buffer.
size_t buf_addstr(struct Buffer *buf, const char *s)
Add a string to a Buffer.
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
size_t buf_copy(struct Buffer *dst, const struct Buffer *src)
Copy a Buffer's contents to another Buffer.
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
#define CSR_SUCCESS
Action completed successfully.
bool mutt_isspace(int arg)
Wrapper for isspace(3)
bool mutt_isalpha(int arg)
Wrapper for isalpha(3)
int mutt_toupper(int arg)
Wrapper for toupper(3)
bool mutt_isalnum(int arg)
Wrapper for isalnum(3)
bool mutt_isdigit(int arg)
Wrapper for isdigit(3)
char * mutt_file_read_line(char *line, size_t *size, FILE *fp, int *line_num, ReadLineFlags flags)
Read a line from a file.
#define mutt_file_fclose(FP)
#define MUTT_RL_NO_FLAGS
No flags are set.
#define mutt_debug(LEVEL,...)
@ LL_DEBUG1
Log at debug level 1.
int filter_wait(pid_t pid)
Wait for the exit of a process and return its status.
pid_t filter_create(const char *cmd, FILE **fp_in, FILE **fp_out, FILE **fp_err, char **envlist)
Set up filter program.
char * mutt_strn_dup(const char *begin, size_t len)
Duplicate a sub-string.
const char * mutt_str_getenv(const char *name)
Get an environment variable.
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
String manipulation buffer.
char * dptr
Current read/write position.
Container for Accounts, Notifications.
char ** env
Private copy of the environment variables.
struct ConfigSubset * sub
Inherited config items.
int cs_subset_str_string_get(const struct ConfigSubset *sub, const char *name, struct Buffer *result)
Get a config item as a string.