static void finalize(cmark_doc_parser *parser, cmark_node* b, int line_number) { int firstlinelen; int pos; cmark_node* item; cmark_node* subitem; if (!b->open) return; // don't do anything if the cmark_node is already closed b->open = false; if (line_number > b->start_line) { b->end_line = line_number - 1; } else { b->end_line = line_number; } switch (b->type) { case NODE_PARAGRAPH: pos = 0; while (strbuf_at(&b->string_content, 0) == '[' && (pos = parse_reference_inline(&b->string_content, parser->refmap))) { strbuf_drop(&b->string_content, pos); } if (is_blank(&b->string_content, 0)) { b->type = NODE_REFERENCE_DEF; } break; case NODE_INDENTED_CODE: remove_trailing_blank_lines(&b->string_content); strbuf_putc(&b->string_content, '\n'); break; case NODE_FENCED_CODE: // first line of contents becomes info firstlinelen = strbuf_strchr(&b->string_content, '\n', 0); strbuf_init(&b->as.code.info, 0); houdini_unescape_html_f( &b->as.code.info, b->string_content.ptr, firstlinelen ); strbuf_drop(&b->string_content, firstlinelen + 1); strbuf_trim(&b->as.code.info); strbuf_unescape(&b->as.code.info); break; case NODE_LIST: // determine tight/loose status b->as.list.tight = true; // tight by default item = b->first_child; while (item) { // check for non-final non-empty list item ending with blank line: if (item->last_line_blank && item->next) { b->as.list.tight = false; break; } // recurse into children of list item, to see if there are // spaces between them: subitem = item->first_child; while (subitem) { if (ends_with_blank_line(subitem) && (item->next || subitem->next)) { b->as.list.tight = false; break; } subitem = subitem->next; } if (!(b->as.list.tight)) { break; } item = item->next; } break; default: break; } }
static int handle_cache(const char *path, unsigned char *sha1, const char *output) { mmfile_t mmfile[3] = {{NULL}}; mmbuffer_t result = {NULL, 0}; const struct cache_entry *ce; int pos, len, i, hunk_no; struct rerere_io_mem io; int marker_size = ll_merge_marker_size(path); /* * Reproduce the conflicted merge in-core */ len = strlen(path); pos = cache_name_pos(path, len); if (0 <= pos) return -1; pos = -pos - 1; for (i = 0; i < 3; i++) { enum object_type type; unsigned long size; int j; if (active_nr <= pos) break; ce = active_cache[pos++]; if (ce_namelen(ce) != len || memcmp(ce->name, path, len)) continue; j = ce_stage(ce) - 1; mmfile[j].ptr = read_sha1_file(ce->sha1, &type, &size); mmfile[j].size = size; } for (i = 0; i < 3; i++) { if (!mmfile[i].ptr && !mmfile[i].size) mmfile[i].ptr = xstrdup(""); } /* * NEEDSWORK: handle conflicts from merges with * merge.renormalize set, too */ ll_merge(&result, path, &mmfile[0], NULL, &mmfile[1], "ours", &mmfile[2], "theirs", NULL); for (i = 0; i < 3; i++) free(mmfile[i].ptr); memset(&io, 0, sizeof(io)); io.io.getline = rerere_mem_getline; if (output) io.io.output = fopen(output, "w"); else io.io.output = NULL; strbuf_init(&io.input, 0); strbuf_attach(&io.input, result.ptr, result.size, result.size); hunk_no = handle_path(sha1, (struct rerere_io *)&io, marker_size); strbuf_release(&io.input); if (io.io.output) fclose(io.io.output); return hunk_no; }
static void json_create_config(lua_State *l) { json_config_t *cfg; int i; cfg = lua_newuserdata(l, sizeof(*cfg)); /* Create GC method to clean up strbuf */ lua_newtable(l); lua_pushcfunction(l, json_destroy_config); lua_setfield(l, -2, "__gc"); lua_setmetatable(l, -2); cfg->encode_sparse_convert = DEFAULT_SPARSE_CONVERT; cfg->encode_sparse_ratio = DEFAULT_SPARSE_RATIO; cfg->encode_sparse_safe = DEFAULT_SPARSE_SAFE; cfg->encode_max_depth = DEFAULT_ENCODE_MAX_DEPTH; cfg->decode_max_depth = DEFAULT_DECODE_MAX_DEPTH; cfg->encode_invalid_numbers = DEFAULT_ENCODE_INVALID_NUMBERS; cfg->decode_invalid_numbers = DEFAULT_DECODE_INVALID_NUMBERS; cfg->encode_keep_buffer = DEFAULT_ENCODE_KEEP_BUFFER; cfg->encode_number_precision = DEFAULT_ENCODE_NUMBER_PRECISION; #if DEFAULT_ENCODE_KEEP_BUFFER > 0 strbuf_init(&cfg->encode_buf, 0); #endif /* Decoding init */ /* Tag all characters as an error */ for (i = 0; i < 256; i++) cfg->ch2token[i] = T_ERROR; /* Set tokens that require no further processing */ cfg->ch2token['{'] = T_OBJ_BEGIN; cfg->ch2token['}'] = T_OBJ_END; cfg->ch2token['['] = T_ARR_BEGIN; cfg->ch2token[']'] = T_ARR_END; cfg->ch2token[','] = T_COMMA; cfg->ch2token[':'] = T_COLON; cfg->ch2token['\0'] = T_END; cfg->ch2token[' '] = T_WHITESPACE; cfg->ch2token['\t'] = T_WHITESPACE; cfg->ch2token['\n'] = T_WHITESPACE; cfg->ch2token['\r'] = T_WHITESPACE; /* Update characters that require further processing */ cfg->ch2token['f'] = T_UNKNOWN; /* false? */ cfg->ch2token['i'] = T_UNKNOWN; /* inf, ininity? */ cfg->ch2token['I'] = T_UNKNOWN; cfg->ch2token['n'] = T_UNKNOWN; /* null, nan? */ cfg->ch2token['N'] = T_UNKNOWN; cfg->ch2token['t'] = T_UNKNOWN; /* true? */ cfg->ch2token['"'] = T_UNKNOWN; /* string? */ cfg->ch2token['+'] = T_UNKNOWN; /* number? */ cfg->ch2token['-'] = T_UNKNOWN; for (i = 0; i < 10; i++) cfg->ch2token['0' + i] = T_UNKNOWN; /* Lookup table for parsing escape characters */ for (i = 0; i < 256; i++) cfg->escape2char[i] = 0; /* String error */ cfg->escape2char['"'] = '"'; cfg->escape2char['\\'] = '\\'; cfg->escape2char['/'] = '/'; cfg->escape2char['b'] = '\b'; cfg->escape2char['t'] = '\t'; cfg->escape2char['n'] = '\n'; cfg->escape2char['f'] = '\f'; cfg->escape2char['r'] = '\r'; cfg->escape2char['u'] = 'u'; /* Unicode parsing required */ }
static int get_stash_info(struct stash_info *info, int argc, const char **argv) { int ret; char *end_of_rev; char *expanded_ref; const char *revision; const char *commit = NULL; struct object_id dummy; struct strbuf symbolic = STRBUF_INIT; if (argc > 1) { int i; struct strbuf refs_msg = STRBUF_INIT; for (i = 0; i < argc; i++) strbuf_addf(&refs_msg, " '%s'", argv[i]); fprintf_ln(stderr, _("Too many revisions specified:%s"), refs_msg.buf); strbuf_release(&refs_msg); return -1; } if (argc == 1) commit = argv[0]; strbuf_init(&info->revision, 0); if (!commit) { if (!ref_exists(ref_stash)) { free_stash_info(info); fprintf_ln(stderr, _("No stash entries found.")); return -1; } strbuf_addf(&info->revision, "%s@{0}", ref_stash); } else if (strspn(commit, "0123456789") == strlen(commit)) { strbuf_addf(&info->revision, "%s@{%s}", ref_stash, commit); } else { strbuf_addstr(&info->revision, commit); } revision = info->revision.buf; if (get_oid(revision, &info->w_commit)) { error(_("%s is not a valid reference"), revision); free_stash_info(info); return -1; } assert_stash_like(info, revision); info->has_u = !get_oidf(&info->u_tree, "%s^3:", revision); end_of_rev = strchrnul(revision, '@'); strbuf_add(&symbolic, revision, end_of_rev - revision); ret = dwim_ref(symbolic.buf, symbolic.len, &dummy, &expanded_ref); strbuf_release(&symbolic); switch (ret) { case 0: /* Not found, but valid ref */ info->is_stash_ref = 0; break; case 1: info->is_stash_ref = !strcmp(expanded_ref, ref_stash); break; default: /* Invalid or ambiguous */ free_stash_info(info); } free(expanded_ref); return !(ret == 0 || ret == 1); }
static int parse_commit(struct strbuf* input, struct string_list* files, struct strbuf* message) { int err; int pos; struct strbuf line; int lineno = 0; enum { BEGIN, FILES, MESSAGE } state = BEGIN; enum { OK, FAILED } result = OK; // if there is no data, just return if (input->len == 0) { return 0; } strbuf_init(&line, 0); pos = 0; while (result == OK) { err = get_strbuf_line(input, &pos, &line); lineno++; if (err != 0) { break; } if (is_comment(&line)) { continue; } switch (state) { case BEGIN: strbuf_trim(&line); if (line.len != 0) { if (0 == strcmp(line.buf, "Files:")) { state = FILES; } else { result = FAILED; } } break; case FILES: strbuf_trim(&line); if (line.len != 0) { if (0 == strcmp(line.buf, "Commit Message:")) { state = MESSAGE; } else if (0 == strip_file_info(&line)) { string_list_insert(line.buf, files); } else { result = FAILED; } } break; case MESSAGE: strbuf_rtrim(&line); strbuf_addbuf(message, &line); strbuf_addch(message, '\n'); break; } } strbuf_trim(message); return result == OK ? 0 : 1; }
/* ** Put up dialog box and begin conversion ** ** 0 okay ** -1 dialog box already up ** -2 could not create window ** -3 could not create conversion thread ** */ static int k2gui_cbox_create_dialog_window(K2PDFOPT_CONVERSION *k2conv,STRBUF *env,STRBUF *cmdline, WILLUSGUIWINDOW *parent,void *hinst) { WILLUSGUIRECT rect; int w,h; static void *data[4]; static char *blabel[]={"Abort","",""}; #if (WILLUSDEBUGX & 0x2000) printf("@k2gui_cbox_create_dialog_window...\n"); #endif if (k2gui_cbox->converting) return(-1); k2gui_cbox->converting=1; k2gui_cbox->hinst=hinst; /* (HINSTANCE)GetModuleHandle(0); */ willusgui_window_get_rect(parent,&rect); w=(rect.right-rect.left)*0.9; h=(rect.bottom-rect.top)*0.75; k2gui_cbox->mainwin.rect.left = rect.left + ((rect.right-rect.left)-w)/2; k2gui_cbox->mainwin.rect.top = rect.top + ((rect.bottom-rect.top)-h)/2; k2gui_cbox->mainwin.rect.right = k2gui_cbox->mainwin.rect.left + w - 1; k2gui_cbox->mainwin.rect.bottom = k2gui_cbox->mainwin.rect.top + h - 1; k2gui_cbox->maxwidth = rect.right-rect.left; k2gui_cbox->mf.size = k2gui_cbox->maxwidth/65; willusgui_font_get(&k2gui_cbox->mf); k2gui_cbox->bf.size = k2gui_cbox->maxwidth/40; willusgui_font_get(&k2gui_cbox->bf); strbuf_init(&k2gui_cbox->buf); k2gui_cbox->rgbcolor=0xb0b0ff; k2gui_cbox->hinst=hinst; k2gui_osdep_cbox_init(k2gui_cbox,&k2gui_cbox->mainwin,parent,hinst,k2gui_cbox->rgbcolor); if (k2gui_cbox->mainwin.handle==NULL) { k2gui_cbox->converting=0; return(-2); } /* ShowWindow(k2gui_cbox->hwnd,SW_SHOW); UpdateWindow(k2gui_cbox->hwnd); */ k2gui_cbox_message_box_add_children(blabel,0); /* UpdateWindow(k2gui_cbox->hwnd); */ willusgui_window_set_focus(&k2gui_cbox->control[1]); /* ** Start new thread to do the conversions */ k2gui_cbox->semaphore = willusgui_semaphore_create_ex("k2pdfopt_conversion",1,1); if (k2gui_cbox->semaphore==NULL) { willusgui_control_enable(&k2gui->mainwin,1); k2gui_cbox_destroy(); k2gui_alertbox(0,"Convert","Cannot create semaphore!"); k2gui_cbox->converting=0; return(-3); } willusgui_semaphore_status_wait(k2gui_cbox->semaphore); /* printf("k2conv=%p\n",k2conv); printf("k2conv->k2settings=%p\n",&k2conv->k2settings); */ data[0] = (void *)k2conv; data[1] = (void *)env; data[2] = (void *)cmdline; /* ** Fork the new thread to k2gui_cbox_start_conversion(). */ k2gui_cbox->pid=willusgui_thread_create(k2gui_cbox_start_conversion,(void *)data); if (k2gui_cbox->pid==NULL) { willusgui_semaphore_close(k2gui_cbox->semaphore); k2gui_alertbox(0,"Convert","Cannot start conversion thread!"); willusgui_control_enable(&k2gui->mainwin,1); k2gui_cbox_destroy(); k2gui_cbox->converting=0; return(-4); } /* ** Test for Franco Vivona (Ittiandro). Put in delay to see if it helps the ** conversion not crash. */ #ifdef HAVE_WIN32_API win_sleep(500); #endif return(0); }
static int run_pre_push_hook(struct transport *transport, struct ref *remote_refs) { int ret = 0, x; struct ref *r; struct child_process proc = CHILD_PROCESS_INIT; struct strbuf buf; const char *argv[4]; if (!(argv[0] = find_hook("pre-push"))) return 0; argv[1] = transport->remote->name; argv[2] = transport->url; argv[3] = NULL; proc.argv = argv; proc.in = -1; if (start_command(&proc)) { finish_command(&proc); return -1; } sigchain_push(SIGPIPE, SIG_IGN); strbuf_init(&buf, 256); for (r = remote_refs; r; r = r->next) { if (!r->peer_ref) continue; if (r->status == REF_STATUS_REJECT_NONFASTFORWARD) continue; if (r->status == REF_STATUS_REJECT_STALE) continue; if (r->status == REF_STATUS_UPTODATE) continue; strbuf_reset(&buf); strbuf_addf( &buf, "%s %s %s %s\n", r->peer_ref->name, oid_to_hex(&r->new_oid), r->name, oid_to_hex(&r->old_oid)); if (write_in_full(proc.in, buf.buf, buf.len) < 0) { /* We do not mind if a hook does not read all refs. */ if (errno != EPIPE) ret = -1; break; } } strbuf_release(&buf); x = close(proc.in); if (!ret) ret = x; sigchain_pop(SIGPIPE); x = finish_command(&proc); if (!ret) ret = x; return ret; }
int main(int argc,char *argv[]) { int i,filecount; static K2PDFOPT_SETTINGS _k2settings; K2PDFOPT_SETTINGS *k2settings; static STRBUF _cmdline,_env,_usermenu; STRBUF *cmdline,*env,*usermenu; k2settings=&_k2settings; cmdline=&_cmdline; env=&_env; usermenu=&_usermenu; strbuf_init(cmdline); strbuf_init(env); strbuf_init(usermenu); strbuf_cpy(env,getenv("K2PDFOPT")); for (i=1;i<argc;i++) strbuf_cat_with_quotes(cmdline,argv[i]); k2sys_init(); k2pdfopt_settings_init(k2settings); /* Only set ansi and user interface */ filecount=parse_cmd_args(k2settings,env,cmdline,usermenu,2,0); if (k2settings->show_usage) { k2sys_header(); if (k2settings->query_user==0 #if (defined(WIN32) || defined(WIN64)) || !win_has_own_window() #endif ) k2usage_show_all(stdout); else { if (!k2pdfopt_usage()) { k2sys_close(k2settings); strbuf_free(usermenu); strbuf_free(env); strbuf_free(cmdline); return(0); } } if (k2settings->query_user!=0) k2sys_enter_to_exit(k2settings); k2sys_close(k2settings); strbuf_free(usermenu); strbuf_free(env); strbuf_free(cmdline); return(0); } if (k2settings->query_user<0) #if (defined(WIN32) || defined(WIN64)) { if (win_has_own_window()) k2settings->query_user=1; else k2settings->query_user=(filecount==0); } #else k2settings->query_user=1; #endif #if (!defined(WIN32) && !defined(WIN64)) if (k2settings->query_user) { int tty_rows; tty_rows = get_ttyrows(); for (i=0;i<tty_rows-16;i++) aprintf("\n"); } #endif k2sys_header(); /* ** Set all options from command-line arguments */ parse_cmd_args(k2settings,env,cmdline,usermenu,1,0); /* ** Get user input */ if (k2pdfopt_menu(k2settings,filecount,env,cmdline,usermenu)==-1) { strbuf_free(usermenu); strbuf_free(env); strbuf_free(cmdline); k2sys_close(k2settings); return(0); } /* ** Re-init and then re-parse after all user menu entries applied. */ k2pdfopt_settings_init(k2settings); parse_cmd_args(k2settings,env,cmdline,usermenu,1,0); /* ** Sanity check / adjust user inputs */ k2pdfopt_settings_sanity_check(k2settings); /* ** Process files */ parse_cmd_args(k2settings,env,cmdline,usermenu,0,1); /* ** All done. */ strbuf_free(usermenu); strbuf_free(env); strbuf_free(cmdline); k2sys_enter_to_exit(k2settings); k2sys_close(k2settings); return(0); }
/* * This returns a dummy child_process if the transport protocol does not * need fork(2), or a struct child_process object if it does. Once done, * finish the connection with finish_connect() with the value returned from * this function (it is safe to call finish_connect() with NULL to support * the former case). * * If it returns, the connect is successful; it just dies on errors (this * will hopefully be changed in a libification effort, to return NULL when * the connection failed). */ struct child_process *git_connect(int fd[2], const char *url_orig, const char *prog, int flags) { char *url; char *host, *path; char *end; int c; struct child_process *conn = &no_fork; enum protocol protocol = PROTO_LOCAL; int free_path = 0; char *port = NULL; const char **arg; struct strbuf cmd; /* Without this we cannot rely on waitpid() to tell * what happened to our children. */ signal(SIGCHLD, SIG_DFL); if (is_url(url_orig)) url = url_decode(url_orig); else url = xstrdup(url_orig); host = strstr(url, "://"); if (host) { *host = '\0'; protocol = get_protocol(url); host += 3; c = '/'; } else { host = url; c = ':'; } /* * Don't do destructive transforms with git:// as that * protocol code does '[]' unwrapping of its own. */ if (host[0] == '[') { end = strchr(host + 1, ']'); if (end) { if (protocol != PROTO_GIT) { *end = 0; host++; } end++; } else end = host; } else end = host; path = strchr(end, c); if (path && !has_dos_drive_prefix(end)) { if (c == ':') { if (path < strchrnul(host, '/')) { protocol = PROTO_SSH; *path++ = '\0'; } else /* '/' in the host part, assume local path */ path = end; } } else path = end; if (!path || !*path) die("No path specified. See 'man git-pull' for valid url syntax"); /* * null-terminate hostname and point path to ~ for URL's like this: * ssh://host.xz/~user/repo */ if (protocol != PROTO_LOCAL && host != url) { char *ptr = path; if (path[1] == '~') path++; else { path = xstrdup(ptr); free_path = 1; } *ptr = '\0'; } /* * Add support for ssh port: ssh://host.xy:<port>/... */ if (protocol == PROTO_SSH && host != url) port = get_port(end); if (protocol == PROTO_GIT) { /* These underlying connection commands die() if they * cannot connect. */ char *target_host = xstrdup(host); if (git_use_proxy(host)) conn = git_proxy_connect(fd, host); else git_tcp_connect(fd, host, flags); /* * Separate original protocol components prog and path * from extended host header with a NUL byte. * * Note: Do not add any other headers here! Doing so * will cause older git-daemon servers to crash. */ packet_write(fd[1], "%s %s%chost=%s%c", prog, path, 0, target_host, 0); free(target_host); free(url); if (free_path) free(path); return conn; } conn = xcalloc(1, sizeof(*conn)); strbuf_init(&cmd, MAX_CMD_LEN); strbuf_addstr(&cmd, prog); strbuf_addch(&cmd, ' '); sq_quote_buf(&cmd, path); if (cmd.len >= MAX_CMD_LEN) die("command line too long"); conn->in = conn->out = -1; conn->argv = arg = xcalloc(7, sizeof(*arg)); if (protocol == PROTO_SSH) { const char *ssh = getenv("GIT_SSH"); int putty = ssh && strcasestr(ssh, "plink"); if (!ssh) ssh = "ssh"; *arg++ = ssh; if (putty && !strcasestr(ssh, "tortoiseplink")) *arg++ = "-batch"; if (port) { /* P is for PuTTY, p is for OpenSSH */ *arg++ = putty ? "-P" : "-p"; *arg++ = port; } *arg++ = host; } else { /* remove repo-local variables from the environment */ conn->env = local_repo_env; conn->use_shell = 1; } *arg++ = cmd.buf; *arg = NULL; if (start_command(conn)) die("unable to fork"); fd[0] = conn->out; /* read from child's stdout */ fd[1] = conn->in; /* write to child's stdin */ strbuf_release(&cmd); free(url); if (free_path) free(path); return conn; }
static char *url_normalize_1(const char *url, struct url_info *out_info, char allow_globs) { /* * Normalize NUL-terminated url using the following rules: * * 1. Case-insensitive parts of url will be converted to lower case * 2. %-encoded characters that do not need to be will be unencoded * 3. Characters that are not %-encoded and must be will be encoded * 4. All %-encodings will be converted to upper case hexadecimal * 5. Leading 0s are removed from port numbers * 6. If the default port for the scheme is given it will be removed * 7. A path part (including empty) not starting with '/' has one added * 8. Any dot segments (. or ..) in the path are resolved and removed * 9. IPv6 host literals are allowed (but not normalized or validated) * * The rules are based on information in RFC 3986. * * Please note this function requires a full URL including a scheme * and host part (except for file: URLs which may have an empty host). * * The return value is a newly allocated string that must be freed * or NULL if the url is not valid. * * If out_info is non-NULL, the url and err fields therein will always * be set. If a non-NULL value is returned, it will be stored in * out_info->url as well, out_info->err will be set to NULL and the * other fields of *out_info will also be filled in. If a NULL value * is returned, NULL will be stored in out_info->url and out_info->err * will be set to a brief, translated, error message, but no other * fields will be filled in. * * This is NOT a URL validation function. Full URL validation is NOT * performed. Some invalid host names are passed through this function * undetected. However, most all other problems that make a URL invalid * will be detected (including a missing host for non file: URLs). */ size_t url_len = strlen(url); struct strbuf norm; size_t spanned; size_t scheme_len, user_off=0, user_len=0, passwd_off=0, passwd_len=0; size_t host_off=0, host_len=0, port_off=0, port_len=0, path_off, path_len, result_len; const char *slash_ptr, *at_ptr, *colon_ptr, *path_start; char *result; /* * Copy lowercased scheme and :// suffix, %-escapes are not allowed * First character of scheme must be URL_ALPHA */ spanned = strspn(url, URL_SCHEME_CHARS); if (!spanned || !isalpha(url[0]) || spanned + 3 > url_len || url[spanned] != ':' || url[spanned+1] != '/' || url[spanned+2] != '/') { if (out_info) { out_info->url = NULL; out_info->err = _("invalid URL scheme name or missing '://' suffix"); } return NULL; /* Bad scheme and/or missing "://" part */ } strbuf_init(&norm, url_len); scheme_len = spanned; spanned += 3; url_len -= spanned; while (spanned--) strbuf_addch(&norm, tolower(*url++)); /* * Copy any username:password if present normalizing %-escapes */ at_ptr = strchr(url, '@'); slash_ptr = url + strcspn(url, "/?#"); if (at_ptr && at_ptr < slash_ptr) { user_off = norm.len; if (at_ptr > url) { if (!append_normalized_escapes(&norm, url, at_ptr - url, "", URL_RESERVED)) { if (out_info) { out_info->url = NULL; out_info->err = _("invalid %XX escape sequence"); } strbuf_release(&norm); return NULL; } colon_ptr = strchr(norm.buf + scheme_len + 3, ':'); if (colon_ptr) { passwd_off = (colon_ptr + 1) - norm.buf; passwd_len = norm.len - passwd_off; user_len = (passwd_off - 1) - (scheme_len + 3); } else { user_len = norm.len - (scheme_len + 3); } } strbuf_addch(&norm, '@'); url_len -= (++at_ptr - url); url = at_ptr; } /* * Copy the host part excluding any port part, no %-escapes allowed */ if (!url_len || strchr(":/?#", *url)) { /* Missing host invalid for all URL schemes except file */ if (strncmp(norm.buf, "file:", 5)) { if (out_info) { out_info->url = NULL; out_info->err = _("missing host and scheme is not 'file:'"); } strbuf_release(&norm); return NULL; } } else { host_off = norm.len; } colon_ptr = slash_ptr - 1; while (colon_ptr > url && *colon_ptr != ':' && *colon_ptr != ']') colon_ptr--; if (*colon_ptr != ':') { colon_ptr = slash_ptr; } else if (!host_off && colon_ptr < slash_ptr && colon_ptr + 1 != slash_ptr) { /* file: URLs may not have a port number */ if (out_info) { out_info->url = NULL; out_info->err = _("a 'file:' URL may not have a port number"); } strbuf_release(&norm); return NULL; } if (allow_globs) spanned = strspn(url, URL_HOST_CHARS "*"); else spanned = strspn(url, URL_HOST_CHARS); if (spanned < colon_ptr - url) { /* Host name has invalid characters */ if (out_info) { out_info->url = NULL; out_info->err = _("invalid characters in host name"); } strbuf_release(&norm); return NULL; } while (url < colon_ptr) { strbuf_addch(&norm, tolower(*url++)); url_len--; } /* * Check the port part and copy if not the default (after removing any * leading 0s); no %-escapes allowed */ if (colon_ptr < slash_ptr) { /* skip the ':' and leading 0s but not the last one if all 0s */ url++; url += strspn(url, "0"); if (url == slash_ptr && url[-1] == '0') url--; if (url == slash_ptr) { /* Skip ":" port with no number, it's same as default */ } else if (slash_ptr - url == 2 && !strncmp(norm.buf, "http:", 5) && !strncmp(url, "80", 2)) { /* Skip http :80 as it's the default */ } else if (slash_ptr - url == 3 && !strncmp(norm.buf, "https:", 6) && !strncmp(url, "443", 3)) { /* Skip https :443 as it's the default */ } else { /* * Port number must be all digits with leading 0s removed * and since all the protocols we deal with have a 16-bit * port number it must also be in the range 1..65535 * 0 is not allowed because that means "next available" * on just about every system and therefore cannot be used */ unsigned long pnum = 0; spanned = strspn(url, URL_DIGIT); if (spanned < slash_ptr - url) { /* port number has invalid characters */ if (out_info) { out_info->url = NULL; out_info->err = _("invalid port number"); } strbuf_release(&norm); return NULL; } if (slash_ptr - url <= 5) pnum = strtoul(url, NULL, 10); if (pnum == 0 || pnum > 65535) { /* port number not in range 1..65535 */ if (out_info) { out_info->url = NULL; out_info->err = _("invalid port number"); } strbuf_release(&norm); return NULL; } strbuf_addch(&norm, ':'); port_off = norm.len; strbuf_add(&norm, url, slash_ptr - url); port_len = slash_ptr - url; } url_len -= slash_ptr - colon_ptr; url = slash_ptr; } if (host_off) host_len = norm.len - host_off - (port_len ? port_len + 1 : 0); /* * Now copy the path resolving any . and .. segments being careful not * to corrupt the URL by unescaping any delimiters, but do add an * initial '/' if it's missing and do normalize any %-escape sequences. */ path_off = norm.len; path_start = norm.buf + path_off; strbuf_addch(&norm, '/'); if (*url == '/') { url++; url_len--; } for (;;) { const char *seg_start; size_t seg_start_off = norm.len; const char *next_slash = url + strcspn(url, "/?#"); int skip_add_slash = 0; /* * RFC 3689 indicates that any . or .. segments should be * unescaped before being checked for. */ if (!append_normalized_escapes(&norm, url, next_slash - url, "", URL_RESERVED)) { if (out_info) { out_info->url = NULL; out_info->err = _("invalid %XX escape sequence"); } strbuf_release(&norm); return NULL; } seg_start = norm.buf + seg_start_off; if (!strcmp(seg_start, ".")) { /* ignore a . segment; be careful not to remove initial '/' */ if (seg_start == path_start + 1) { strbuf_setlen(&norm, norm.len - 1); skip_add_slash = 1; } else { strbuf_setlen(&norm, norm.len - 2); } } else if (!strcmp(seg_start, "..")) { /* * ignore a .. segment and remove the previous segment; * be careful not to remove initial '/' from path */ const char *prev_slash = norm.buf + norm.len - 3; if (prev_slash == path_start) { /* invalid .. because no previous segment to remove */ if (out_info) { out_info->url = NULL; out_info->err = _("invalid '..' path segment"); } strbuf_release(&norm); return NULL; } while (*--prev_slash != '/') {} if (prev_slash == path_start) { strbuf_setlen(&norm, prev_slash - norm.buf + 1); skip_add_slash = 1; } else { strbuf_setlen(&norm, prev_slash - norm.buf); } } url_len -= next_slash - url; url = next_slash; /* if the next char is not '/' done with the path */ if (*url != '/') break; url++; url_len--; if (!skip_add_slash) strbuf_addch(&norm, '/'); } path_len = norm.len - path_off; /* * Now simply copy the rest, if any, only normalizing %-escapes and * being careful not to corrupt the URL by unescaping any delimiters. */ if (*url) { if (!append_normalized_escapes(&norm, url, url_len, "", URL_RESERVED)) { if (out_info) { out_info->url = NULL; out_info->err = _("invalid %XX escape sequence"); } strbuf_release(&norm); return NULL; } } result = strbuf_detach(&norm, &result_len); if (out_info) { out_info->url = result; out_info->err = NULL; out_info->url_len = result_len; out_info->scheme_len = scheme_len; out_info->user_off = user_off; out_info->user_len = user_len; out_info->passwd_off = passwd_off; out_info->passwd_len = passwd_len; out_info->host_off = host_off; out_info->host_len = host_len; out_info->port_off = port_off; out_info->port_len = port_len; out_info->path_off = path_off; out_info->path_len = path_len; } return result; }
static void show_commit(struct commit *commit) { graph_show_commit(revs.graph); if (show_timestamp) printf("%lu ", commit->date); if (header_prefix) fputs(header_prefix, stdout); if (!revs.graph) { if (commit->object.flags & BOUNDARY) putchar('-'); else if (commit->object.flags & UNINTERESTING) putchar('^'); else if (revs.left_right) { if (commit->object.flags & SYMMETRIC_LEFT) putchar('<'); else putchar('>'); } } if (revs.abbrev_commit && revs.abbrev) fputs(find_unique_abbrev(commit->object.sha1, revs.abbrev), stdout); else fputs(sha1_to_hex(commit->object.sha1), stdout); if (revs.print_parents) { struct commit_list *parents = commit->parents; while (parents) { printf(" %s", sha1_to_hex(parents->item->object.sha1)); parents = parents->next; } } if (revs.children.name) { struct commit_list *children; children = lookup_decoration(&revs.children, &commit->object); while (children) { printf(" %s", sha1_to_hex(children->item->object.sha1)); children = children->next; } } show_decorations(commit); if (revs.commit_format == CMIT_FMT_ONELINE) putchar(' '); else putchar('\n'); if (revs.verbose_header && commit->buffer) { struct strbuf buf; strbuf_init(&buf, 0); pretty_print_commit(revs.commit_format, commit, &buf, revs.abbrev, NULL, NULL, revs.date_mode, 0); if (revs.graph) { if (buf.len) { if (revs.commit_format != CMIT_FMT_ONELINE) graph_show_oneline(revs.graph); graph_show_commit_msg(revs.graph, &buf); /* * Add a newline after the commit message. * * Usually, this newline produces a blank * padding line between entries, in which case * we need to add graph padding on this line. * * However, the commit message may not end in a * newline. In this case the newline simply * ends the last line of the commit message, * and we don't need any graph output. (This * always happens with CMIT_FMT_ONELINE, and it * happens with CMIT_FMT_USERFORMAT when the * format doesn't explicitly end in a newline.) */ if (buf.len && buf.buf[buf.len - 1] == '\n') graph_show_padding(revs.graph); putchar('\n'); } else { /* * If the message buffer is empty, just show * the rest of the graph output for this * commit. */ if (graph_show_remainder(revs.graph)) putchar('\n'); } } else { if (buf.len) printf("%s%c", buf.buf, hdr_termination); } strbuf_release(&buf); } else { if (graph_show_remainder(revs.graph)) putchar('\n'); } maybe_flush_or_die(stdout, "stdout"); finish_commit(commit); }
/* Search the CHM storage stream (an HTML file) for the requested text. * * Before searching the HTML file all HTML tags are removed so that only * the content of the document is scanned. If the search string is found * then the title of the document is returned. */ static WCHAR *SearchCHM_File(IStorage *pStorage, const WCHAR *file, const char *needle) { char *buffer = heap_alloc(BLOCK_SIZE); strbuf_t content, node, node_name; IStream *temp_stream = NULL; DWORD i, buffer_size = 0; WCHAR *title = NULL; BOOL found = FALSE; stream_t stream; HRESULT hres; hres = IStorage_OpenStream(pStorage, file, NULL, STGM_READ, 0, &temp_stream); if(FAILED(hres)) { FIXME("Could not open '%s' stream: %08x\n", debugstr_w(file), hres); goto cleanup; } strbuf_init(&node); strbuf_init(&content); strbuf_init(&node_name); stream_init(&stream, temp_stream); /* Remove all HTML formatting and record the title */ while(next_node(&stream, &node)) { get_node_name(&node, &node_name); if(next_content(&stream, &content) && content.len > 1) { char *text = &content.buf[1]; int textlen = content.len-1; if(!strcasecmp(node_name.buf, "title")) { int wlen = MultiByteToWideChar(CP_ACP, 0, text, textlen, NULL, 0); title = heap_alloc((wlen+1)*sizeof(WCHAR)); MultiByteToWideChar(CP_ACP, 0, text, textlen, title, wlen); title[wlen] = 0; } buffer = heap_realloc(buffer, buffer_size + textlen + 1); memcpy(&buffer[buffer_size], text, textlen); buffer[buffer_size + textlen] = '\0'; buffer_size += textlen; } strbuf_zero(&node); strbuf_zero(&content); } /* Convert the buffer to lower case for comparison against the * requested text (already in lower case). */ for(i=0;i<buffer_size;i++) buffer[i] = tolower(buffer[i]); /* Search the decoded buffer for the requested text */ if(strstr(buffer, needle)) found = TRUE; strbuf_free(&node); strbuf_free(&content); strbuf_free(&node_name); cleanup: heap_free(buffer); if(temp_stream) IStream_Release(temp_stream); if(!found) { heap_free(title); return NULL; } return title; }
static void handle_from(const struct strbuf *from) { char *at; size_t el; struct strbuf f; strbuf_init(&f, from->len); strbuf_addbuf(&f, from); at = strchr(f.buf, '@'); if (!at) { parse_bogus_from(from); return; } /* * If we already have one email, don't take any confusing lines */ if (email.len && strchr(at + 1, '@')) { strbuf_release(&f); return; } /* Pick up the string around '@', possibly delimited with <> * pair; that is the email part. */ while (at > f.buf) { char c = at[-1]; if (isspace(c)) break; if (c == '<') { at[-1] = ' '; break; } at--; } el = strcspn(at, " \n\t\r\v\f>"); strbuf_reset(&email); strbuf_add(&email, at, el); strbuf_remove(&f, at - f.buf, el + (at[el] ? 1 : 0)); /* The remainder is name. It could be * * - "John Doe <john.doe@xz>" (a), or * - "john.doe@xz (John Doe)" (b), or * - "John (zzz) Doe <john.doe@xz> (Comment)" (c) * * but we have removed the email part, so * * - remove extra spaces which could stay after email (case 'c'), and * - trim from both ends, possibly removing the () pair at the end * (cases 'a' and 'b'). */ cleanup_space(&f); strbuf_trim(&f); if (f.buf[0] == '(' && f.len && f.buf[f.len - 1] == ')') { strbuf_remove(&f, 0, 1); strbuf_setlen(&f, f.len - 1); } get_sane_name(&name, &f, &email); strbuf_release(&f); }
static int update_one(struct cache_tree *it, struct cache_entry **cache, int entries, const char *base, int baselen, int missing_ok, int dryrun) { struct strbuf buffer; int i; if (0 <= it->entry_count && has_sha1_file(it->sha1)) return it->entry_count; /* * We first scan for subtrees and update them; we start by * marking existing subtrees -- the ones that are unmarked * should not be in the result. */ for (i = 0; i < it->subtree_nr; i++) it->down[i]->used = 0; /* * Find the subtrees and update them. */ for (i = 0; i < entries; i++) { struct cache_entry *ce = cache[i]; struct cache_tree_sub *sub; const char *path, *slash; int pathlen, sublen, subcnt; path = ce->name; pathlen = ce_namelen(ce); if (pathlen <= baselen || memcmp(base, path, baselen)) break; /* at the end of this level */ slash = strchr(path + baselen, '/'); if (!slash) continue; /* * a/bbb/c (base = a/, slash = /c) * ==> * path+baselen = bbb/c, sublen = 3 */ sublen = slash - (path + baselen); sub = find_subtree(it, path + baselen, sublen, 1); if (!sub->cache_tree) sub->cache_tree = cache_tree(); subcnt = update_one(sub->cache_tree, cache + i, entries - i, path, baselen + sublen + 1, missing_ok, dryrun); if (subcnt < 0) return subcnt; i += subcnt - 1; sub->used = 1; } discard_unused_subtrees(it); /* * Then write out the tree object for this level. */ strbuf_init(&buffer, 8192); for (i = 0; i < entries; i++) { struct cache_entry *ce = cache[i]; struct cache_tree_sub *sub; const char *path, *slash; int pathlen, entlen; const unsigned char *sha1; unsigned mode; path = ce->name; pathlen = ce_namelen(ce); if (pathlen <= baselen || memcmp(base, path, baselen)) break; /* at the end of this level */ slash = strchr(path + baselen, '/'); if (slash) { entlen = slash - (path + baselen); sub = find_subtree(it, path + baselen, entlen, 0); if (!sub) die("cache-tree.c: '%.*s' in '%s' not found", entlen, path + baselen, path); i += sub->cache_tree->entry_count - 1; sha1 = sub->cache_tree->sha1; mode = S_IFDIR; } else { sha1 = ce->sha1; mode = ce->ce_mode; entlen = pathlen - baselen; } if (mode != S_IFGITLINK && !missing_ok && !has_sha1_file(sha1)) return error("invalid object %s", sha1_to_hex(sha1)); if (ce->ce_flags & CE_REMOVE) continue; /* entry being removed */ strbuf_grow(&buffer, entlen + 100); strbuf_addf(&buffer, "%o %.*s%c", mode, entlen, path + baselen, '\0'); strbuf_add(&buffer, sha1, 20); #if DEBUG fprintf(stderr, "cache-tree update-one %o %.*s\n", mode, entlen, path + baselen); #endif } if (dryrun) hash_sha1_file(buffer.buf, buffer.len, tree_type, it->sha1); else if (write_sha1_file(buffer.buf, buffer.len, tree_type, it->sha1)) { strbuf_release(&buffer); return -1; } strbuf_release(&buffer); it->entry_count = i; #if DEBUG fprintf(stderr, "cache-tree update-one (%d ent, %d subtree) %s\n", it->entry_count, it->subtree_nr, sha1_to_hex(it->sha1)); #endif return i; }
static void json_create_config(lua_State *l) { json_config_t *cfg; int i; cfg = lua_newuserdata(l, sizeof(*cfg)); /* Create GC method to clean up strbuf */ lua_newtable(l); lua_pushcfunction(l, json_destroy_config); lua_setfield(l, -2, "__gc"); lua_setmetatable(l, -2); strbuf_init(&cfg->encode_buf, 0); cfg->encode_sparse_convert = DEFAULT_SPARSE_CONVERT; cfg->encode_sparse_ratio = DEFAULT_SPARSE_RATIO; cfg->encode_sparse_safe = DEFAULT_SPARSE_SAFE; cfg->encode_max_depth = DEFAULT_MAX_DEPTH; cfg->encode_refuse_badnum = DEFAULT_ENCODE_REFUSE_BADNUM; cfg->decode_refuse_badnum = DEFAULT_DECODE_REFUSE_BADNUM; cfg->encode_keep_buffer = DEFAULT_ENCODE_KEEP_BUFFER; json_set_number_precision(cfg, 14); /* Decoding init */ /* Tag all characters as an error */ for (i = 0; i < 256; i++) cfg->ch2token[i] = T_ERROR; /* Set tokens that require no further processing */ cfg->ch2token['{'] = T_OBJ_BEGIN; cfg->ch2token['}'] = T_OBJ_END; cfg->ch2token['['] = T_ARR_BEGIN; cfg->ch2token[']'] = T_ARR_END; cfg->ch2token[','] = T_COMMA; cfg->ch2token[':'] = T_COLON; cfg->ch2token['\0'] = T_END; cfg->ch2token[' '] = T_WHITESPACE; cfg->ch2token['\t'] = T_WHITESPACE; cfg->ch2token['\n'] = T_WHITESPACE; cfg->ch2token['\r'] = T_WHITESPACE; /* Update characters that require further processing */ cfg->ch2token['f'] = T_UNKNOWN; /* false? */ cfg->ch2token['i'] = T_UNKNOWN; /* inf, ininity? */ cfg->ch2token['I'] = T_UNKNOWN; cfg->ch2token['n'] = T_UNKNOWN; /* null, nan? */ cfg->ch2token['N'] = T_UNKNOWN; cfg->ch2token['t'] = T_UNKNOWN; /* true? */ cfg->ch2token['"'] = T_UNKNOWN; /* string? */ cfg->ch2token['+'] = T_UNKNOWN; /* number? */ cfg->ch2token['-'] = T_UNKNOWN; for (i = 0; i < 10; i++) cfg->ch2token['0' + i] = T_UNKNOWN; /* Lookup table for parsing escape characters */ for (i = 0; i < 256; i++) cfg->escape2char[i] = 0; /* String error */ cfg->escape2char['"'] = '"'; cfg->escape2char['\\'] = '\\'; cfg->escape2char['/'] = '/'; cfg->escape2char['b'] = '\b'; cfg->escape2char['t'] = '\t'; cfg->escape2char['n'] = '\n'; cfg->escape2char['f'] = '\f'; cfg->escape2char['r'] = '\r'; cfg->escape2char['u'] = 'u'; /* Unicode parsing required */ #if 0 /* Initialise separate storage for pre-generated escape codes. * Escapes 0-31 map directly, 34, 92, 127 follow afterwards to * save memory. */ for (i = 0 ; i < 32; i++) sprintf(cfg->escapes[i], "\\u%04x", i); strcpy(cfg->escapes[8], "\b"); /* Override simpler escapes */ strcpy(cfg->escapes[9], "\t"); strcpy(cfg->escapes[10], "\n"); strcpy(cfg->escapes[12], "\f"); strcpy(cfg->escapes[13], "\r"); strcpy(cfg->escapes[32], "\\\""); /* chr(34) */ strcpy(cfg->escapes[33], "\\\\"); /* chr(92) */ sprintf(cfg->escapes[34], "\\u%04x", 127); /* char(127) */ /* Initialise encoding escape lookup table */ for (i = 0; i < 32; i++) cfg->char2escape[i] = cfg->escapes[i]; for (i = 32; i < 256; i++) cfg->char2escape[i] = NULL; cfg->char2escape[34] = cfg->escapes[32]; cfg->char2escape[92] = cfg->escapes[33]; cfg->char2escape[127] = cfg->escapes[34]; #endif }
static HRESULT do_process_key(LPCOLESTR *pstr, HKEY parent_key, strbuf *buf, BOOL do_register) { LPCOLESTR iter; HRESULT hres; LONG lres; HKEY hkey = 0; strbuf name; enum { NORMAL, NO_REMOVE, IS_VAL, FORCE_REMOVE, DO_DELETE } key_type = NORMAL; static const WCHAR wstrNoRemove[] = {'N','o','R','e','m','o','v','e',0}; static const WCHAR wstrForceRemove[] = {'F','o','r','c','e','R','e','m','o','v','e',0}; static const WCHAR wstrDelete[] = {'D','e','l','e','t','e',0}; static const WCHAR wstrval[] = {'v','a','l',0}; iter = *pstr; hres = get_word(&iter, buf); if(FAILED(hres)) return hres; strbuf_init(&name); while(buf->str[1] || buf->str[0] != '}') { key_type = NORMAL; if(!lstrcmpiW(buf->str, wstrNoRemove)) key_type = NO_REMOVE; else if(!lstrcmpiW(buf->str, wstrForceRemove)) key_type = FORCE_REMOVE; else if(!lstrcmpiW(buf->str, wstrval)) key_type = IS_VAL; else if(!lstrcmpiW(buf->str, wstrDelete)) key_type = DO_DELETE; if(key_type != NORMAL) { hres = get_word(&iter, buf); if(FAILED(hres)) break; } TRACE("name = %s\n", debugstr_w(buf->str)); if(do_register) { if(key_type == IS_VAL) { hkey = parent_key; strbuf_write(buf->str, &name, -1); }else if(key_type == DO_DELETE) { TRACE("Deleting %s\n", debugstr_w(buf->str)); RegDeleteTreeW(parent_key, buf->str); }else { if(key_type == FORCE_REMOVE) RegDeleteTreeW(parent_key, buf->str); lres = RegCreateKeyW(parent_key, buf->str, &hkey); if(lres != ERROR_SUCCESS) { WARN("Could not create(open) key: %08x\n", lres); hres = HRESULT_FROM_WIN32(lres); break; } } }else if(key_type != IS_VAL && key_type != DO_DELETE) { strbuf_write(buf->str, &name, -1); lres = RegOpenKeyW(parent_key, buf->str, &hkey); if(lres != ERROR_SUCCESS) WARN("Could not open key %s: %08x\n", debugstr_w(name.str), lres); } if(key_type != DO_DELETE && *iter == '=') { iter++; hres = get_word(&iter, buf); if(FAILED(hres)) break; if(buf->len != 1) { WARN("Wrong registry type: %s\n", debugstr_w(buf->str)); hres = DISP_E_EXCEPTION; break; } if(do_register) { switch(buf->str[0]) { case 's': hres = get_word(&iter, buf); if(FAILED(hres)) break; lres = RegSetValueExW(hkey, name.len ? name.str : NULL, 0, REG_SZ, (PBYTE)buf->str, (lstrlenW(buf->str)+1)*sizeof(WCHAR)); if(lres != ERROR_SUCCESS) { WARN("Could set value of key: %08x\n", lres); hres = HRESULT_FROM_WIN32(lres); break; } break; case 'd': { DWORD dw; hres = get_word(&iter, buf); if(FAILED(hres)) break; dw = atoiW(buf->str); lres = RegSetValueExW(hkey, name.len ? name.str : NULL, 0, REG_DWORD, (PBYTE)&dw, sizeof(dw)); if(lres != ERROR_SUCCESS) { WARN("Could set value of key: %08x\n", lres); hres = HRESULT_FROM_WIN32(lres); break; } break; } case 'b': { BYTE *bytes; DWORD count; DWORD i; hres = get_word(&iter, buf); if(FAILED(hres)) break; count = (lstrlenW(buf->str) + 1) / 2; bytes = HeapAlloc(GetProcessHeap(), 0, count); if(bytes == NULL) { hres = E_OUTOFMEMORY; break; } for(i = 0; i < count && buf->str[2*i]; i++) { WCHAR digits[3]; if(!isxdigitW(buf->str[2*i]) || !isxdigitW(buf->str[2*i + 1])) { hres = E_FAIL; break; } digits[0] = buf->str[2*i]; digits[1] = buf->str[2*i + 1]; digits[2] = 0; bytes[i] = (BYTE) strtoulW(digits, NULL, 16); } if(SUCCEEDED(hres)) { lres = RegSetValueExW(hkey, name.len ? name.str : NULL, 0, REG_BINARY, bytes, count); if(lres != ERROR_SUCCESS) { WARN("Could not set value of key: 0x%08x\n", lres); hres = HRESULT_FROM_WIN32(lres); } } HeapFree(GetProcessHeap(), 0, bytes); break; } default: WARN("Wrong resource type: %s\n", debugstr_w(buf->str)); hres = DISP_E_EXCEPTION; }; if(FAILED(hres)) break; }else { if(*iter == '-') iter++; hres = get_word(&iter, buf); if(FAILED(hres)) break; } }else if(key_type == IS_VAL) { WARN("value not set!\n"); hres = DISP_E_EXCEPTION; break; } if(key_type != IS_VAL && key_type != DO_DELETE && *iter == '{' && isspaceW(iter[1])) { hres = get_word(&iter, buf); if(FAILED(hres)) break; hres = do_process_key(&iter, hkey, buf, do_register); if(FAILED(hres)) break; } TRACE("%x %x\n", do_register, key_type); if(!do_register && (key_type == NORMAL || key_type == FORCE_REMOVE)) { TRACE("Deleting %s\n", debugstr_w(name.str)); RegDeleteKeyW(parent_key, name.str); } if(hkey && key_type != IS_VAL) RegCloseKey(hkey); hkey = 0; name.len = 0; hres = get_word(&iter, buf); if(FAILED(hres)) break; } HeapFree(GetProcessHeap(), 0, name.str); if(hkey && key_type != IS_VAL) RegCloseKey(hkey); *pstr = iter; return hres; }
/* * Loads the per-directory exclude list for the substring of base * which has a char length of baselen. */ static void prep_exclude(struct dir_struct *dir, const char *base, int baselen) { struct exclude_list_group *group; struct exclude_list *el; struct exclude_stack *stk = NULL; int current; group = &dir->exclude_list_group[EXC_DIRS]; /* * Pop the exclude lists from the EXCL_DIRS exclude_list_group * which originate from directories not in the prefix of the * path being checked. */ while ((stk = dir->exclude_stack) != NULL) { if (stk->baselen <= baselen && !strncmp(dir->basebuf.buf, base, stk->baselen)) break; el = &group->el[dir->exclude_stack->exclude_ix]; dir->exclude_stack = stk->prev; dir->exclude = NULL; free((char *)el->src); /* see strbuf_detach() below */ clear_exclude_list(el); free(stk); group->nr--; } /* Skip traversing into sub directories if the parent is excluded */ if (dir->exclude) return; /* * Lazy initialization. All call sites currently just * memset(dir, 0, sizeof(*dir)) before use. Changing all of * them seems lots of work for little benefit. */ if (!dir->basebuf.buf) strbuf_init(&dir->basebuf, PATH_MAX); /* Read from the parent directories and push them down. */ current = stk ? stk->baselen : -1; strbuf_setlen(&dir->basebuf, current < 0 ? 0 : current); while (current < baselen) { const char *cp; stk = xcalloc(1, sizeof(*stk)); if (current < 0) { cp = base; current = 0; } else { cp = strchr(base + current + 1, '/'); if (!cp) die("oops in prep_exclude"); cp++; } stk->prev = dir->exclude_stack; stk->baselen = cp - base; stk->exclude_ix = group->nr; el = add_exclude_list(dir, EXC_DIRS, NULL); strbuf_add(&dir->basebuf, base + current, stk->baselen - current); assert(stk->baselen == dir->basebuf.len); /* Abort if the directory is excluded */ if (stk->baselen) { int dt = DT_DIR; dir->basebuf.buf[stk->baselen - 1] = 0; dir->exclude = last_exclude_matching_from_lists(dir, dir->basebuf.buf, stk->baselen - 1, dir->basebuf.buf + current, &dt); dir->basebuf.buf[stk->baselen - 1] = '/'; if (dir->exclude && dir->exclude->flags & EXC_FLAG_NEGATIVE) dir->exclude = NULL; if (dir->exclude) { dir->exclude_stack = stk; return; } } /* Try to read per-directory file */ if (dir->exclude_per_dir) { /* * dir->basebuf gets reused by the traversal, but we * need fname to remain unchanged to ensure the src * member of each struct exclude correctly * back-references its source file. Other invocations * of add_exclude_list provide stable strings, so we * strbuf_detach() and free() here in the caller. */ struct strbuf sb = STRBUF_INIT; strbuf_addbuf(&sb, &dir->basebuf); strbuf_addstr(&sb, dir->exclude_per_dir); el->src = strbuf_detach(&sb, NULL); add_excludes_from_file_to_list(el->src, el->src, stk->baselen, el, 1); } dir->exclude_stack = stk; current = stk->baselen; } strbuf_setlen(&dir->basebuf, baselen); }
static int update_one(struct cache_tree *it, const struct cache_entry * const *cache, int entries, const char *base, int baselen, int *skip_count, int flags) { struct strbuf buffer; int missing_ok = flags & WRITE_TREE_MISSING_OK; int dryrun = flags & WRITE_TREE_DRY_RUN; int to_invalidate = 0; int i; *skip_count = 0; if (0 <= it->entry_count && has_sha1_file(it->sha1)) return it->entry_count; /* * We first scan for subtrees and update them; we start by * marking existing subtrees -- the ones that are unmarked * should not be in the result. */ for (i = 0; i < it->subtree_nr; i++) it->down[i]->used = 0; /* * Find the subtrees and update them. */ i = 0; while (i < entries) { const struct cache_entry *ce = cache[i]; struct cache_tree_sub *sub; const char *path, *slash; int pathlen, sublen, subcnt, subskip; path = ce->name; pathlen = ce_namelen(ce); if (pathlen <= baselen || memcmp(base, path, baselen)) break; /* at the end of this level */ slash = strchr(path + baselen, '/'); if (!slash) { i++; continue; } /* * a/bbb/c (base = a/, slash = /c) * ==> * path+baselen = bbb/c, sublen = 3 */ sublen = slash - (path + baselen); sub = find_subtree(it, path + baselen, sublen, 1); if (!sub->cache_tree) sub->cache_tree = cache_tree(); subcnt = update_one(sub->cache_tree, cache + i, entries - i, path, baselen + sublen + 1, &subskip, flags); if (subcnt < 0) return subcnt; i += subcnt; sub->count = subcnt; /* to be used in the next loop */ *skip_count += subskip; sub->used = 1; } discard_unused_subtrees(it); /* * Then write out the tree object for this level. */ strbuf_init(&buffer, 8192); i = 0; while (i < entries) { const struct cache_entry *ce = cache[i]; struct cache_tree_sub *sub; const char *path, *slash; int pathlen, entlen; const unsigned char *sha1; unsigned mode; path = ce->name; pathlen = ce_namelen(ce); if (pathlen <= baselen || memcmp(base, path, baselen)) break; /* at the end of this level */ slash = strchr(path + baselen, '/'); if (slash) { entlen = slash - (path + baselen); sub = find_subtree(it, path + baselen, entlen, 0); if (!sub) die("cache-tree.c: '%.*s' in '%s' not found", entlen, path + baselen, path); i += sub->count; sha1 = sub->cache_tree->sha1; mode = S_IFDIR; if (sub->cache_tree->entry_count < 0) to_invalidate = 1; } else { sha1 = ce->sha1; mode = ce->ce_mode; entlen = pathlen - baselen; i++; } if (mode != S_IFGITLINK && !missing_ok && !has_sha1_file(sha1)) { strbuf_release(&buffer); return error("invalid object %06o %s for '%.*s'", mode, sha1_to_hex(sha1), entlen+baselen, path); } /* * CE_REMOVE entries are removed before the index is * written to disk. Skip them to remain consistent * with the future on-disk index. */ if (ce->ce_flags & CE_REMOVE) { *skip_count = *skip_count + 1; continue; } /* * CE_INTENT_TO_ADD entries exist on on-disk index but * they are not part of generated trees. Invalidate up * to root to force cache-tree users to read elsewhere. */ if (ce->ce_flags & CE_INTENT_TO_ADD) { to_invalidate = 1; continue; } strbuf_grow(&buffer, entlen + 100); strbuf_addf(&buffer, "%o %.*s%c", mode, entlen, path + baselen, '\0'); strbuf_add(&buffer, sha1, 20); #if DEBUG fprintf(stderr, "cache-tree update-one %o %.*s\n", mode, entlen, path + baselen); #endif } if (dryrun) hash_sha1_file(buffer.buf, buffer.len, tree_type, it->sha1); else if (write_sha1_file(buffer.buf, buffer.len, tree_type, it->sha1)) { strbuf_release(&buffer); return -1; } strbuf_release(&buffer); it->entry_count = to_invalidate ? -1 : i - *skip_count; #if DEBUG fprintf(stderr, "cache-tree update-one (%d ent, %d subtree) %s\n", it->entry_count, it->subtree_nr, sha1_to_hex(it->sha1)); #endif return i; }
/* ** Conversion thread. This is launched as a separate thread to do the ** conversions while the dialog box displays the progress. */ static void k2gui_cbox_start_conversion(void *data) { void **ptrs; int i; K2PDFOPT_CONVERSION *k2conv; K2PDFOPT_SETTINGS *k2settings; K2PDFOPT_FILELIST_PROCESS k2listproc; static char *funcname="k2gui_cbox_start_conversion"; ptrs=(void **)data; k2conv=(K2PDFOPT_CONVERSION *)ptrs[0]; k2settings=&k2conv->k2settings; /* ** Count files */ k2gui_cbox_set_num_files(1); k2gui_cbox_set_files_completed(0,"Counting files..."); overwrite_set(1); for (i=k2listproc.filecount=0;i<k2conv->k2files.n;i++) { k2listproc.bmp=NULL; k2listproc.outname=NULL; k2listproc.mode=K2PDFOPT_FILELIST_PROCESS_MODE_GET_FILECOUNT; k2pdfopt_proc_wildarg(k2settings,k2conv->k2files.file[i],&k2listproc); willus_mem_free((double **)&k2listproc.outname,funcname); } if (k2listproc.filecount==0) { k2gui_cbox_set_files_completed(0,"No files"); k2gui_alertbox(0,"No files","No files can be opened for conversion."); k2gui_cbox_conversion_thread_cleanup(); return; } k2gui_cbox_set_num_files(k2listproc.filecount); k2gui_cbox_set_files_completed(0,NULL); /* ** Process files */ k2gui_cbox_set_error_count(0); k2gui_cbox_freelist(); overwrite_set(0); for (i=k2listproc.filecount=0;i<k2conv->k2files.n;i++) { char *buf; K2PDFOPT_CONVERSION *k2c; STRBUF *cmdline,_cmdline; willus_mem_alloc_warn((void **)&buf,1024,funcname,10); k2gui_cbox_set_num_pages(1); sprintf(buf,"Starting conversion of %s...",k2gui_short_name(k2conv->k2files.file[i])); k2gui_cbox_set_pages_completed(0,buf); willus_mem_alloc_warn((void **)&k2c,sizeof(K2PDFOPT_CONVERSION),funcname,10); k2pdfopt_conversion_init(k2c); cmdline=&_cmdline; strbuf_init(cmdline); k2gui_settings_to_cmdline(cmdline,&k2conv->k2settings); parse_cmd_args(k2c,k2gui->env,cmdline,&k2gui->cmdxtra,1,1); k2listproc.outname=NULL; k2listproc.bmp=NULL; k2listproc.mode=K2PDFOPT_FILELIST_PROCESS_MODE_CONVERT_FILES; k2pdfopt_proc_wildarg(&k2c->k2settings,k2conv->k2files.file[i],&k2listproc); #if (WILLUSDEBUGX & 0x2000) printf("\n\nDone conversion...\n\n"); #endif str0_addstring(&k2gui_cbox->filelist,&k2gui_cbox->filelist_na,k2listproc.outname); willus_mem_free((double **)&k2listproc.outname,funcname); k2pdfopt_conversion_close(k2c); willus_mem_free((double **)&k2c,funcname); willus_mem_free((double **)&buf,funcname); } k2gui_cbox_set_files_completed(k2listproc.filecount,NULL); if (k2listproc.filecount==k2conv->k2files.n && k2gui_cbox->error_count==0) k2gui_cbox->successful=1; k2gui_cbox_conversion_thread_cleanup(); }
static int update_one(struct cache_tree *it, struct cache_entry **cache, int entries, const char *base, int baselen, int *skip_count, int flags) { struct strbuf buffer; int missing_ok = flags & WRITE_TREE_MISSING_OK; int dryrun = flags & WRITE_TREE_DRY_RUN; int repair = flags & WRITE_TREE_REPAIR; int to_invalidate = 0; int i; assert(!(dryrun && repair)); *skip_count = 0; if (0 <= it->entry_count && has_sha1_file(it->oid.hash)) return it->entry_count; /* * We first scan for subtrees and update them; we start by * marking existing subtrees -- the ones that are unmarked * should not be in the result. */ for (i = 0; i < it->subtree_nr; i++) it->down[i]->used = 0; /* * Find the subtrees and update them. */ i = 0; while (i < entries) { const struct cache_entry *ce = cache[i]; struct cache_tree_sub *sub; const char *path, *slash; int pathlen, sublen, subcnt, subskip; path = ce->name; pathlen = ce_namelen(ce); if (pathlen <= baselen || memcmp(base, path, baselen)) break; /* at the end of this level */ slash = strchr(path + baselen, '/'); if (!slash) { i++; continue; } /* * a/bbb/c (base = a/, slash = /c) * ==> * path+baselen = bbb/c, sublen = 3 */ sublen = slash - (path + baselen); sub = find_subtree(it, path + baselen, sublen, 1); if (!sub->cache_tree) sub->cache_tree = cache_tree(); subcnt = update_one(sub->cache_tree, cache + i, entries - i, path, baselen + sublen + 1, &subskip, flags); if (subcnt < 0) return subcnt; if (!subcnt) die("index cache-tree records empty sub-tree"); i += subcnt; sub->count = subcnt; /* to be used in the next loop */ *skip_count += subskip; sub->used = 1; } discard_unused_subtrees(it); /* * Then write out the tree object for this level. */ strbuf_init(&buffer, 8192); i = 0; while (i < entries) { const struct cache_entry *ce = cache[i]; struct cache_tree_sub *sub = NULL; const char *path, *slash; int pathlen, entlen; const struct object_id *oid; unsigned mode; int expected_missing = 0; int contains_ita = 0; int ce_missing_ok; path = ce->name; pathlen = ce_namelen(ce); if (pathlen <= baselen || memcmp(base, path, baselen)) break; /* at the end of this level */ slash = strchr(path + baselen, '/'); if (slash) { entlen = slash - (path + baselen); sub = find_subtree(it, path + baselen, entlen, 0); if (!sub) die("cache-tree.c: '%.*s' in '%s' not found", entlen, path + baselen, path); i += sub->count; oid = &sub->cache_tree->oid; mode = S_IFDIR; contains_ita = sub->cache_tree->entry_count < 0; if (contains_ita) { to_invalidate = 1; expected_missing = 1; } } else { oid = &ce->oid; mode = ce->ce_mode; entlen = pathlen - baselen; i++; } ce_missing_ok = mode == S_IFGITLINK || missing_ok || (repository_format_partial_clone && ce_skip_worktree(ce)); if (is_null_oid(oid) || (!ce_missing_ok && !has_object_file(oid))) { strbuf_release(&buffer); if (expected_missing) return -1; return error("invalid object %06o %s for '%.*s'", mode, oid_to_hex(oid), entlen+baselen, path); } /* * CE_REMOVE entries are removed before the index is * written to disk. Skip them to remain consistent * with the future on-disk index. */ if (ce->ce_flags & CE_REMOVE) { *skip_count = *skip_count + 1; continue; } /* * CE_INTENT_TO_ADD entries exist on on-disk index but * they are not part of generated trees. Invalidate up * to root to force cache-tree users to read elsewhere. */ if (!sub && ce_intent_to_add(ce)) { to_invalidate = 1; continue; } /* * "sub" can be an empty tree if all subentries are i-t-a. */ if (contains_ita && is_empty_tree_oid(oid)) continue; strbuf_grow(&buffer, entlen + 100); strbuf_addf(&buffer, "%o %.*s%c", mode, entlen, path + baselen, '\0'); strbuf_add(&buffer, oid->hash, the_hash_algo->rawsz); #if DEBUG fprintf(stderr, "cache-tree update-one %o %.*s\n", mode, entlen, path + baselen); #endif } if (repair) { struct object_id oid; hash_object_file(buffer.buf, buffer.len, tree_type, &oid); if (has_object_file(&oid)) oidcpy(&it->oid, &oid); else to_invalidate = 1; } else if (dryrun) { hash_object_file(buffer.buf, buffer.len, tree_type, &it->oid); } else if (write_object_file(buffer.buf, buffer.len, tree_type, &it->oid)) { strbuf_release(&buffer); return -1; } strbuf_release(&buffer); it->entry_count = to_invalidate ? -1 : i - *skip_count; #if DEBUG fprintf(stderr, "cache-tree update-one (%d ent, %d subtree) %s\n", it->entry_count, it->subtree_nr, oid_to_hex(&it->oid)); #endif return i; }
static int handle_alias(int *argcp, const char ***argv) { int envchanged = 0, ret = 0, saved_errno = errno; const char *subdir; int count, option_count; const char **new_argv; const char *alias_command; char *alias_string; int unused_nongit; subdir = setup_git_directory_gently(&unused_nongit); alias_command = (*argv)[0]; alias_string = alias_lookup(alias_command); if (alias_string) { if (alias_string[0] == '!') { commit_pager_choice(); if (*argcp > 1) { struct strbuf buf; strbuf_init(&buf, PATH_MAX); strbuf_addstr(&buf, alias_string); sq_quote_argv(&buf, (*argv) + 1, PATH_MAX); free(alias_string); alias_string = buf.buf; } trace_printf("trace: alias to shell cmd: %s => %s\n", alias_command, alias_string + 1); ret = system(alias_string + 1); if (ret >= 0 && WIFEXITED(ret) && WEXITSTATUS(ret) != 127) exit(WEXITSTATUS(ret)); die("Failed to run '%s' when expanding alias '%s'", alias_string + 1, alias_command); } count = split_cmdline(alias_string, &new_argv); if (count < 0) die("Bad alias.%s string: %s", alias_command, split_cmdline_strerror(count)); option_count = handle_options(&new_argv, &count, &envchanged); if (envchanged) die("alias '%s' changes environment variables\n" "You can use '!git' in the alias to do this.", alias_command); memmove(new_argv - option_count, new_argv, count * sizeof(char *)); new_argv -= option_count; if (count < 1) die("empty alias for %s", alias_command); if (!strcmp(alias_command, new_argv[0])) die("recursive alias: %s", alias_command); trace_argv_printf(new_argv, "trace: alias expansion: %s =>", alias_command); new_argv = xrealloc(new_argv, sizeof(char *) * (count + *argcp)); /* insert after command name */ memcpy(new_argv + count, *argv + 1, sizeof(char *) * *argcp); *argv = new_argv; *argcp += count - 1; ret = 1; } if (subdir && chdir(subdir)) die_errno("Cannot change to '%s'", subdir); errno = saved_errno; return ret; }
static int process_request_coro(coro_t *coro) { strbuf_t *strbuf = coro_malloc_full(coro, sizeof(*strbuf), strbuf_free); lwan_connection_t *conn = coro_get_data(coro); lwan_t *lwan = conn->thread->lwan; int fd = lwan_connection_get_fd(conn); char request_buffer[DEFAULT_BUFFER_SIZE]; lwan_value_t buffer = { .value = request_buffer, .len = 0 }; char *next_request = NULL; strbuf_init(strbuf); while (true) { lwan_request_t request = { .conn = conn, .fd = fd, .response = { .buffer = strbuf }, }; assert(conn->flags & CONN_IS_ALIVE); next_request = lwan_process_request(lwan, &request, &buffer, next_request); if (!next_request) break; coro_yield(coro, CONN_CORO_MAY_RESUME); if (UNLIKELY(!strbuf_reset_length(strbuf))) return CONN_CORO_ABORT; } return CONN_CORO_FINISHED; } static ALWAYS_INLINE void resume_coro_if_needed(struct death_queue_t *dq, lwan_connection_t *conn, int epoll_fd) { assert(conn->coro); if (!(conn->flags & CONN_SHOULD_RESUME_CORO)) return; lwan_connection_coro_yield_t yield_result = coro_resume(conn->coro); /* CONN_CORO_ABORT is -1, but comparing with 0 is cheaper */ if (yield_result < CONN_CORO_MAY_RESUME) { destroy_coro(dq, conn); return; } bool write_events; if (conn->flags & CONN_MUST_READ) { write_events = true; } else { bool should_resume_coro = (yield_result == CONN_CORO_MAY_RESUME); if (should_resume_coro) conn->flags |= CONN_SHOULD_RESUME_CORO; else conn->flags &= ~CONN_SHOULD_RESUME_CORO; write_events = (conn->flags & CONN_WRITE_EVENTS); if (should_resume_coro == write_events) return; } struct epoll_event event = { .events = events_by_write_flag[write_events], .data.ptr = conn }; int fd = lwan_connection_get_fd(conn); if (UNLIKELY(epoll_ctl(epoll_fd, EPOLL_CTL_MOD, fd, &event) < 0)) lwan_status_perror("epoll_ctl"); conn->flags ^= CONN_WRITE_EVENTS; } static void death_queue_kill_waiting(struct death_queue_t *dq) { dq->time++; while (!death_queue_empty(dq)) { lwan_connection_t *conn = death_queue_idx_to_node(dq, dq->head.next); if (conn->time_to_die > dq->time) return; destroy_coro(dq, conn); } /* Death queue exhausted: reset epoch */ dq->time = 0; }
int run_commit(int argc, char const* const* argv) { int result; char tmp_file_path[PATH_MAX]; struct strbuf buffer; struct string_list files; struct strbuf message; int fd; FILE* tmp_file; printf("commit!\n"); strcpy(tmp_file_path, "/tmp/commit.XXXXXX.fut"); fd = mkstemps(tmp_file_path, 4); if (fd == -1) { fprintf(stderr, "Error opening temp file: %s.\n", tmp_file_path); return 1; } tmp_file = fdopen(fd, "w"); fprintf(tmp_file, "# Remove any files you don't want to commit, and enter a\n" "# commit message. To cancel, leave an empty commit message.\n" "\n"); fprintf(tmp_file, "Files:\n"); write_file_status(tmp_file); fprintf(tmp_file, "\n"); fprintf(tmp_file, "Commit Message:\n\n"); fclose(tmp_file); result = launch_editor(tmp_file_path, NULL, NULL); printf("editor returned %d\n", result); if (result != 0) { fprintf(stderr, "result=%d\n", result); return 1; } strbuf_init(&buffer, 0); strbuf_init(&message, 0); memset(&files, 0, sizeof(struct string_list)); files.strdup_strings = 1; if (strbuf_read_file(&buffer, tmp_file_path, 0) < 0) { result = 1; fprintf(stderr, "Error reading temp file. %s\n", strerror(errno)); goto done; } printf("They wrote --[%s]--\n", buffer.buf); result = parse_commit(&buffer, &files, &message); if (result != 0) { fprintf(stderr, "Error parsing commit message.\n"); result = 1; goto done; } if (message.len == 0 || files.nr == 0) { fprintf(stderr, "Commit aborted.\n"); result = 1; goto done; } printf("file count %d\n", files.nr); print_string_list("files--", &files); printf("\nMessage --[[%s]]--\n", message.buf); done: strbuf_release(&buffer); strbuf_release(&message); string_list_clear(&files, 0); unlink(tmp_file_path); return result; }
static int decode_file (idn_resconf_t conf1, idn_resconf_t conf2, FILE * fp, int flags) { idn_result_t r; idnconv_strbuf_t buf1, buf2; idn_action_t actions1, actions2; int nl_trimmed; int local_ace_hack, idn_ace_hack; idn_converter_t conv; /* * See if the input codeset is an ACE. */ conv = idn_resconf_getidnconverter (conf1); if (conv != NULL && idn_converter_isasciicompatible (conv) && (flags & FLAG_SELECTIVE)) idn_ace_hack = 1; else idn_ace_hack = 0; if (conv != NULL) idn_converter_destroy (conv); conv = idn_resconf_getlocalconverter (conf1); if (conv != NULL && idn_converter_isasciicompatible (conv) && (flags & FLAG_SELECTIVE)) local_ace_hack = 1; else local_ace_hack = 0; if (conv != NULL) idn_converter_destroy (conv); actions1 = IDN_IDNCONV; if (local_ace_hack) { actions2 = IDN_IDNCONV; if (flags & FLAG_MAP) actions2 |= IDN_MAP; if (flags & FLAG_NORMALIZE) actions2 |= IDN_NORMALIZE; if (flags & FLAG_PROHIBITCHECK) actions2 |= IDN_PROHCHECK; if (flags & FLAG_UNASSIGNCHECK) actions2 |= IDN_UNASCHECK; if (flags & FLAG_BIDICHECK) actions2 |= IDN_BIDICHECK; if (flags & FLAG_ASCIICHECK) actions2 |= IDN_ASCCHECK; if (flags & FLAG_LENGTHCHECK) actions2 |= IDN_LENCHECK; } else { actions2 = IDN_LOCALCONV; } if (flags & FLAG_DELIMMAP) actions1 |= IDN_DELIMMAP; if (flags & FLAG_MAP) actions1 |= IDN_MAP; if (flags & FLAG_NORMALIZE) actions1 |= IDN_NORMALIZE; if (flags & FLAG_NORMALIZE) actions1 |= IDN_NORMALIZE; if (flags & FLAG_PROHIBITCHECK) actions1 |= IDN_PROHCHECK; if (flags & FLAG_UNASSIGNCHECK) actions1 |= IDN_UNASCHECK; if (flags & FLAG_BIDICHECK) actions1 |= IDN_BIDICHECK; if (flags & FLAG_ASCIICHECK) actions1 |= IDN_ASCCHECK; if (flags & FLAG_ROUNDTRIPCHECK) actions1 |= IDN_RTCHECK; strbuf_init (&buf1); strbuf_init (&buf2); line_number = 1; while (strbuf_getline (&buf1, fp) != NULL) { /* * Trim newline at the end. This is needed for * those ascii-comatible encodings such as UTF-5 or RACE * not to try converting newlines, which will result * in `invalid encoding' error. */ nl_trimmed = trim_newline (&buf1); /* * Treat input line as the string encoded in local * encoding and convert it to UTF-8 encoded string. */ if (local_ace_hack) { if (strbuf_copy (&buf2, strbuf_get (&buf1)) == NULL) r = idn_nomemory; else r = idn_success; } else { r = convert_line (&buf1, &buf2, conf1, IDN_LOCALCONV, 0); } if (r != idn_success) { errormsg ("conversion failed at line %d: %s\n", line_number, idn_result_tostring (r)); goto error; } /* * Convert internationalized domain names in the line. */ if (idn_ace_hack) { r = convert_line (&buf2, &buf1, conf1, actions1, FLAG_REVERSE | FLAG_SELECTIVE); } else { r = convert_line (&buf2, &buf1, conf1, actions1, FLAG_REVERSE); } if (r != idn_success) { errormsg ("conversion failed at line %d: %s\n", line_number, idn_result_tostring (r)); goto error; } if (!idn_utf8_isvalidstring (strbuf_get (&buf1))) { errormsg ("conversion to utf-8 failed at line %d\n", line_number); goto error; } /* * Perform round trip check and convert to the output * codeset. */ if (local_ace_hack) { r = convert_line (&buf1, &buf2, conf2, actions2, FLAG_SELECTIVE); } else { r = convert_line (&buf1, &buf2, conf1, actions2, FLAG_REVERSE); } if (r != idn_success) { errormsg ("error in nameprep or output conversion " "at line %d: %s\n", line_number, idn_result_tostring (r)); goto error; } fputs (strbuf_get (&buf2), stdout); if (nl_trimmed) putc ('\n', stdout); if (flush_every_line) fflush (stdout); line_number++; } strbuf_reset (&buf1); strbuf_reset (&buf2); return (0); error: strbuf_reset (&buf1); strbuf_reset (&buf2); return (1); }
/* ** Return file count ** setvals==1 to set all values based on options ** ==2 to set only ansi, user interface, exit on complete ** ==0 to not set any values ** procfiles == 1 to process files ** == 0 to count files only */ int parse_cmd_args(K2PDFOPT_SETTINGS *k2settings,STRBUF *env,STRBUF *cmdline, STRBUF *usermenu,int setvals,int procfiles) { CMDLINEINPUT _cl,*cl; STRBUF *allopts,_allopts; int filecount,readnext; allopts=&_allopts; strbuf_init(allopts); strbuf_cpy(allopts,env->s); strbuf_cat(allopts,cmdline->s); strbuf_cat(allopts,usermenu->s); cl=&_cl; filecount=0; cmdlineinput_init(cl,0,NULL,allopts->s); readnext=1; while (1) { if (readnext && cmdlineinput_next(cl)==NULL) break; readnext=1; if (!stricmp(cl->cmdarg,"-?") || !stricmp(cl->cmdarg,"-?-")) { if (setvals==2) k2settings->show_usage = cl->cmdarg[2]=='-' ? 0 : 1; continue; } if (!stricmp(cl->cmdarg,"-a") || !stricmp(cl->cmdarg,"-a-")) { if (setvals>=1) ansi_set(cl->cmdarg[2]=='-' ? 0 : 1); continue; } if (!stricmp(cl->cmdarg,"-x") || !stricmp(cl->cmdarg,"-x-")) { if (setvals>=1) k2settings->exit_on_complete=(cl->cmdarg[2]=='-' ? 0 : 1); continue; } if (!strnicmp(cl->cmdarg,"-ui",3)) { if (setvals>=1) { if (cl->cmdarg[3]!='-') k2settings->query_user_explicit=1; k2settings->query_user=(cl->cmdarg[3]!='-') ? 1 : 0; } continue; } if (!stricmp(cl->cmdarg,"-evl")) { if (cmdlineinput_next(cl)==NULL) break; if (setvals==1) k2settings->erase_vertical_lines=atoi(cl->cmdarg); continue; } if (!stricmp(cl->cmdarg,"-vls")) { if (cmdlineinput_next(cl)==NULL) break; if (setvals==1) k2settings->vertical_line_spacing=atof(cl->cmdarg); continue; } if (!stricmp(cl->cmdarg,"-vm")) { if (cmdlineinput_next(cl)==NULL) break; if (setvals==1) { k2settings->vertical_multiplier=fabs(atof(cl->cmdarg)); if (k2settings->vertical_multiplier < 0.1) k2settings->vertical_multiplier = 0.1; } continue; } if (!stricmp(cl->cmdarg,"-vs")) { if (cmdlineinput_next(cl)==NULL) break; if (setvals==1) k2settings->max_vertical_gap_inches=atof(cl->cmdarg); continue; } if (!stricmp(cl->cmdarg,"-de")) { if (cmdlineinput_next(cl)==NULL) break; if (setvals==1) k2settings->defect_size_pts=atof(cl->cmdarg); continue; } if (!stricmp(cl->cmdarg,"-dev")) { if (cmdlineinput_next(cl)==NULL) break; if (setvals==2 && !strcmp(cl->cmdarg,"?")) { devprofiles_echo(stdout); k2sys_exit(k2settings,0); } if (setvals==1) { if (!k2pdfopt_settings_set_to_device(k2settings,devprofile_get(cl->cmdarg))) aprintf(TTEXT_WARN "\aDevice profile '%s' not known." TTEXT_NORMAL "\n",cl->cmdarg); } continue; } if (!stricmp(cl->cmdarg,"-pi") || !stricmp(cl->cmdarg,"-pi-")) { if (setvals==1) k2settings->preserve_indentation=(cl->cmdarg[3]=='-') ? 0 : 1; continue; } if (!strnicmp(cl->cmdarg,"-wrap",5)) { if (setvals==1) { k2settings->text_wrap=(cl->cmdarg[5]=='-') ? 0 : (cl->cmdarg[5]=='+' ? 2 : 1); if (k2settings->text_wrap) k2settings->use_crop_boxes=0; } continue; } #ifdef HAVE_MUPDF_LIB if (!stricmp(cl->cmdarg,"-gs") || !stricmp(cl->cmdarg,"-gs-") || !stricmp(cl->cmdarg,"-gs--")) { if (setvals==1) k2settings->user_usegs=(cl->cmdarg[3]=='-' ? (cl->cmdarg[4]=='-' ? -1 : 0) : 1); continue; } if (!stricmp(cl->cmdarg,"-n") || !stricmp(cl->cmdarg,"-n-")) { if (setvals==1) { k2settings->use_crop_boxes=(cl->cmdarg[2]=='-') ? 0 : 1; if (k2settings->use_crop_boxes) { k2settings->text_wrap=0; #ifdef HAVE_OCR_LIB k2settings->dst_ocr=0; #endif } } continue; } #endif if (!stricmp(cl->cmdarg,"-neg") || !stricmp(cl->cmdarg,"-neg-")) { if (setvals==1) k2settings->dst_negative=(cl->cmdarg[4]=='-') ? 0 : 1; continue; } if (!stricmp(cl->cmdarg,"-r") || !stricmp(cl->cmdarg,"-r-")) { if (setvals==1) k2settings->src_left_to_right=(cl->cmdarg[2]=='-') ? 1 : 0; continue; } if (!strnicmp(cl->cmdarg,"-hy",3)) { if (setvals==1) k2settings->hyphen_detect=(cl->cmdarg[3]=='-') ? 0 : 1; continue; } if (!strnicmp(cl->cmdarg,"-ls",3)) { if (setvals==1) k2settings->dst_landscape=(cl->cmdarg[3]=='-') ? 0 : 1; continue; } if (!stricmp(cl->cmdarg,"-mode")) { if (cmdlineinput_next(cl)==NULL) break; if (setvals==1) { if (!stricmp(cl->cmdarg,"pdfr") || !stricmp(cl->cmdarg,"copy")) { /* -n- -wrap- -col 1 -vb -2 -w -1 -h -1 -dpi 150 -rt 0 -c -t- -f2p -2 */ /* -m 0 -om 0 -pl 0 -pr 0 -pt 0 -pb 0 -mc- */ k2settings->use_crop_boxes=0; k2settings->text_wrap=0; k2settings->max_columns=1; k2settings->vertical_break_threshold=-2; k2settings->dst_userwidth=-1.0; k2settings->dst_userwidth_units=UNITS_PIXELS; k2settings->dst_userheight=-1.0; k2settings->dst_userheight_units=UNITS_PIXELS; k2settings->dst_dpi=150; k2settings->src_rot=0.; k2settings->dst_color=1; k2settings->src_trim=0; k2settings->dst_fit_to_page=-2; k2settings->mar_left=k2settings->mar_top=k2settings->mar_right=k2settings->mar_bot=0.; k2settings->dst_mar=k2settings->dst_marleft=k2settings->dst_martop=k2settings->dst_marright=k2settings->dst_marbot=0.; k2settings->pad_left=k2settings->pad_top=k2settings->pad_bottom=k2settings->pad_right=0; k2settings->mark_corners=0; } else if (!stricmp(cl->cmdarg,"fw") || !stricmp(cl->cmdarg,"sopdf") || !stricmp(cl->cmdarg,"fitwidth")) { /* -wrap- -col 1 -vb -2 -t -ls */ k2settings->use_crop_boxes=1; k2settings->text_wrap=0; k2settings->max_columns=1; k2settings->vertical_break_threshold=-2; k2settings->src_trim=1; k2settings->dst_landscape=1; } else if (!stricmp(cl->cmdarg,"2col") || !stricmp(cl->cmdarg,"col2")) { k2settings->use_crop_boxes=1; k2settings->text_wrap=0; k2settings->max_columns=2; k2settings->vertical_break_threshold=-2; k2settings->src_trim=1; } else if (!stricmp(cl->cmdarg,"def") || !stricmp(cl->cmdarg,"default") || !stricmp(cl->cmdarg,"std") || !stricmp(cl->cmdarg,"standard")) { k2pdfopt_settings_set_to_device(k2settings,devprofile_get("k2")); k2settings->use_crop_boxes=1; k2settings->text_wrap=1; k2settings->max_columns=2; k2settings->vertical_break_threshold=1.75; k2settings->src_rot=SRCROT_AUTO; k2settings->src_trim=1; k2settings->dst_fit_to_page=0; k2settings->mar_left=k2settings->mar_top=k2settings->mar_right=k2settings->mar_bot=0.25; k2settings->dst_mar=k2settings->dst_marleft=k2settings->dst_martop=k2settings->dst_marright=k2settings->dst_marbot=0.02; } else aprintf(TTEXT_WARN "\a\n** Unknown mode: %s **\n\n" TTEXT_NORMAL, cl->cmdarg); } continue; } if (!stricmp(cl->cmdarg,"-o")) { if (cmdlineinput_next(cl)==NULL) break; if (setvals==1) { strncpy(k2settings->dst_opname_format,cl->cmdarg,127); k2settings->dst_opname_format[127]='\0'; } continue; } if (!stricmp(cl->cmdarg,"-ow") || !stricmp(cl->cmdarg,"-ow-")) { int always_prompt; char *ptr; always_prompt = (cl->cmdarg[3]=='-'); if (((ptr=cmdlineinput_next(cl))==NULL) || !is_a_number(cl->cmdarg)) { readnext=0; if (setvals==1) k2settings->overwrite_minsize_mb= always_prompt ? 0 : -1; if (ptr==NULL) break; continue; } if (setvals==1) k2settings->overwrite_minsize_mb=atof(cl->cmdarg); continue; } if (!stricmp(cl->cmdarg,"-grid")) { if (cmdlineinput_next(cl)==NULL) break; if (setvals==1) { char buf[128]; double v[3]; int na,i; strncpy(buf,cl->cmdarg,127); buf[127]='\0'; k2settings->src_grid_order=0; for (i=0; buf[i]!='\0'; i++) { if (tolower(buf[i])=='x') buf[i]=' '; if (buf[i]=='+' && buf[i+1]=='\0') k2settings->src_grid_order=1; } na=string_read_doubles(buf,v,3); if (na>=2) { k2settings->src_grid_cols=(int)(v[0]+.5); k2settings->src_grid_rows=(int)(v[1]+.5); if (na>2) k2settings->src_grid_overlap_percentage=(int)(v[2]+.5); } else k2settings->src_grid_cols = k2settings->src_grid_rows = -1; if (k2settings->src_grid_cols>0 && k2settings->src_grid_rows>0) { k2settings->use_crop_boxes=1; k2settings->dst_fit_to_page=-2; k2settings->vertical_break_threshold=-2; k2settings->text_wrap=1; k2settings->max_columns=1; } } continue; } if (!stricmp(cl->cmdarg,"-f2p")) { if (cmdlineinput_next(cl)==NULL) break; if (setvals==1) { k2settings->dst_fit_to_page=atoi(cl->cmdarg); if (k2settings->dst_fit_to_page == -2) k2settings->vertical_break_threshold=-2.; } continue; } if (!stricmp(cl->cmdarg,"-vb")) { if (cmdlineinput_next(cl)==NULL) break; if (setvals==1) k2settings->vertical_break_threshold=atof(cl->cmdarg); continue; } if (!stricmp(cl->cmdarg,"-sm") || !stricmp(cl->cmdarg,"-sm-")) { if (setvals==1) k2settings->show_marked_source=(cl->cmdarg[3]=='-' ? 0 : 1); continue; } if (!stricmp(cl->cmdarg,"-bp") || !stricmp(cl->cmdarg,"-bp-")) { if (cl->cmdarg[3]=='-') { if (setvals==1) k2settings->dst_break_pages=0; continue; } if (cmdlineinput_next(cl)==NULL) break; if (is_a_number(cl->cmdarg)) { if (setvals==1) k2settings->dst_break_pages= -1 - (int)(atof(cl->cmdarg)*1000.+.5); } else { if (setvals==1) k2settings->dst_break_pages=1; readnext=0; } continue; } if (!strnicmp(cl->cmdarg,"-fc",3)) { if (setvals==1) k2settings->fit_columns=(cl->cmdarg[3]=='-') ? 0 : 1; continue; } if (!stricmp(cl->cmdarg,"-d") || !stricmp(cl->cmdarg,"-d-")) { if (setvals==1) k2settings->dst_dither=(cl->cmdarg[2]=='-') ? 0 : 1; continue; } if (!stricmp(cl->cmdarg,"-c") || !stricmp(cl->cmdarg,"-c-")) { if (setvals==1) { k2settings->dst_color=(cl->cmdarg[2]=='-') ? 0 : 1; /* wrapbmp_set_color(k2settings->dst_color); */ } continue; } if (!strnicmp(cl->cmdarg,"-v",2)) { if (setvals==1) k2settings->verbose=(cl->cmdarg[2]=='-') ? 0 : 1; continue; } if (!strnicmp(cl->cmdarg,"-png",4)) { if (setvals==1) k2settings->jpeg_quality=(cl->cmdarg[4]=='-') ? 90 : -1; continue; } if (!strnicmp(cl->cmdarg,"-mc",3)) { if (setvals==1) k2settings->mark_corners=(cl->cmdarg[3]=='-') ? 0 : 1; continue; } if (!stricmp(cl->cmdarg,"-ocrlang") || !stricmp(cl->cmdarg,"-l")) { if (cmdlineinput_next(cl)==NULL) break; #ifdef HAVE_TESSERACT_LIB strncpy(k2settings->dst_ocr_lang,cl->cmdarg,15); k2settings->dst_ocr_lang[15]='\0'; #endif continue; } if (!stricmp(cl->cmdarg,"-ocrvis")) { if (cmdlineinput_next(cl)==NULL) break; #ifdef HAVE_OCR_LIB if (setvals==1) { k2settings->dst_ocr_visibility_flags=0; if (in_string(cl->cmdarg,"s")>=0) k2settings->dst_ocr_visibility_flags |= 1; if (in_string(cl->cmdarg,"t")>=0) k2settings->dst_ocr_visibility_flags |= 2; if (in_string(cl->cmdarg,"b")>=0) k2settings->dst_ocr_visibility_flags |= 4; } #endif continue; } if (!stricmp(cl->cmdarg,"-ocrhmax")) { if (cmdlineinput_next(cl)==NULL) break; #ifdef HAVE_OCR_LIB if (setvals==1) k2settings->ocr_max_height_inches=atof(cl->cmdarg); #endif continue; } if (!stricmp(cl->cmdarg,"-ocr") || !stricmp(cl->cmdarg,"-ocr-")) { #ifndef HAVE_OCR_LIB if (setvals==1) { static int warned=0; if (!warned) aprintf(TTEXT_WARN "\a\n** No OCR capability in this compile of k2pdfopt! **\n\n" TTEXT_NORMAL); warned=1; } #endif if (cl->cmdarg[4]=='-') { #ifdef HAVE_OCR_LIB if (setvals==1) k2settings->dst_ocr=0; #endif continue; } if (cmdlineinput_next(cl)==NULL || !stricmp(cl->cmdarg,"t")) { #ifdef HAVE_OCR_LIB if (setvals==1) { k2settings->dst_ocr='t'; k2settings->use_crop_boxes=0; } #endif continue; } if (!stricmp(cl->cmdarg,"g") || !stricmp(cl->cmdarg,"j")) { #ifdef HAVE_OCR_LIB if (setvals==1) { k2settings->dst_ocr='g'; k2settings->use_crop_boxes=0; } #endif continue; } #ifdef HAVE_OCR_LIB if (setvals==1) { #ifdef HAVE_TESSERACT_LIB k2settings->dst_ocr='t'; #else k2settings->dst_ocr='g'; #endif k2settings->use_crop_boxes=0; } #endif readnext=0; continue; } if (!stricmp(cl->cmdarg,"-t") || !stricmp(cl->cmdarg,"-t-")) { if (setvals==1) k2settings->src_trim=(cl->cmdarg[2]=='-') ? 0 : 1; continue; } if (!stricmp(cl->cmdarg,"-s") || !stricmp(cl->cmdarg,"-s-")) { if (setvals==1) k2settings->dst_sharpen=(cl->cmdarg[2]=='-') ? 0 : 1; continue; } if (!stricmp(cl->cmdarg,"-as")) { if (setvals==1) k2settings->src_autostraighten=4.; if (cmdlineinput_next(cl)==NULL) break; if (is_a_number(cl->cmdarg)) { if (setvals==1) k2settings->src_autostraighten=atof(cl->cmdarg); } else readnext=0; if (k2settings->src_autostraighten > 45.) k2settings->src_autostraighten = 45.; continue; } if (!stricmp(cl->cmdarg,"-rt")) { if (cmdlineinput_next(cl)==NULL) break; if (setvals==1) { if (!stricmp(cl->cmdarg,"auto")) k2settings->src_rot=SRCROT_AUTO; else if (!stricmp(cl->cmdarg,"aep")) k2settings->src_rot=SRCROT_AUTOEP; else k2settings->src_rot=atoi(cl->cmdarg); } continue; } if (!stricmp(cl->cmdarg,"-crgh")) { if (cmdlineinput_next(cl)==NULL) break; if (setvals==1) { k2settings->column_row_gap_height_in=atof(cl->cmdarg); if (k2settings->column_row_gap_height_in < 0.001) k2settings->column_row_gap_height_in = 0.001; } continue; } if (!stricmp(cl->cmdarg,"-cgr")) { if (cmdlineinput_next(cl)==NULL) break; if (setvals==1) { k2settings->column_gap_range=atof(cl->cmdarg); if (k2settings->column_gap_range < 0.) k2settings->column_gap_range = 0.; if (k2settings->column_gap_range > 1.0) k2settings->column_gap_range = 1.0; } continue; } if (!stricmp(cl->cmdarg,"-comax")) { if (cmdlineinput_next(cl)==NULL) break; if (setvals==1) { k2settings->column_offset_max=atof(cl->cmdarg); if (k2settings->column_offset_max > 1.0) k2settings->column_offset_max = 1.0; } continue; } if (!stricmp(cl->cmdarg,"-col")) { if (cmdlineinput_next(cl)==NULL) break; if (setvals==1) { k2settings->max_columns=atoi(cl->cmdarg); if (k2settings->max_columns<1) k2settings->max_columns=1; if (k2settings->max_columns>2) k2settings->max_columns=4; } continue; } if (!strnicmp(cl->cmdarg,"-jpg",4) || !strnicmp(cl->cmdarg,"-jpeg",5)) { int ic; ic = (tolower(cl->cmdarg[3])=='g') ? 4 : 5; if (cl->cmdarg[ic]=='-') { if (setvals==1) k2settings->jpeg_quality=-1; } else { if (cmdlineinput_next(cl)==NULL) { if (setvals==1) k2settings->jpeg_quality=90; } else if (is_an_integer(cl->cmdarg)) { if (setvals==1) k2settings->jpeg_quality=atoi(cl->cmdarg); } else { readnext=0; if (setvals==1) k2settings->jpeg_quality=90; } } if (k2settings->jpeg_quality>100) k2settings->jpeg_quality=100; continue; } if (!stricmp(cl->cmdarg,"-col")) { if (cmdlineinput_next(cl)==NULL) break; if (setvals==1) { k2settings->max_columns=atoi(cl->cmdarg); if (k2settings->max_columns<1) k2settings->max_columns=1; if (k2settings->max_columns>2) k2settings->max_columns=4; } continue; } if (!stricmp(cl->cmdarg,"-p")) { if (cmdlineinput_next(cl)==NULL) break; if (setvals==1) { strncpy(k2settings->pagelist,cl->cmdarg,1023); k2settings->pagelist[1023]='\0'; } continue; } if (!stricmp(cl->cmdarg,"-bpc")) { if (cmdlineinput_next(cl)==NULL) break; if (setvals==1) { k2settings->dst_bpc=atoi(cl->cmdarg); if (k2settings->dst_bpc>=6) k2settings->dst_bpc=8; else if (k2settings->dst_bpc>=3) k2settings->dst_bpc=4; else if (k2settings->dst_bpc<1) k2settings->dst_bpc=1; } continue; } if (!stricmp(cl->cmdarg,"-g")) { if (cmdlineinput_next(cl)==NULL) break; if (setvals==1) { k2settings->dst_gamma=atof(cl->cmdarg); if (k2settings->dst_gamma<.01) k2settings->dst_gamma=.01; if (k2settings->dst_gamma>100.) k2settings->dst_gamma=100.; } continue; } if (!stricmp(cl->cmdarg,"-cg")) { if (cmdlineinput_next(cl)==NULL) break; if (setvals==1) k2settings->min_column_gap_inches=atof(cl->cmdarg); continue; } if (!stricmp(cl->cmdarg,"-cgmax")) { if (cmdlineinput_next(cl)==NULL) break; if (setvals==1) k2settings->max_column_gap_inches=atof(cl->cmdarg); continue; } if (!stricmp(cl->cmdarg,"-gtr")) { if (cmdlineinput_next(cl)==NULL) break; if (setvals==1) { k2settings->gtr_in=atof(cl->cmdarg); if (k2settings->gtr_in<0.) k2settings->gtr_in=0.; } continue; } if (!stricmp(cl->cmdarg,"-gtc")) { if (cmdlineinput_next(cl)==NULL) break; if (setvals==1) { k2settings->gtc_in=atof(cl->cmdarg); if (k2settings->gtc_in<0.) k2settings->gtc_in=0.; } continue; } if (!stricmp(cl->cmdarg,"-gtw")) { if (cmdlineinput_next(cl)==NULL) break; if (setvals==1) { k2settings->gtw_in=atof(cl->cmdarg); if (k2settings->gtw_in<0.) k2settings->gtw_in=0.; } continue; } /* if (i<argc-1 && !stricmp(cl->cmdarg,"-cd")) { if (setvals==1) { cdthresh=atof(argv[++i]); if (cdthresh<0.) cdthresh=0.; else if (cdthresh>100.) cdthresh=100.; } else i++; continue; } */ if (!stricmp(cl->cmdarg,"-cmax")) { if (cmdlineinput_next(cl)==NULL) break; if (setvals==1) k2settings->contrast_max=atof(cl->cmdarg); continue; } if (!stricmp(cl->cmdarg,"-ch")) { if (cmdlineinput_next(cl)==NULL) break; if (setvals==1) k2settings->min_column_height_inches=atof(cl->cmdarg); continue; } if (!stricmp(cl->cmdarg,"-ds")) { if (cmdlineinput_next(cl)==NULL) break; if (setvals==1 && atof(cl->cmdarg)>0.) k2settings->document_scale_factor=atof(cl->cmdarg); continue; } if (!stricmp(cl->cmdarg,"-idpi")) { if (cmdlineinput_next(cl)==NULL) break; if (setvals==1 && atof(cl->cmdarg)!=0.) k2settings->user_src_dpi=atof(cl->cmdarg); continue; } if (!stricmp(cl->cmdarg,"-odpi") || !stricmp(cl->cmdarg,"-dpi")) { if (cmdlineinput_next(cl)==NULL) break; if (setvals==1) k2settings->dst_dpi=atoi(cl->cmdarg); continue; } if (!stricmp(cl->cmdarg,"-jf")) { if (cmdlineinput_next(cl)==NULL) break; if (setvals==1) k2settings->dst_figure_justify=atoi(cl->cmdarg); if (cmdlineinput_next(cl)==NULL) break; if (!is_a_number(cl->cmdarg)) { readnext=0; continue; } if (setvals==1) k2settings->dst_min_figure_height_in=atof(cl->cmdarg); continue; } if (!stricmp(cl->cmdarg,"-j")) { if (cmdlineinput_next(cl)==NULL) break; if (setvals==1) { k2settings->dst_justify=atoi(cl->cmdarg); if (in_string(cl->cmdarg,"+")>=0) k2settings->dst_fulljustify=1; else if (in_string(&cl->cmdarg[1],"-")>=0) k2settings->dst_fulljustify=0; else k2settings->dst_fulljustify=-1; } continue; } if (!stricmp(cl->cmdarg,"-dr")) { if (cmdlineinput_next(cl)==NULL) break; if (setvals==1) k2settings->dst_display_resolution=atof(cl->cmdarg); continue; } if (!stricmp(cl->cmdarg,"-h")) { if (cmdlineinput_next(cl)==NULL) break; if (setvals==1) set_value_with_units(cl->cmdarg,&k2settings->dst_userheight,&k2settings->dst_userheight_units); continue; } if (!stricmp(cl->cmdarg,"-ws")) { if (cmdlineinput_next(cl)==NULL) break; if (setvals==1) k2settings->word_spacing=atof(cl->cmdarg); continue; } if (!stricmp(cl->cmdarg,"-wt")) { if (cmdlineinput_next(cl)==NULL) break; if (setvals==1) { k2settings->src_whitethresh=atoi(cl->cmdarg); if (k2settings->src_whitethresh>255) k2settings->src_whitethresh=255; } continue; } if (!stricmp(cl->cmdarg,"-w")) { if (cmdlineinput_next(cl)==NULL) break; if (setvals==1) set_value_with_units(cl->cmdarg,&k2settings->dst_userwidth,&k2settings->dst_userwidth_units); continue; } if (!stricmp(cl->cmdarg,"-omb")) { if (cmdlineinput_next(cl)==NULL) break; if (setvals==1) k2settings->dst_marbot=atof(cl->cmdarg); continue; } if (!stricmp(cl->cmdarg,"-omt")) { if (cmdlineinput_next(cl)==NULL) break; if (setvals==1) k2settings->dst_martop=atof(cl->cmdarg); continue; } if (!stricmp(cl->cmdarg,"-omr")) { if (cmdlineinput_next(cl)==NULL) break; if (setvals==1) k2settings->dst_marright=atof(cl->cmdarg); continue; } if (!stricmp(cl->cmdarg,"-oml")) { if (cmdlineinput_next(cl)==NULL) break; if (setvals==1) k2settings->dst_marleft=atof(cl->cmdarg); continue; } if (!stricmp(cl->cmdarg,"-om")) { if (cmdlineinput_next(cl)==NULL) break; if (setvals==1) { double v[4]; int na; na=string_read_doubles(cl->cmdarg,v,4); if (na>=1) k2settings->dst_mar=k2settings->dst_marleft=k2settings->dst_martop=k2settings->dst_marright=k2settings->dst_marbot=v[0]; if (na>=2) k2settings->dst_martop=k2settings->dst_marright=k2settings->dst_marbot=v[1]; if (na>=3) k2settings->dst_marright=k2settings->dst_marbot=v[2]; if (na>=4) k2settings->dst_marbot=v[3]; } continue; } if (!stricmp(cl->cmdarg,"-mb")) { if (cmdlineinput_next(cl)==NULL) break; if (setvals==1) k2settings->mar_bot=atof(cl->cmdarg); continue; } if (!stricmp(cl->cmdarg,"-mt")) { if (cmdlineinput_next(cl)==NULL) break; if (setvals==1) k2settings->mar_top=atof(cl->cmdarg); continue; } if (!stricmp(cl->cmdarg,"-mr")) { if (cmdlineinput_next(cl)==NULL) break; if (setvals==1) k2settings->mar_right=atof(cl->cmdarg); continue; } if (!stricmp(cl->cmdarg,"-ml")) { if (cmdlineinput_next(cl)==NULL) break; if (setvals==1) k2settings->mar_left=atof(cl->cmdarg); continue; } if (!stricmp(cl->cmdarg,"-pb")) { if (cmdlineinput_next(cl)==NULL) break; if (setvals==1) k2settings->pad_bottom=atoi(cl->cmdarg); continue; } if (!stricmp(cl->cmdarg,"-pt")) { if (cmdlineinput_next(cl)==NULL) break; if (setvals==1) k2settings->pad_top=atoi(cl->cmdarg); continue; } if (!stricmp(cl->cmdarg,"-pr")) { if (cmdlineinput_next(cl)==NULL) break; if (setvals==1) k2settings->pad_right=atoi(cl->cmdarg); continue; } if (!stricmp(cl->cmdarg,"-pl")) { if (cmdlineinput_next(cl)==NULL) break; if (setvals==1) k2settings->pad_left=atoi(cl->cmdarg); continue; } if (!stricmp(cl->cmdarg,"-m")) { if (cmdlineinput_next(cl)==NULL) break; if (setvals==1) { double v[4]; int na; na=string_read_doubles(cl->cmdarg,v,4); if (na>=1) k2settings->mar_left=k2settings->mar_top=k2settings->mar_right=k2settings->mar_bot=v[0]; if (na>=2) k2settings->mar_top=k2settings->mar_right=k2settings->mar_bot=v[1]; if (na>=3) k2settings->mar_right=k2settings->mar_bot=v[2]; if (na>=4) k2settings->mar_bot=v[3]; } continue; } if (!strnicmp(cl->cmdarg,"-hq",3)) { if (setvals==1) continue; if (cl->cmdarg[3]=='-') { k2settings->dst_dpi=167; k2settings->user_src_dpi = -2.0; k2settings->dst_userwidth=DEFAULT_WIDTH; k2settings->dst_userwidth_units=UNITS_PIXELS; k2settings->dst_userheight=DEFAULT_HEIGHT; k2settings->dst_userheight_units=UNITS_PIXELS; } else { k2settings->dst_dpi=333; k2settings->user_src_dpi = -2.0; k2settings->dst_userwidth=DEFAULT_WIDTH*2; k2settings->dst_userheight=DEFAULT_HEIGHT*2; k2settings->dst_userwidth_units=UNITS_PIXELS; k2settings->dst_userheight_units=UNITS_PIXELS; } continue; } if (!stricmp(cl->cmdarg,"-debug")) { if (setvals==1) k2settings->debug=1; if (cmdlineinput_next(cl)==NULL) break; if (is_an_integer(cl->cmdarg)) { if (setvals==1) k2settings->debug=atoi(cl->cmdarg); } else readnext=0; continue; } /* ** UNDOCUMENTED COMMAND-LINE ARGS */ if (!stricmp(cl->cmdarg,"-whmax")) { if (cmdlineinput_next(cl)==NULL) break; if (setvals==1) k2settings->no_wrap_height_limit_inches=atof(cl->cmdarg); continue; } if (!stricmp(cl->cmdarg,"-arlim")) { if (cmdlineinput_next(cl)==NULL) break; if (setvals==1) k2settings->no_wrap_ar_limit=atof(cl->cmdarg); continue; } if (!stricmp(cl->cmdarg,"-rwmin")) { if (cmdlineinput_next(cl)==NULL) break; if (setvals==1) k2settings->little_piece_threshold_inches=atof(cl->cmdarg); continue; } filecount++; /* if (filecount==1 && firstfile!=NULL) { strncpy(firstfile,cl->cmdarg,255); firstfile[255]='\0'; } */ if (procfiles) k2pdfopt_proc_wildarg(k2settings,cl->cmdarg); } strbuf_free(allopts); return(filecount); }
void init_notes_merge_options(struct notes_merge_options *o) { memset(o, 0, sizeof(struct notes_merge_options)); strbuf_init(&(o->commit_msg), 0); o->verbosity = NOTES_MERGE_VERBOSITY_DEFAULT; }
static inline void strbuf_reset(StringBuffer *b) { if (b->buf != b->buf1) free(b->buf); strbuf_init(b); }
static int handle_alias(int *argcp, const char ***argv) { int envchanged = 0, ret = 0, saved_errno = errno; int count, option_count; const char **new_argv; const char *alias_command; char *alias_string; alias_command = (*argv)[0]; alias_string = alias_lookup(alias_command); if (alias_string) { if (alias_string[0] == '!') { if (*argcp > 1) { struct strbuf buf; strbuf_init(&buf, PATH_MAX); strbuf_addstr(&buf, alias_string); sq_quote_argv(&buf, (*argv) + 1, PATH_MAX); free(alias_string); alias_string = buf.buf; } ret = system(alias_string + 1); if (ret >= 0 && WIFEXITED(ret) && WEXITSTATUS(ret) != 127) exit(WEXITSTATUS(ret)); die("Failed to run '%s' when expanding alias '%s'", alias_string + 1, alias_command); } count = split_cmdline(alias_string, &new_argv); if (count < 0) die("Bad alias.%s string", alias_command); option_count = handle_options(&new_argv, &count, &envchanged); if (envchanged) die("alias '%s' changes environment variables\n" "You can use '!perf' in the alias to do this.", alias_command); memmove(new_argv - option_count, new_argv, count * sizeof(char *)); new_argv -= option_count; if (count < 1) die("empty alias for %s", alias_command); if (!strcmp(alias_command, new_argv[0])) die("recursive alias: %s", alias_command); new_argv = realloc(new_argv, sizeof(char *) * (count + *argcp + 1)); /* insert after command name */ memcpy(new_argv + count, *argv + 1, sizeof(char *) * *argcp); new_argv[count + *argcp] = NULL; *argv = new_argv; *argcp += count - 1; ret = 1; } errno = saved_errno; return ret; }
void pp_title_line(struct pretty_print_context *pp, const char **msg_p, struct strbuf *sb, const char *encoding, int need_8bit_cte) { static const int max_length = 78; /* per rfc2047 */ struct strbuf title; strbuf_init(&title, 80); *msg_p = format_subject(&title, *msg_p, pp->preserve_subject ? "\n" : " "); strbuf_grow(sb, title.len + 1024); if (pp->subject) { strbuf_addstr(sb, pp->subject); if (needs_rfc2047_encoding(title.buf, title.len, RFC2047_SUBJECT)) add_rfc2047(sb, title.buf, title.len, encoding, RFC2047_SUBJECT); else strbuf_add_wrapped_bytes(sb, title.buf, title.len, -last_line_length(sb), 1, max_length); } else { strbuf_addbuf(sb, &title); } strbuf_addch(sb, '\n'); if (need_8bit_cte == 0) { int i; for (i = 0; i < pp->in_body_headers.nr; i++) { if (has_non_ascii(pp->in_body_headers.items[i].string)) { need_8bit_cte = 1; break; } } } if (need_8bit_cte > 0) { const char *header_fmt = "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=%s\n" "Content-Transfer-Encoding: 8bit\n"; strbuf_addf(sb, header_fmt, encoding); } if (pp->after_subject) { strbuf_addstr(sb, pp->after_subject); } if (pp->fmt == CMIT_FMT_EMAIL) { strbuf_addch(sb, '\n'); } if (pp->in_body_headers.nr) { int i; for (i = 0; i < pp->in_body_headers.nr; i++) { strbuf_addstr(sb, pp->in_body_headers.items[i].string); free(pp->in_body_headers.items[i].string); } string_list_clear(&pp->in_body_headers, 0); strbuf_addch(sb, '\n'); } strbuf_release(&title); }
int cmd_format_patch(int argc, const char **argv, const char *prefix) { struct commit *commit; struct commit **list = NULL; struct rev_info rev; int nr = 0, total, i, j; int use_stdout = 0; int start_number = -1; int keep_subject = 0; int numbered_files = 0; /* _just_ numbers */ int subject_prefix = 0; int ignore_if_in_upstream = 0; int thread = 0; int cover_letter = 0; int boundary_count = 0; int no_binary_diff = 0; struct commit *origin = NULL, *head = NULL; const char *in_reply_to = NULL; struct patch_ids ids; char *add_signoff = NULL; struct strbuf buf; git_config(git_format_config, NULL); init_revisions(&rev, prefix); rev.commit_format = CMIT_FMT_EMAIL; rev.verbose_header = 1; rev.diff = 1; rev.combine_merges = 0; rev.ignore_merges = 1; DIFF_OPT_SET(&rev.diffopt, RECURSIVE); rev.subject_prefix = fmt_patch_subject_prefix; /* * Parse the arguments before setup_revisions(), or something * like "git format-patch -o a123 HEAD^.." may fail; a123 is * possibly a valid SHA1. */ for (i = 1, j = 1; i < argc; i++) { if (!strcmp(argv[i], "--stdout")) use_stdout = 1; else if (!strcmp(argv[i], "-n") || !strcmp(argv[i], "--numbered")) numbered = 1; else if (!strcmp(argv[i], "-N") || !strcmp(argv[i], "--no-numbered")) { numbered = 0; auto_number = 0; } else if (!prefixcmp(argv[i], "--start-number=")) start_number = strtol(argv[i] + 15, NULL, 10); else if (!strcmp(argv[i], "--numbered-files")) numbered_files = 1; else if (!strcmp(argv[i], "--start-number")) { i++; if (i == argc) die("Need a number for --start-number"); start_number = strtol(argv[i], NULL, 10); } else if (!prefixcmp(argv[i], "--cc=")) { ALLOC_GROW(extra_cc, extra_cc_nr + 1, extra_cc_alloc); extra_cc[extra_cc_nr++] = xstrdup(argv[i] + 5); } else if (!strcmp(argv[i], "-k") || !strcmp(argv[i], "--keep-subject")) { keep_subject = 1; rev.total = -1; } else if (!strcmp(argv[i], "--output-directory") || !strcmp(argv[i], "-o")) { i++; if (argc <= i) die("Which directory?"); if (output_directory) die("Two output directories?"); output_directory = argv[i]; } else if (!strcmp(argv[i], "--signoff") || !strcmp(argv[i], "-s")) { const char *committer; const char *endpos; committer = git_committer_info(IDENT_ERROR_ON_NO_NAME); endpos = strchr(committer, '>'); if (!endpos) die("bogos committer info %s\n", committer); add_signoff = xmemdupz(committer, endpos - committer + 1); } else if (!strcmp(argv[i], "--attach")) { rev.mime_boundary = git_version_string; rev.no_inline = 1; } else if (!prefixcmp(argv[i], "--attach=")) { rev.mime_boundary = argv[i] + 9; rev.no_inline = 1; } else if (!strcmp(argv[i], "--inline")) { rev.mime_boundary = git_version_string; rev.no_inline = 0; } else if (!prefixcmp(argv[i], "--inline=")) { rev.mime_boundary = argv[i] + 9; rev.no_inline = 0; } else if (!strcmp(argv[i], "--ignore-if-in-upstream")) ignore_if_in_upstream = 1; else if (!strcmp(argv[i], "--thread")) thread = 1; else if (!prefixcmp(argv[i], "--in-reply-to=")) in_reply_to = argv[i] + 14; else if (!strcmp(argv[i], "--in-reply-to")) { i++; if (i == argc) die("Need a Message-Id for --in-reply-to"); in_reply_to = argv[i]; } else if (!prefixcmp(argv[i], "--subject-prefix=")) { subject_prefix = 1; rev.subject_prefix = argv[i] + 17; } else if (!prefixcmp(argv[i], "--suffix=")) fmt_patch_suffix = argv[i] + 9; else if (!strcmp(argv[i], "--cover-letter")) cover_letter = 1; else if (!strcmp(argv[i], "--no-binary")) no_binary_diff = 1; else argv[j++] = argv[i]; } argc = j; strbuf_init(&buf, 0); for (i = 0; i < extra_hdr_nr; i++) { strbuf_addstr(&buf, extra_hdr[i]); strbuf_addch(&buf, '\n'); } if (extra_to_nr) strbuf_addstr(&buf, "To: "); for (i = 0; i < extra_to_nr; i++) { if (i) strbuf_addstr(&buf, " "); strbuf_addstr(&buf, extra_to[i]); if (i + 1 < extra_to_nr) strbuf_addch(&buf, ','); strbuf_addch(&buf, '\n'); } if (extra_cc_nr) strbuf_addstr(&buf, "Cc: "); for (i = 0; i < extra_cc_nr; i++) { if (i) strbuf_addstr(&buf, " "); strbuf_addstr(&buf, extra_cc[i]); if (i + 1 < extra_cc_nr) strbuf_addch(&buf, ','); strbuf_addch(&buf, '\n'); } rev.extra_headers = strbuf_detach(&buf, 0); if (start_number < 0) start_number = 1; if (numbered && keep_subject) die ("-n and -k are mutually exclusive."); if (keep_subject && subject_prefix) die ("--subject-prefix and -k are mutually exclusive."); if (numbered_files && use_stdout) die ("--numbered-files and --stdout are mutually exclusive."); argc = setup_revisions(argc, argv, &rev, "HEAD"); if (argc > 1) die ("unrecognized argument: %s", argv[1]); if (!rev.diffopt.output_format) rev.diffopt.output_format = DIFF_FORMAT_DIFFSTAT | DIFF_FORMAT_SUMMARY | DIFF_FORMAT_PATCH; if (!DIFF_OPT_TST(&rev.diffopt, TEXT) && !no_binary_diff) DIFF_OPT_SET(&rev.diffopt, BINARY); if (!output_directory && !use_stdout) output_directory = prefix; if (output_directory) { if (use_stdout) die("standard output, or directory, which one?"); if (mkdir(output_directory, 0777) < 0 && errno != EEXIST) die("Could not create directory %s", output_directory); } if (rev.pending.nr == 1) { if (rev.max_count < 0 && !rev.show_root_diff) { /* * This is traditional behaviour of "git format-patch * origin" that prepares what the origin side still * does not have. */ rev.pending.objects[0].item->flags |= UNINTERESTING; add_head_to_pending(&rev); } /* * Otherwise, it is "format-patch -22 HEAD", and/or * "format-patch --root HEAD". The user wants * get_revision() to do the usual traversal. */ } if (cover_letter) { /* remember the range */ int i; for (i = 0; i < rev.pending.nr; i++) { struct object *o = rev.pending.objects[i].item; if (!(o->flags & UNINTERESTING)) head = (struct commit *)o; } /* We can't generate a cover letter without any patches */ if (!head) return 0; } if (ignore_if_in_upstream) get_patch_ids(&rev, &ids, prefix); if (!use_stdout) realstdout = xfdopen(xdup(1), "w"); if (prepare_revision_walk(&rev)) die("revision walk setup failed"); rev.boundary = 1; while ((commit = get_revision(&rev)) != NULL) { if (commit->object.flags & BOUNDARY) { boundary_count++; origin = (boundary_count == 1) ? commit : NULL; continue; } /* ignore merges */ if (commit->parents && commit->parents->next) continue; if (ignore_if_in_upstream && has_commit_patch_id(commit, &ids)) continue; nr++; list = xrealloc(list, nr * sizeof(list[0])); list[nr - 1] = commit; } total = nr; if (!keep_subject && auto_number && total > 1) numbered = 1; if (numbered) rev.total = total + start_number - 1; if (in_reply_to) rev.ref_message_id = clean_message_id(in_reply_to); if (cover_letter) { if (thread) gen_message_id(&rev, "cover"); make_cover_letter(&rev, use_stdout, numbered, numbered_files, origin, nr, list, head); total++; start_number--; } rev.add_signoff = add_signoff; while (0 <= --nr) { int shown; commit = list[nr]; rev.nr = total - nr + (start_number - 1); /* Make the second and subsequent mails replies to the first */ if (thread) { /* Have we already had a message ID? */ if (rev.message_id) { /* * If we've got the ID to be a reply * to, discard the current ID; * otherwise, make everything a reply * to that. */ if (rev.ref_message_id) free(rev.message_id); else rev.ref_message_id = rev.message_id; } gen_message_id(&rev, sha1_to_hex(commit->object.sha1)); } if (!use_stdout && reopen_stdout(numbered_files ? NULL : get_oneline_for_filename(commit, keep_subject), rev.nr, rev.total)) die("Failed to create output files"); shown = log_tree_commit(&rev, commit); free(commit->buffer); commit->buffer = NULL; /* We put one extra blank line between formatted * patches and this flag is used by log-tree code * to see if it needs to emit a LF before showing * the log; when using one file per patch, we do * not want the extra blank line. */ if (!use_stdout) rev.shown_one = 0; if (shown) { if (rev.mime_boundary) printf("\n--%s%s--\n\n\n", mime_boundary_leader, rev.mime_boundary); else printf("-- \n%s\n\n", git_version_string); } if (!use_stdout) fclose(stdout); } free(list); if (ignore_if_in_upstream) free_patch_ids(&ids); return 0; }