Style * new_style(const char *name, LList *spec) { Style *style; Iterator *it; StrBuf *prebuf; StrBuf *postbuf; style = xmalloc(sizeof(Style)); style->name = xstrdup(name); prebuf = strbuf_new(); postbuf = strbuf_new(); for (it = llist_iterator(spec); iterator_has_next(it); ) { StyleInfo *info = iterator_next(it); if (info->type == STYLEINFO_PRE) { strbuf_append(prebuf, info->value); } else if (info->type == STYLEINFO_POST) { strbuf_prepend(postbuf, info->value); } else if (info->type == STYLEINFO_STYLE) { const Style *add_style = info->value; strbuf_append(prebuf, add_style->pre_string); strbuf_prepend(postbuf, add_style->post_string); } } style->pre_string = strbuf_free_to_string(prebuf); style->post_string = strbuf_free_to_string(postbuf); style->refs = 1; return style; }
static FILE * extract_outfile_gen(char **outname_ptr, int w, int h, int bc, int i) { char *inname = *outname_ptr; if (output == NULL || is_directory(output)) { StrBuf *outname; char *inbase; outname = strbuf_new(); if (output != NULL) { strbuf_append(outname, output); if (!ends_with(output, "/")) strbuf_append(outname, "/"); } inbase = strrchr(inname, '/'); inbase = (inbase == NULL ? inname : inbase+1); if (ends_with_nocase(inbase, ".ico") || ends_with_nocase(inbase, ".cur")) { strbuf_append_substring(outname, inbase, 0, strlen(inbase)-4); } else { strbuf_append(outname, inbase); } strbuf_appendf(outname, "_%d_%dx%dx%d.png", i, w, h, bc); *outname_ptr = strbuf_free_to_string(outname); return fopen(*outname_ptr, "wb"); } else if (strcmp(output, "-") == 0) { *outname_ptr = xstrdup(_("(standard out)")); return stdout; } *outname_ptr = xstrdup(output); return fopen(output, "wb"); }
static void fix_string(bool retain_backslashes, int skip_count, char endchar) { StrBuf *out = strbuf_new(); int c; for (c = 1+skip_count; yytext[c] != endchar; c++) { char ch = yytext[c]; if (ch == '\\' && c+1 < yyleng) { ch = yytext[++c]; if (retain_backslashes) { strbuf_append_char(out, '\\'); } else { switch (ch) { case 'a': ch = '\a'; break; case 'b': ch = '\b'; break; case 't': ch = '\t'; break; case 'n': ch = '\n'; break; case 'v': ch = '\v'; break; case 'f': ch = '\f'; break; case 'r': ch = '\r'; break; case 'e': case 'E': ch = 27; break; } } } strbuf_append_char(out, ch); } set_string(strbuf_free_to_string(out)); }
char * backticks(const char *program, char *const args[], int *status) { int child_pipe[2]; int child_pid; FILE *pipe_file; char *line; StrBuf *out; if (pipe(child_pipe) == -1) return NULL; child_pid = fork(); if (child_pid == -1) return NULL; if (child_pid == 0) { if (close(child_pipe[0]) == -1) die_errno(NULL); if (close(STDOUT_FILENO) == -1) die_errno(NULL); if (dup2(child_pipe[1], STDOUT_FILENO) == -1) die_errno(NULL); execvp(program, args); die_errno(NULL); } if (close(child_pipe[1]) == -1) return NULL; pipe_file = fdopen(child_pipe[0], "r"); if (pipe_file == NULL) return NULL; out = strbuf_new(); if (out == NULL) return NULL; while ((line = read_line(pipe_file)) != NULL) { strbuf_append(out, line); free(line); } if (errno != 0) return NULL; if (waitpid(child_pid, status, 0) != child_pid) return NULL; if (fclose(pipe_file) != 0) return NULL; return strbuf_free_to_string(out); }
static char * var_get_display_flags(DCVariable *var) { StrBuf *out; uint32_t c; uint32_t flags; flags = *(uint32_t *) var->value; out = strbuf_new(); for (c = 0; c < display_flag_count; c++) { if (flags & display_flag_details[c].flag) { if (!strbuf_is_empty(out)) strbuf_append_char(out, ' '); strbuf_append(out, display_flag_details[c].name); } } return strbuf_free_to_string(out); }
/* Note: It is kind of stupid to first call strbuf_free_to_string, * then later free (above this function). But with the current API * of strbuf_free there's no other way! */ char * expand_substitution(const char *repl, MatchState *ms, uint32_t subc, SubmatchSpec *subv) { StrBuf *buf = strbuf_new(); /* XXX: memory management */ bool escaped = false; uint32_t c; for (c = 0; repl[c] != '\0'; c++) { if (!escaped && repl[c] == '$') { uint32_t d; if (repl[c+1] == '{') { for (d = c+2; repl[d] != '}' && repl[d] != '\0'; d++); if (repl[d] != '\0') { if (expand_variable(buf, repl+c+2, d-c-2, ms, subc, subv)) { c = d; continue; } } } else if (isdigit(repl[c+1])) { for (d = c+2; isdigit(repl[d]); d++); if (expand_variable(buf, repl+c+1, d-c-1, ms, subc, subv)) { c = d-1; continue; } } else if (repl[c+1] != '\0' && strchr("`'&", repl[c+1]) != NULL) { expand_variable(buf, repl+c+1, 1, ms, subc, subv); c++; continue; } } escaped = (!escaped && repl[c] == '\\'); if (!escaped) strbuf_append_char(buf, repl[c]); } return strbuf_free_to_string(buf); }
/* Quote STRING with double quotes if QUOTED is true, otherwise * by escaping whitespace, double quote and backslash as well * as characters in QC. Also, if the first character in STRING * is found in LEADING_QC, that character will be escaped. */ char * quote_word_full(const char *string, bool quoted, bool add_end_quote, const char *qc, const char *leading_qc, bool quote_non_print_hex, bool quote_non_print_oct, bool quote_non_print_c, bool quote_wc) { StrBuf *r = strbuf_new(); const char *s; const unsigned char *u_s; if (quoted) { strbuf_append_char(r, '"'); for (s = string; *s != '\0'; s++) { if (quote_non_print_c) { int chr = 0; switch (*s) { case '\a': chr = 'a'; break; case '\b': chr = 'b'; break; case '\f': chr = 'f'; break; case '\n': chr = 'n'; break; case '\r': chr = 'r'; break; case '\t': chr = 't'; break; case '\v': chr = 'v'; break; } if (chr != 0) { strbuf_appendf(r, "\\%c", chr); continue; } } u_s = (const unsigned char *)s; if (quote_non_print_hex && !isprint(*u_s)) { strbuf_appendf(r, "\\x%02x", (unsigned)*s); } else if (quote_non_print_oct && !isprint(*u_s)) { strbuf_appendf(r, "\\%03o", (unsigned)*s); } else { if (*s == '"' || *s == '\\') strbuf_append_char(r, '\\'); strbuf_append_char(r, *s); } } if (add_end_quote) strbuf_append_char(r, '"'); } else { for (s = string; *s != '\0'; s++) { if (quote_non_print_c) { int chr = 0; switch (*s) { case '\a': chr = 'a'; break; case '\b': chr = 'b'; break; case '\f': chr = 'f'; break; case '\n': chr = 'n'; break; case '\r': chr = 'r'; break; case '\t': chr = 't'; break; case '\v': chr = 'v'; break; } if (chr != 0) { strbuf_appendf(r, "\\%c", chr); continue; } } u_s = (const unsigned char *)s; if (quote_non_print_hex && !isprint(*u_s)) { strbuf_appendf(r, "\\x%02x", (unsigned)*s); } else if (quote_non_print_oct && !isprint(*u_s)) { strbuf_appendf(r, "\\%03o", (unsigned)*u_s); } else { if (*s == '"' || *s == '\\' || (quote_wc && *s == ' ') || strchr(qc, *s) != NULL || (s == string && strchr(leading_qc, *u_s) != NULL)) strbuf_append_char(r, '\\'); strbuf_append_char(r, *s); } } } return strbuf_free_to_string(r); }