commit 8fdd74013d2ab6f5b07646abb8a8a48b9d3c38d0
Author: Oswald Buddenhagen <[email protected]>
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
[email protected]
https://lists.sourceforge.net/lists/listinfo/isync-devel