Beispiel #1
0
static int get_next_part(char** s, char** part, char delim, int read_only) {
	char *c, *c2;
	char flag = 0;

	c = c2 = *s;
	eat_spaces(c);

	while (!(((*c2 == delim) && !flag) || *c2==0)) {
		if (*c2=='\'')
			flag = !flag;
		c2++;
	}
	if ((*c2)==0 && flag) {
		ERR(MODULE_NAME": string '%s' is not terminated\n", *s);
		return E_CFG;
	}
	if (*c2) {
		if (!read_only) *c2 = 0;
		*s = c2+1;
	}
	else {
		*s = c2;
	}
	eat_spaces(*s);
	c2--;
	/* rtrim */
	while ( c2 > c && ((*c2 == ' ')||(*c2 == '\t')) ) {
		if (!read_only) *c2 = 0;
		c2--;
	}
	*part = c;
	return 0;
}
/* Syntax: array ( type, N|argN ) */
static int
parse_array(struct protolib *plib, struct locus *loc,
	    char **str, struct arg_type_info *info)
{
	eat_spaces(str);
	if (parse_char(loc, str, '(') < 0)
		return -1;

	eat_spaces(str);
	int own;
	struct arg_type_info *elt_info
		= parse_lens(plib, loc, str, NULL, 0, &own, NULL);
	if (elt_info == NULL)
		return -1;

	eat_spaces(str);
	parse_char(loc, str, ',');

	eat_spaces(str);
	int own_length;
	struct expr_node *length = parse_argnum(loc, str, &own_length, 0);
	if (length == NULL) {
		if (own) {
			type_destroy(elt_info);
			free(elt_info);
		}
		return -1;
	}

	type_init_array(info, elt_info, own, length, own_length);

	eat_spaces(str);
	parse_char(loc, str, ')');
	return 0;
}
static struct arg_type_info *
parse_lens(struct protolib *plib, struct locus *loc,
	   char **str, struct param **extra_param,
	   size_t param_num, int *ownp, int *forwardp)
{
	int own_lens;
	struct lens *lens = name2lens(str, &own_lens);
	int has_args = 1;
	struct arg_type_info *info;
	if (lens != NULL) {
		eat_spaces(str);

		/* Octal lens gets special treatment, because of
		 * backward compatibility.  */
		if (lens == &octal_lens && **str != '(') {
			has_args = 0;
			info = type_get_simple(ARGTYPE_INT);
			*ownp = 0;
		} else if (parse_char(loc, str, '(') < 0) {
			report_error(loc->filename, loc->line_no,
				     "expected type argument after the lens");
			return NULL;
		}
	}

	if (has_args) {
		eat_spaces(str);
		info = parse_type(plib, loc, str, extra_param, param_num,
				  ownp, forwardp);
		if (info == NULL) {
		fail:
			if (own_lens && lens != NULL)
				lens_destroy(lens);
			return NULL;
		}
	}

	if (lens != NULL && has_args) {
		eat_spaces(str);
		parse_char(loc, str, ')');
	}

	/* We can't modify shared types.  Make a copy if we have a
	 * lens.  */
	if (lens != NULL && unshare_type_info(loc, &info, ownp) < 0)
		goto fail;

	if (lens != NULL) {
		info->lens = lens;
		info->own_lens = own_lens;
	}

	return info;
}
/* Syntax: struct ( type,type,type,... ) */
static int
parse_struct(struct protolib *plib, struct locus *loc,
	     char **str, struct arg_type_info *info,
	     int *forwardp)
{
	eat_spaces(str);

	if (**str == ';') {
		if (forwardp == NULL) {
			report_error(loc->filename, loc->line_no,
				     "Forward struct can be declared only "
				     "directly after a typedef.");
			return -1;
		}

		/* Forward declaration is currently handled as an
		 * empty struct.  */
		type_init_struct(info);
		*forwardp = 1;
		return 0;
	}

	if (parse_char(loc, str, '(') < 0)
		return -1;

	eat_spaces(str); // Empty arg list with whitespace inside

	type_init_struct(info);

	while (1) {
		eat_spaces(str);
		if (**str == 0 || **str == ')') {
			parse_char(loc, str, ')');
			return 0;
		}

		/* Field delimiter.  */
		if (type_struct_size(info) > 0)
			parse_char(loc, str, ',');

		eat_spaces(str);
		int own;
		struct arg_type_info *field
			= parse_lens(plib, loc, str, NULL, 0, &own, NULL);
		if (field == NULL || type_struct_add(info, field, own)) {
			type_destroy(info);
			return -1;
		}
	}
}
static struct expr_node *
parse_zero(struct locus *loc, char **str, int *ownp)
{
	eat_spaces(str);
	if (**str == '(') {
		++*str;
		int own;
		struct expr_node *arg = parse_argnum(loc, str, &own, 0);
		if (arg == NULL)
			return NULL;
		if (parse_char(loc, str, ')') < 0) {
		fail:
			expr_destroy(arg);
			free(arg);
			return NULL;
		}

		struct expr_node *ret = build_zero_w_arg(arg, own);
		if (ret == NULL)
			goto fail;
		*ownp = 1;
		return ret;

	} else {
		*ownp = 0;
		return expr_node_zero();
	}
}
Beispiel #6
0
void TsvFile::read_file (const std::string &filename) {
    std::ifstream is (filename.c_str ());
    if (!is)
        throw unreadable_file (filename);
    // iostreams exceptions just suck.
    //is.exceptions (std::ios::badbit);
    std::vector <double> line;
    for (;;) {
        eat_spaces (is);
        int pk = is.peek ();
        switch (pk) {
        case '\n':
            is.get ();
            if (line.size ()) {
                my_data.push_back (line);
                line.clear ();
            }
            continue;
        case EOF:
            if (line.size ()) {
                my_data.push_back (line);
                line.clear ();
            }
            return;
        case '#':
            eat_line (is);
            continue;
        default:
            double tmp;
            is >> tmp;
            line.push_back (tmp);
        }
    }
}
static struct arg_type_info *
parse_type(struct protolib *plib, struct locus *loc, char **str,
	   struct param **extra_param, size_t param_num,
	   int *ownp, int *forwardp)
{
	struct arg_type_info *info
		= parse_nonpointer_type(plib, loc, str, extra_param,
					param_num, ownp, forwardp);
	if (info == NULL)
		return NULL;

	while (1) {
		eat_spaces(str);
		if (**str == '*') {
			struct arg_type_info *outer = malloc(sizeof(*outer));
			if (outer == NULL) {
				if (*ownp) {
					type_destroy(info);
					free(info);
				}
				report_error(loc->filename, loc->line_no,
					     "malloc: %s", strerror(errno));
				return NULL;
			}
			type_init_pointer(outer, info, *ownp);
			*ownp = 1;
			(*str)++;
			info = outer;
		} else
			break;
	}
	return info;
}
Beispiel #8
0
static int dbops_fixup_func(void** param, int init_act) {
	struct dbops_action **p, *a;
	char *c;
	int res;

	/* check if is it a declare_no that references to declare_xxxx */
	c = *param;
	eat_spaces(c);
	*param = c;
	eat_alphanum(c);
	if (*c == 0) {
		a = find_action_by_name(*param, -1);
		if (!a) {
			ERR(MODULE_NAME": fixup_func: query (%s) not declared\n", (char*) *param);
			return -1;
		}
		*param = (void*) a;
		return 0;
	}

	for (p = &dbops_actions; *p; p=&(*p)->next);	/* add at the end of list */
	res = parse_ops(*param, p, init_act == 0 /* declare query has name */);
	if (res < 0) return res;
	/* pkg_free(*param); do not free it!*/
	*param = (void*) *p;
	if (init_act)
		return init_action(*p);   /* fixup is acquired after init_mod() therefore initialize new action */
	else
		return 0;
}
Beispiel #9
0
static char *
get_last_field (char *line)
{
   int i;
   char *field;
   int n = 6;

   n--;
   field = eat_spaces (line);
   for (i = 0; i < n; i++) {
      field = strchr (field, ' ');
      field = eat_spaces (field);
   }

   return field;
}
Beispiel #10
0
static void
list__process_line (char     *line,
		    gpointer  data)
{
	FileData      *fdata;
	FrCommand     *comm = FR_COMMAND (data);
	FrCommandIso  *comm_iso = FR_COMMAND_ISO (comm);
	char         **fields;
	const char    *name_field;

	g_return_if_fail (line != NULL);

	if (line[0] == 'd') /* Ignore directories. */
		return;

	if (line[0] == 'D') {
		g_free (comm_iso->cur_path);
		comm_iso->cur_path = g_strdup (get_last_field (line, 4));

	} else if (line[0] == '-') { /* Is file */
		const char *last_field, *first_bracket;

		fdata = file_data_new ();

		fields = split_line (line, 8);
		fdata->size = g_ascii_strtoull (fields[4], NULL, 10);
		fdata->modified = mktime_from_string (fields[5], fields[6], fields[7]);
		g_strfreev (fields);

		/* Full path */

		last_field = get_last_field (line, 9);
		first_bracket = strchr (last_field, ']');
		if (first_bracket == NULL) {
			file_data_free (fdata);
			return;
		}

		name_field = eat_spaces (first_bracket + 1);
		if ((name_field == NULL)
		    || (strcmp (name_field, ".") == 0)
		    || (strcmp (name_field, "..") == 0)) {
			file_data_free (fdata);
			return;
		}

		if (comm_iso->cur_path[0] != '/')
			fdata->full_path = g_strstrip (g_strconcat ("/", comm_iso->cur_path, name_field, NULL));
		else
			fdata->full_path = g_strstrip (g_strconcat (comm_iso->cur_path, name_field, NULL));
		fdata->original_path = fdata->full_path;
		fdata->name = g_strdup (file_name_from_path (fdata->full_path));
		fdata->path = remove_level_from_path (fdata->full_path);

		fr_command_add_file (comm, fdata);
	}
}
Beispiel #11
0
static int get_next_part(char** s, str* part, char delim) {
	char *c, *c2;
	c = c2 = *s;
	eat_spaces(c);
	while (*c2!=delim && *c2!=0) c2++;

	if (*c2) {
		*s = c2+1;
	}
	else {
		*s = c2;
	}
	eat_spaces(*s);
	c2--;
	/* rtrim */
	while ( c2 >= c && ((*c2 == ' ')||(*c2 == '\t')) ) c2--;
	part->s = c;
	part->len = c2-c+1;
	return part->len;
}
Beispiel #12
0
int str_chk(char *string, int i)
{
  int j;
  
  i=eat_spaces(i);
  if (i<0) return -1;

  j=0;
  while (string[j] && i+j<BUF_LEN && buf[i+j]==string[j]) j++;
  if (string[j]=='\0') return i+j;
  if (i+j>=BUF_LEN) return -1;
  return -1;
}
Beispiel #13
0
static const char *
get_last_field_zoo (char *line)
{
	const char *field;
	int         i;
	int         n = 6;

	field = eat_spaces (line);
	for (i = 0; i < n; i++) {
		field = strchr (field, ' ');
		field = eat_spaces (field);
	}
	field = strchr (field, ' ');
	if (g_ascii_strncasecmp (field, " C ", 3) == 0) {
		field = eat_spaces (field);
		field = strchr (field, ' ');
		field = eat_spaces (field);
	} else
		field = eat_spaces (field);

	return field;
}
Beispiel #14
0
char *get_id(int i)
{
  int j;

  i=eat_spaces(i);
  if (i<0) return 0;

  j=0;
  while ( i+j<BUF_LEN && buf[i+j] ) {
	if (!isgraph(buf[i+j])) break;
	idbuf[j]=buf[i+j]; j++; }

  idbuf[j]='\0';
  return idbuf;  
}
Beispiel #15
0
static const char *
get_last_field_lha (char *line)
{
	int         i;
	const char *field;
	int         n = 7;

	if (strncmp (line, "[MS-DOS]", 8) == 0)
		n--;

	if (strncmp (line, "[generic]", 9) == 0)
		n--;

	if (strncmp (line, "[unknown]", 9) == 0)
		n--;

	field = eat_spaces (line);
	for (i = 0; i < n; i++) {
		field = strchr (field, ' ');
		field = eat_spaces (field);
	}

	return field;
}
Beispiel #16
0
/*
 * parse scanf format string 
 */
