commit 8fdd74013d2ab6f5b07646abb8a8a48b9d3c38d0 Author: Oswald Buddenhagen <o...@kde.org> Date: Sat Sep 15 11:24:57 2012 +0200
make config parser a bit more careful about quotes the parsing is more shell-like now: - quoted and unquoted parts can be mixed in one argument - the hashmark can be meaningfully quoted src/config.c | 70 +++++++++++++++++++++++++++++++++++++----------- src/drv_imap.c | 31 +++++++++++++++++++++ src/isync.h | 2 - src/util.c | 32 ---------------------- 4 files changed, 85 insertions(+), 50 deletions(-) diff --git a/src/config.c b/src/config.c index 9421bae..1404c32 100644 --- a/src/config.c +++ b/src/config.c @@ -22,10 +22,12 @@ #include "isync.h" +#include <assert.h> #include <unistd.h> #include <limits.h> #include <pwd.h> #include <sys/types.h> +#include <ctype.h> #include <string.h> #include <stdlib.h> #include <stdio.h> @@ -38,6 +40,46 @@ group_conf_t *groups; int global_ops[2]; char *global_sync_state; +#define ARG_OPTIONAL 0 +#define ARG_REQUIRED 1 + +static char * +get_arg( conffile_t *cfile, int required, int *comment ) +{ + char *ret, *p, *t; + int quoted; + char c; + + p = cfile->rest; + assert( p ); + while ((c = *p) && isspace( (unsigned char) c )) + p++; + if (!c || c == '#') { + if (comment) + *comment = (c == '#'); + if (required) + error( "%s:%d: parameter missing\n", cfile->file, cfile->line ); + ret = 0; + } else { + for (quoted = 0, ret = t = p; c; c = *p) { + p++; + if (c == '"') + quoted ^= 1; + else if (!quoted && isspace( (unsigned char) c )) + break; + else + *t++ = c; + } + *t = 0; + if (quoted) { + error( "%s:%d: missing closing quote\n", cfile->file, cfile->line ); + ret = 0; + } + } + cfile->rest = p; + return ret; +} + int parse_bool( conffile_t *cfile ) { @@ -132,7 +174,7 @@ getopt_helper( conffile_t *cfile, int *cops, int ops[], char **sync_state ) else if (strcasecmp( "None", arg ) && strcasecmp( "Noop", arg )) error( "%s:%d: invalid Sync arg '%s'\n", cfile->file, cfile->line, arg ); - while ((arg = next_arg( &cfile->rest ))); + while ((arg = get_arg( cfile, ARG_OPTIONAL, 0 ))); ops[M] |= XOP_HAVE_TYPE; } else if (!strcasecmp( "Expunge", cfile->cmd )) { arg = cfile->val; @@ -146,7 +188,7 @@ getopt_helper( conffile_t *cfile, int *cops, int ops[], char **sync_state ) else if (strcasecmp( "None", arg )) error( "%s:%d: invalid Expunge arg '%s'\n", cfile->file, cfile->line, arg ); - while ((arg = next_arg( &cfile->rest ))); + while ((arg = get_arg( cfile, ARG_OPTIONAL, 0 ))); ops[M] |= XOP_HAVE_EXPUNGE; } else if (!strcasecmp( "Create", cfile->cmd )) { arg = cfile->val; @@ -160,7 +202,7 @@ getopt_helper( conffile_t *cfile, int *cops, int ops[], char **sync_state ) else if (strcasecmp( "None", arg )) error( "%s:%d: invalid Create arg '%s'\n", cfile->file, cfile->line, arg ); - while ((arg = next_arg( &cfile->rest ))); + while ((arg = get_arg( cfile, ARG_OPTIONAL, 0 ))); ops[M] |= XOP_HAVE_CREATE; } else if (!strcasecmp( "SyncState", cfile->cmd )) *sync_state = expand_strdup( cfile->val ); @@ -172,20 +214,18 @@ getopt_helper( conffile_t *cfile, int *cops, int ops[], char **sync_state ) int getcline( conffile_t *cfile ) { - char *p; + int comment; while (fgets( cfile->buf, cfile->bufl, cfile->fp )) { cfile->line++; - p = cfile->buf; - if (!(cfile->cmd = next_arg( &p ))) + cfile->rest = cfile->buf; + if (!(cfile->cmd = get_arg( cfile, ARG_OPTIONAL, &comment ))) { + if (comment) + continue; return 1; - if (*cfile->cmd == '#') - continue; - if (!(cfile->val = next_arg( &p ))) { - error( "%s:%d: parameter missing\n", cfile->file, cfile->line ); - continue; } - cfile->rest = p; + if (!(cfile->val = get_arg( cfile, ARG_REQUIRED, 0 ))) + continue; return 1; } return 0; @@ -311,7 +351,7 @@ load_config( const char *where, int pseudo ) arg = cfile.val; do add_string_list( &channel->patterns, arg ); - while ((arg = next_arg( &cfile.rest ))); + while ((arg = get_arg( &cfile, ARG_OPTIONAL, 0 ))); } else if (!strcasecmp( "Master", cfile.cmd )) { ms = M; @@ -367,8 +407,7 @@ load_config( const char *where, int pseudo ) *groupapp = 0; chanlistapp = &group->channels; *chanlistapp = 0; - p = cfile.rest; - while ((arg = next_arg( &p ))) { + while ((arg = get_arg( &cfile, ARG_OPTIONAL, 0 ))) { addone: len = strlen( arg ); chanlist = nfmalloc( sizeof(*chanlist) + len ); @@ -383,7 +422,6 @@ load_config( const char *where, int pseudo ) if (!strcasecmp( "Channel", cfile.cmd ) || !strcasecmp( "Channels", cfile.cmd )) { - p = cfile.rest; arg = cfile.val; goto addone; } diff --git a/src/drv_imap.c b/src/drv_imap.c index 4dbf0b4..51d7d10 100644 --- a/src/drv_imap.c +++ b/src/drv_imap.c @@ -450,6 +450,37 @@ imap_refcounted_done_box( imap_store_t *ctx ATTR_UNUSED, struct imap_cmd *cmd, i imap_refcounted_done( sts ); } +static char * +next_arg( char **s ) +{ + char *ret; + + if (!s || !*s) + return 0; + while (isspace( (unsigned char) **s )) + (*s)++; + if (!**s) { + *s = 0; + return 0; + } + if (**s == '"') { + ++*s; + ret = *s; + *s = strchr( *s, '"' ); + } else { + ret = *s; + while (**s && !isspace( (unsigned char) **s )) + (*s)++; + } + if (*s) { + if (**s) + *(*s)++ = 0; + if (!**s) + *s = 0; + } + return ret; +} + static int is_atom( list_t *list ) { diff --git a/src/isync.h b/src/isync.h index c637dac..4cb2f3e 100644 --- a/src/isync.h +++ b/src/isync.h @@ -412,8 +412,6 @@ void ATTR_PRINTFLIKE(1, 2) error( const char *, ... ); void ATTR_PRINTFLIKE(1, 2) sys_error( const char *, ... ); void flushn( void ); -char *next_arg( char ** ); - void add_string_list( string_list_t **list, const char *str ); void free_string_list( string_list_t *list ); diff --git a/src/util.c b/src/util.c index bc614e6..507f91a 100644 --- a/src/util.c +++ b/src/util.c @@ -28,7 +28,6 @@ #include <fcntl.h> #include <string.h> #include <pwd.h> -#include <ctype.h> int DFlags; static int need_nl; @@ -145,37 +144,6 @@ sys_error( const char *msg, ... ) perror( buf ); } -char * -next_arg( char **s ) -{ - char *ret; - - if (!s || !*s) - return 0; - while (isspace( (unsigned char) **s )) - (*s)++; - if (!**s) { - *s = 0; - return 0; - } - if (**s == '"') { - ++*s; - ret = *s; - *s = strchr( *s, '"' ); - } else { - ret = *s; - while (**s && !isspace( (unsigned char) **s )) - (*s)++; - } - if (*s) { - if (**s) - *(*s)++ = 0; - if (!**s) - *s = 0; - } - return ret; -} - void add_string_list( string_list_t **list, const char *str ) { ------------------------------------------------------------------------------ How fast is your code? 3 out of 4 devs don\\\'t know how their code performs in production. Find out how slow your code is with AppDynamics Lite. http://ad.doubleclick.net/clk;262219672;13503038;z? http://info.appdynamics.com/FreeJavaPerformanceDownload.html _______________________________________________ isync-devel mailing list isync-devel@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/isync-devel