コード例 #1
0
ファイル: mkmarshal.c プロジェクト: BackupTheBerlios/irci6
static char *
typefix(char *p)
{
	unsigned int i, usigned = 0;
	char *type = p;

	if (*p == '\0')
		return "int";

	SKIP_SPACES(p);

	if (!strncmp(p, "unsigned", 7)) {
		usigned = 1;
		p += 8;
		SKIP_SPACES(p);
	}

	for (i = 0; i < typefixed_idx; i++)
		if (!strncmp(p, typefixed[i], strlen(typefixed[i])))
			break;

	if (i == typefixed_idx)
		return type;
	else
		p += strlen(typefixed[i]);

	SKIP_SPACES(p);

	return (*p == '*') ? type : (usigned ? "unsigned int" : "int");
}
コード例 #2
0
ファイル: filter_env.c プロジェクト: chutz/pkgcore
static const inline char *
is_function(const char *p, char **start, char **end)
{
	#define SKIP_SPACES(p) while('\0' != *(p) && \
		(' ' == *(p) || '\t' == *(p))) ++p;
	#define FUNC_LEN 8
	SKIP_SPACES(p);
	if(strncmp(p, "function", FUNC_LEN) == 0) {
		if(isspace(p[FUNC_LEN])) {
			p += FUNC_LEN;
		}
	}
	while('\0' != *p && isspace(*p))
		++p;
	*start = (char *)p;
	while('\0' != *p && ' ' != *p && '\t' != *p && '\n' != *p &&
		'=' != *p && '"' != *p && '\'' != *p && '(' != *p && ')' != *p)
		++p;
	*end = (char *)p;
	if(*end == *start)
		return NULL;
	SKIP_SPACES(p);
	if('\0' == *p || '(' != *p)
		return NULL;
	++p;
	SKIP_SPACES(p);
	if('\0' == *p || ')' != *p)
		return NULL;
	++p;
	while('\0' != *p && isspace(*p))
		++p;
	if('\0' == *p || '{' != *p)
		return NULL;
	return ++p;
}
コード例 #3
0
void CBBSHyperLink::Load(char* section)
{
	SKIP_SPACES(section);
	if (*section)
	{
		links.RemoveAll();
		char* line = strtok(section, "\r\n");
		for (; line; line = strtok(NULL, "\r\n"))
		{
			// format of each line: schema=program|color
			CBBSHyperLinkData data;
			char* eq = strchr(line, '=');
			if (!eq)
				continue;
			*eq = '\0';
			data.scheme = line;
			line = eq + 1;
			eq = strchr(line, '|');
			if (!eq)
				continue;
			*eq = '\0';
			data.program = line;
			line = eq + 1;
			int r, g, b;
			if (sscanf(line, "%d,%d,%d", &r, &g, &b) < 3)
				continue;
			data.color = RGB(r, g, b);
			int i = links.Add(data);
			if (links[i].scheme == '@')
				email = i;
		}
	}
}
コード例 #4
0
ファイル: filter_env.c プロジェクト: chutz/pkgcore
static inline const char *
is_envvar(const char *p, char **start, char **end)
{
	SKIP_SPACES(p);
	*start = (char *)p;
	for(;;) {
		switch(*p) {
		case '\0':
		case '"':
		case '\'':
		case '(':
		case ')':
		case '-':
		case ' ':
		case '\t':
		case'\n':
			return NULL;
		case '=':
			if(p == *start)
				return NULL;
			*end = (char *)p;
			return ++p;
		default:
			++p;
		}
	}
}
コード例 #5
0
ファイル: gda-ldap-provider.c プロジェクト: arthurnn/libgda
/*
 * consumes @str for a singly quoted string
 * Returns: a pointer to the next non analysed char
 */
static gchar *
parse_string (gchar *str, gchar **out_part)
{
	gchar *ptr = str;
	*out_part = NULL;

	SKIP_SPACES (ptr);
	if (!*ptr)
		return NULL;
	if (*ptr != '\'') {
		if (!g_ascii_strncasecmp (ptr, "null", 4)) {
			ptr += 4;
			return ptr;
		}
		else
			return NULL;
	}
	ptr++;
	*out_part = ptr;
	for (; *ptr && (*ptr != '\''); ptr++);
	if (!*ptr)
		return NULL;
	*ptr = 0;
	ptr++;
	return ptr;
}
コード例 #6
0
ファイル: mkmarshal.c プロジェクト: BackupTheBerlios/irci6
static int
is_void(char *p)
{
	if (p == NULL)
		return 0;
	else if (*p == '\0')
		return 1;

	SKIP_SPACES(p);

	if (strncmp(p, "void", 4))
		return 0;
	else
		p += 4;

	SKIP_SPACES(p);

	return (*p != '*');
}
コード例 #7
0
void CTriggerList::Load(char* section)
{
    SKIP_SPACES(section);
    if (*section)
    {
        CAES crypto;

        RemoveAll();
        char* line = section;
        char* nextline = NULL;
        for (; line; line = nextline)
        {
            nextline = strnextline(line);
            // format of each trigger item:
            // <item>
            // first=int
            // count=int
            // recv=str
            // send=str
            //   If str[0] == '-', it's a normal string.
            //   If str[0] == '+', it's a base64 encoded binary string
            // </item>
            SKIP_SPACES(line);
            if (strcmp(line, "<item>"))
                continue;

            CTriggerItem* item = Add();
            while ((line = nextline))
            {
                nextline = strnextline(line);
                if (0 == strcmp(line, "</item>"))
                    break;
                SetTriggerItem(*item, line, crypto);
            }
        }
    }

}
コード例 #8
0
ファイル: gda-ldap-provider.c プロジェクト: arthurnn/libgda
/*
 * consumes @str for an identifier
 * Returns: a pointer to the next non analysed char
 */
static gchar *
parse_ident (gchar *str, gchar **out_part)
{
	gchar *ptr = str;
	*out_part = NULL;

	SKIP_SPACES (ptr);
	*out_part = ptr;
	for (; *ptr && (g_ascii_isalnum (*ptr) || (*ptr == '_')) ; ptr++);
	if (ptr == *out_part) {
		*out_part = NULL;
		return NULL;
	}
	return ptr;
}
コード例 #9
0
/* rtpmap contains:
 *
 *  <payload> <encoding_name>/<clock_rate>[/<encoding_params>]
 */