int
__scanf(const char *input, FILE *stream, bool stream_or_memory,
                                       const char *fmt, va_list ap)
{
    unsigned int assign_count = 0;
    va_list ap_copy, ap_tmp;
    int width, base = 0;
    char *p, *s;
    long long num_res = 0;
    unsigned long long num_ures = 0;
    bool num_unsigned = false;
    bool suppress = false;
    bool use_width = false;
    bool using_nth = false;
    /* length modifiers */
    bool lm_h, lm_hh, lm_l, lm_ll, lm_j, lm_z, lm_t, lm_L;
    int arg_nth = 0;
    int i = 0;
    bool list_not;
    char *list_start, *list_end;
    unsigned char *user_us;
    unsigned long *user_ul;
    unsigned long long *user_ull;
    unsigned short *user_ush;
    unsigned int *user_ui;
    uintmax_t *user_uj;
    char *user_s = NULL;
    long *user_l;
    long long *user_ll;
    short *user_sh;
    int *user_i;
    intmax_t *user_j;
    size_t *user_z;
    ptrdiff_t *user_t;
    void **user_pp;
#ifndef CONFIG_WITHOUT_FLOATING
#ifndef CONFIG_WITHOUT_LONG_DOUBLE
    long double *user_ld;
#endif /* CONFIG_WITHOUT_LONG_DOUBLE */
    double *user_d;
    float *user_f;
#endif /* CONFIG_WITHOUT_FLOATING */
    struct st_mem_stream mem_stream;
    mem_stream.stream_or_memory = stream_or_memory;
    mem_stream.mem = (char**)&input;
    mem_stream.stream = stream;
    mem_stream.last_stream_char = '\0';
    mem_stream.read_bytes = 0;

    __va_copy(ap_copy, ap);

    if (stream != NULL)
        lock_stream(stream);

    for (p = (char*)fmt; *p != '\0'; p++) {
        use_width = false;
        width = 1;
        num_unsigned = false;
        suppress = false;
        num_res = 0;
        num_ures = 0;
        lm_h = false;
        lm_hh = false;
        lm_l = false;
        lm_ll = false;
        lm_j = false;
        lm_z = false;
        lm_t = false;
        lm_L = false;
        if (*p != '%') {
char_comp:
            s = __get_next_char(&mem_stream);
            if (__is_eof(s)) {
                goto eof_failure;
            }
            if (isspace(*p)) {
                while (isspace(*s)) {
                    __inc_next_char(&mem_stream);
                    s = __get_next_char(&mem_stream);
                    if (__is_eof(s)) {
                        goto eof_failure;
                    }
                }
            } else {
                if (*p == *s) {
                    __inc_next_char(&mem_stream);
                } else {
                    goto matching_failure;
                }
            }
            continue;
        }
        /* *p == '%' */
again_inc:
        p++;
again:
        switch(*p) {
        case '%':
            goto char_comp;
            break;
        case '*':
            suppress = true;
            goto again_inc;
        case '0':
        case '1':
        case '2':
        case '3':
        case '4':
        case '5':
        case '6':
        case '7':
        case '8':
        case '9':
            i = *p - '0';
            for (p++; p && (unsigned int)(*p - '0') < 10; p++) {
                i = i * 10 + (*p - '0');
            }
            if (*p == '$') {
                using_nth = true;
                if (i == 0) {
                    goto matching_failure;
                } else {
                    arg_nth = i;
                }
                p++;
            } else {
                width = i;
                if (width != 0) {
                    use_width = true;
                }
            }
            goto again;
        /* Length modifiers */
        case 'h':
            if (lm_h) {
                lm_hh = true;
                lm_h = false;
            } else {
                lm_h = true;
            }
            goto again_inc;
        case 'l':
            if (lm_l) {
                lm_ll = true;
                lm_l = false;
            } else {
                lm_l = true;
            }
            goto again_inc;
        case 'j':
            lm_j = true;
            goto again_inc;
        case 'z':
            lm_z = true;
            goto again_inc;
        case 't':
            lm_t = true;
            goto again_inc;
#ifndef CONFIG_WITHOUT_LONG_DOUBLE
        case 'L':
            lm_L = true;
            goto again_inc;
#endif /* CONFIG_WITHOUT_LONG_DOUBLE */
        /* Numbers */
        case 'd':
            base = 10;
            goto number;
        case 'i':
            base = 0;
            goto number;
        case 'o':
            base = 8;
            num_unsigned = true;
            goto number;
        case 'u':
            base = 10;
            num_unsigned = true;
            goto number;
        case 'x':
        case 'X':
            base = 16;
            num_unsigned = true;
number:
            eat_spaces(&mem_stream);
            if (!use_width) {
                width = 0;
            }
    
            errno = 0; /* Check for strto* errors */
            if (suppress) {
                (void)__strtoll(NULL, base, width, get_next_char, inc_next_char,
                                                    (void*)&mem_stream);
            } else {
                if (num_unsigned) {
                    uintmax_t num_tmp;

                    errno = 0;
                    num_tmp = __strtoull(NULL, base, width, get_next_char,
                                               inc_next_char, (void*)&mem_stream);

                    if(errno == EINVAL) {
                        goto matching_failure;
                    }

                    assign_count++;

                    if (lm_ll) {
                        GET_ARG(user_ull, unsigned long long*);
                        *user_ull = (unsigned long long)num_tmp;
                    } else if (lm_l) {
                        GET_ARG(user_ul, unsigned long*);
                        *user_ul = (unsigned long)num_tmp;
                    } else if (lm_hh) {
                        GET_ARG(user_us, unsigned char*);
                        *user_us = (unsigned char)num_tmp;
                    } else if (lm_h) {
                        GET_ARG(user_ush, unsigned short*);
                        *user_ush = (unsigned short)num_tmp;
                    } else if (lm_j) {
                        GET_ARG(user_uj, uintmax_t*);
                        *user_uj = (uintmax_t)num_tmp;
                    } else if (lm_z) {
                        GET_ARG(user_z, size_t*);
                        *user_z = (size_t)num_tmp;
                    } else if (lm_t) {
                        GET_ARG(user_t, ptrdiff_t*);
                        *user_t = (unsigned long)num_tmp;
                    } else {
                        GET_ARG(user_ui, unsigned int*);
                        *user_ui = (unsigned int)num_tmp;
                    }
                } else {
                    intmax_t num_tmp;

                    errno = 0;
                    num_tmp = __strtoll(NULL, base, width, get_next_char,
                                               inc_next_char, (void*)&mem_stream);

                    if(errno == EINVAL) {
                        goto matching_failure;
                    }

                    assign_count++;

                    if (lm_ll) {
                        GET_ARG(user_ll, long long*);
                        *user_ll = (long long)num_tmp;
                    } else if (lm_l) {
                        GET_ARG(user_l, long*);
                        *user_l = (long int)num_tmp;
                    } else if (lm_hh) {
                        GET_ARG(user_s, char*);
                        *user_s = (char)num_tmp;
                    } else if (lm_h) {
                        GET_ARG(user_sh, short*);
                        *user_sh = (short)num_tmp;
                    } else if (lm_j) {
                        GET_ARG(user_j, intmax_t*);
                        *user_j = (intmax_t)num_tmp;
                    } else if (lm_z) {
                        GET_ARG(user_z, size_t*);
                        *user_z = (signed long)num_tmp;
                    } else if (lm_t) {
                        GET_ARG(user_t, ptrdiff_t*);
                        *user_t = (ptrdiff_t)num_tmp;
                    } else {
                        GET_ARG(user_i, int*);
                        *user_i = (int)num_tmp;
                    }
                }
            }
            /*
            if (errno == EINVAL) {
                goto matching_failure;
            }
            */
            break;
#ifndef CONFIG_WITHOUT_FLOATING
        case 'A':
        case 'a':
        case 'E':
        case 'e':
        case 'F':
        case 'f':
        case 'G':
        case 'g':
            eat_spaces(&mem_stream);
            if (!use_width) {
                width = 0;
            }

            s = __get_next_char(&mem_stream);
            if (__is_eof(s)) {
                goto eof_failure;
            }
            if (*s == 'i' || *s == 'I') {
                if (!eat_infinity(&mem_stream)) {
                    s = __get_next_char(&mem_stream);
                    if (*s == '\0') {
                        goto input_failure;
                    } else {
                        goto matching_failure;
                    }
                }
                /*
                if (!suppress) {
                    assign_count++;
                    if (lm_l) {
                        GET_ARG(user_d, double*);
                        *user_d = INFINITY;
#ifndef CONFIG_WITHOUT_LONG_DOUBLE
                    } else if (lm_L) {
                        GET_ARG(user_ld, long double*);
                        *user_ld = INFINITY;
#endif
                    } else {
                        GET_ARG(user_f, float*);
                        *user_f = INFINITY;
                    }
                }
                */
            } else if (*s == 'n' || *s == 'N') {
                if (!eat_nan(&mem_stream)) {
                    goto matching_failure;
                }
                /*
                if (!suppress) {
                    assign_count++;
                    if (lm_l) {
                        GET_ARG(user_d, double*);
                        *user_d = NAN;
#ifndef CONFIG_WITHOUT_LONG_DOUBLE
                    } else if (lm_L) {
                        GET_ARG(user_ld, long double*);
                        *user_ld = NAN;
#endif
                    } else {
                        GET_ARG(user_f, float*);
                        *user_f = NAN;
                    }
                }
                */
            } else {
                if (suppress) {
                    (void)__strtold(NULL, width, get_next_char, inc_next_char,
                                                    (void*)&mem_stream);
                } else {
                    assign_count++;
                    if (lm_l) {
                        GET_ARG(user_d, double*);
                        *user_d = (double)__strtold(NULL, width, get_next_char,
                                        inc_next_char, (void*)&mem_stream);
#ifndef CONFIG_WITHOUT_LONG_DOUBLE
                    } else if (lm_L) {
                        GET_ARG(user_ld, long double*);
                        *user_ld = (long double)__strtold(NULL, width,
                                                          get_next_char,
                                                          inc_next_char,
                                                          (void*)&mem_stream);
#endif /* CONFIG_WITHOUT_LONG_DOUBLE */
                    } else {
                        GET_ARG(user_f, float*);
                        *user_f = (float)__strtold(NULL, width, get_next_char,
                                        inc_next_char, (void*)&mem_stream);
                    }
                }
            }
            break;
#endif /* CONFIG_WITHOUT_FLOATING */
        case 'S':
            lm_l = true;
        case 's':
            eat_spaces(&mem_stream);
            if (!suppress) {
                GET_ARG(user_s, char*);
                i = 0;
            }
            s = __get_next_char(&mem_stream);
            if (__is_eof(s)) {
                goto eof_failure;
            }
            while (s != NULL && *s != '\0' && !isspace(*s)) {
                if (use_width) {
                    if (width > 0) {
                        width--;
                    } else {
                        break;
                    }
                }
                if (!suppress) {
                    user_s[i] = *s;
                    i++;
                }
                __inc_next_char(&mem_stream);
                s = __get_next_char(&mem_stream);
            }
            if (!suppress) {
                assign_count++;
                user_s[i] = '\0';
            }
            break;
        case '[':
            list_not = false;
            p++;
            if (*p == '^') {
                list_not = true;
                p++;
            }
            if (*p == '\0') {
                goto matching_failure;
            }
            list_start = p;
            p++;
            while (*p != ']') {
                if (*p == '\0') {
                    goto matching_failure;
                }
                p++;
            }
            list_end = p;

            if (!suppress) {
                GET_ARG(user_s, char*);
                i = 0;
            }
            s = __get_next_char(&mem_stream);
            if (__is_eof(s)) {
                goto eof_failure;
            }
            while (s != NULL && *s != '\0' &&
                        check_list(*s, list_start, list_end, list_not)) {
                if (use_width) {
                    if (width > 0) {
                        width--;
                    } else {
                        break;
                    }
                }
                if (!suppress) {
                    user_s[i] = *s;
                    i++;
                }
                __inc_next_char(&mem_stream);
                s = __get_next_char(&mem_stream);
            }
            if (!suppress) {
                assign_count++;
                user_s[i] = '\0';
            }
            break;
        case 'C':
            lm_l = true;
        case 'c':
            use_width = true;
            if (!suppress) {
                GET_ARG(user_s, char*);
                i = 0;
            }
            s = __get_next_char(&mem_stream);
            if (__is_eof(s)) {
                goto eof_failure;
            }
            for (; width > 0 && s != NULL && *s != '\0'; width--) {
                if (!suppress) {
                    user_s[i] = *s;
                    i++;
                }
                __inc_next_char(&mem_stream);
                s = __get_next_char(&mem_stream);
            }
            if (__is_eof(s) && width > 0) {
                goto eof_failure;
            }
            if (!suppress) {
                assign_count++;
                user_s[i] = '\0';
            }
            break;
        case 'p':
            eat_spaces(&mem_stream);
            if (!use_width) {
                width = 0;
            } else if (width < 2) {
                goto matching_failure;
            }
            s = __get_next_char(&mem_stream);
            if (__is_eof(s)) {
                goto eof_failure;
            }
            if (*s != '0') {
                goto matching_failure;
            }
            __inc_next_char(&mem_stream);
            s = __get_next_char(&mem_stream);
            if (__is_eof(s)) {
                goto eof_failure;
            }
            if (*s != 'x' && *s != 'X') {
                goto matching_failure;
            }
            __inc_next_char(&mem_stream);
            width -= 2;
            if (suppress) {
                (void)__strtoll(NULL, 16, width, get_next_char, inc_next_char,
                                                    (void*)&mem_stream);
            } else {
                assign_count++;
                GET_ARG(user_pp, void**);
                *user_pp = (void*)(long)__strtoll(NULL, 16, width, get_next_char,
                                    inc_next_char, (void*)&mem_stream);
            }
            break;
        case 'n':
            if (lm_ll) {
                GET_ARG(user_ll, long long*);
                *user_ll = (long long)mem_stream.read_bytes;
            } else if (lm_l) {
                GET_ARG(user_l, long*);
                *user_l = (long)mem_stream.read_bytes;
            } else if (lm_hh) {
                GET_ARG(user_s, char*);
                *user_s = (char)mem_stream.read_bytes;
            } else if (lm_h) {
                GET_ARG(user_sh, short*);
                *user_sh = (short)mem_stream.read_bytes;
            } else if (lm_j) {
                GET_ARG(user_j, intmax_t*);
                *user_j = (intmax_t)mem_stream.read_bytes;
            } else if (lm_z) {
                GET_ARG(user_i, int*);
                *user_i = (int)mem_stream.read_bytes;
            } else if (lm_t) {
                GET_ARG(user_t, ptrdiff_t*);
                *user_t = (ptrdiff_t)mem_stream.read_bytes;
            } else {
                GET_ARG(user_i, int*);
                *user_i = (int)mem_stream.read_bytes;
            }
            break;
        default:
            if (*p == '\0') {
                break;
            }
        }
    }

matching_failure:
    if (stream != NULL) {
        unlock_stream(stream);
    }

    return assign_count;
    /* XXX: va_end */

input_failure:
    if (stream != NULL) {
        unlock_stream(stream);
    }
    return EOF;

eof_failure:
    if (assign_count > 0) {
        goto matching_failure;
    } else {
        goto input_failure;
    }

}
Beispiel #17
0
/* parse:  hname [ ([] | [*] | [number]) ] [ "." param ] */
static int fixup_hname_param(char *hname, struct hname_data** h) {
	struct hdr_field hdr;
	char *savep, savec;

	*h = pkg_malloc(sizeof(**h));
	if (!*h) return E_OUT_OF_MEM;
	memset(*h, 0, sizeof(**h));

	memset(&hdr, 0, sizeof(hdr));
	eat_spaces(hname);
	(*h)->hname.s = hname;
	savep = hname;
	eat_while_alphanum(hname);
	(*h)->hname.len = hname - (*h)->hname.s;
	savec = *hname;
	*hname = ':';
	parse_hname2((*h)->hname.s, (*h)->hname.s+(*h)->hname.len+3, &hdr);
	*hname = savec;

	if (hdr.type == HDR_ERROR_T) goto err;
	(*h)->htype = hdr.type;

	eat_spaces(hname);
	savep = hname;
	if (*hname == '[') {
		hname++;
		eat_spaces(hname);
		savep = hname;
		(*h)->flags |= HNF_IDX;
		if (*hname == '*') {
			(*h)->flags |= HNF_ALL;
			hname++;
		}
		else if (*hname != ']') {
			char* c;
			(*h)->idx = strtol(hname, &c, 10);
			if (hname == c) goto err;
			hname = c;
		}
		eat_spaces(hname);
		savep = hname;
		if (*hname != ']') goto err;
		hname++;
	}
	eat_spaces(hname);
	savep = hname;
	if (*hname == '.') {
		hname++;
		eat_spaces(hname);
		savep = hname;
		(*h)->param.s = hname;
		eat_while_alphanum(hname);
		(*h)->param.len = hname-(*h)->param.s;
		if ((*h)->param.len == 0) goto err;
	}
	else {
		(*h)->param.s = hname;
	}
	savep = hname;
	if (*hname != '\0') goto err;
	(*h)->hname.s[(*h)->hname.len] = '\0';
	(*h)->param.s[(*h)->param.len] = '\0';
	return 0;
err:
	pkg_free(*h);
	LOG(L_ERR, "ERROR: textops: cannot parse header near '%s'\n", savep);
	return E_CFG;
}
Beispiel #18
0
static int parse_ops(char* act_s, struct dbops_action** action, int has_name) {
	int res = 0, i;
	char *c, *s, *part;
	static int query_no = 0;

	s = act_s;
	*action = pkg_malloc(sizeof(**action));
	if (!*action) return E_OUT_OF_MEM;
	memset(*action, 0, sizeof(**action));
	(*action)->query_no = query_no++;

	eat_spaces(s);
	c = s;
	eat_alphanum(c);
	if (has_name) {
		char *c2;
		c2 = c;
		eat_spaces(c2);
		if (c != s && *c2 == '=') {
			*c = '\0';
			if (find_action_by_name(s, -1) != NULL) {
				ERR(MODULE_NAME": parse_ops: duplicate query name: %s\n", s);
				return E_CFG;
			}		
			(*action)->query_name = s;
			s = c2+1;
			eat_spaces(s);
			c = s;
			eat_alphanum(c);
		}
		else {
			ERR(MODULE_NAME": parse_ops: query_no: %d, valid query name not found in '%s'\n%s\n%s\n", (*action)->query_no, s, c, c2);
			return E_CFG;
		}
	}

	if (c[0] == ':' && c[1] == '/' && c[2] == '/') { /* database part is optional */
		for (c=s; *c!=':'; c++) {
			*c = tolower(*c);                       /* _type_://user:host/database_name/ */
		}
		(*action)->db_url = s;
		s = c+1;
		while (*s == '/') s++;
		res = get_next_part(&s, &part, PART_DELIM, 1);  /* type://_user:host_/database_name/ */
		if (res < 0) return res;


		res = get_next_part(&s, &part, PART_DELIM, 0);  /* type://user:host/_database_name_/ */
		if (res < 0) return res;
	}
	res = get_next_part(&s, &part, PART_DELIM, 0);
	if (res < 0) return res;

	for (c = part; *c && *c != PART_DELIM; c++) {
		if (*c == ' ') {
			(*action)->is_raw_query = 1;
			*c = '\0';
			break;
		}
	}
	if (strcasecmp(part, "select") == 0)
		(*action)->operation = OPEN_QUERY_OPS;
	else if (strcasecmp(part, "insert") == 0)
		(*action)->operation = INSERT_OPS;
	else if (strcasecmp(part, "update") == 0)
		(*action)->operation = UPDATE_OPS;
	else if (strcasecmp(part, "replace") == 0)
		(*action)->operation = REPLACE_OPS;
	else if (strcasecmp(part, "delete") == 0)
		(*action)->operation = DELETE_OPS;
	else {
		if ((*action)->is_raw_query) *c = ' ';
		ERR(MODULE_NAME": parse_ops: query: %s(%d), unknown type of query '%s'\n", (*action)->query_name, (*action)->query_no, part);
		return E_CFG;
	}
	if ((*action)->is_raw_query) {
		*c = ' ';
		(*action)->raw.s = part;
		(*action)->table.s = part;
	}

	res = get_next_part(&s, &part, PART_DELIM, 0);
	if (res < 0) return res;
	if (!(*action)->is_raw_query) {

		if (!*part) {
			ERR(MODULE_NAME": parse_ops: query: %s(%d), table not specified near '%s' in '%s'\n", (*action)->query_name, (*action)->query_no, s, act_s);
			return E_CFG;
		}
		trim_apostr(&part);
		(*action)->table.s = part;

		res = get_next_part(&s, &part, PART_DELIM, 0);
		if (res < 0) return res;
		switch ((*action)->operation) {
			case OPEN_QUERY_OPS:
			case UPDATE_OPS:
			case REPLACE_OPS:
			case INSERT_OPS:
				res = split_fields(part, &(*action)->field_count, &(*action)->fields);
				if (res < 0) return res;
				if ((*action)->field_count == 0) {
					ERR(MODULE_NAME": parse_ops: query: %s(%d), no field specified near '%s' ?n '%s'\n", (*action)->query_name, (*action)->query_no, part, act_s);
					return E_CFG;
				}
				break;
			case DELETE_OPS:
				res = split_fields(part, &(*action)->where_count, &(*action)->wheres);
				if (res < 0) return res;
				res = get_next_part(&s, &part, PART_DELIM, 0);
				if (res < 0) return res;
				res = split_fields(part, &(*action)->op_count, &(*action)->ops);
				if (res < 0) return res;
				break;
			default:;
		}

		res = get_next_part(&s, &part, PART_DELIM, 0);
		if (res < 0) return res;
		switch ((*action)->operation) {
			case OPEN_QUERY_OPS:
			case UPDATE_OPS:
				res = split_fields(part, &(*action)->where_count, &(*action)->wheres);
				if (res < 0) return res;
				res = get_next_part(&s, &part, PART_DELIM, 0);
				if (res < 0) return res;
				res = split_fields(part, &(*action)->op_count, &(*action)->ops);
				if (res < 0) return res;
				res = get_next_part(&s, &part, PART_DELIM, 0);
				if (res < 0) return res;
				switch ((*action)->operation) {
					case OPEN_QUERY_OPS:
						if (*part) {
							(*action)->order.s = part;
						}
						res = get_next_part(&s, &part, PART_DELIM, 0);
						if (res < 0) return res;
						break;
					default:;
				}
				break;
			default:
				;
		}
	}

	/* values */
	res = split_fields(part, &(*action)->value_count, &(*action)->values);
	if (res < 0) return res;

	if ((*action)->value_count) {
		(*action)->value_types = (int*)pkg_malloc(sizeof(int) * (*action)->value_count);
		if ((*action)->value_types == NULL) {
			ERR(MODULE_NAME": No memory left\n");
			return -1;
		}

		for (i=0; i<(*action)->value_count; i++) {
			(*action)->value_types[i] = DB_CSTR; // DB_NONE; /* let decide db driver itself, FIXME: until jjanak changes then default type is string */
			res = get_type(&(*action)->values[i].s, &(*action)->value_types[i]);
			if (res < 0) return res;
		}
	}

	/* extra options */
	res = get_next_part(&s, &part, PART_DELIM, 0);
	if (res < 0) return res;

	(*action)->extra_ops_count = 0;
	c = part;
	while (*c) {
		char *fld;
		res = get_next_part(&c, &fld, FLD_DELIM, 1);
		if (res < 0) return res;
		(*action)->extra_ops_count++;
	}
	if ((*action)->extra_ops_count > 0) {
		(*action)->extra_ops = pkg_malloc( (*action)->extra_ops_count*sizeof(*(*action)->extra_ops));
		if (!(*action)->extra_ops) {
			ERR(MODULE_NAME": parse_ops: not enough pkg memory\n");
			return E_OUT_OF_MEM;
		}
		memset((*action)->extra_ops, 0, (*action)->extra_ops_count*sizeof(*(*action)->extra_ops));

		i = 0;
		c = part;
		while (*c) {
			char *fld;
			res = get_next_part(&c, &fld, FLD_DELIM, 0);
			if (res < 0) return res;
			/* name=[i|s]:value */
			(*action)->extra_ops[i].name = fld;
			eat_alphanum(fld);
			if (*fld != '=') {
				ERR(MODULE_NAME": parse_ops: query: %s(%d), bad extra parameter format in '%s'\n", (*action)->query_name, (*action)->query_no, (*action)->extra_ops[i].name);
				return E_CFG;
			}
			*fld = '\0';
			fld++;
			while (*fld==' ' || *fld=='\t') fld++;
			(*action)->extra_ops[i].type = DB_NONE;
			res = get_type(&fld, &(*action)->extra_ops[i].type);
			if (res < 0) return res;
			trim_apostr(&fld);
			(*action)->extra_ops[i].value = fld;
			DEBUG(MODULE_NAME": extra_ops #%d, name='%s', type=%d, val='%s'\n", i, (*action)->extra_ops[i].name, (*action)->extra_ops[i].type, (*action)->extra_ops[i].value);
			i++;
		}
	}

	if (*s) {
		ERR(MODULE_NAME": parse_ops: query: %s(%d), too many parameters/parts, remaining '%s' in '%s'\n", (*action)->query_name, (*action)->query_no, s, act_s);
		return E_CFG;
	}
	if ((*action)->is_raw_query) {
		DEBUG(MODULE_NAME": query: %s(%d) oper:%d database:'%s' query:'%s' value#:%d extra_ops#:%d\n", (*action)->query_name, (*action)->query_no, (*action)->operation, (*action)->db_url, (*action)->raw.s, (*action)->value_count, (*action)->extra_ops_count);
	}
	else {
		/* check num of fields */
		if ((((*action)->operation==OPEN_QUERY_OPS)?0:(*action)->field_count)+(*action)->where_count != (*action)->value_count) {
			ERR(MODULE_NAME": parse_ops: query: %s(%d), number of values does not correspond to number of fields (%d+%d!=%d) in '%s'\n", (*action)->query_name, (*action)->query_no, ((*action)->operation==OPEN_QUERY_OPS)?0:(*action)->field_count,  (*action)->where_count, (*action)->value_count, act_s);
			return E_CFG;
		}
		DEBUG(MODULE_NAME": query_no:%d oper:%d database:'%s' table:'%s' 'field#:'%d' where#:'%d' order:'%s' value#:%d extra_ops#:%d\n", (*action)->query_no, (*action)->operation, (*action)->db_url, (*action)->table.s, (*action)->field_count,  (*action)->where_count, (*action)->order.s, (*action)->value_count, (*action)->extra_ops_count);
	}
	return 0;
}
Beispiel #19
0
int
main(int argc, char ** argv)
{
  int anum;
  char *ctmp;
  int i;
  int flag;
  int state1;
  FILE *inf;
  struct dentry *etmp;
  struct dentry *eroot;
  struct dentry *elast;

  anum=1;
  state1=0;
  eroot=0;
  elast=0;
  etmp=0;

  while (anum<argc) {
#ifdef DEBUG
	printf("reading file %s\n",argv[anum]);
#endif
	inf=fopen(argv[anum],"r");
	if (!inf) {
	  printf("error opening file\n");
	  printf("warning: file \"%s\" skipped\n",argv[anum]);
	  continue; }

	while (fgets(buf,BUF_LEN,inf)) {

	  /* ignore empty lines */
	  if ((i=eat_spaces(0))<0) continue;

	  switch (state1) {
	  case 0: {
		/* wait for new function header */
		if ((i=str_chk(";;",i))<0) break;
		if ((i=str_chk("function:",i))>0) {
		  ctmp=get_id(i);
		  etmp=(struct dentry*) malloc(sizeof(struct dentry));
		  if (!etmp) {
			printf("out of memory\n");
			exit(1); }
		  etmp->function=str_dup(ctmp);
		  etmp->in_list=0;
		  etmp->out_list=0;
		  etmp->comment=0;
		  etmp->changes=0;
		  etmp->calls=0;
		  etmp->next=0;
		  state1=1;
		}
		break;
	  }
	  case 1: {
		/* read rest of function header */
		if ((i=str_chk(";;",i))<0) {
		  /* end of function header reached */
#ifdef DEBUG
		  printf("==> add function\n");
		  printf("    name    =%s\n",etmp->function);
/* 		  printf("    inputs  =%s\n",etmp->in_list); */
/* 		  printf("    outputs =%s\n",etmp->out_list); */
/* 		  printf("    comment =%s\n",etmp->comment); */
		  printf("    calls   =%s\n",etmp->calls);
		  printf("    changes =%s\n",etmp->changes);
#endif
		  if (elast) elast->next=etmp;
		  else eroot=etmp;
		  elast=etmp;
		  state1=0;
		}
		else {
		  int k;
		  if ((k=str_chk("<",i))>0) {
			/* add to in_list */
			ctmp=add_str(etmp->in_list,&buf[k]);
			REPL(etmp->in_list,ctmp);
			break; }
		  if ((k=str_chk(">",i))>0) {
			/* add to out_list */
			ctmp=add_str(etmp->out_list,&buf[k]);
			REPL(etmp->out_list,ctmp);
			break; }
		  if ((k=str_chk("calls:",i))>0) {
			/* add to calls */
			ctmp=get_id(k);
			k=strlen(ctmp);
			ctmp[k]='\n';
			ctmp[k+1]=0;
			ctmp=add_str(etmp->calls,ctmp);
			REPL(etmp->calls,ctmp);
			break; }
		  if ((k=str_chk("changes:",i))>0) {
			/* add to changes */
			ctmp=get_id(k);
			k=strlen(ctmp);
			ctmp[k]='\n';
			ctmp[k+1]=0;
			ctmp=add_str(etmp->changes,ctmp);
			REPL(etmp->changes,ctmp);
			break; }
		  /* add to comment */
		  ctmp=add_str(etmp->comment,&buf[i]);
		  REPL(etmp->comment,ctmp);
		}
		break;
	  }
	  default: ;
	  }
	}
	fclose(inf);
	anum++;
  }

  /* expand all elements in changes sections */
  etmp=eroot;
  while (etmp) {
	int bp;
	int l,k;
	bp=0;
	ctmp=etmp->changes;
	if (ctmp) {
#ifdef DEBUG
	  printf("\"%s\" expands to\n",ctmp);
#endif
	  while (*ctmp) {
		i=0;
		while (ctmp[i]!='\n' && ctmp[i]!='(') i++;
		k=i;
		if (ctmp[i]!='\n') {
		  while (ctmp[i]!=')') {
			i++;
			for (l=0; l<k; l++) buf[bp++]=ctmp[l];
			while (isalnum(ctmp[i]))
			  buf[bp++]=ctmp[i++];
			buf[bp++]='\n'; }
		  i++; }
		else {
		  for (l=0; l<k; l++) buf[bp++]=ctmp[l];
		  buf[bp++]='\n'; }
		ctmp=&ctmp[i+1]; }

	  buf[bp]='\0';
#ifdef DEBUG
	  printf("\"%s\"\n",buf);
#endif
	  ctmp=str_dup(buf);
	  REPL(etmp->changes,ctmp);
	}
	etmp=etmp->next;
  }

  /* expand all calls */
  flag=1;
  while (flag) {
	int k,l;
	
#ifdef DEBUG
	printf("<--- new pass --->\n");
#endif

	flag=0;
	etmp=eroot;
	while (etmp) {
	  char calls_buf[BUF_LEN];
	  char changes_buf[BUF_LEN];
	  char ch_tmp[32];
	  char ca_tmp[32];
	  int calls_bp;
	  int changes_bp;

#ifdef DEBUG
	  printf("working on %s\n",etmp->function);
#endif

	  if (etmp->changes) {
		strcpy(changes_buf,etmp->changes);
		changes_bp=strlen(changes_buf);
	  } else {
		*changes_buf=0;
		changes_bp=0; }
		
	  *calls_buf=0;
	  calls_bp=0;
	  
	  ctmp=etmp->calls;
	  while (ctmp && *ctmp) {
		struct dentry *etmp2;

		i=0;
		while (ctmp[i]!='\n') { 
		  ca_tmp[i]=ctmp[i];
		  i++; }
		ca_tmp[i]='\0';
		ctmp=&ctmp[i+1];
#ifdef DEBUG
		printf("examine \"%s\"\n",ca_tmp);
#endif
		etmp2=eroot;
		while (etmp2) {
		  if (!strcmp(etmp2->function,ca_tmp) && etmp2->calls==0) {
			char *ctmp2;
			char *ctmp3;

#ifdef DEBUG
			printf("expanding function %s for %s\n",ca_tmp,etmp->function);
#endif
			ctmp2=etmp2->changes;
			while (ctmp2 && *ctmp2) {
			  int flag2;

			  k=0;
			  while (ctmp2[k]!='\n') { 
				ch_tmp[k]=ctmp2[k];
				k++; }
			  ch_tmp[k]='\0';


			  ctmp3=changes_buf;
			  flag2=0;
			  while (*ctmp3) {
				l=0;
				while (ch_tmp[l] && ch_tmp[l]==ctmp3[l]) l++;
				if (!ch_tmp[l] && ctmp3[l]=='\n') {
				  printf("warning: %s->%s might cause inconsistency in %s\n",
						 etmp->function, ca_tmp, ch_tmp);
				  flag2=1;
				}
				while (*ctmp3++!='\n');
			  }

			  if (!flag2) {
				/* adding changes */
				printf("  <= %s\n",ch_tmp);
				l=0;
				while (ch_tmp[l])
				  changes_buf[changes_bp++]=ch_tmp[l++];				  
				changes_buf[changes_bp++]='\n';
				changes_buf[changes_bp]=0;
			  }
			  ctmp2=&ctmp2[k+1];
			}
		    flag=1;
			break;
		  }
		  etmp2=etmp2->next;
		}
		if (!etmp2) {
		  /* function has not been expanded, so keep its name in the list */
		  i=0;
		  while (ca_tmp[i])
			calls_buf[calls_bp++]=ca_tmp[i++];
		  calls_buf[calls_bp++]='\n';
		  calls_buf[calls_bp]=0;
		}
	  }

	  if (etmp->calls) 
		free(etmp->calls);

	  if (calls_buf[0])
		etmp->calls=str_dup(calls_buf);
	  else
		etmp->calls=0;


	  if (etmp->changes) 
		free(etmp->changes);

	  if (changes_buf[0])
		etmp->changes=str_dup(changes_buf);
	  else
		etmp->changes=0;

	  etmp=etmp->next;
	}
  }

  /* dump results */

  printf("\nSummary\n=======\n");

  etmp=eroot;
  while (etmp) {
	printf("\n Name    = %s",etmp->function);
  printf("\n inputs  = %s",etmp->in_list); 
  printf("\n outputs = %s",etmp->out_list); 
  printf("\n comment = %s",etmp->comment); 
	printf("\n Changes = "); print_str(etmp->changes);
	if (etmp->calls) 
	  printf("\n Unresolved calls = "); print_str(etmp->calls);
	printf("\n");
	etmp=etmp->next;
  }

  return 0;
}
Beispiel #20
0
void init_board( army_type * army )
{
  static piece_def_type pc_def[NUM_PIECE_DEFS] = {
    { "Pawn", PAWN_TOKEN, PAWN_VALUE, 4, 0,
      { {0,0} /* {1,0},{1,1},{2,0} */ }, TRUE },
    { "Knight", KNIGHT_TOKEN, KNIGHT_VALUE, 3, 8,
      {{2,1},{1,2},{-1,2},{-2,1},{-2,-1},{-1,-2},{1,-2},
        {2,-1},{0,0} },TRUE},
    { "Bishop", BISHOP_TOKEN, BISHOP_VALUE, 3, 4,
      { {1,1},{-1,1},{-1,-1},{1,-1},{0,0} }, FALSE },
    { "Rook", ROOK_TOKEN, ROOK_VALUE, 2, 4,
      { {0,1},{1,0},{0,-1},{-1,0},{0,0} }, FALSE },
    { "Queen", QUEEN_TOKEN, QUEEN_VALUE, 1, 8,
      {{1,0},{1,1},{0,1},{-1,1},{-1,0},{-1,-1},{0,-1},{1,-1},
        {0,0} }, FALSE},
    { "King", KING_TOKEN, KING_VALUE, 0, 8,
      { {1,0},{1,1},{0,1},{-1,1},{-1,0},{-1,-1},{0,-1},{1,-1},
        {0,0} }, TRUE }
  };
  static shared_type shared_data;
  shared_type * sh = &shared_data;
  army_type * owner;
  unsigned int i, j, row, col,
    init_slot_size[NUM_ALIST_SLOTS]
      = {10, 10, 10, 20, 40, 60};
  char str[10], c;
  move_assoc_list_type * alist;
  slot_type * slot;

  sh->pc_def = pc_def;

  sh->best_move_slot.size = INIT_BEST_SLOT_SIZE;
  sh->best_move_slot.moves = (move_type *)malloc(
    INIT_BEST_SLOT_SIZE * sizeof(move_type));

  for( i = 0; i < MAX_MAX_PLY; i++ ) {
    alist = &sh->alists[i];

    for( j = 0; j < NUM_ALIST_SLOTS; j++) {
      slot = &alist->slots[j];
      slot->len = 0;
      slot->size = init_slot_size[j];
      slot->moves = (move_type *)malloc(
        slot->size * sizeof(move_type));
    }
  }

  sh->move_rec = (char *)malloc( INIT_MOVE_REC_SIZE );
  sh->move_rec_idx = 0;
  sh->move_rec_size = INIT_MOVE_REC_SIZE;
  sh->capture_by_or_draw = 200;
  army[O_BLACK].sh = army[O_WHITE].sh = sh;
  army[O_BLACK].opponent = &army[O_WHITE];
  army[O_WHITE].opponent = &army[O_BLACK];

  // Set all squares to empty

  for( row = 0; row < BOARD_SIZE; row++ ) {

    for( col = 0; col < BOARD_SIZE; col++ ) {
      sh->board.ptr[row][col] = NULL;
    }
  }

  init_army( &army[O_WHITE], O_WHITE );
  init_army( &army[O_BLACK], O_BLACK );

#if 1
    do {        // Idiot-proofed input
        printf( "Game or study? (g/s): " );
        scanf( "%s", str );
        c = *(eat_spaces( str ));
        c = tolower( c );
    } while( c != 'g'  &&  c != 's' );
#else
    c = 'g';
#endif

  if( c == 'g' ) {    // Play a normal game
    open_open_book( sh );
    init_army_pieces( &army[O_WHITE] );
    init_army_pieces( &army[O_BLACK] );
  } else {                    // Construct and play a study
    construct_study( army );
  }

  for( i = 0; i < 2; i++ ) {
    owner = &army[i];

#if 1
    do {
      printf( "\n%s: human or computer (h/c): ",
        owner->name );
      scanf( "%s", str );
      c = *(eat_spaces( str ));
      c = tolower( c );
    } while( c != 'h'  &&  c != 'c' );
#else
    c = ( i == 0 ) ? 'h' : 'c';
#endif

    if( c == 'c' ) {
      owner->auto_until = AUTO_INDEFINITELY;
      owner->move_proc = &computer_move;
      owner->type = PT_COMPUTER;
      init_computer_army( owner );
//      owner->max_ply = 3;
//      owner->max_ply_cap = 5;
		} else {
      owner->auto_until = 0;
      owner->move_proc = &human_move;
      owner->type = PT_HUMAN;
  	}
  }

#if 0
  sh->resign_thresh = 8;
#else
  do {
    printf( "Resign threshold (3-%d): ", KING_VALUE );
    scanf( "%d", &sh->resign_thresh );
  } while( sh->resign_thresh < 3
    ||  sh->resign_thresh > KING_VALUE );
#endif
} // init_board()
/* Syntax:
 *   enum (keyname[=value],keyname[=value],... )
 *   enum<type> (keyname[=value],keyname[=value],... )
 */
