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(); } }
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; }
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; }
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; }
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); } }
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; }
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; }
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; }
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; }
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; }
/* * 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; } }
/* 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; }
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; }
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; }
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; }
/** 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; }
/** * 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; }
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(¶m); if (prototype_push_param(&fun, ¶m) < 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(¶m, type, own); if (prototype_push_param(&fun, ¶m) < 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; }