static gboolean
gst_sdp_parse_rtpmap (const gchar * rtpmap, gint * payload, gchar ** name,
    gint * rate, gchar ** params)
{
  gchar *p, *t;

  p = (gchar *) rtpmap;

  PARSE_INT (p, " ", *payload);
  if (*payload == -1)
    return FALSE;

  SKIP_SPACES (p);
  if (*p == '\0')
    return FALSE;

  PARSE_STRING (p, "/", *name);
  if (*name == NULL) {
    GST_DEBUG ("no rate, name %s", p);
    /* no rate, assume -1 then, this is not supposed to happen but RealMedia
     * streams seem to omit the rate. */
    *name = p;
    *rate = -1;
    return TRUE;
  }

  t = p;
  p = strstr (p, "/");
  if (p == NULL) {
    *rate = atoi (t);
    return TRUE;
  }
  *p = '\0';
  p++;
  *rate = atoi (t);

  t = p;
  if (*p == '\0')
    return TRUE;
  *params = t;

  return TRUE;
}
コード例 #10
0
ファイル: gstsdpdemux.c プロジェクト: spunktsch/svtplayer
/* rtpmap contains:
 *
 *  <payload> <encoding_name>/<clock_rate>[/<encoding_params>]
 */
static gboolean
gst_sdp_demux_parse_rtpmap (const gchar * rtpmap, gint * payload, gchar ** name,
    gint * rate, gchar ** params)
{
  gchar *p, *t;

  t = p = (gchar *) rtpmap;

  PARSE_INT (p, " ", *payload);
  if (*payload == -1)
    return FALSE;

  SKIP_SPACES (p);
  if (*p == '\0')
    return FALSE;

  PARSE_STRING (p, "/", *name);
  if (*name == NULL) {
    GST_DEBUG ("no rate, name %s", p);
    /* no rate, assume -1 then */
    *name = p;
    *rate = -1;
    return TRUE;
  }

  t = p;
  p = strstr (p, "/");
  if (p == NULL) {
    *rate = atoi (t);
    return TRUE;
  }
  *p = '\0';
  p++;
  *rate = atoi (t);

  t = p;
  if (*p == '\0')
    return TRUE;
  *params = t;

  return TRUE;
}
コード例 #11
0
ファイル: gda-ldap-provider.c プロジェクト: arthurnn/libgda
static GObject *
gda_ldap_provider_statement_execute (GdaServerProvider *provider, GdaConnection *cnc,
				     GdaStatement *stmt, GdaSet *params,
				     GdaStatementModelUsage model_usage,
				     GType *col_types, GdaSet **last_inserted_row, GError **error)
{
	gchar *sql;
	sql = gda_statement_to_sql (stmt, params, NULL);
	if (sql) {
		/* parse SQL:
		 * CREATE LDAP TABLE <table name> WITH BASE='base_dn' FILTER='filter'
		 *              ATTRIBUTES='attributes' SCOPE='scope'
		 */
		gchar *ssql = sql;
		SKIP_SPACES (ssql);
		if (! g_ascii_strncasecmp (ssql, "CREATE", 6)) {
			ExtraSqlCommand *cmde;
			GError *lerror = NULL;
			GObject *retval = NULL;
			cmde = parse_extra_sql_command (ssql, "CREATE", &lerror);
			if (cmde != NOT_AN_EXTRA_SQL_COMMAND) {
				GdaConnectionEvent *event = NULL;
				if (cmde) {
					if (gda_ldap_connection_declare_table (GDA_LDAP_CONNECTION (cnc),
									       cmde->table_name, cmde->base_dn,
									       cmde->filter, cmde->attributes,
									       cmde->scope, &lerror))
						retval = (GObject*) gda_set_new (NULL);
					else {
						event = gda_connection_point_available_event (cnc,
											      GDA_CONNECTION_EVENT_ERROR);
						gda_connection_event_set_description (event, lerror && lerror->message ? 
										      lerror->message : _("No detail"));
						gda_connection_add_event (cnc, event);
						g_propagate_error (error, lerror);
					}
					extra_sql_command_free (cmde);
				}
				else {
					event = gda_connection_point_available_event (cnc,
										      GDA_CONNECTION_EVENT_ERROR);
					gda_connection_event_set_description (event, lerror && lerror->message ? 
									      lerror->message : _("No detail"));
					gda_connection_add_event (cnc, event);
					g_propagate_error (error, lerror);
				}

				gda_connection_internal_statement_executed (cnc, stmt, params, event);
				g_free (sql);
				return retval;
			}
		}

		/* parse SQL:
		 * DROP LDAP TABLE <table name>
		 */
		else if (! g_ascii_strncasecmp (ssql, "DROP", 4)) {
			ExtraSqlCommand *cmde;
			GError *lerror = NULL;
			GObject *retval = NULL;
			cmde = parse_extra_sql_command (ssql, "DROP", &lerror);
			if (cmde != NOT_AN_EXTRA_SQL_COMMAND) {
				GdaConnectionEvent *event = NULL;
				if (cmde) {
					if (cmde->other_args) {
						g_set_error (&lerror, GDA_SQL_PARSER_ERROR,
							     GDA_SQL_PARSER_SYNTAX_ERROR,
							     "%s",
							     _("Too many arguments"));
						event = gda_connection_point_available_event (cnc,
											      GDA_CONNECTION_EVENT_ERROR);
						gda_connection_event_set_description (event,
										      lerror->message);
						gda_connection_add_event (cnc, event);
						g_propagate_error (error, lerror);
					}
					else {
						if (gda_ldap_connection_undeclare_table (GDA_LDAP_CONNECTION (cnc),
											 cmde->table_name, &lerror))
							retval = (GObject*) gda_set_new (NULL);
						else {
							event = gda_connection_point_available_event (cnc,
												      GDA_CONNECTION_EVENT_ERROR);
							gda_connection_event_set_description (event, lerror && lerror->message ? 
											      lerror->message : _("No detail"));
							gda_connection_add_event (cnc, event);
							g_propagate_error (error, lerror);
						}
					}
					extra_sql_command_free (cmde);
				}
				else {
					event = gda_connection_point_available_event (cnc,
										      GDA_CONNECTION_EVENT_ERROR);
					gda_connection_event_set_description (event, lerror && lerror->message ? 
									      lerror->message : _("No detail"));
					gda_connection_add_event (cnc, event);
					g_propagate_error (error, lerror);
				}
				gda_connection_internal_statement_executed (cnc, stmt, params, event);
				g_free (sql);
				return retval;
			}
		}
		/* parse SQL:
		 * ALTER LDAP TABLE <table name> [...]
		 * DESCRIBE LDAP TABLE <table name>
		 */
		else if (! g_ascii_strncasecmp (ssql, "ALTER", 5) ||
			 ! g_ascii_strncasecmp (ssql, "DESCRIBE", 8)) {
			ExtraSqlCommand *cmde;
			GError *lerror = NULL;
			GObject *retval = NULL;
			gboolean alter;

			alter = g_ascii_strncasecmp (ssql, "ALTER", 5) ? FALSE : TRUE;
			    
			cmde = parse_extra_sql_command (ssql, alter ? "ALTER" : "DESCRIBE", &lerror);
			if ((cmde != NOT_AN_EXTRA_SQL_COMMAND) &&
			    (alter || (!alter && !cmde->other_args))) {
				GdaConnectionEvent *event = NULL;
				if (cmde) {
					const gchar *base_dn, *filter, *attributes;
					GdaLdapSearchScope scope;
					if (gda_ldap_connection_describe_table (GDA_LDAP_CONNECTION (cnc),
										cmde->table_name,
										&base_dn, &filter,
										&attributes, &scope, &lerror)) {
						if (cmde->other_args) {
							if (! cmde->base_dn && base_dn)
								cmde->base_dn = g_strdup (base_dn);
							if (! cmde->filter && filter)
								cmde->filter = g_strdup (filter);
							if (! cmde->attributes && attributes)
								cmde->attributes = g_strdup (attributes);
							if (! cmde->scope)
								cmde->scope = scope;
							if (gda_ldap_connection_undeclare_table (GDA_LDAP_CONNECTION (cnc),
												 cmde->table_name, &lerror) &&
							    gda_ldap_connection_declare_table (GDA_LDAP_CONNECTION (cnc),
											       cmde->table_name, cmde->base_dn,
											       cmde->filter, cmde->attributes,
											       cmde->scope, &lerror))
								retval = (GObject*) gda_set_new (NULL);
						}
						else {
							GdaDataModel *array;
							array = table_parameters_describe (base_dn, filter,
											   attributes, scope);
							retval = (GObject*) array;
						}
					}
					if (!retval) {
						event = gda_connection_point_available_event (cnc,
											      GDA_CONNECTION_EVENT_ERROR);
						gda_connection_event_set_description (event, lerror && lerror->message ? 
										      lerror->message : _("No detail"));
						gda_connection_add_event (cnc, event);
						g_propagate_error (error, lerror);
					}
					extra_sql_command_free (cmde);
				}
				gda_connection_internal_statement_executed (cnc, stmt, params, event);
				g_free (sql);
				return retval;
			}
		}
		g_free (sql);
	}

	/* check connection to LDAP is Ok */
	if (! gda_ldap_ensure_bound (GDA_LDAP_CONNECTION (cnc), error))
		return NULL;

	GdaServerProviderBase *fset;
	fset = gda_server_provider_get_impl_functions_for_class (parent_class, GDA_SERVER_PROVIDER_FUNCTIONS_BASE);
	return fset->statement_execute (provider, cnc, stmt, params,
					model_usage, col_types,
					last_inserted_row, error);
}
コード例 #12
0
ファイル: depset.c プロジェクト: radhermit/pkgcore
static PyObject *
internal_parse_depset(PyObject *dep_str, char **ptr, int *has_conditionals,
	PyObject *element_func,
	PyObject *and_func, PyObject *or_func,
	PyObject *parent_func,
	char initial_frame)
{
	char *start = *ptr;
	char *p = NULL;
	PyObject *restrictions = NULL;
	PyObject *item = NULL;
	PyObject *tmp = NULL;

	// should just use alloca here.

	#define PARSE_DEPSET_STACK_STORAGE 16
	PyObject *stack_restricts[PARSE_DEPSET_STACK_STORAGE];
	Py_ssize_t item_count = 0, tup_size = PARSE_DEPSET_STACK_STORAGE;
	Py_ssize_t item_size = 1;

	SKIP_SPACES(start);
	p = start;
	while('\0' != *start) {
		start = p;
		SKIP_NONSPACES(p);
		if('(' == *start) {
			// new and frame.
			if(!and_func) {
				Err_SetParse(dep_str, "this depset doesn't support and blocks",
				start, p);
				goto internal_parse_depset_error;
			}
			if(p - start != 1) {
				Err_SetParse(dep_str,
					"either a space or end of string is required after (",
					start, p);
				goto internal_parse_depset_error;
			}
			if(!(tmp = internal_parse_depset(dep_str, &p, has_conditionals,
				element_func, and_func, or_func, and_func, 0)))
				goto internal_parse_depset_error;

			if(tmp == Py_None) {
				Py_DECREF(tmp);
				Err_SetParse(dep_str, "empty payload", start, p);
				goto internal_parse_depset_error;
			} else if(!PyTuple_CheckExact(tmp)) {
				item = tmp;
			} else {
				item = PyObject_CallObject(and_func, tmp);
				Py_DECREF(tmp);
				if(!item)
					goto internal_parse_depset_error;
			}

		} else if(')' == *start) {
			// end of a frame
			if(initial_frame) {
				Err_SetParse(dep_str, ") found without matching (",
					NULL, NULL);
				goto internal_parse_depset_error;
			}
			if(p - start != 1) {
				Err_SetParse(dep_str,
					"either a space or end of string is required after )",
					start, p);
				goto internal_parse_depset_error;
			}

			if(!*p)
				p--;
			break;

		} else if('?' == p[-1]) {
			// use conditional
			if (p - start == 1 || ('!' == *start && p - start == 2)) {
				Err_SetParse(dep_str, "empty use conditional", start, p);
				goto internal_parse_depset_error;
			}
			char *conditional_end = p - 1;
			SKIP_SPACES(p);
			if ('(' != *p) {
				Err_SetParse(dep_str,
					"( has to be the next token for a conditional",
					start, p);
				goto internal_parse_depset_error;
			} else if(!isspace(*(p + 1)) || '\0' == p[1]) {
				Err_SetParse(dep_str,
					"( has to be followed by whitespace",
					start, p);
				goto internal_parse_depset_error;
			}
			p++;
			if(!(tmp = internal_parse_depset(dep_str, &p, has_conditionals,
				element_func, and_func, or_func, NULL, 0)))
				goto internal_parse_depset_error;

			if(tmp == Py_None) {
				Py_DECREF(tmp);
				Err_SetParse(dep_str, "empty payload", start, p);
				goto internal_parse_depset_error;

			} else if(!PyTuple_CheckExact(tmp)) {
				item = PyTuple_New(1);
				if(!tmp) {
					Py_DECREF(item);
					goto internal_parse_depset_error;
				}
				PyTuple_SET_ITEM(item, 0, tmp);
				tmp = item;
			}
			item = make_use_conditional(start, conditional_end, tmp);
			Py_DECREF(tmp);
			if(!item)
				goto internal_parse_depset_error;
			*has_conditionals = 1;

		} else if ('|' == *start) {
			if('|' != start[1] || !or_func) {
				Err_SetParse(dep_str,
					"stray |, or this depset doesn't support or blocks",
					NULL, NULL);
				goto internal_parse_depset_error;
			}

			if(p - start != 2) {
				Err_SetParse(dep_str, "|| must have space followed by a (",
					start, p);
				goto internal_parse_depset_error;
			}
			SKIP_SPACES(p);
			if ('(' != *p || (!isspace(*(p + 1)) && '\0' != p[1])) {
				Err_SetParse(dep_str,
					"( has to be the next token for a conditional",
					start, p);
				goto internal_parse_depset_error;
			}
			p++;
			if(!(tmp = internal_parse_depset(dep_str, &p, has_conditionals,
				element_func, and_func, or_func, NULL, 0)))
				goto internal_parse_depset_error;

			if(tmp == Py_None) {
				Py_DECREF(tmp);
				Err_SetParse(dep_str, "empty payload", start, p);
				goto internal_parse_depset_error;
			} else if (!PyTuple_CheckExact(tmp)) {
				item = tmp;
			} else {
				item = PyObject_CallObject(or_func, tmp);
				Py_DECREF(tmp);
				if(!item)
					goto internal_parse_depset_error;
			}
		} else {
			item = PyObject_CallFunction(element_func, "s#", start, p - start);
			if(!item) {
				Err_WrapException(dep_str, start, p);
				goto internal_parse_depset_error;
			}
			assert(!PyErr_Occurred());
		}

		// append it.
		if(item_count + item_size > tup_size) {
			while(tup_size < item_count + item_size)
				tup_size <<= 1;
			if(!restrictions) {
				// switch over.
				if(!(restrictions = PyTuple_New(tup_size))) {
					Py_DECREF(item);
					goto internal_parse_depset_error;
				}
				Py_ssize_t x = 0;
				for(; x < item_count; x++) {
					PyTuple_SET_ITEM(restrictions, x,
						stack_restricts[x]);
				}
			} else if(_PyTuple_Resize(&restrictions, tup_size)) {
				Py_DECREF(item);
				goto internal_parse_depset_error;
			}
			// now we're using restrictions.
		}
		if(restrictions) {
			if(item_size == 1) {
				PyTuple_SET_ITEM(restrictions, item_count++, item);
			} else {
				Py_ssize_t x = 0;
				for(; x < item_size; x++) {
					Py_INCREF(PyTuple_GET_ITEM(item, x));
					PyTuple_SET_ITEM(restrictions, item_count + x,
						PyTuple_GET_ITEM(item, x));
				}
				item_count += x;
				item_size = 1;
				// we're done with the tuple, already stole the items from it.
				Py_DECREF(item);
			}
		} else {
			if(item_size == 1) {
				stack_restricts[item_count++] = item;
			} else {
				Py_ssize_t x = 0;
				for(;x < item_size; x++) {
					Py_INCREF(PyTuple_GET_ITEM(item, x));
					stack_restricts[item_count + x] = PyTuple_GET_ITEM(item, x);
				}
				item_count += item_size;
				item_size = 1;
				// we're done with the tuple, already stole the items from it.
				Py_DECREF(item);
			}
		}
		SKIP_SPACES(p);
		start = p;
	}

	if(initial_frame) {
		if(*p) {
			Err_SetParse(dep_str, "stray ')' encountered", start, p);
			goto internal_parse_depset_error;
		}
	} else {
		if('\0' == *p) {
			Err_SetParse(dep_str, "depset lacks closure", *ptr, p);
			goto internal_parse_depset_error;
		}
		p++;
	}

	if(!restrictions) {
		if(item_count == 0) {
			restrictions = Py_None;
			Py_INCREF(restrictions);
		} else if(item_count == 1) {
			restrictions = stack_restricts[0];
		} else {
			restrictions = PyTuple_New(item_count);
			if(!restrictions)
				goto internal_parse_depset_error;
			Py_ssize_t x =0;
			for(;x < item_count; x++) {
				PyTuple_SET_ITEM(restrictions, x,
					stack_restricts[x]);
			}
		}
	} else if(item_count < tup_size) {
		if(_PyTuple_Resize(&restrictions, item_count))
			goto internal_parse_depset_error;
	}
	*ptr = p;
	return restrictions;

	internal_parse_depset_error:
	if(item_count) {
		if(!restrictions) {
			item_count--;
			while(item_count >= 0) {
				Py_DECREF(stack_restricts[item_count]);
				item_count--;
			}
		} else
			Py_DECREF(restrictions);
	}
	// dealloc.
	return NULL;
}
コード例 #13
0
ファイル: misc.c プロジェクト: BackupTheBerlios/bar-svn
String Misc_expandMacros(String          string,
                         const char      *macroTemplate,
                         const TextMacro macros[],
                         uint            macroCount
                        )
{
  #define APPEND_CHAR(string,index,ch) \
    do \
    { \
      if ((index) < sizeof(string)-1) \
      { \
        (string)[index] = ch; \
        (index)++; \
      } \
    } \
    while (0)

  #define SKIP_SPACES(string,i) \
    do \
    { \
      while (   ((string)[i] != '\0') \
             && isspace((string)[i]) \
            ) \
      { \
        (i)++; \
      } \
    } \
    while (0)

  bool  macroFlag;
  ulong i;
  uint  j;
  char  name[128];
  char  format[128];

  assert(macroTemplate != NULL);
  assert((macroCount == 0) || (macros != NULL));

  String_clear(string);
  i = 0;
  do
  {
    // add prefix string
    macroFlag = FALSE;
    while ((macroTemplate[i] != '\0') && !macroFlag)
    {
      if (macroTemplate[i] == '%')
      {
        if ((macroTemplate[i+1] == '%'))
        {
          String_appendChar(string,'%');
          i+=2;
        }
        else
        {
          macroFlag = TRUE;
          i++;
        }
      }
      else
      {
        String_appendChar(string,macroTemplate[i]);
        i++;
      }
    }

    if (macroFlag)
    {
      // skip spaces
      SKIP_SPACES(macroTemplate,i);

      // get macro name
      j = 0;
      if (   (macroTemplate[i] != '\0')
          && isalpha(macroTemplate[i])
         )
      {
        APPEND_CHAR(name,j,'%');
        do
        {
          APPEND_CHAR(name,j,macroTemplate[i]);
          i++;
        }
        while (   (macroTemplate[i] != '\0')
               && isalnum(macroTemplate[i])
              );
      }
      name[j] = '\0';

      // get format data (if any)
      j = 0;
      if (macroTemplate[i] == ':')
      {
        // skip ':'
        i++;

        // skip spaces
        SKIP_SPACES(macroTemplate,i);

        // get format string
        APPEND_CHAR(format,j,'%');
        while (   (macroTemplate[i] != '\0')
               && (   isdigit(macroTemplate[i])
                   || (macroTemplate[i] == '-')
                   || (macroTemplate[i] == '.')
                  )
              )
        {
          APPEND_CHAR(format,j,macroTemplate[i]);
          i++;
        }
        while (   (macroTemplate[i] != '\0')
               && (strchr("l",macroTemplate[i]) != NULL)
              )
        {
          APPEND_CHAR(format,j,macroTemplate[i]);
          i++;
        }
        if (   (macroTemplate[i] != '\0')
            && (strchr("duxfsS",macroTemplate[i]) != NULL)
           )
        {
          APPEND_CHAR(format,j,macroTemplate[i]);
          i++;
        }
      }
      format[j] = '\0';

      // find macro
      if (strlen(name) > 0)
      {
        // find macro
        j = 0;
        while (   (j < macroCount)
               && (strcmp(name,macros[j].name) != 0)
              )
        {
          j++;
        }

        if (j < macroCount)
        {
          // get default format if no format given
          if (strlen(format) == 0)
          {
            switch (macros[j].type)
            {
              case TEXT_MACRO_TYPE_INTEGER:
                strcpy(format,"%d");
                break;
              case TEXT_MACRO_TYPE_INTEGER64:
                strcpy(format,"%lld");
                break;
              case TEXT_MACRO_TYPE_DOUBLE:
                strcpy(format,"%lf");
                break;
              case TEXT_MACRO_TYPE_CSTRING:
                strcpy(format,"%s");
                break;
              case TEXT_MACRO_TYPE_STRING:
                strcpy(format,"%S");
                break;
              #ifndef NDEBUG
                default:
                  HALT_INTERNAL_ERROR_UNHANDLED_SWITCH_CASE();
                  break; /* not reached */
              #endif /* NDEBUG */
            }
          }

          // expand macro
          switch (macros[j].type)
          {
            case TEXT_MACRO_TYPE_INTEGER:
              String_format(string,format,macros[j].value.i);
              break;
            case TEXT_MACRO_TYPE_INTEGER64:
              String_format(string,format,macros[j].value.l);
              break;
            case TEXT_MACRO_TYPE_DOUBLE:
              String_format(string,format,macros[j].value.d);
              break;
            case TEXT_MACRO_TYPE_CSTRING:
              String_format(string,format,macros[j].value.s);
              break;
            case TEXT_MACRO_TYPE_STRING:
              String_format(string,format,macros[j].value.string);
              break;
            #ifndef NDEBUG
              default:
                HALT_INTERNAL_ERROR_UNHANDLED_SWITCH_CASE();
                break; /* not reached */
            #endif /* NDEBUG */
          }
        }
        else
        {
          // keep unknown macro
          String_appendCString(string,name);
        }
      }
      else
      {
        // empty macro: add empty string
        String_format(string,format,"");
      }
    }
  }
  while (macroFlag);

  return string;

  #undef SKIP_SPACES
  #undef APPEND_CHAR
}
コード例 #14
0
ファイル: config.cpp プロジェクト: Fale/qtmoko
/*!
  Load, parse, and process a qdoc configuration file. This
  function is only called by the other load() function, but
  this one is recursive, i.e., it calls itself when it sees
  an \c{include} statement in the qdog configuration file.
 */
void Config::load(Location location, const QString& fileName)
{
    QRegExp keySyntax("\\w+(?:\\.\\w+)*");

#define SKIP_CHAR() \
    do { \
        location.advance(c); \
        ++i; \
        c = text.at(i); \
        cc = c.unicode(); \
    } while (0)

#define SKIP_SPACES() \
    while (c.isSpace() && cc != '\n') \
        SKIP_CHAR()

#define PUT_CHAR() \
    word += c; \
    SKIP_CHAR();

    if (location.depth() > 16)
        location.fatal(tr("Too many nested includes"));

    QFile fin(fileName);
    if (!fin.open(QFile::ReadOnly | QFile::Text)) {
        fin.setFileName(fileName + ".qdoc");
        if (!fin.open(QFile::ReadOnly | QFile::Text))
            location.fatal(tr("Cannot open file '%1': %2").arg(fileName).arg(fin.errorString()));
    }

    QString text = fin.readAll();
    text += QLatin1String("\n\n");
    text += QChar('\0');
    fin.close();

    location.push(fileName);
    location.start();

    int i = 0;
    QChar c = text.at(0);
    uint cc = c.unicode();
    while (i < (int) text.length()) {
        if (cc == 0)
            ++i;
        else if (c.isSpace()) {
            SKIP_CHAR();
        }
        else if (cc == '#') {
            do {
                SKIP_CHAR();
            } while (cc != '\n');
        }
        else if (isMetaKeyChar(c)) {
            Location keyLoc = location;
            bool plus = false;
            QString stringValue;
            QStringList stringListValue;
            QString word;
            bool inQuote = false;
            bool prevWordQuoted = true;
            bool metWord = false;

            MetaStack stack;
            do {
                stack.process(c, location);
                SKIP_CHAR();
            } while (isMetaKeyChar(c));

            QStringList keys = stack.getExpanded(location);
            SKIP_SPACES();

            if (keys.count() == 1 && keys.first() == "include") {
                QString includeFile;

                if (cc != '(')
                    location.fatal(tr("Bad include syntax"));
                SKIP_CHAR();
                SKIP_SPACES();
                while (!c.isSpace() && cc != '#' && cc != ')') {
                    includeFile += c;
                    SKIP_CHAR();
                }
                SKIP_SPACES();
                if (cc != ')')
                    location.fatal(tr("Bad include syntax"));
                SKIP_CHAR();
                SKIP_SPACES();
                if (cc != '#' && cc != '\n')
                    location.fatal(tr("Trailing garbage"));

                /*
                  Here is the recursive call.
                 */
                load(location,
                      QFileInfo(QFileInfo(fileName).dir(), includeFile)
                      .filePath());
            }
            else {
                /*
                  It wasn't an include statement, so it;s something else.
                 */
                if (cc == '+') {
                    plus = true;
                    SKIP_CHAR();
                }
                if (cc != '=')
                    location.fatal(tr("Expected '=' or '+=' after key"));
                SKIP_CHAR();
                SKIP_SPACES();

                for (;;) {
                    if (cc == '\\') {
                        int metaCharPos;

                        SKIP_CHAR();
                        if (cc == '\n') {
                            SKIP_CHAR();
                        }
                        else if (cc > '0' && cc < '8') {
                            word += QChar(c.digitValue());
                            SKIP_CHAR();
                        }
                        else if ((metaCharPos = QString(QLatin1String("abfnrtv")).indexOf(c)) != -1) {
                            word += "\a\b\f\n\r\t\v"[metaCharPos];
                            SKIP_CHAR();
                        }
                        else {
                            PUT_CHAR();
                        }
                    }
                    else if (c.isSpace() || cc == '#') {
                        if (inQuote) {
                            if (cc == '\n')
                                location.fatal(tr("Unterminated string"));
                            PUT_CHAR();
                        }
                        else {
                            if (!word.isEmpty()) {
                                if (metWord)
                                    stringValue += QLatin1Char(' ');
                                stringValue += word;
                                stringListValue << word;
                                metWord = true;
                                word.clear();
                                prevWordQuoted = false;
                            }
                            if (cc == '\n' || cc == '#')
                                break;
                            SKIP_SPACES();
                        }
                    }
                    else if (cc == '"') {
                        if (inQuote) {
                            if (!prevWordQuoted)
                                stringValue += QLatin1Char(' ');
                            stringValue += word;
                            if (!word.isEmpty())
                                stringListValue << word;
                            metWord = true;
                            word.clear();
                            prevWordQuoted = true;
                        }
                        inQuote = !inQuote;
                        SKIP_CHAR();
                    }
                    else if (cc == '$') {
                        QString var;
                        SKIP_CHAR();
                        while (c.isLetterOrNumber() || cc == '_') {
                            var += c;
                            SKIP_CHAR();
                        }
                        if (!var.isEmpty()) {
                            char *val = getenv(var.toLatin1().data());
                            if (val == 0) {
                                location.fatal(tr("Environment variable '%1' undefined").arg(var));
                            }
                            else {
                                word += QString(val);
                            }
                        }
                    }
                    else {
                        if (!inQuote && cc == '=')
                            location.fatal(tr("Unexpected '='"));
                        PUT_CHAR();
                    }
                }

                QStringList::ConstIterator key = keys.begin();
                while (key != keys.end()) {
                    if (!keySyntax.exactMatch(*key))
                        keyLoc.fatal(tr("Invalid key '%1'").arg(*key));

                    if (plus) {
                        if (locMap[*key].isEmpty()) {
                            locMap[*key] = keyLoc;
                        }
                        else {
                            locMap[*key].setEtc(true);
                        }
                        if (stringValueMap[*key].isEmpty()) {
                            stringValueMap[*key] = stringValue;
                        }
                        else {
                            stringValueMap[*key] +=
                                QLatin1Char(' ') + stringValue;
                        }
                        stringListValueMap[*key] += stringListValue;
                    }
                    else {
                        locMap[*key] = keyLoc;
                        stringValueMap[*key] = stringValue;
                        stringListValueMap[*key] = stringListValue;
                    }
                    ++key;
                }
            }
        }
        else {
            location.fatal(tr("Unexpected character '%1' at beginning of line")
                            .arg(c));
        }
    }
}
コード例 #15
0
ファイル: mac.c プロジェクト: jkrauska/prads
/* load_mac: fill **macp with mac_entry
 *
 * sigp is a pointer to either
 ** a pointer to a preallocated buffer of size max_sigs * fp_entry OR
 ** a NULL pointer indicating that we should allocate max_sigs for you
 * max_sigs is the maximal size of the buffer, or 0 in which case we decide
 *
 * Theory:   snarf sigs in serially, easypeasy
 *
 * returns errno
 */