static int
parse_enum(struct protolib *plib, struct locus *loc, char **str,
	   struct arg_type_info **retp, int *ownp)
{
	/* Optional type argument.  */
	eat_spaces(str);
	if (**str == '[') {
		parse_char(loc, str, '[');
		eat_spaces(str);
		*retp = parse_nonpointer_type(plib, loc, str, NULL, 0, ownp, 0);
		if (*retp == NULL)
			return -1;

		if (!type_is_integral((*retp)->type)) {
			report_error(loc->filename, loc->line_no,
				     "integral type required as enum argument");
		fail:
			if (*ownp) {
				/* This also releases associated lens
				 * if any was set so far.  */
				type_destroy(*retp);
				free(*retp);
			}
			return -1;
		}

		eat_spaces(str);
		if (parse_char(loc, str, ']') < 0)
			goto fail;

	} else {
		*retp = type_get_simple(ARGTYPE_INT);
		*ownp = 0;
	}

	/* We'll need to set the lens, so unshare.  */
	if (unshare_type_info(loc, retp, ownp) < 0)
		goto fail;

	eat_spaces(str);
	if (parse_char(loc, str, '(') < 0)
		goto fail;

	struct enum_lens *lens = malloc(sizeof(*lens));
	if (lens == NULL) {
		report_error(loc->filename, loc->line_no,
			     "malloc enum lens: %s", strerror(errno));
		return -1;
	}

