示例#1
0
文件: linklist.c 项目: chixsh/libhl
int
slice_foreach_value(slice_t *slice, int (*item_handler)(void *item, size_t idx, void *user), void *user)
{
    linked_list_t *list = slice->list;
    MUTEX_LOCK(list->lock);
    size_t idx = 0;
    list_entry_t *e = pick_entry(list, slice->offset);
    while(e && idx < slice->length) {
        int rc = item_handler(e->value, idx++, user);
        if (rc == 0) {
            break;
        } else if (rc == -1 || rc == -2) {
            list_entry_t *d = e;
            e = e->next;
            if (list->head == list->tail && list->tail == d) {
                list->head = list->tail = NULL;
            } else if (d == list->head) {
                list->head = d->next;
                list->head->prev = NULL;
            } else if (d == list->tail) {
                list->tail = d->prev;
                list->tail->next = NULL;
            } else {
                e->prev = d->prev;
                e->prev->next = e;
            }
            d->list = NULL;
            if (list->cur == d)
                list->cur = NULL;
            list->length--;
            slice->length--;
            // the callback got the value and will take care of releasing it
            destroy_entry(d);
            if (rc == -2) // -2 means : remove and stop the iteration
                break;
            // -1 instead means that we still want to remove the item
            // but we also want to go ahead with the iteration
        } else {
            e = e->next;
        }
    }
    MUTEX_UNLOCK(list->lock);
    return idx;
}
示例#2
0
文件: config.c 项目: fqxp/dvswitch
/* Read configuration file.  Exit if it is unreadable or invalid.
 * The configuration format consists of Bourne shell variable assignments
 * and comments, with no variable references or escaped line breaks
 * allowed.
 */
static void read_config(const char * path,
			void (*item_handler)(const char *, const char *))
{
    FILE * file;
    unsigned line_no = 0;
    char line_buf[1000]; /* this is just going to have to be long enough */

    if ((file = fopen(path, "r")) == NULL)
    {
	/* Configuration files are optional so this is only an error if
	 * the file exists yet is unreadable.
	 */
	if (errno == ENOENT)
	    return;
	perror("ERROR: fopen");
	exit(1);
    }

    while (fgets(line_buf, sizeof(line_buf), file))
    {
	const char * name, * value;
	char * p;
	int ch;
	bool valid = true;

	++line_no;

	/* Find first non-space. */
	p = line_buf;
	while ((ch = (unsigned char)*p) && isspace(ch))
	    ++p;

	if (ch == 0 || ch == '#')
	{
	    /* This is a blank or comment line. */
	    continue;
	}
	else if (isalpha(ch) || ch == '_')
	{
	    /* Find end of name. */
	    name = p++;
	    while ((ch = (unsigned char)*p) && (isalnum(ch) || ch == '_'))
		++p;
	    *p = 0; /* ensure name is terminated */

	    if (ch != '=')
	    {
		valid = false;
	    }
	    else
	    {
		char * out;

		++p;
		value = out = p;

		while ((ch = (unsigned char)*p) && !isspace(ch))
		{
		    int quote = (ch == '\'' || ch == '"') ? ch : 0;

		    if (quote)
			++p;

		    while ((ch = (unsigned char)*p)
			   && !(quote ? ch == quote
				: (isspace(ch) || ch == '\'' || ch == '"')))
		    {
			++p;
			if (quote != '\'')
			{
			    if (ch == '$')
			    {
				/* We're not going to do $-expansion. */
				valid = false;
			    }
			    else if (ch == '\\')
			    {
				/* Check whether it's a valid escape. */
				ch = (unsigned char)*p;
				switch (ch)
				{
				case '$':
				case '\'':
				case '\"':
				case '\\':
				    ++p;
				    break;
				case ' ':
				    if (quote)
					valid = false;
				    else
					++p;
				    break;
				default:
				    valid = false;
				    break;
				}
			    }
			}
			*out++ = ch;
		    }

		    if (quote && ch)
			++p;
		}

		while ((ch = (unsigned char)*p) && isspace(ch) && ch != '\n')
		    ++p;
		if (ch != '\n')
		    valid = false; /* new-line was quoted or missing */

		*out = 0; /* terminate value */
	    }
	}
	else
	{
	    valid = false;
	}

	if (valid)
	{
	    item_handler(name, value);
	}
	else
	{
	    /* XXX This could be more informative! */
	    fprintf(stderr, "ERROR: syntax error at %s:%d\n", path, line_no);
	    exit(2);
	}
    }

    fclose(file);
}