int load_mac(const char *file, mac_entry **sigp[], int hashsize)
{
    mac_entry **sig; // output
    uint32_t ln = 0;
    uint32_t sigcnt = 0;
    //debug("opening %s\n", file);
    FILE *f = fopen(file, "r");
    char buf[MAXLINE];
    char *p;
    if (!f) {
        perror("failed to open file");
        return errno;
    }
    if(!sigp) {
        fclose(f);
        perror("need a pointer to fill");
        return -1;
    }
    if(!hashsize)
        hashsize = MAC_HASHSIZE;
    if(*sigp == NULL) {
        *sigp = calloc(hashsize, sizeof(mac_entry *));
        sig = *sigp;
    }

    // read a line at a time and load it into the hash.
    while ((p = fgets(buf, sizeof(buf), f))) {
        mac_entry entry = {{0}}; //guarantee it's empty
        uint32_t l, lp;
        uint8_t octet = 0;
        char vendor[128] = {0};
        char *comment = 0;

        mac_entry *e;

        ln++;

        /* Remove leading and trailing blanks */
        SKIP_SPACES(p);
        l = strlen(p);
        while (l && isspace(*(p + l - 1)))
            *(p + (l--) - 1) = 0;

        /* Skip empty lines and comments */
        if (!l)
            continue;
        if (*p == '#')
            continue;

        /* first part: mac address */
        while (*p && !isspace(*p))
        {
            if (isxdigit(*p) && isxdigit(*(p+1))) {
                //mac.o[octet++] = strtol(p,&(p+1), 16);
                sscanf(p, "%2hhx", &entry.o[octet]);
                octet++;
                p += 2;
                continue;
            } else if (*p == '-' || *p == ':') {
                p++;
                continue;
            } else if (*p == '/') {
                // mac mask
                entry.mask = strtol(p+1, NULL, 10);
                p += 2;
                continue;
            } // else
            p++; // skip unknown chars...
        }
        SKIP_SPACES(p);
        /* second part: vendor */
        sscanf(p, "%127s", vendor);
        // scan forward..
        while (*p && !isspace(*p))
            p++;
        SKIP_SPACES(p);

        /* third part, #comment (optional) */
        if(*p == '#') {
            /* chomp it first */
            p++;
            SKIP_SPACES(p);
            lp = strlen(p);

            while (lp && isspace(*(p + lp - 1)))
                *(p + (lp--) - 1) = 0;

            /* then copy the comment */
            comment = calloc(1, lp + 1);
            strncpy(comment, p, lp);
        }

        /* roll hash */
        entry.vendor = strdup(vendor);
        entry.comment = comment;

        // if there is no mask, all octets count
        if(!entry.mask)
            entry.mask = octet * 8; //48 - octet * 8;

        int index = hash_mac(entry.o, octet);
        e = sig[index];

        if (!e) {
            sig[index] = alloc_mac(&entry);
        } else {
            int cc = 0;
            // collision!
            while (e->next) {
                e = e->next;
                cc++;
            }
            /*
            printf("hash collision %d: at index %d\n", cc, index);
            print_mac(&entry);
            */
            e->next = alloc_mac(&entry);
        }
        sigcnt++;
    }

    fclose(f);
#ifdef DEBUG_HASH
    {
        int i,max;
        mac_entry *p;
        printf("Hash table layout: ");
        max = 0;
        for (i = 0; i < MAC_HASHSIZE; i++) {
            int z = 0;
            p = sig[i];
            while (p) {
                p = p->next;
                z++;
            }
            max = (max > z)? max : z;
            printf("%d ", z);

        }
        putchar('\n');
        printf ("max : %d\n", max);
    }
#endif                          /* DEBUG_HASH */

    if (!sigcnt)
        debug("[!] WARNING: no signatures loaded from config file.\n");
    else
        dlog("%d sigs from %d lines\n", sigcnt, ln);

    return 0;
}
コード例 #16
0
/*----------------------------------------------------------------------------*/
int
LoadConfig(char *file_name, struct conf_var *vlist, int size)
{
	assert(file_name != NULL);

	FILE *fp = fopen(file_name, "r");
	char line_buf[MAX_LINE_LEN] = {0};
	int i;
	char *p;

	if (fp == NULL) {
		fprintf(stderr, "%s not found\n", file_name);
		return -1;
	}

	while ((p = fgets(line_buf, MAX_LINE_LEN, fp)) != NULL) {
		char *temp;

		if (p[MAX_LINE_LEN - 1]) {
			fprintf(stderr, "%s has a line longer than %d\n",
					file_name, MAX_LINE_LEN);
			return -1;
		}

		SKIP_SPACES(p);
		if (*p == '\0' || *p == '#')
			continue;

		/* comments */
		if ((temp = strchr(p, '#')))
			*temp = '\0';

		/* remove spaces at the end of the line */
		while (isspace(p[strlen(p) - 1]))
			p[strlen(p) - 1] = '\0';

		for (i = 0; i < size; i++) {
			int len = strlen(vlist[i].name);
			if (strncmp(vlist[i].name, p, len))
				continue;

			if (!isspace(p[len]))
				continue;

			if (!(p = strchr(p, '=')))
				break;

			p++;
			SKIP_SPACES(p);

			if ((len = strlen(p)) > CONF_VALUE_LEN)
				break;

			strncpy(vlist[i].value, p, len);
			vlist[i].value[len] = '\0';
		}
	}
	
	fclose(fp);
	return 0;
}
コード例 #17
0
ファイル: config.cpp プロジェクト: 2gis/2gisqt5android
/*!
  Load, parse, and process a qdoc configuration file. This
  function is only called by the other load() function, but
  this one is recursive, i.e., it calls itself when it sees
  an \c{include} statement in the qdoc configuration file.
 */