	lens_init_enum(lens);
	(*retp)->lens = &lens->super;
	(*retp)->own_lens = 1;

	long last_val = 0;
	while (1) {
		eat_spaces(str);
		if (**str == 0 || **str == ')') {
			parse_char(loc, str, ')');
			return 0;
		}

		/* Field delimiter.  XXX should we support the C
		 * syntax, where the enumeration can end in pending
		 * comma?  */
		if (lens_enum_size(lens) > 0)
			parse_char(loc, str, ',');

		eat_spaces(str);
		char *key = parse_ident(loc, str);
		if (key == NULL) {
		err:
			free(key);
			goto fail;
		}

		if (**str == '=') {
			++*str;
			eat_spaces(str);
			if (parse_int(loc, str, &last_val) < 0)
				goto err;
		}

		struct value *value = malloc(sizeof(*value));
		if (value == NULL)
			goto err;
		value_init_detached(value, NULL, *retp, 0);
		value_set_word(value, last_val);

		if (lens_enum_add(lens, key, 1, value, 1) < 0)
			goto err;

		last_val++;
	}

	return 0;
}
Beispiel #22
0
/** Reading the debug file, parsing it and setting the msx_debug_level variable
    according to the entries found in the file
 @param *fname       Alternative debug file name
 @return 0 on error 1 on success
*/
int msx_read_debug_file(char *fname) {
	FILE *dbgFile;
	char *ptr;
	char line[256];
	int  found_out_file = 0;
	
	if(!fname)
		fname = DEFAULT_DEBUG_FILE;
	
	if(!(dbgFile = fopen(fname, "r")))
		return 0;

        msx_debug_level = 0;

	while(fgets(line, 256, dbgFile)) {
		char *out_file;
		
                // Skeeping comments
		if(line[0] == '#')
			continue;
		// removing spaces and newline
		ptr = line;
                ptr = eat_spaces(ptr);
                trim_spaces(ptr);

                // Getting the output file to use
		if((out_file = strstr(ptr, MSX_DEBUG_OUT_FILE_STR))) {
			found_out_file = 1;
                        out_file+= strlen(MSX_DEBUG_OUT_FILE_STR);
			out_file = eat_spaces(out_file);
			if(*out_file == '=') {
                             out_file++;
                             out_file = eat_spaces(out_file);
                        }

                        // out_file should now point to the file name
			if(!msx_debug_file ||
			   strcmp(msx_debug_file, out_file) != 0) {
				if(msx_debug_file)
					free(msx_debug_file);
				if(msx_debug_filp)
					fclose(msx_debug_filp);
				msx_debug_filp = NULL;
				msx_debug_file = strdup(out_file);
			}
			
			if(msx_debug_filp == NULL) {
				msx_debug_filp = fopen(out_file, "w");
				if(msx_debug_filp == NULL) {
					free(msx_debug_file);
					msx_debug_file = NULL;
					msx_debug_filp = NULL;
				} else {
					setlinebuf(msx_debug_filp);
				}
			}
		}

                // Getting the flags to set
                int flag;
                if((flag = get_debug_flag(ptr)))
                     msx_debug_level |= flag;
                
        }
        
	fclose(dbgFile);
	if(!found_out_file) {
             if(msx_debug_file) {
                  fclose(msx_debug_filp);
                  free(msx_debug_file);
                  msx_debug_file = NULL;
             }
             msx_debug_filp = NULL;
	}
	
	return 1;
}
static int
parse_string(struct protolib *plib, struct locus *loc,
	     char **str, struct arg_type_info **retp, int *ownp)
{
	struct arg_type_info *info = NULL;
	struct expr_node *length;
	int own_length;

	if (isdigit(CTYPE_CONV(**str))) {
		/* string0 is string[retval], length is zero(retval)
		 * stringN is string[argN], length is zero(argN) */
		long l;
		if (parse_int(loc, str, &l) < 0
		    || check_int(loc, l) < 0)
			return -1;

		struct expr_node *length_arg = malloc(sizeof(*length_arg));
		if (length_arg == NULL)
			return -1;

		if (l == 0)
			expr_init_named(length_arg, "retval", 0);
		else
			expr_init_argno(length_arg, l - 1);

		length = build_zero_w_arg(length_arg, 1);
		if (length == NULL) {
			expr_destroy(length_arg);
			free(length_arg);
			return -1;
		}
		own_length = 1;

	} else {
		eat_spaces(str);
		if (**str == '[') {
			(*str)++;
			eat_spaces(str);

			length = parse_argnum(loc, str, &own_length, 1);
			if (length == NULL)
				return -1;

			eat_spaces(str);
			parse_char(loc, str, ']');

		} else if (**str == '(') {
			/* Usage of "string" as lens.  */
			++*str;

			eat_spaces(str);
			info = parse_type(plib, loc, str, NULL, 0, ownp, NULL);
			if (info == NULL)
				return -1;

			length = NULL;
			own_length = 0;

			eat_spaces(str);
			parse_char(loc, str, ')');

		} else {
			/* It was just a simple string after all.  */
			length = expr_node_zero();
			own_length = 0;
		}
	}

	/* String is a pointer to array of chars.  */
	if (info == NULL) {
		struct arg_type_info *info1 = malloc(sizeof(*info1));
		struct arg_type_info *info2 = malloc(sizeof(*info2));
		if (info1 == NULL || info2 == NULL) {
			free(info1);
			free(info2);
		fail:
			if (own_length) {
				assert(length != NULL);
				expr_destroy(length);
				free(length);
			}
			return -1;
		}
		type_init_array(info2, type_get_simple(ARGTYPE_CHAR), 0,
				length, own_length);
		type_init_pointer(info1, info2, 1);

		info = info1;
		*ownp = 1;
	}

	/* We'll need to set the lens, so unshare.  */
	if (unshare_type_info(loc, &info, ownp) < 0)
		/* If unshare_type_info failed, it must have been as a
		 * result of cloning attempt because *OWNP was 0.
		 * Thus we don't need to destroy INFO.  */
		goto fail;

	info->lens = &string_lens;
	info->own_lens = 0;

	*retp = info;
	return 0;
}
static int
parse_typedef(struct protolib *plib, struct locus *loc, char **str)
{
	(*str) += strlen("typedef");
	eat_spaces(str);
	char *name = parse_ident(loc, str);

	/* Look through the typedef list whether we already have a
	 * forward of this type.  If we do, it must be forward
	 * structure.  */
	struct named_type *forward = protolib_lookup_type(plib, name, true);
	if (forward != NULL
	    && (forward->info->type != ARGTYPE_STRUCT
		|| !forward->forward)) {
		report_error(loc->filename, loc->line_no,
			     "Redefinition of typedef '%s'", name);
	err:
		free(name);
		return -1;
	}

	// Skip = sign
	eat_spaces(str);
	if (parse_char(loc, str, '=') < 0)
		goto err;
	eat_spaces(str);

	int fwd = 0;
	int own = 0;
	struct arg_type_info *info
		= parse_lens(plib, loc, str, NULL, 0, &own, &fwd);
	if (info == NULL)
		goto err;

	struct named_type this_nt;
	named_type_init(&this_nt, info, own);
	this_nt.forward = fwd;

	if (forward == NULL) {
		if (protolib_add_named_type(plib, name, 1, &this_nt) < 0) {
			named_type_destroy(&this_nt);
			goto err;
		}
		return 0;
	}

	/* If we are defining a forward, make sure the definition is a
	 * structure as well.  */
	if (this_nt.info->type != ARGTYPE_STRUCT) {
		report_error(loc->filename, loc->line_no,
			     "Definition of forward '%s' must be a structure.",
			     name);
		named_type_destroy(&this_nt);
		goto err;
	}

	/* Now move guts of the actual type over to the forward type.
	 * We can't just move pointers around, because references to
	 * forward must stay intact.  */
	assert(this_nt.own_type);
	type_destroy(forward->info);
	*forward->info = *this_nt.info;
	forward->forward = 0;
	free(this_nt.info);
	free(name);
	return 0;
}
Beispiel #25
0
/**
 * Parses the PING configuration string. Its format is 
 * "ping_period:pings_lost:ping_timeout"
 * ping_period : time between pings
 * pings_lost: number of lost pings before failure
 * ping_timeout: time to consider a ping failed
 *
 * returns 
 * 0 if no clusters present
 * -1 if config is malformed (unable to parse);
 *  1 if config is successfully set
 */
