mirror of
git://git.gnu.org.ua/wordsplit.git
synced 2025-04-26 00:29:54 +03:00
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.
This commit is contained in:
parent
943d725e7f
commit
b712b11eef
3 changed files with 156 additions and 14 deletions
145
doc/wordsplit.3
145
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>
|
||||
|
|
|
@ -2267,6 +2267,18 @@ wordsplit_free (struct wordsplit *ws)
|
|||
wordsplit_free_envbuf (ws);
|
||||
}
|
||||
|
||||
void
|
||||
wordsplit_getwords (struct wordsplit *ws, int *wordc, char ***wordv)
|
||||
{
|
||||
char **p = realloc (ws->ws_wordv,
|
||||
(ws->ws_wordc + 1) * sizeof (ws->ws_wordv[0]));
|
||||
*wordv = p ? p : ws->ws_wordv;
|
||||
*wordc = ws->ws_wordc;
|
||||
ws->ws_wordv = NULL;
|
||||
ws->ws_wordc = 0;
|
||||
ws->ws_wordn = 0;
|
||||
}
|
||||
|
||||
const char *_wordsplit_errstr[] = {
|
||||
N_("no error"),
|
||||
N_("missing closing quote"),
|
||||
|
|
|
@ -226,17 +226,16 @@ struct wordsplit
|
|||
#define WRDSE_GLOBERR 8
|
||||
#define WRDSE_USERERR 9
|
||||
|
||||
int wordsplit (const char *s, wordsplit_t *p, int flags);
|
||||
int wordsplit_len (const char *s, size_t len,
|
||||
wordsplit_t *p, int flags);
|
||||
void wordsplit_free (wordsplit_t *p);
|
||||
int wordsplit (const char *s, wordsplit_t *ws, int flags);
|
||||
int wordsplit_len (const char *s, size_t len, wordsplit_t *ws, int flags);
|
||||
void wordsplit_free (wordsplit_t *ws);
|
||||
void wordsplit_free_words (wordsplit_t *ws);
|
||||
void wordsplit_free_envbuf (struct wordsplit *ws);
|
||||
void wordsplit_free_envbuf (wordsplit_t *ws);
|
||||
void wordsplit_getwords (wordsplit_t *ws, int *wordc, char ***wordv);
|
||||
|
||||
int wordsplit_c_unquote_char (int c);
|
||||
int wordsplit_c_quote_char (int c);
|
||||
size_t wordsplit_c_quoted_length (const char *str, int quote_hex,
|
||||
int *quote);
|
||||
size_t wordsplit_c_quoted_length (const char *str, int quote_hex, int *quote);
|
||||
void wordsplit_c_quote_copy (char *dst, const char *src, int quote_hex);
|
||||
|
||||
void wordsplit_perror (wordsplit_t *ws);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue