diff options
author | Sergey Poznyakoff <gray@gnu.org.ua> | 2014-10-30 18:55:04 +0200 |
---|---|---|
committer | Sergey Poznyakoff <gray@gnu.org.ua> | 2015-12-17 15:26:28 +0200 |
commit | 5ce27a8cdee32f53a922c459a4f9beae307543f7 (patch) | |
tree | 0e3d4c6e0a4b260df941bd160b5b47b3990a8b9f /doc | |
parent | 59d4374b24e9f9f077f2e2e973fa75f3c3d505e0 (diff) | |
download | grecs-5ce27a8cdee32f53a922c459a4f9beae307543f7.tar.gz grecs-5ce27a8cdee32f53a922c459a4f9beae307543f7.tar.bz2 |
wordsplit: improve docs, add new function
* src/wordsplit.c (wordsplit_getwords): New functon.
* src/wordsplit.h (wordsplit_getwords): New proto.
* doc/wordsplit.3: Add example section, document wordsplit_getwords.
Diffstat (limited to 'doc')
-rw-r--r-- | doc/wordsplit.3 | 145 |
1 files changed, 138 insertions, 7 deletions
diff --git a/doc/wordsplit.3 b/doc/wordsplit.3 index 123bfb7..3c666bc 100644 --- a/doc/wordsplit.3 +++ b/doc/wordsplit.3 @@ -32,6 +32,9 @@ wordsplit \- split string into words .sp \fBvoid wordsplit_free_words (wordsplit_t *\fIws\fB);\fR .sp +\fBvoid wordsplit_getwords (wordsplit_t *\fIws\fB,\ + int *\fIwordc\fB, char ***\fIwordv\fB); +.sp \fBvoid wordsplit_perror (wordsplit_t *\fIws\fB);\fR .sp \fBconst char *wordsplit_strerror (wordsplit_t *\fIws\fB);\fR @@ -80,6 +83,14 @@ wordsplit_free(&ws); .EE .PP The function +.B wordsplit_getwords +returns in \fIwordv\fR an array of words, and in \fIwordc\fR the number +of elements in \fIwordv\fR. The array can be used after calling +.BR wordsplit_free . +The caller becomes responsible for freeing the memory allocated for +each element of the array and the array pointer itself. +.PP +The function .B wordsplit_perror prints error message from the last invocation of \fBwordsplit\fR. It uses the function pointed to by the @@ -401,6 +412,17 @@ from \fBwordsplit\fR. Error code, if the invocation of \fBwordsplit\fR or \fBwordsplit_len\fR failed. This is the same value as returned from the function in that case. +.PP +The caller should not attempt to free or reallocate \fIws_wordv\fR or +any elements thereof, nor to modify \fIws_wordc\fR. +.PP +To store away the words for use after freeing \fIws\fR with +.BR wordsplit_free , +the caller should use +.BR wordsplit_getwords . +It is more effective than copying the contents of +.I ws_wordv +manually. .SS INPUT .TP .BI "size_t " ws_offs @@ -496,7 +518,8 @@ must have the form \fB\(dq\fINAME\fB=\fIVALUE\fR, where \fINAME\fR is the name of the variable, and \fIVALUE\fR is its value. Alternatively, if the \fBWRDSF_ENV_KV\fR flag is set, each variable is described by two elements of -.IR ws_env : one containing variable name, and the next one with its +.IR ws_env : +one containing variable name, and the next one with its value. .TP .BI "int (*" ws_getvar ") (char **ret, const char *var, size_t len, void *clos)" @@ -712,7 +735,7 @@ contains variable name, and .IR ws_env [ "n+1" ] contains its value. .TP -.B WRDSF_ESCAPE 0x10000000 +.B WRDSF_ESCAPE .I ws_escape is set. .TP @@ -831,17 +854,125 @@ returns a pointer to the constant string describing the last error condition that occurred in .IR ws . .SH EXAMPLE +The short program below implements a function that parses the +input string similarly to the shell. All expansions are performed. +Default error reporting is used. +.PP +.EX +#include <stdlib.h> +#include <stdio.h> +#include <errno.h> +#include <string.h> +#include <wordsplit.h> + +/* Run command from \fIstr\fR (\fIlen\fR bytes long) and store its + output in \fIret\fR. + \fIargv\fR and \fIclosure\fR are not used. + Return wordsplit error code. + */ +static int runcmd(char **ret, const char *str, size_t len, + char **argv, void *closure) +{ + FILE *fp; + char *cmd; + int c, lastc; + char *buffer = NULL; + size_t bufsize = 0; + size_t buflen = 0; + + /* Convert to a null-terminated string for \fBpopen\fR(3) */ + cmd = malloc(len + 1); + if (!cmd) + return WRDSE_NOSPACE; + memcpy(cmd, str, len); + cmd[len] = 0; + + fp = popen(cmd, "r"); + if (!fp) { + char buf[128]; + + snprintf(buf, sizeof buf, "can't run %s: %s", + cmd, strerror(errno)); + *ret = strdup(buf); + if (!*ret) + return WRDSE_NOSPACE; + else + return WRDSE_USERERR; + } + + /* Collect the output, reallocating \fIbuffer\fR as needed. */ + while ((c = fgetc(fp)) != EOF) { + lastc = c; + if (c == '\n') + c = ' '; + if (buflen == bufsize) { + char *p; + + if (bufsize == 0) + bufsize = 80; + else + bufsize *= 2; + p = realloc(buffer, bufsize); + if (!p) { + free(buffer); + free(cmd); + return WRDSE_NOSPACE; + } + buffer = p; + } + buffer[buflen++] = c; + } + + /* Tream off the trailing newline */ + if (buffer) { + if (lastc == '\n') + --buflen; + buffer[buflen] = 0; + } + + pclose(fp); + free(cmd); + + /* Return the composed string. */ + *ret = buffer; + return WRDSE_OK; +} + +extern char **environ; + +/* Parse \fIs\fR much as shell does. Return the array of words on + succes, and NULL on error. + */ +char **shell_parse(char *s) +{ + wordsplit_t ws; + size_t wc; + char **wv; + int rc; + + /* Initialize \fIws\fR */ + ws.ws_env = (const char **) environ; + ws.ws_command = runcmd; + /* Call \fBwordsplit\fR. Let it report the errors. */ + rc = wordsplit(s, &ws, + WRDSF_QUOTE | WRDSF_SQUEEZE_DELIMS | WRDSF_PATHEXPAND + | WRDSF_SHOWERR); + if (rc == WRDSE_OK) + /* Store away the resulting words on success. */ + wordsplit_getwords(&ws, &wc, &wv); + else + wv = NULL; + wordsplit_free(&ws); + return wv; +} +.EE .SH "SEE ALSO" .SH AUTHORS Sergey Poznyakoff .SH "BUG REPORTS" Report bugs to <gray+grecs@gnu.org.ua>. -.SH COLOPHON -The \fBGrecs\fR library is constantly changing, so this manual page -may be incorrect or out-of-date. For the latest copy of \fBGrecs\fR -documentation, visit <http://www.gnu.org.ua/software/grecs>. .SH COPYRIGHT -Copyright \(co 2011 Sergey Poznyakoff +Copyright \(co 2009-2014 Sergey Poznyakoff .br .na License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html> |