int parse_cluster_cfg(void)
{
   char *p,*start;
   int n,k;
   struct as_entry **entry,*tmp,*tmp2;

   if((p=cluster_cfg)==0 || *cluster_cfg==0){
      return 0;
   }
   entry=&as_list;

   while (*p)
   {
      eat_spaces(p);
      /*get cluster name*/
      start = p;
      while (*p!=' ' && *p!='\t' && *p!='[' && *p!=0)
	 p++;
      if ( p==start || *p==0 ){
	 LM_ERR("cluster names must only contain alphanumeric chars\n");
	 goto error;
      }
      if (!((*entry)=(struct as_entry*)shm_malloc(sizeof(struct as_entry)))) {
	 LM_ERR("Out of shm mem for as_entry\n");
	 goto error;
      }
      memset(*entry,0,sizeof(struct as_entry));
      if (!((*entry)->name.s=shm_malloc(p-start))) {
	 LM_ERR("Out of shm malloc for cluster name\n");
	 goto error;
      }
      memcpy((*entry)->name.s, start, p-start);
      (*entry)->name.len=p-start;
      (*entry)->connected=0;
      (*entry)->type=CLUSTER_TYPE;
      (*entry)->u.cs.name=(*entry)->name;
      /*get as names*/
      eat_spaces(p);
      if (*p!='['){
	 LM_ERR("Malformed cluster cfg string %s\n",cluster_cfg);
	 goto error;
      }
      p++;
      n=0;
      while (*p!=']')
      {
	 eat_spaces(p);
	 start = p;
	 while(*p!=' ' && *p!='\t' && *p!=']' && *p!=',' && *p!=0)
	    p++;
	 if ( p==start || *p==0 )
	    goto error;
	 if (!((*entry)->u.cs.as_names[n].s=shm_malloc(p-start))) {
	    LM_ERR("Out of shm_mem for AS name in cluster\n");
	    goto error;
	 }
	 (*entry)->u.cs.as_names[n].len=p-start;
	 memcpy((*entry)->u.cs.as_names[n].s,start,p-start);
	 n++;
	 if(n>=MAX_AS_PER_CLUSTER){
	    LM_ERR("too many AS per cluster\n");
	    goto error;
	 }
	 eat_spaces(p);
	 if (*p==',') {
	    p++;
	    eat_spaces(p);
	 }
      }
      p++;
      (*entry)->u.cs.num=n;
      /* end of element */
      eat_spaces(p);
      if (*p==',')
	 p++;
      eat_spaces(p);
      entry=&((*entry)->next);
   }
   for (tmp=as_list;tmp->next;tmp=tmp->next){
      LM_DBG("%.*s\n",tmp->name.len,tmp->name.s);
   }
   LM_DBG("%.*s\n",tmp->name.len,tmp->name.s);
   entry=&(tmp->next);
   for(tmp=as_list;tmp;tmp=tmp->next){
      if (tmp->type!=CLUSTER_TYPE) 
	 continue;
      LM_DBG("cluster:[%.*s]\n",tmp->name.len,tmp->name.s);
      for(k=0;k<tmp->u.cs.num;k++){
	 LM_DBG("\tAS:[%.*s]\n",tmp->u.cs.as_names[k].len,tmp->u.cs.as_names[k].s);
	 for (tmp2=as_list;tmp2;tmp2=tmp2->next) {
	    if (tmp2->type== AS_TYPE && tmp->u.cs.as_names[k].len == tmp2->name.len && 
		  !memcmp(tmp->u.cs.as_names[k].s,tmp2->name.s,tmp2->name.len)) {
	       tmp->u.cs.servers[k]=&tmp2->u.as;
	       break;
	    }
	 }
	 if(tmp2)
	    continue;
	 if (!((*entry)=shm_malloc(sizeof(struct as_entry)))) {
	    LM_ERR("Out of shm mem \n");
	    goto error;
	 }
	 memset(*entry,0,sizeof(struct as_entry));
	 (*entry)->type=AS_TYPE;
	 if (!((*entry)->name.s=shm_malloc(tmp->u.cs.as_names[k].len))) {
	    LM_ERR("out of shm mem\n");
	    goto error;
	 }
	 memcpy((*entry)->name.s,tmp->u.cs.as_names[k].s,tmp->u.cs.as_names[k].len);
	 (*entry)->name.len=tmp->u.cs.as_names[k].len;
	 (*entry)->u.as.name=(*entry)->name;
	 tmp->u.cs.servers[k]=&(*entry)->u.as;
	 entry=&((*entry)->next);
      }
   }
   for(tmp=as_list;tmp;tmp=tmp->next){
      LM_DBG("%.*s %s",tmp->name.len,tmp->name.s,tmp->next?"":"\n");
   }
   return 1;
error:
   tmp=as_list;
   while(tmp){
      for(k=0;k<tmp->u.cs.num;k++){
	 if(tmp->u.cs.as_names[k].s)
	    shm_free(tmp->u.cs.as_names[k].s);
      }
      if(tmp->name.s)
	 shm_free(tmp->name.s);
      tmp2=tmp;
      tmp=tmp->next;
      shm_free(tmp2);
   }
   as_list=(struct as_entry *)0;
   return -1;
}
Beispiel #26
0
int parse_config_lines(void)
{
	char *p,*start;
	int  i, k, step;
	int  mdm_nr, net_nr;

	nr_of_networks = 0;
	nr_of_modems = 0;

	step = 1;
	/* parsing modems configuration string */
	if ( (p = modems_config)==0) {
		LM_ERR("param \"modems\" not found\n");
		goto error;
	}
	while (*p)
	{
		eat_spaces(p);
		/*get modem's name*/
		start = p;
		while (*p!=' ' && *p!='\t' && *p!='[' && *p!=0)
			p++;
		if ( p==start || *p==0 )
			goto parse_error;
		memcpy(modems[nr_of_modems].name, start, p-start);
		modems[nr_of_modems].name[p-start] = 0;
		modems[nr_of_modems].smsc[0] = 0;
		modems[nr_of_modems].device[0] = 0;
		modems[nr_of_modems].pin[0] = 0;
		modems[nr_of_modems].mode = MODE_NEW;
		modems[nr_of_modems].retry = 4;
		modems[nr_of_modems].looping_interval = 20;
		modems[nr_of_modems].baudrate = B9600;
		modems[nr_of_modems].scan = SMS_BODY_SCAN;
		modems[nr_of_modems].to[0] = 0;
		memset(modems[nr_of_modems].net_list,0XFF,
			sizeof(modems[nr_of_modems].net_list) );
		/*get modem parameters*/
		eat_spaces(p);
		if (*p!='[')
			goto parse_error;
		p++;
		while (*p!=']')
		{
			eat_spaces(p);
			start = p;
			while(*p!=' ' && *p!='\t' && *p!=']' && *p!=';' && *p!=0)
				p++;
			if ( p==start || *p==0 )
				goto parse_error;
			if (set_modem_arg( &(modems[nr_of_modems]), start, p)==-1)
				goto error;
			eat_spaces(p);
			if (*p==';') {
				p++;
				eat_spaces(p);
			}
		}
		if (*p!=']')
			goto parse_error;
		p++;
		/* end of element */
		if (modems[nr_of_modems].device[0]==0) {
			LM_ERR("modem %s has no device associated\n",
					modems[nr_of_modems].name);
			goto error;
		}
		if (modems[nr_of_modems].smsc[0]==0) {
			LM_WARN("modem %s has no sms center associated -> using"
				" the default one from modem\n",modems[nr_of_modems].name);
		}
		nr_of_modems++;
		eat_spaces(p);
		if (*p==';') {
			p++;
			eat_spaces(p);
		}
	}
	if (nr_of_modems==0)
	{
		LM_ERR("failed to parse config modems - no modem found!\n");
		goto error;
	}

	step++;
	/* parsing networks configuration string */
	if ( (p = networks_config)==0) {
		LM_ERR("param \"networks\" not found\n");
		goto error;
	}
	while (*p)
	{
		eat_spaces(p);
		/*get network name*/
		start = p;
		while (*p!=' ' && *p!='\t' && *p!='[' && *p!=0)
			p++;
		if ( p==start || *p==0 )
			goto parse_error;
		memcpy(networks[nr_of_networks].name, start, p-start);
		networks[nr_of_networks].name[p-start] = 0;
		networks[nr_of_networks].max_sms_per_call = 10;
		/*get network parameters*/
		eat_spaces(p);
		if (*p!='[')
			goto parse_error;
		p++;
		while (*p!=']')
		{
			eat_spaces(p);
			start = p;
			while(*p!=' ' && *p!='\t' && *p!=']' && *p!=';' && *p!=0)
				p++;
			if ( p==start || *p==0 )
				goto parse_error;
			if (set_network_arg( &(networks[nr_of_networks]), start, p)==-1)
				goto error;
			eat_spaces(p);
			if (*p==';') {
				p++;
				eat_spaces(p);
			}
		}
		if (*p!=']')
			goto parse_error;
		p++;
		/* end of element */
		nr_of_networks++;
		eat_spaces(p);
		if (*p==';')
			p++;
		eat_spaces(p);
	}
	if (nr_of_networks==0)
	{
		LM_ERR("no network found!\n");
		goto error;
	}

	step++;
	/* parsing links configuration string */
	if ( (p = links_config)==0) {
		LM_ERR("param \"links\" not found\n");
		goto error;
	}
	while (*p)
	{
		eat_spaces(p);
		/*get modem's device*/
		start = p;
		while (*p!=' ' && *p!='\t' && *p!='[' && *p!=0)
			p++;
		if ( p==start || *p==0 )
			goto parse_error;
		/*looks for modem index*/
		for(mdm_nr=-1,i=0;i<nr_of_modems && mdm_nr==-1;i++)
			if (!strncasecmp(modems[i].name,start,p-start)&&
			modems[i].name[p-start]==0)
				mdm_nr = i;
		if (mdm_nr==-1) {
			LM_ERR("unknown modem %.*s \n,",(int)(p-start), start);
			goto error;
		}
		/*get associated networks list*/
		eat_spaces(p);
		if (*p!='[')
			goto parse_error;
		p++;
		k=0;
		while (*p!=']')
		{
			eat_spaces(p);
			start = p;
			while(*p!=' ' && *p!='\t' && *p!=']' && *p!=';' && *p!=0)
				p++;
			if ( p==start || *p==0 )
				goto parse_error;
			/* lookup for the network -> get its index */
			for(net_nr=-1,i=0;i<nr_of_networks&&net_nr==-1;i++)
				if (!strncasecmp(networks[i].name,start,p-start)
				&& networks[i].name[p-start]==0)
					net_nr = i;
			if (net_nr==-1) {
				LM_ERR("associated net <%.*s> not found in net list\n",
					(int)(p-start), start);
				goto error;
			}
			LM_DBG("linking net \"%s\" to modem \"%s\" on pos %d.\n",
					networks[net_nr].name,modems[mdm_nr].name,k);
			modems[mdm_nr].net_list[k++]=net_nr;
			eat_spaces(p);
			if (*p==';') {
				p++;
				eat_spaces(p);
			}
		}
		if (*p!=']')
			goto parse_error;
		p++;
		/* end of element */
		eat_spaces(p);
		if (*p==';') {
			p++;
			eat_spaces(p);
		}
	}

	/* resolving default network name - if any*/
	if (default_net_str) {
		for(net_nr=-1,i=0;i<nr_of_networks&&net_nr==-1;i++)
			if (!strcasecmp(networks[i].name,default_net_str))
				net_nr = i;
		if (net_nr==-1) {
			LM_ERR("network \"%s\" not found in net list!\n",default_net_str);
			goto error;
		}
		default_net = net_nr;
	}

	return 0;
parse_error:
	LM_ERR("SMS %s config: parse error before  chr %d [%.*s]\n",
		(step==1)?"modems":(step==2?"networks":"links"),
		(int)(p - ((step==1)?modems_config:
				   (step==2?networks_config:links_config))),
		(*p==0)?4:1,(*p==0)?"NULL":p );
error:
	return -1;
}
static int
process_line(struct protolib *plib, struct locus *loc, char *buf)
{
	char *str = buf;
	char *tmp;

	debug(3, "Reading line %d of `%s'", loc->line_no, loc->filename);
	eat_spaces(&str);

	/* A comment or empty line.  */
	if (*str == ';' || *str == 0 || *str == '\n' || *str == '#')
		return 0;

	if (strncmp(str, "typedef", 7) == 0) {
		parse_typedef(plib, loc, &str);
		return 0;
	}

	struct prototype fun;
	prototype_init(&fun);

	struct param *extra_param = NULL;
	char *proto_name = NULL;
	int own;
	fun.return_info = parse_lens(plib, loc, &str, NULL, 0, &own, NULL);
	if (fun.return_info == NULL) {
	err:
		debug(3, " Skipping line %d", loc->line_no);

		if (extra_param != NULL) {
			param_destroy(extra_param);
			free(extra_param);
		}

		prototype_destroy(&fun);
		free(proto_name);
		return -1;
	}
	fun.own_return_info = own;
	debug(4, " return_type = %d", fun.return_info->type);

	eat_spaces(&str);
	tmp = start_of_arg_sig(str);
	if (tmp == NULL) {
		report_error(loc->filename, loc->line_no, "syntax error");
		goto err;
	}
	*tmp = '\0';

	proto_name = strdup(str);
	if (proto_name == NULL) {
	oom:
		report_error(loc->filename, loc->line_no,
			     "%s", strerror(errno));
		goto err;
	}

	str = tmp + 1;
	debug(3, " name = %s", proto_name);

	int have_stop = 0;

	while (1) {
		eat_spaces(&str);
		if (*str == ')')
			break;

		if (str[0] == '+') {
			if (have_stop == 0) {
				struct param param;
				param_init_stop(&param);
				if (prototype_push_param(&fun, &param) < 0)
					goto oom;
				have_stop = 1;
			}
			str++;
		}

		int own;
		size_t param_num = prototype_num_params(&fun) - have_stop;
		struct arg_type_info *type
			= parse_lens(plib, loc, &str, &extra_param,
				     param_num, &own, NULL);
		if (type == NULL) {
			report_error(loc->filename, loc->line_no,
				     "unknown argument type");
			goto err;
		}

		struct param param;
		param_init_type(&param, type, own);
		if (prototype_push_param(&fun, &param) < 0)
			goto oom;

		eat_spaces(&str);
		if (*str == ',') {
			str++;
			continue;
		} else if (*str == ')') {
			continue;
		} else {
			if (str[strlen(str) - 1] == '\n')
				str[strlen(str) - 1] = '\0';
			report_error(loc->filename, loc->line_no,
				     "syntax error around \"%s\"", str);
			goto err;
		}
	}

	/* We used to allow void parameter as a synonym to an argument
	 * that shouldn't be displayed.  But backends really need to
	 * know the exact type that they are dealing with.  The proper
	 * way to do this these days is to use the hide lens.
	 *
	 * So if there are any voids in the parameter list, show a
	 * warning and assume that they are ints.  If there's a sole
	 * void, assume the function doesn't take any arguments.  The
	 * latter is conservative, we can drop the argument
	 * altogether, instead of fetching and then not showing it,
	 * without breaking any observable behavior.  */
	if (prototype_num_params(&fun) == 1
	    && param_is_void(prototype_get_nth_param(&fun, 0))) {
		if (0)
			/* Don't show this warning.  Pre-0.7.0
			 * ltrace.conf often used this idiom.  This
			 * should be postponed until much later, when
			 * extant uses are likely gone.  */
			report_warning(loc->filename, loc->line_no,
				       "sole void parameter ignored");
		prototype_destroy_nth_param(&fun, 0);
	} else {
		prototype_each_param(&fun, NULL, void_to_hidden_int, loc);
	}

	if (extra_param != NULL) {
		prototype_push_param(&fun, extra_param);
		free(extra_param);
		extra_param = NULL;
	}

	if (protolib_add_prototype(plib, proto_name, 1, &fun) < 0) {
		report_error(loc->filename, loc->line_no,
			     "couldn't add prototype: %s",
			     strerror(errno));
		goto err;
	}

	return 0;
}