void Config::load(Location location, const QString& fileName)
{
    QFileInfo fileInfo(fileName);
    QString path = fileInfo.canonicalPath();
    pushWorkingDir(path);
    QDir::setCurrent(path);
    QRegExp keySyntax(QLatin1String("\\w+(?:\\.\\w+)*"));

#define SKIP_CHAR() \
    do { \
    location.advance(c); \
    ++i; \
    c = text.at(i); \
    cc = c.unicode(); \
} while (0)

#define SKIP_SPACES() \
    while (c.isSpace() && cc != '\n') \
    SKIP_CHAR()

#define PUT_CHAR() \
    word += c; \
    SKIP_CHAR();

    if (location.depth() > 16)
        location.fatal(tr("Too many nested includes"));

    QFile fin(fileInfo.fileName());
    if (!fin.open(QFile::ReadOnly | QFile::Text)) {
        if (!Config::installDir.isEmpty()) {
            int prefix = location.filePath().length() - location.fileName().length();
            fin.setFileName(Config::installDir + QLatin1Char('/') + fileName.right(fileName.length() - prefix));
        }
        if (!fin.open(QFile::ReadOnly | QFile::Text))
            location.fatal(tr("Cannot open file '%1': %2").arg(fileName).arg(fin.errorString()));
    }

    QTextStream stream(&fin);
#ifndef QT_NO_TEXTCODEC
    stream.setCodec("UTF-8");
#endif
    QString text = stream.readAll();
    text += QLatin1String("\n\n");
    text += QLatin1Char('\0');
    fin.close();

    location.push(fileName);
    location.start();

    int i = 0;
    QChar c = text.at(0);
    uint cc = c.unicode();
    while (i < (int) text.length()) {
        if (cc == 0) {
            ++i;
        } else if (c.isSpace()) {
            SKIP_CHAR();
        } else if (cc == '#') {
            do {
                SKIP_CHAR();
            } while (cc != '\n');
        } else if (isMetaKeyChar(c)) {
            Location keyLoc = location;
            bool plus = false;
            QString stringValue;
            QStringList rhsValues;
            QString word;
            bool inQuote = false;
            bool prevWordQuoted = true;
            bool metWord = false;

            MetaStack stack;
            do {
                stack.process(c, location);
                SKIP_CHAR();
            } while (isMetaKeyChar(c));

            QStringList keys = stack.getExpanded(location);
            SKIP_SPACES();

            if (keys.count() == 1 && keys.first() == QLatin1String("include")) {
                QString includeFile;

                if (cc != '(')
                    location.fatal(tr("Bad include syntax"));
                SKIP_CHAR();
                SKIP_SPACES();

                while (!c.isSpace() && cc != '#' && cc != ')') {

                    if (cc == '$') {
                        QString var;
                        SKIP_CHAR();
                        while (c.isLetterOrNumber() || cc == '_') {
                            var += c;
                            SKIP_CHAR();
                        }
                        if (!var.isEmpty()) {
                            const QByteArray val = qgetenv(var.toLatin1().data());
                            if (val.isNull()) {
                                location.fatal(tr("Environment variable '%1' undefined").arg(var));
                            }
                            else {
                                includeFile += QString::fromLatin1(val);
                            }
                        }
                    } else {
                        includeFile += c;
                        SKIP_CHAR();
                    }
                }
                SKIP_SPACES();
                if (cc != ')')
                    location.fatal(tr("Bad include syntax"));
                SKIP_CHAR();
                SKIP_SPACES();
                if (cc != '#' && cc != '\n')
                    location.fatal(tr("Trailing garbage"));

                /*
                  Here is the recursive call.
                 */
                load(location, QFileInfo(QDir(path), includeFile).filePath());
            }
            else {
                /*
                  It wasn't an include statement, so it's something else.
                  We must see either '=' or '+=' next. If not, fatal error.
                 */
                if (cc == '+') {
                    plus = true;
                    SKIP_CHAR();
                }
                if (cc != '=')
                    location.fatal(tr("Expected '=' or '+=' after key"));
                SKIP_CHAR();
                SKIP_SPACES();

                for (;;) {
                    if (cc == '\\') {
                        int metaCharPos;

                        SKIP_CHAR();
                        if (cc == '\n') {
                            SKIP_CHAR();
                        }
                        else if (cc > '0' && cc < '8') {
                            word += QChar(c.digitValue());
                            SKIP_CHAR();
                        }
                        else if ((metaCharPos = QString::fromLatin1("abfnrtv").indexOf(c)) != -1) {
                            word += QLatin1Char("\a\b\f\n\r\t\v"[metaCharPos]);
                            SKIP_CHAR();
                        }
                        else {
                            PUT_CHAR();
                        }
                    }
                    else if (c.isSpace() || cc == '#') {
                        if (inQuote) {
                            if (cc == '\n')
                                location.fatal(tr("Unterminated string"));
                            PUT_CHAR();
                        }
                        else {
                            if (!word.isEmpty()) {
                                if (metWord)
                                    stringValue += QLatin1Char(' ');
                                stringValue += word;
#if 0
                                if (metWord)
                                    rhsValues << QString(" " + word);
                                else
#endif
                                rhsValues << word;
                                metWord = true;
                                word.clear();
                                prevWordQuoted = false;
                            }
                            if (cc == '\n' || cc == '#')
                                break;
                            SKIP_SPACES();
                        }
                    }
                    else if (cc == '"') {
                        if (inQuote) {
                            if (!prevWordQuoted)
                                stringValue += QLatin1Char(' ');
                            stringValue += word;
                            if (!word.isEmpty())
                                rhsValues << word;
                            metWord = true;
                            word.clear();
                            prevWordQuoted = true;
                        }
                        inQuote = !inQuote;
                        SKIP_CHAR();
                    }
                    else if (cc == '$') {
                        QString var;
                        SKIP_CHAR();
                        while (c.isLetterOrNumber() || cc == '_') {
                            var += c;
                            SKIP_CHAR();
                        }
                        if (!var.isEmpty()) {
                            const QByteArray val = qgetenv(var.toLatin1().constData());
                            if (val.isNull()) {
                                location.fatal(tr("Environment variable '%1' undefined").arg(var));
                            }
                            else {
                                word += QString::fromLatin1(val);
                            }
                        }
                    }
                    else {
                        if (!inQuote && cc == '=')
                            location.fatal(tr("Unexpected '='"));
                        PUT_CHAR();
                    }
                }

                QStringList::ConstIterator key = keys.constBegin();
                while (key != keys.constEnd()) {
                    if (!keySyntax.exactMatch(*key))
                        keyLoc.fatal(tr("Invalid key '%1'").arg(*key));

                    ConfigVarMultimap::Iterator i;
                    i = configVars_.insert(*key, ConfigVar(*key, rhsValues, QDir::currentPath(), keyLoc));
                    i.value().plus_ = plus;
                    ++key;
                }
            }
        } else {
            location.fatal(tr("Unexpected character '%1' at beginning of line").arg(c));
        }
    }
    popWorkingDir();
    if (!workingDirs_.isEmpty())
        QDir::setCurrent(workingDirs_.top());
}
コード例 #18
0
ファイル: gda-ldap-provider.c プロジェクト: arthurnn/libgda
/*
 * CREATE LDAP TABLE <table name> BASE='base_dn' FILTER='filter' ATTRIBUTES='attributes' SCOPE='scope'
 * DROP LDAP TABLE <table name>
 * ALTER LDAP TABLE <table name>
 * ALTER LDAP TABLE <table name> BASE='base_dn' FILTER='filter' ATTRIBUTES='attributes' SCOPE='scope'
 *
 * Returns: a #ExtraSqlCommand pointer, or %NULL, or NOT_AN_EXTRA_SQL_COMMAND (if not "CREATE LDAP...")
 */
