void do_line_insertion_deletion_costs (struct frame *frame, const char *ins_line_string, const char *multi_ins_string, const char *del_line_string, const char *multi_del_string, const char *setup_string, const char *cleanup_string, int coefficient) { int frame_total_lines = FRAME_TOTAL_LINES (frame); FRAME_INSERT_COST (frame) = xnrealloc (FRAME_INSERT_COST (frame), frame_total_lines, sizeof (int)); FRAME_DELETEN_COST (frame) = xnrealloc (FRAME_DELETEN_COST (frame), frame_total_lines, sizeof (int)); FRAME_INSERTN_COST (frame) = xnrealloc (FRAME_INSERTN_COST (frame), frame_total_lines, sizeof (int)); FRAME_DELETE_COST (frame) = xnrealloc (FRAME_DELETE_COST (frame), frame_total_lines, sizeof (int)); ins_del_costs (frame, ins_line_string, multi_ins_string, setup_string, cleanup_string, FRAME_INSERT_COST (frame), FRAME_INSERTN_COST (frame), coefficient); ins_del_costs (frame, del_line_string, multi_del_string, setup_string, cleanup_string, FRAME_DELETE_COST (frame), FRAME_DELETEN_COST (frame), coefficient); }
void xstring_set_content(struct _xstring *p, const char *new_content) { p->cur_pos = strlen(new_content); if (p->cur_pos >= p->cur_size) { p->cur_size = p->cur_pos + 1; p->content = (char *) xnrealloc(p->content, p->cur_size * sizeof(char)); p->keycode = (KeyCode *) xnrealloc(p->keycode, p->cur_size * sizeof(KeyCode)); p->keycode_modifiers = (int *) xnrealloc(p->keycode_modifiers, p->cur_size * sizeof(int)); } if (p->cur_pos) memcpy(p->content, new_content, p->cur_pos); p->content[p->cur_pos] = NULLSYM; }
void output_file_name_check (char **file_name, bool source) { bool conflict = false; if (STREQ (*file_name, grammar_file)) { complain (NULL, complaint, _("refusing to overwrite the input file %s"), quote (*file_name)); conflict = true; } else { int i; for (i = 0; i < generated_files_size; i++) if (STREQ (generated_files[i].name, *file_name)) { complain (NULL, Wother, _("conflicting outputs to file %s"), quote (generated_files[i].name)); conflict = true; } } if (conflict) { free (*file_name); *file_name = strdup ("/dev/null"); } else { generated_files = xnrealloc (generated_files, ++generated_files_size, sizeof *generated_files); generated_files[generated_files_size-1].name = xstrdup (*file_name); generated_files[generated_files_size-1].is_source = source; } }
/* * save_file() adds file name and associated module to the file list to select. * * If "dir" is null, store a file name as is. * If "name" is null, store a directory name with a '*' on the front. * Else, store concatenated "dir/name". * * Later, in the "select" stage: * - if it starts with '*', it is prefix-matched against the repository. * - if it has a '/' in it, it is matched against the repository/file. * - else it is matched against the file name. */ static void save_file (char *dir, char *name, char *module) { struct file_list_str *fl; if (file_count == file_max) { file_max = xsum (file_max, FILE_INCREMENT); if (size_overflow_p (xtimes (file_max, sizeof (*fl)))) { error (0, 0, "save_file: too many files"); return; } file_list = xnrealloc (file_list, file_max, sizeof (*fl)); } fl = &file_list[file_count++]; fl->l_module = module; if (dir && *dir) { if (name && *name) fl->l_file = Xasprintf ("%s/%s", dir, name); else fl->l_file = Xasprintf ("*%s", dir); } else { if (name && *name) fl->l_file = xstrdup (name); else error (0, 0, "save_file: null dir and file name"); } }
void output_file_name_check (char **file_name) { bool conflict = false; if (STREQ (*file_name, grammar_file)) { complain (NULL, complaint, _("refusing to overwrite the input file %s"), quote (*file_name)); conflict = true; } else { int i; for (i = 0; i < file_names_count; i++) if (STREQ (file_names[i], *file_name)) { complain (NULL, Wother, _("conflicting outputs to file %s"), quote (*file_name)); conflict = true; } } if (conflict) { free (*file_name); *file_name = _strdup ("/dev/null"); } else { file_names = xnrealloc (file_names, ++file_names_count, sizeof *file_names); file_names[file_names_count-1] = xstrdup (*file_name); } }
void dynvec_freeze (struct dynvec *dv) { if (dv->dv_fill == dv->dv_capacity) return; dv->dv_capacity = dv->dv_fill; dv->dv_vec = xnrealloc (dv->dv_vec, dv->dv_capacity, sizeof *dv->dv_vec); }
static void xkeymap_store_keymaps(struct _xkeymap *p, int group) { int min_keycode, max_keycode, keysyms_per_keycode; KeySym *keymap; XDisplayKeycodes (main_window->display, &min_keycode, &max_keycode); keymap = XGetKeyboardMapping (main_window->display, min_keycode, max_keycode - min_keycode + 1, &keysyms_per_keycode); p->min_keycode = min_keycode; p->max_keycode = max_keycode; if (p->total_key_arrays < group) p->total_key_arrays = group; p->alphabet = xnrealloc(p->alphabet, (group + 1) * sizeof(struct _xkeymap_alpha)); p->alphabet[group] = xnmalloc((max_keycode + 1) * sizeof(struct _xkeymap_alpha)); for (int i = min_keycode; i <= max_keycode; i++) { int j; p->alphabet[group][i].lower_sym = xnmalloc(1); p->alphabet[group][i].lower_sym[0] = NULLSYM; p->alphabet[group][i].upper_sym = xnmalloc(1); p->alphabet[group][i].upper_sym[0] = NULLSYM; for (j = group*2; j <= group*2 + 1; j++) { KeySym ks = keymap[j]; int groups[4] = {0x00000000, 0x00002000, 0x00004000, 0x00006000}; if (ks != NoSymbol) { XEvent event = create_basic_event(); event.xkey.keycode = i; event.xkey.state = groups[group]; if (j == group*2 + 1) event.xkey.state |= ShiftMask; int nbytes; char str[256+1]; nbytes = XLookupString ((XKeyEvent *) &event, str, 256, &ks, NULL); if (nbytes > 0) { if (j == group*2) { p->alphabet[group][i].lower_sym = xnmalloc(nbytes+1); strncpy(p->alphabet[group][i].lower_sym, str, nbytes+1); p->alphabet[group][i].lower_sym[nbytes] = NULLSYM; } else { p->alphabet[group][i].upper_sym = xnmalloc(nbytes+1); strncpy(p->alphabet[group][i].upper_sym, str, nbytes+1); p->alphabet[group][i].upper_sym[nbytes] = NULLSYM; } } } } keymap += keysyms_per_keycode; } }
void xstring_add_symbol(struct _xstring *p, char sym) { if (p->cur_pos == p->cur_size - 1) { p->cur_size *= 2; p->content = (char *) xnrealloc(p->content, p->cur_size * sizeof(char)); p->keycode = (KeyCode *) xnrealloc(p->keycode, p->cur_size * sizeof(KeyCode)); p->keycode_modifiers = (int *) xnrealloc(p->keycode_modifiers, p->cur_size * sizeof(int)); } p->content[p->cur_pos] = sym; p->keycode[p->cur_pos] = 0; p->keycode_modifiers[p->cur_pos] = 0; p->cur_pos++; p->content[p->cur_pos] = NULLSYM; }
size_t readtokens (FILE *stream, size_t projected_n_tokens, const char *delim, size_t n_delim, char ***tokens_out, size_t **token_lengths) { token_buffer tb, *token = &tb; char **tokens; size_t *lengths; size_t sz; size_t n_tokens; if (projected_n_tokens == 0) projected_n_tokens = 64; else projected_n_tokens++; /* add one for trailing NULL pointer */ sz = projected_n_tokens; tokens = xnmalloc (sz, sizeof *tokens); lengths = xnmalloc (sz, sizeof *lengths); n_tokens = 0; init_tokenbuffer (token); for (;;) { char *tmp; size_t token_length = readtoken (stream, delim, n_delim, token); if (n_tokens >= sz) { tokens = x2nrealloc (tokens, &sz, sizeof *tokens); lengths = xnrealloc (lengths, sz, sizeof *lengths); } if (token_length == (size_t) -1) { /* don't increment n_tokens for NULL entry */ tokens[n_tokens] = NULL; lengths[n_tokens] = 0; break; } tmp = xnmalloc (token_length + 1, sizeof *tmp); lengths[n_tokens] = token_length; tokens[n_tokens] = memcpy (tmp, token->buffer, token_length + 1); n_tokens++; } free (token->buffer); *tokens_out = tokens; if (token_lengths != NULL) *token_lengths = lengths; else free (lengths); return n_tokens; }
void dynvec_append (struct dynvec *dv, void *element) { if (dv->dv_fill == dv->dv_capacity) { dv->dv_capacity *= 2; dv->dv_vec = xnrealloc (dv->dv_vec, dv->dv_capacity, sizeof *dv->dv_vec); } dv->dv_vec[dv->dv_fill++] = element; }
static void ult_trace (struct ult_trace *trace, const char *s) { if (!trace) return; if (trace->len >= trace->max) { trace->max *= 2; trace->names = xnrealloc (trace->names, trace->max, sizeof (char *)); } trace->names[trace->len++] = xstrdup (s); }
/* Add a numeric value to the values vector, allocating memory as needed */ void field_op_add_value (struct fieldop *op, long double val) { if (op->num_values >= op->alloc_values) { op->alloc_values += VALUES_BATCH_INCREMENT; op->values = xnrealloc (op->values, op->alloc_values, sizeof (long double)); } op->values[op->num_values] = val; op->num_values++; }
/* Add a directory to list of dirs to ignore. */ void ign_dir_add (char *name) { /* Make sure we've got the space for the entry. */ if (dir_ign_current <= dir_ign_max) { dir_ign_max += IGN_GROW; dir_ign_list = xnrealloc (dir_ign_list, dir_ign_max + 1, sizeof (char *)); } dir_ign_list[dir_ign_current++] = xstrdup (name); }
static void save_module (char *module) { if (mod_count == mod_max) { mod_max = xsum (mod_max, MODULE_INCREMENT); if (size_overflow_p (xtimes (mod_max, sizeof (char *)))) { error (0, 0, "save_module: too many modules"); return; } mod_list = xnrealloc (mod_list, mod_max, sizeof (char *)); } mod_list[mod_count++] = xstrdup (module); }
/* * save_user() adds a user name to the user list to select. Zero-length * username ("") matches any user. */ static void save_user (char *name) { if (user_count == user_max) { user_max = xsum (user_max, USER_INCREMENT); if (size_overflow_p (xtimes (user_max, sizeof (char *)))) { error (0, 0, "save_user: too many users"); return; } user_list = xnrealloc (user_list, user_max, sizeof (char *)); } user_list[user_count++] = xstrdup (name); }
void run_add_arg_p (int *iargc, size_t *iarg_allocated, char ***iargv, const char *s) { /* allocate more argv entries if we've run out */ if (*iargc >= *iarg_allocated) { *iarg_allocated += 50; *iargv = xnrealloc (*iargv, *iarg_allocated, sizeof (char **)); } if (s) (*iargv)[(*iargc)++] = xstrdup (s); else (*iargv)[*iargc] = NULL; /* not post-incremented on purpose! */ }
/* Add an argument. OPT is the option letter, e.g. 'a'. ARG is the argument to that option, or NULL if omitted (whether NULL can actually happen depends on whether the option was specified as optional to getopt). */ static void arg_add (struct admin_data *dat, int opt, char *arg) { char *newelt = Xasprintf ("-%c%s", opt, arg ? arg : ""); if (dat->av_alloc == 0) { dat->av_alloc = 1; dat->av = xnmalloc (dat->av_alloc, sizeof (*dat->av)); } else if (dat->ac >= dat->av_alloc) { dat->av_alloc *= 2; dat->av = xnrealloc (dat->av, dat->av_alloc, sizeof (*dat->av)); } dat->av[dat->ac++] = newelt; }
/** * \pre * - \c *edgesp and \c edge_counts were computed by * \c ielr_compute_internal_follow_edges. * \post * - \c *always_followsp is a new \c bitsetv with \c ngotos rows and * \c ntokens columns. * - <tt>(*always_followsp)[i][j]</tt> is set iff token \c j is an always * follow (that is, it's computed by internal and successor edges) of goto * \c i. * - Rows of \c *edgesp have been realloc'ed and extended to include * successor follow edges. \c edge_counts has not been updated. */ static void ielr_compute_always_follows (goto_number ***edgesp, int const edge_counts[], bitsetv *always_followsp) { *always_followsp = bitsetv_create (ngotos, ntokens, BITSET_FIXED); { goto_number *edge_array = xnmalloc (ngotos, sizeof *edge_array); goto_number i; for (i = 0; i < ngotos; ++i) { goto_number nedges = edge_counts[i]; { int j; transitions *trans = states[to_state[i]]->transitions; FOR_EACH_SHIFT (trans, j) bitset_set ((*always_followsp)[i], TRANSITION_SYMBOL (trans, j)); for (; j < trans->num; ++j) { symbol_number sym = TRANSITION_SYMBOL (trans, j); if (nullable[sym - ntokens]) edge_array[nedges++] = map_goto (to_state[i], sym); } } if (nedges - edge_counts[i]) { (*edgesp)[i] = xnrealloc ((*edgesp)[i], nedges + 1, sizeof *(*edgesp)[i]); memcpy ((*edgesp)[i] + edge_counts[i], edge_array + edge_counts[i], (nedges - edge_counts[i]) * sizeof *(*edgesp)[i]); (*edgesp)[i][nedges] = END_NODE; } } free (edge_array); } relation_digraph (*edgesp, ngotos, always_followsp); if (trace_flag & trace_ielr) { fprintf (stderr, "always follow edges:\n"); relation_print (*edgesp, ngotos, stderr); fprintf (stderr, "always_follows:\n"); debug_bitsetv (*always_followsp); } }
static void tokenize_args_string (char *args_string, int *argcp, char ***argvp) { static char horizontal_space[] = " \t"; char **argv_0 = xmalloc (sizeof(char *) * strlen (args_string) / 2); char **argv = argv_0; char *arg; *argv++ = program_name; arg = strsep (&args_string, horizontal_space); while (arg) { *argv++ = arg; arg = strsep (&args_string, horizontal_space); } *argcp = argv - argv_0; *argvp = xnrealloc (argv_0, *argcp, sizeof **argvp); }
/* Parse all the aggregate functions. */ static bool parse_aggregate_functions (struct lexer *lexer, const struct dictionary *dict, struct agr_proc *agr) { struct agr_var *tail; /* Tail of linked list starting at agr->vars. */ /* Parse everything. */ tail = NULL; for (;;) { char **dest; char **dest_label; size_t n_dest; struct string function_name; enum mv_class exclude; const struct agr_func *function; int func_index; union agr_argument arg[2]; const struct variable **src; size_t n_src; size_t i; dest = NULL; dest_label = NULL; n_dest = 0; src = NULL; function = NULL; n_src = 0; arg[0].c = NULL; arg[1].c = NULL; ds_init_empty (&function_name); /* Parse the list of target variables. */ while (!lex_match (lexer, T_EQUALS)) { size_t n_dest_prev = n_dest; if (!parse_DATA_LIST_vars (lexer, dict, &dest, &n_dest, (PV_APPEND | PV_SINGLE | PV_NO_SCRATCH | PV_NO_DUPLICATE))) goto error; /* Assign empty labels. */ { int j; dest_label = xnrealloc (dest_label, n_dest, sizeof *dest_label); for (j = n_dest_prev; j < n_dest; j++) dest_label[j] = NULL; } if (lex_is_string (lexer)) { dest_label[n_dest - 1] = xstrdup (lex_tokcstr (lexer)); lex_get (lexer); } } /* Get the name of the aggregation function. */ if (lex_token (lexer) != T_ID) { lex_error (lexer, _("expecting aggregation function")); goto error; } ds_assign_substring (&function_name, lex_tokss (lexer)); exclude = ds_chomp_byte (&function_name, '.') ? MV_SYSTEM : MV_ANY; for (function = agr_func_tab; function->name; function++) if (!c_strcasecmp (function->name, ds_cstr (&function_name))) break; if (NULL == function->name) { msg (SE, _("Unknown aggregation function %s."), ds_cstr (&function_name)); goto error; } ds_destroy (&function_name); func_index = function - agr_func_tab; lex_get (lexer); /* Check for leading lparen. */ if (!lex_match (lexer, T_LPAREN)) { if (function->src_vars == AGR_SV_YES) { lex_force_match (lexer, T_LPAREN); goto error; } } else { /* Parse list of source variables. */ { int pv_opts = PV_NO_SCRATCH; if (func_index == SUM || func_index == MEAN || func_index == SD) pv_opts |= PV_NUMERIC; else if (function->n_args) pv_opts |= PV_SAME_TYPE; if (!parse_variables_const (lexer, dict, &src, &n_src, pv_opts)) goto error; } /* Parse function arguments, for those functions that require arguments. */ if (function->n_args != 0) for (i = 0; i < function->n_args; i++) { int type; lex_match (lexer, T_COMMA); if (lex_is_string (lexer)) { arg[i].c = recode_string (dict_get_encoding (agr->dict), "UTF-8", lex_tokcstr (lexer), -1); type = VAL_STRING; } else if (lex_is_number (lexer)) { arg[i].f = lex_tokval (lexer); type = VAL_NUMERIC; } else { msg (SE, _("Missing argument %zu to %s."), i + 1, function->name); goto error; } lex_get (lexer); if (type != var_get_type (src[0])) { msg (SE, _("Arguments to %s must be of same type as " "source variables."), function->name); goto error; } } /* Trailing rparen. */ if (!lex_force_match (lexer, T_RPAREN)) goto error; /* Now check that the number of source variables match the number of target variables. If we check earlier than this, the user can get very misleading error message, i.e. `AGGREGATE x=SUM(y t).' will get this error message when a proper message would be more like `unknown variable t'. */ if (n_src != n_dest) { msg (SE, _("Number of source variables (%zu) does not match " "number of target variables (%zu)."), n_src, n_dest); goto error; } if ((func_index == PIN || func_index == POUT || func_index == FIN || func_index == FOUT) && (var_is_numeric (src[0]) ? arg[0].f > arg[1].f : str_compare_rpad (arg[0].c, arg[1].c) > 0)) { union agr_argument t = arg[0]; arg[0] = arg[1]; arg[1] = t; msg (SW, _("The value arguments passed to the %s function " "are out-of-order. They will be treated as if " "they had been specified in the correct order."), function->name); } } /* Finally add these to the linked list of aggregation variables. */ for (i = 0; i < n_dest; i++) { struct agr_var *v = xzalloc (sizeof *v); /* Add variable to chain. */ if (agr->agr_vars != NULL) tail->next = v; else agr->agr_vars = v; tail = v; tail->next = NULL; v->moments = NULL; /* Create the target variable in the aggregate dictionary. */ { struct variable *destvar; v->function = func_index; if (src) { v->src = src[i]; if (var_is_alpha (src[i])) { v->function |= FSTRING; v->string = xmalloc (var_get_width (src[i])); } if (function->alpha_type == VAL_STRING) destvar = dict_clone_var_as (agr->dict, v->src, dest[i]); else { assert (var_is_numeric (v->src) || function->alpha_type == VAL_NUMERIC); destvar = dict_create_var (agr->dict, dest[i], 0); if (destvar != NULL) { struct fmt_spec f; if ((func_index == N || func_index == NMISS) && dict_get_weight (dict) != NULL) f = fmt_for_output (FMT_F, 8, 2); else f = function->format; var_set_both_formats (destvar, &f); } } } else { struct fmt_spec f; v->src = NULL; destvar = dict_create_var (agr->dict, dest[i], 0); if (destvar != NULL) { if ((func_index == N || func_index == NMISS) && dict_get_weight (dict) != NULL) f = fmt_for_output (FMT_F, 8, 2); else f = function->format; var_set_both_formats (destvar, &f); } } if (!destvar) { msg (SE, _("Variable name %s is not unique within the " "aggregate file dictionary, which contains " "the aggregate variables and the break " "variables."), dest[i]); goto error; } free (dest[i]); if (dest_label[i]) var_set_label (destvar, dest_label[i]); v->dest = destvar; } v->exclude = exclude; if (v->src != NULL) { int j; if (var_is_numeric (v->src)) for (j = 0; j < function->n_args; j++) v->arg[j].f = arg[j].f; else for (j = 0; j < function->n_args; j++) v->arg[j].c = xstrdup (arg[j].c); } } if (src != NULL && var_is_alpha (src[0])) for (i = 0; i < function->n_args; i++) { free (arg[i].c); arg[i].c = NULL; } free (src); free (dest); free (dest_label); if (!lex_match (lexer, T_SLASH)) { if (lex_token (lexer) == T_ENDCMD) return true; lex_error (lexer, "expecting end of command"); return false; } continue; error: ds_destroy (&function_name); for (i = 0; i < n_dest; i++) { free (dest[i]); free (dest_label[i]); } free (dest); free (dest_label); free (arg[0].c); free (arg[1].c); if (src && n_src && var_is_alpha (src[0])) for (i = 0; i < function->n_args; i++) { free (arg[i].c); arg[i].c = NULL; } free (src); return false; } }
static enum numbered_backup_result numbered_backup (char **buffer, size_t buffer_size, size_t filelen) { enum numbered_backup_result result = BACKUP_IS_NEW; DIR *dirp; struct dirent *dp; char *buf = *buffer; size_t versionlenmax = 1; char *base = last_component (buf); size_t base_offset = base - buf; size_t baselen = base_len (base); /* Temporarily modify the buffer into its parent directory name, open the directory, and then restore the buffer. */ char tmp[sizeof "."]; memcpy (tmp, base, sizeof "."); strcpy (base, "."); dirp = opendir (buf); memcpy (base, tmp, sizeof "."); strcpy (base + baselen, ".~1~"); if (!dirp) return result; while ((dp = readdir (dirp)) != NULL) { char const *p; char *q; bool all_9s; size_t versionlen; size_t new_buflen; if (! REAL_DIR_ENTRY (dp) || _D_EXACT_NAMLEN (dp) < baselen + 4) continue; if (memcmp (buf + base_offset, dp->d_name, baselen + 2) != 0) continue; p = dp->d_name + baselen + 2; /* Check whether this file has a version number and if so, whether it is larger. Use string operations rather than integer arithmetic, to avoid problems with integer overflow. */ if (! ('1' <= *p && *p <= '9')) continue; all_9s = (*p == '9'); for (versionlen = 1; ISDIGIT (p[versionlen]); versionlen++) all_9s &= (p[versionlen] == '9'); if (! (p[versionlen] == '~' && !p[versionlen + 1] && (versionlenmax < versionlen || (versionlenmax == versionlen && memcmp (buf + filelen + 2, p, versionlen) <= 0)))) continue; /* This directory has the largest version number seen so far. Append this highest numbered extension to the file name, prepending '0' to the number if it is all 9s. */ versionlenmax = all_9s + versionlen; result = (all_9s ? BACKUP_IS_LONGER : BACKUP_IS_SAME_LENGTH); new_buflen = filelen + 2 + versionlenmax + 1; if (buffer_size <= new_buflen) { buf = xnrealloc (buf, 2, new_buflen); buffer_size = new_buflen * 2; } q = buf + filelen; *q++ = '.'; *q++ = '~'; *q = '0'; q += all_9s; memcpy (q, p, versionlen + 2); /* Add 1 to the version number. */ q += versionlen; while (*--q == '9') *q = '0'; ++*q; } closedir (dirp); *buffer = buf; return result; }
/* Call ioctl(2) with FS_IOC_FIEMAP (available in linux 2.6.27) to obtain a map of file extents excluding holes. */ extern bool extent_scan_read (struct extent_scan *scan) { unsigned int si = 0; struct extent_info *last_ei = scan->ext_info; while (true) { union { struct fiemap f; char c[4096]; } fiemap_buf; struct fiemap *fiemap = &fiemap_buf.f; struct fiemap_extent *fm_extents = &fiemap->fm_extents[0]; enum { count = (sizeof fiemap_buf - sizeof *fiemap)/sizeof *fm_extents }; verify (count > 1); /* This is required at least to initialize fiemap->fm_start, but also serves (in mid 2010) to appease valgrind, which appears not to know the semantics of the FIEMAP ioctl. */ memset (&fiemap_buf, 0, sizeof fiemap_buf); fiemap->fm_start = scan->scan_start; fiemap->fm_flags = scan->fm_flags; fiemap->fm_extent_count = count; fiemap->fm_length = FIEMAP_MAX_OFFSET - scan->scan_start; /* Fall back to the standard copy if call ioctl(2) failed for the first time. */ if (ioctl (scan->fd, FS_IOC_FIEMAP, fiemap) < 0) { if (scan->scan_start == 0) scan->initial_scan_failed = true; return false; } /* If 0 extents are returned, then no more scans are needed. */ if (fiemap->fm_mapped_extents == 0) { scan->hit_final_extent = true; return scan->scan_start != 0; } assert (scan->ei_count <= SIZE_MAX - fiemap->fm_mapped_extents); scan->ei_count += fiemap->fm_mapped_extents; { /* last_ei points into a buffer that may be freed via xnrealloc. Record its offset and adjust after allocation. */ size_t prev_idx = last_ei - scan->ext_info; scan->ext_info = xnrealloc (scan->ext_info, scan->ei_count, sizeof (struct extent_info)); last_ei = scan->ext_info + prev_idx; } unsigned int i = 0; for (i = 0; i < fiemap->fm_mapped_extents; i++) { assert (fm_extents[i].fe_logical <= OFF_T_MAX - fm_extents[i].fe_length); if (si && last_ei->ext_flags == (fm_extents[i].fe_flags & ~FIEMAP_EXTENT_LAST) && (last_ei->ext_logical + last_ei->ext_length == fm_extents[i].fe_logical)) { /* Merge previous with last. */ last_ei->ext_length += fm_extents[i].fe_length; /* Copy flags in case different. */ last_ei->ext_flags = fm_extents[i].fe_flags; } else if ((si == 0 && scan->scan_start > fm_extents[i].fe_logical) || (si && (last_ei->ext_logical + last_ei->ext_length > fm_extents[i].fe_logical))) { /* BTRFS before 2.6.38 could return overlapping extents for sparse files. We adjust the returned extents rather than failing, as otherwise it would be inefficient to detect this on the initial scan. */ uint64_t new_logical; uint64_t length_adjust; if (si == 0) new_logical = scan->scan_start; else { /* We could return here if scan->scan_start == 0 but don't so as to minimize special cases. */ new_logical = last_ei->ext_logical + last_ei->ext_length; } length_adjust = new_logical - fm_extents[i].fe_logical; /* If an extent is contained within the previous one, fail. */ if (length_adjust < fm_extents[i].fe_length) { if (scan->scan_start == 0) scan->initial_scan_failed = true; return false; } fm_extents[i].fe_logical = new_logical; fm_extents[i].fe_length -= length_adjust; /* Process the adjusted extent again. */ i--; continue; } else { last_ei = scan->ext_info + si; last_ei->ext_logical = fm_extents[i].fe_logical; last_ei->ext_length = fm_extents[i].fe_length; last_ei->ext_flags = fm_extents[i].fe_flags; si++; } } if (last_ei->ext_flags & FIEMAP_EXTENT_LAST) scan->hit_final_extent = true; /* If we have enough extents, discard the last as it might be merged with one from the next scan. */ if (si > count && !scan->hit_final_extent) last_ei = scan->ext_info + --si - 1; /* We don't bother reallocating any trailing slots. */ scan->ei_count = si; if (scan->hit_final_extent) break; else scan->scan_start = last_ei->ext_logical + last_ei->ext_length; if (si >= count) break; } return true; }
void GEAcompile (char const *pattern, size_t size, reg_syntax_t syntax_bits) { const char *err; const char *p, *sep; size_t total = size; char *motif; if (match_icase) syntax_bits |= RE_ICASE; re_set_syntax (syntax_bits); dfasyntax (syntax_bits, match_icase, eolbyte); /* For GNU regex compiler we have to pass the patterns separately to detect errors like "[\nallo\n]\n". The patterns here are "[", "allo" and "]" GNU regex should have raise a syntax error. The same for backref, where the backref should have been local to each pattern. */ p = pattern; do { size_t len; sep = memchr (p, '\n', total); if (sep) { len = sep - p; sep++; total -= (len + 1); } else { len = total; total = 0; } patterns = xnrealloc (patterns, pcount + 1, sizeof *patterns); patterns[pcount] = patterns0; if ((err = re_compile_pattern (p, len, &(patterns[pcount].regexbuf))) != NULL) error (EXIT_TROUBLE, 0, "%s", err); pcount++; p = sep; } while (sep && total != 0); /* In the match_words and match_lines cases, we use a different pattern for the DFA matcher that will quickly throw out cases that won't work. Then if DFA succeeds we do some hairy stuff using the regex matcher to decide whether the match should really count. */ if (match_words || match_lines) { static char const line_beg_no_bk[] = "^("; static char const line_end_no_bk[] = ")$"; static char const word_beg_no_bk[] = "(^|[^[:alnum:]_])("; static char const word_end_no_bk[] = ")([^[:alnum:]_]|$)"; static char const line_beg_bk[] = "^\\("; static char const line_end_bk[] = "\\)$"; static char const word_beg_bk[] = "\\(^\\|[^[:alnum:]_]\\)\\("; static char const word_end_bk[] = "\\)\\([^[:alnum:]_]\\|$\\)"; int bk = !(syntax_bits & RE_NO_BK_PARENS); char *n = xmalloc (sizeof word_beg_bk - 1 + size + sizeof word_end_bk); strcpy (n, match_lines ? (bk ? line_beg_bk : line_beg_no_bk) : (bk ? word_beg_bk : word_beg_no_bk)); total = strlen(n); memcpy (n + total, pattern, size); total += size; strcpy (n + total, match_lines ? (bk ? line_end_bk : line_end_no_bk) : (bk ? word_end_bk : word_end_no_bk)); total += strlen (n + total); pattern = motif = n; size = total; } else motif = NULL; dfa = dfaalloc (); dfacomp (pattern, size, dfa, 1); kwsmusts (); free(motif); }
bool xifocus_update(struct _xifocus *p) { struct _xobj *owner = p->owner; Window old_window = owner->xWindow; char *old_app_name = NULL; if (old_window != None) old_app_name = owner->get_wmclass_name(owner); int revert_to; Window new_window; XGetInputFocus(owner->xDisplay, &new_window, &revert_to); if (new_window == None) // If no window focused { p->ptr_count = 0; return FALSE; } p->changed = FALSE; if (new_window != old_window) { p->changed = TRUE; owner->xWindow = new_window; char *new_app_name = owner->get_wmclass_name(owner); if (!new_app_name || !old_app_name || strcmp(new_app_name, old_app_name) != 0) log_message(DEBUG, "New processed window with name '%s' (%d)", new_app_name, new_window); if (new_app_name) free(new_app_name); } if (old_app_name) free(old_app_name); p->ptr_count = 0; if (revert_to != RevertToPointerRoot) return TRUE; while (1) { int dummy; unsigned int dummyU; Window root_window; bool is_same_screen = XQueryPointer(owner->xDisplay, new_window, &root_window, &new_window, &dummy, &dummy, &dummy, &dummy, &dummyU); if (!is_same_screen || new_window == None) return TRUE; p->ptr_count++; if (p->ptr_count >= p->ptr_size) { p->ptr_size = p->ptr_count; p->ptr = (struct _xobj **) xnrealloc(p->ptr, p->ptr_size * sizeof(struct _xobj *)); p->ptr[p->ptr_count - 1] = xobj_init(); } struct _xobj *new_obj = p->ptr[p->ptr_count - 1]; new_obj->xDisplay = owner->xDisplay; new_obj->xWindow = new_window; } }
/* Parse a line of space-separated wildcards and add them to the list. */ void ign_add (char *ign, int hold) { if (!ign || !*ign) return; for (; *ign; ign++) { char *mark; char save; /* ignore whitespace before the token */ if (isspace ((unsigned char) *ign)) continue; /* If we have used up all the space, add some more. Do this before processing `!', since an "empty" list still contains the `CVS' entry. */ if (ign_count >= ign_size) { ign_size += IGN_GROW; ign_list = xnrealloc (ign_list, ign_size + 1, sizeof (char *)); } /* * if we find a single character !, we must re-set the ignore list * (saving it if necessary). We also catch * as a special case in a * global ignore file as an optimization */ if ((!*(ign+1) || isspace ((unsigned char) *(ign+1))) && (*ign == '!' || *ign == '*')) { if (!hold) { /* permanently reset the ignore list */ int i; for (i = 0; i < ign_count; i++) free (ign_list[i]); ign_count = 1; /* Always ignore the "CVS" directory. */ ign_list[0] = xstrdup ("CVS"); ign_list[1] = NULL; /* if we are doing a '!', continue; otherwise add the '*' */ if (*ign == '!') { ign_inhibit_server = 1; continue; } } else if (*ign == '!') { /* temporarily reset the ignore list */ int i; if (ign_hold >= 0) { for (i = ign_hold; i < ign_count; i++) free (ign_list[i]); ign_hold = -1; } if (s_ign_list) { /* Don't save the ignore list twice - if there are two * bangs in a local .cvsignore file then we don't want to * save the new list the first bang created. * * We still need to free the "new" ignore list. */ for (i = 0; i < ign_count; i++) free (ign_list[i]); } else { /* Save the ignore list for later. */ s_ign_list = xnmalloc (ign_count, sizeof (char *)); for (i = 0; i < ign_count; i++) s_ign_list[i] = ign_list[i]; s_ign_count = ign_count; } ign_count = 1; /* Always ignore the "CVS" directory. */ ign_list[0] = xstrdup ("CVS"); ign_list[1] = NULL; continue; } } /* find the end of this token */ for (mark = ign; *mark && !isspace ((unsigned char) *mark); mark++) /* do nothing */ ; save = *mark; *mark = '\0'; ign_list[ign_count++] = xstrdup (ign); ign_list[ign_count] = NULL; *mark = save; if (save) ign = mark; else ign = mark - 1; } }
/* read_hrecs_file's job is to read a history file and fill in new "hrec" * (history record) array elements with the ones we need to print. * * Logic: * - Read a block from the file. * - Walk through the block parsing line into hr records. * - if the hr isn't used, free its strings, if it is, bump the hrec counter * - at the end of a block, copy the end of the current block to the start * of space for the next block, then read in the next block. If we get less * than the whole block, we're done. */ static int read_hrecs_file (Node *p, void *closure) { char *cpstart, *cpend, *cp, *nl; char *hrline; int i; int fd; struct stat st_buf; const char *fname = p->key; if ((fd = CVS_OPEN (fname, O_RDONLY | OPEN_BINARY)) < 0) { error (0, errno, "cannot open history file `%s'", fname); return 0; } if (fstat (fd, &st_buf) < 0) { error (0, errno, "can't stat history file `%s'", fname); return 0; } if (!(st_buf.st_size)) { error (0, 0, "history file `%s' is empty", fname); return 0; } cpstart = xnmalloc (2, STAT_BLOCKSIZE (st_buf)); cpstart[0] = '\0'; cp = cpend = cpstart; for (;;) { for (nl = cp; nl < cpend && *nl != '\n'; nl++) if (!isprint (*nl)) *nl = ' '; if (nl >= cpend) { if (nl - cp >= STAT_BLOCKSIZE (st_buf)) { error(1, 0, "history line %ld too long (> %lu)", hrec_idx + 1, (unsigned long) STAT_BLOCKSIZE(st_buf)); } if (nl > cp) memmove (cpstart, cp, nl - cp); nl = cpstart + (nl - cp); cp = cpstart; i = read (fd, nl, STAT_BLOCKSIZE(st_buf)); if (i > 0) { cpend = nl + i; *cpend = '\0'; continue; } if (i < 0) { error (0, errno, "error reading history file `%s'", fname); return 0; } if (nl == cp) break; error (0, 0, "warning: no newline at end of history file `%s'", fname); } *nl = '\0'; if (hrec_count == hrec_max) { struct hrec *old_head = hrec_head; hrec_max += HREC_INCREMENT; hrec_head = xnrealloc (hrec_head, hrec_max, sizeof (struct hrec)); if (last_since_tag) last_since_tag = hrec_head + (last_since_tag - old_head); if (last_backto) last_backto = hrec_head + (last_backto - old_head); } /* fill_hrec dates from when history read the entire history file in one chunk, and then records were pulled out by pointing to the various parts of this big chunk. This is why there are ugly hacks here: I don't want to completely re-write the whole history stuff right now. */ hrline = xstrdup (cp); fill_hrec (hrline, &hrec_head[hrec_count]); if (select_hrec (&hrec_head[hrec_count])) hrec_count++; else free (hrline); cp = nl + 1; } free (cpstart); close (fd); return 1; }