static void print_spaces(struct strbuf *buf, int count) { static const char s[] = " "; while (count >= sizeof(s)) { strbuf_write(buf, s, sizeof(s) - 1); count -= sizeof(s) - 1; } strbuf_write(buf, s, count); }
static int pp_collect_finished(struct parallel_processes *pp) { int i, code; int n = pp->max_processes; int result = 0; while (pp->nr_processes > 0) { for (i = 0; i < pp->max_processes; i++) if (pp->children[i].state == GIT_CP_WAIT_CLEANUP) break; if (i == pp->max_processes) break; code = finish_command(&pp->children[i].process); code = pp->task_finished(code, &pp->children[i].err, pp->data, &pp->children[i].data); if (code) result = code; if (code < 0) break; pp->nr_processes--; pp->children[i].state = GIT_CP_FREE; pp->pfd[i].fd = -1; child_process_init(&pp->children[i].process); if (i != pp->output_owner) { strbuf_addbuf(&pp->buffered_output, &pp->children[i].err); strbuf_reset(&pp->children[i].err); } else { strbuf_write(&pp->children[i].err, stderr); strbuf_reset(&pp->children[i].err); /* Output all other finished child processes */ strbuf_write(&pp->buffered_output, stderr); strbuf_reset(&pp->buffered_output); /* * Pick next process to output live. * NEEDSWORK: * For now we pick it randomly by doing a round * robin. Later we may want to pick the one with * the most output or the longest or shortest * running process time. */ for (i = 0; i < n; i++) if (pp->children[(pp->output_owner + i) % n].state == GIT_CP_WORKING) break; pp->output_owner = (pp->output_owner + i) % n; } } return result; }
static void pp_output(struct parallel_processes *pp) { int i = pp->output_owner; if (pp->children[i].state == GIT_CP_WORKING && pp->children[i].err.len) { strbuf_write(&pp->children[i].err, stderr); strbuf_reset(&pp->children[i].err); } }
static HRESULT do_preprocess(const Registrar *This, LPCOLESTR data, strbuf *buf) { LPCOLESTR iter, iter2 = data; rep_list *rep_iter; static const WCHAR wstr[] = {'%',0}; iter = strchrW(data, '%'); while(iter) { strbuf_write(iter2, buf, iter-iter2); iter2 = ++iter; if(!*iter2) return DISP_E_EXCEPTION; iter = strchrW(iter2, '%'); if(!iter) return DISP_E_EXCEPTION; if(iter == iter2) { strbuf_write(wstr, buf, 1); }else { for(rep_iter = This->rep; rep_iter; rep_iter = rep_iter->next) { if(rep_iter->key_len == iter-iter2 && !memicmpW(iter2, rep_iter->key, rep_iter->key_len)) break; } if(!rep_iter) { WARN("Could not find replacement: %s\n", debugstr_wn(iter2, iter-iter2)); return DISP_E_EXCEPTION; } strbuf_write(rep_iter->item, buf, -1); } iter2 = ++iter; iter = strchrW(iter, '%'); } strbuf_write(iter2, buf, -1); TRACE("%s\n", debugstr_w(buf->str)); return S_OK; }
static HRESULT get_word(LPCOLESTR *str, strbuf *buf) { LPCOLESTR iter, iter2 = *str; buf->len = 0; buf->str[0] = '\0'; while(isspaceW(*iter2)) iter2++; iter = iter2; if(!*iter) { *str = iter; return S_OK; } if(*iter == '}' || *iter == '=') { strbuf_write(iter++, buf, 1); }else if(*iter == '\'') { iter2 = ++iter; iter = strchrW(iter, '\''); if(!iter) { WARN("Unexpected end of script\n"); *str = iter; return DISP_E_EXCEPTION; } strbuf_write(iter2, buf, iter-iter2); iter++; }else { while(*iter && !isspaceW(*iter)) iter++; strbuf_write(iter2, buf, iter-iter2); } while(isspaceW(*iter)) iter++; *str = iter; return S_OK; }
static void strbuf_add_indented_text(struct strbuf *buf, const char *text, int indent, int indent2) { if (indent < 0) indent = 0; while (*text) { const char *eol = strchrnul(text, '\n'); if (*eol == '\n') eol++; print_spaces(buf, indent); strbuf_write(buf, text, eol - text); text = eol; indent = indent2; } }
static void pp_cleanup(struct parallel_processes *pp) { int i; trace_printf("run_processes_parallel: done"); for (i = 0; i < pp->max_processes; i++) { strbuf_release(&pp->children[i].err); child_process_clear(&pp->children[i].process); } free(pp->children); free(pp->pfd); /* * When get_next_task added messages to the buffer in its last * iteration, the buffered output is non empty. */ strbuf_write(&pp->buffered_output, stderr); strbuf_release(&pp->buffered_output); sigchain_pop_common(); }
static HRESULT do_process_key(LPCOLESTR *pstr, HKEY parent_key, strbuf *buf, BOOL do_register) { LPCOLESTR iter = *pstr; 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)); lres = 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': { WCHAR *end; DWORD dw; if(*iter == '0' && iter[1] == 'x') { iter += 2; dw = strtolW(iter, &end, 16); }else { dw = strtolW(iter, &end, 10); } iter = end; 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; } 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; }
size_t rbm_fwrite(const void *ptr, size_t size, size_t nitems, FILE *stream) { return strbuf_write((STRBUF *) stream, ptr, nitems * size); }
/* * Wrap the text, if necessary. The variable indent is the indent for the * first line, indent2 is the indent for all other lines. * If indent is negative, assume that already -indent columns have been * consumed (and no extra indent is necessary for the first line). */ int strbuf_add_wrapped_text(struct strbuf *buf, const char *text, int indent, int indent2, int width) { int w = indent, assume_utf8 = is_utf8(text); const char *bol = text, *space = NULL; if (width <= 0) { strbuf_add_indented_text(buf, text, indent, indent2); return 1; } if (indent < 0) { w = -indent; space = text; } for (;;) { char c; size_t skip; while ((skip = display_mode_esc_sequence_len(text))) text += skip; c = *text; if (!c || isspace(c)) { if (w < width || !space) { const char *start = bol; if (!c && text == start) return w; if (space) start = space; else print_spaces(buf, indent); strbuf_write(buf, start, text - start); if (!c) return w; space = text; if (c == '\t') w |= 0x07; else if (c == '\n') { space++; if (*space == '\n') { strbuf_write(buf, "\n", 1); goto new_line; } else if (!isalnum(*space)) goto new_line; else strbuf_write(buf, " ", 1); } w++; text++; } else { new_line: strbuf_write(buf, "\n", 1); text = bol = space + isspace(*space); space = NULL; w = indent = indent2; } continue; } if (assume_utf8) w += utf8_width(&text, NULL); else { w++; text++; } } }