static ExtraSqlCommand *
parse_extra_sql_command (gchar *cmd, const gchar *cmde_name, GError **error)
{
	ExtraSqlCommand *args;
	gchar *ptr, *errptr, *part, *tmp;
	args = g_new0 (ExtraSqlCommand, 1);
	args->other_args = FALSE;
	
	ptr = cmd + strlen (cmde_name);
	
	/* make sure about complete command */
	errptr = ptr;
	if (! (ptr = parse_ident (ptr, &part)))
		return NOT_AN_EXTRA_SQL_COMMAND;
	if (!part || g_ascii_strncasecmp (part, "ldap", 4))
		return NOT_AN_EXTRA_SQL_COMMAND;

	errptr = ptr;
	if (! (ptr = parse_ident (ptr, &part)))
		goto onerror;
	if (!part || g_ascii_strncasecmp (part, "table", 5))
		goto onerror;

	/* table name */
	SKIP_SPACES (ptr);
	errptr = ptr;
	if (! (ptr = parse_ident (ptr, &part)))
		goto onerror;
	tmp = g_strndup (part, ptr-part);
	args->table_name = g_ascii_strdown (tmp, -1);
	g_free (tmp);

	/* key=value arguments */
	while (TRUE) {
		errptr = ptr;
		SKIP_SPACES (ptr);
		if (! (ptr = parse_ident (ptr, &part))) {
			ptr = errptr;
			break;
		}
		if (part) {
			gchar **where = NULL;
			if (!g_ascii_strncasecmp (part, "base", 4))
				where = &(args->base_dn);
			else if (!g_ascii_strncasecmp (part, "filter", 6))
				where = &(args->filter);
			else if (!g_ascii_strncasecmp (part, "attributes", 10))
				where = &(args->attributes);
			else if (!g_ascii_strncasecmp (part, "scope", 5))
				where = NULL;
			else
				goto onerror;
			
			/* = */
			errptr = ptr;
			SKIP_SPACES (ptr);
			if (*ptr != '=')
				goto onerror;
			ptr++;
			
			/* value */
			errptr = ptr;
			SKIP_SPACES (ptr);
			if (! (ptr = parse_string (ptr, &part)))
				goto onerror;
			if (part) {
				if (where)
					*where = g_strdup (part);
				else {
					if (!g_ascii_strcasecmp (part, "base"))
						args->scope = GDA_LDAP_SEARCH_BASE;
					else if (!g_ascii_strcasecmp (part, "onelevel"))
						args->scope = GDA_LDAP_SEARCH_ONELEVEL;
					else if (!g_ascii_strcasecmp (part, "subtree"))
						args->scope = GDA_LDAP_SEARCH_SUBTREE;
					else
						goto onerror;
				}
				args->other_args = TRUE;
			}
			else
				goto onerror;
		}
		else
			break;
	}

	/* end */
	SKIP_SPACES (ptr);
	if (*ptr && (*ptr != ';'))
		goto onerror;
#ifdef GDA_DEBUG_NO
	g_print ("TABLE=>%s, BASE=>%s, FILTER=>%s, ATTRIBUTES=>%s, SCOPE=>%d\n", args->table_name,
		 args->base_dn, args->filter,
		 args->attributes, args->scope);
#endif

	return args;

 onerror:
	SKIP_SPACES (errptr);
	g_set_error (error, GDA_SQL_PARSER_ERROR, GDA_SQL_PARSER_SYNTAX_ERROR,
		     _("near \"%s\": syntax error"), errptr);
	extra_sql_command_free (args);
	return NULL;
}