struct encoding * get_path_encoding(const char *path, struct encoding *default_encoding) { const char *check_attr_argv[] = { "git", "check-attr", "encoding", "--", path, NULL }; char buf[SIZEOF_STR]; char *encoding; /* <path>: encoding: <encoding> */ if (!*path || !io_run_buf(check_attr_argv, buf, sizeof(buf)) || !(encoding = strstr(buf, ENCODING_SEP))) return default_encoding; encoding += STRING_SIZE(ENCODING_SEP); if (!strcmp(encoding, ENCODING_UTF8) || !strcmp(encoding, "unspecified") || !strcmp(encoding, "set")) { const char *file_argv[] = { "file", "-I", "--", path, NULL }; if (!*path || !io_run_buf(file_argv, buf, sizeof(buf)) || !(encoding = strstr(buf, CHARSET_SEP))) return default_encoding; encoding += STRING_SIZE(CHARSET_SEP); } return encoding_open(encoding); }
void parse_author_line(char *ident, const struct ident **author, struct time *time) { char *nameend = strchr(ident, '<'); char *emailend = strchr(ident, '>'); const char *name, *email = ""; if (nameend && emailend) *nameend = *emailend = 0; name = chomp_string(ident); if (nameend) email = chomp_string(nameend + 1); if (!*name) name = *email ? email : unknown_ident.name; if (!*email) email = *name ? name : unknown_ident.email; *author = get_author(name, email); /* Parse epoch and timezone */ if (time && emailend && emailend[1] == ' ') { char *secs = emailend + 2; char *zone = strchr(secs, ' '); parse_timesec(time, secs); if (zone && strlen(zone) == STRING_SIZE(" +0700")) parse_timezone(time, zone + 1); } }
bool draw_mode(struct view *view, mode_t mode) { const char *str = mkmode(mode); return draw_field(view, LINE_MODE, str, STRING_SIZE("-rw-r--r--"), ALIGN_LEFT, FALSE); }
YogVal YogRegexp_new(YogEnv* env, YogVal pattern, BOOL ignore_case) { YogHandle* h = VAL2HDL(env, pattern); YogVal regexp = ALLOC_OBJ(env, YogBasicObj_keep_children, YogRegexp_finalize, YogRegexp); YogBasicObj_init(env, regexp, TYPE_REGEXP, 0, env->vm->cRegexp); size_t size = sizeof(CorgiRegexp); CorgiRegexp* corgi_regexp = (CorgiRegexp*)YogGC_malloc(env, size); corgi_init_regexp(corgi_regexp); PTR_AS(YogRegexp, regexp)->corgi_regexp = corgi_regexp; CorgiChar* begin = STRING_CHARS(HDL2VAL(h)); CorgiOptions opts = 0; if (ignore_case) { opts |= CORGI_OPT_IGNORE_CASE; } CorgiRegexp* reg = PTR_AS(YogRegexp, regexp)->corgi_regexp; CorgiChar* end = begin + STRING_SIZE(HDL2VAL(h)); CorgiStatus status = corgi_compile(reg, begin, end, opts); if (status != CORGI_OK) { const char* msg = corgi_strerror(status); YogError_raise_ValueError(env, "corgi error: %s", msg); /* NOTREACHED */ } return regexp; }
bool pager_common_read(struct view *view, const char *data, enum line_type type, struct line **line_ptr) { struct line *line; if (!data) return true; if (opt_wrap_lines) { line = pager_wrap_line(view, data, type); } else { line = add_line_text(view, data, type); } if (!line) return false; if (line_ptr) *line_ptr = line; if (line->type == LINE_COMMIT && view_has_flags(view, VIEW_ADD_PAGER_REFS)) add_pager_refs(view, data + STRING_SIZE("commit ")); return true; }
void init_colors(void) { struct line_rule query = { "default", STRING_SIZE("default") }; struct line_rule *rule = find_line_rule(&query); int default_bg = rule->info.bg; int default_fg = rule->info.fg; enum line_type type; start_color(); if (assume_default_colors(default_fg, default_bg) == ERR) { default_bg = COLOR_BLACK; default_fg = COLOR_WHITE; } for (type = 0; type < line_rules; type++) { struct line_rule *rule = &line_rule[type]; struct line_info *info; for (info = &rule->info; info; info = info->next) { init_line_info_color_pair(info, type, default_bg, default_fg); } } }
bool parse_chunk_header(struct chunk_header *header, const char *line) { memset(header, 0, sizeof(*header)); if (!prefixcmp(line, "@@ -")) line += STRING_SIZE("@@ -") - 1; else if (!prefixcmp(line, "@@@ -") && (line = strchr(line + STRING_SIZE("@@@ -"), '-'))) /* Stay at that '-'. */ ; else return FALSE; return parse_ulong(&line, &header->old.position, '-', FALSE) && parse_ulong(&line, &header->old.lines, ',', TRUE) && parse_ulong(&line, &header->new.position, '+', FALSE) && parse_ulong(&line, &header->new.lines, ',', FALSE); }
static bool branch_read(struct view *view, char *line) { struct branch_state *state = view->private; const char *title = NULL; const struct ident *author = NULL; struct time time = {}; size_t i; if (!line) return TRUE; switch (get_line_type(line)) { case LINE_COMMIT: string_copy_rev_from_commit_line(state->id, line); return TRUE; case LINE_AUTHOR: parse_author_line(line + STRING_SIZE("author "), &author, &time); break; default: title = line + STRING_SIZE("title "); } for (i = 0; i < view->lines; i++) { struct branch *branch = view->line[i].data; if (strcmp(branch->ref->id, state->id)) continue; if (author) { branch->author = author; branch->time = time; } if (title) string_expand(branch->title, sizeof(branch->title), title, 1); view->line[i].dirty = TRUE; } return TRUE; }
static int reload_refs(bool force) { const char *head_argv[] = { "git", "symbolic-ref", "HEAD", NULL }; const char *ls_remote_argv[SIZEOF_ARG] = { "git", "ls-remote", repo.git_dir, NULL }; static bool init = FALSE; struct ref_opt opt = { repo.remote, repo.head, WATCH_NONE }; struct repo_info old_repo = repo; size_t i; if (!init) { if (!argv_from_env(ls_remote_argv, "TIG_LS_REMOTE")) return ERR; init = TRUE; } if (!*repo.git_dir) return OK; if ((force || !*repo.head) && io_run_buf(head_argv, repo.head, sizeof(repo.head)) && !prefixcmp(repo.head, "refs/heads/")) { char *offset = repo.head + STRING_SIZE("refs/heads/"); memmove(repo.head, offset, strlen(offset) + 1); } if (strcmp(old_repo.head, repo.head)) opt.changed |= WATCH_HEAD; refs_head = NULL; for (i = 0; i < refs_size; i++) refs[i]->valid = 0; done_ref_lists(); if (io_run_load(ls_remote_argv, "\t", read_ref, &opt) == ERR) return ERR; for (i = 0; i < refs_size; i++) if (!refs[i]->valid) { refs[i]->id[0] = 0; opt.changed |= WATCH_REFS; } if (opt.changed) watch_apply(NULL, opt.changed); qsort(refs, refs_size, sizeof(*refs), compare_refs); return OK; }
static void set_package_as_parent_attr(YogEnv* env, YogVM* vm, YogHandle* parent, YogHandle* name, uint_t begin, int_t end, YogHandle* pkg) { if (parent == NULL) { return; } uint_t len = (end < 0 ? STRING_SIZE(HDL2VAL(name)) : end) - begin; YogVal s = YogString_slice(env, name, begin, len); ID id = YogVM_intern2(env, vm, s); YogObj_set_attr_id(env, HDL2VAL(parent), id, HDL2VAL(pkg)); }
static uint_t compute_bytes(YogEnv* env, YogHandle* self, YogHandle* s) { uint_t n = 0; uint_t size = STRING_SIZE(HDL2VAL(s)); uint_t i; for (i = 0; i < size; i++) { YogChar c = STRING_CHARS(HDL2VAL(s))[i]; n += HDL_AS(YogEncoding, self)->get_yog_char_bytes(env, self, c); } return n; }
uint16_t l9p_sizeof_stat(struct l9p_stat *stat, enum l9p_version version) { uint16_t size = L9P_WORD /* size */ + L9P_WORD /* type */ + L9P_DWORD /* dev */ + QID_SIZE /* qid */ + 3 * L9P_DWORD /* mode, atime, mtime */ + L9P_QWORD /* length */ + STRING_SIZE(stat->name) + STRING_SIZE(stat->uid) + STRING_SIZE(stat->gid) + STRING_SIZE(stat->muid); if (version == L9P_2000U) { size += STRING_SIZE(stat->extension) + 3 * L9P_DWORD; } return (size); }
const char * mkdate(const struct time *time, enum date date) { static char buf[STRING_SIZE("2006-04-29 14:21") + 1]; static const struct enum_map_entry reldate[] = { { "second", 1, 60 * 2 }, { "minute", 60, 60 * 60 * 2 }, { "hour", 60 * 60, 60 * 60 * 24 * 2 }, { "day", 60 * 60 * 24, 60 * 60 * 24 * 7 * 2 }, { "week", 60 * 60 * 24 * 7, 60 * 60 * 24 * 7 * 5 }, { "month", 60 * 60 * 24 * 30, 60 * 60 * 24 * 365 }, { "year", 60 * 60 * 24 * 365, 0 }, }; struct tm tm; const char *format; if (!date || !time || !time->sec) return ""; if (date == DATE_RELATIVE) { struct timeval now; time_t date = time->sec + time->tz; time_t seconds; int i; gettimeofday(&now, NULL); seconds = now.tv_sec < date ? date - now.tv_sec : now.tv_sec - date; for (i = 0; i < ARRAY_SIZE(reldate); i++) { if (seconds >= reldate[i].value && reldate[i].value) continue; seconds /= reldate[i].namelen; if (!string_format(buf, "%ld %s%s %s", seconds, reldate[i].name, seconds > 1 ? "s" : "", now.tv_sec >= date ? "ago" : "ahead")) break; return buf; } } if (date == DATE_LOCAL) { time_t date = time->sec + time->tz; localtime_r(&date, &tm); } else { gmtime_r(&time->sec, &tm); } format = date == DATE_SHORT ? "%Y-%m-%d" : "%Y-%m-%d %H:%M"; return strftime(buf, sizeof(buf), format, &tm) ? buf : NULL; }
YogVal YogEncoding_normalize_name(YogEnv* env, YogVal name) { YogVal s = YogString_clone(env, name); uint_t size = STRING_SIZE(s); uint_t i; for (i = 0; i < size; i++) { YogChar c = STRING_CHARS(s)[i]; STRING_CHARS(s)[i] = c == '_' ? '-' : tolower(c); } return s; }
static YogHandle* package_name2path_head(YogEnv* env, YogVal name) { YogVal s = YogString_clone(env, name); uint_t size = STRING_SIZE(s); uint_t i; for (i = 0; i < size; i++) { if (STRING_CHARS(s)[i] == '.') { STRING_CHARS(s)[i] = PATH_SEPARATOR; } } return VAL2HDL(env, s); }
void exec_process(char *cmd, char **args, pid_t pgid, int fin, int fout, char fg) { int err; /* set the pgid */ if( setpgid(0, pgid) == -1 ) { perror("setpgid"); _exit(EXIT_FAILURE); } //printf("%s new pgid: %d\n", args[0],getpgid(0)); if( fg && tcsetpgrp(STDIN_FILENO, getpgid(0)) == -1 ) { perror("tcsetpgrp"); _exit(EXIT_FAILURE); } /* set stdin, stdout */ if(fin != STDIN_FILENO) { dup2(fin, STDIN_FILENO); close(fin); } if(fout != STDOUT_FILENO) { dup2(fout, STDOUT_FILENO); close(fout); } /* reset signal handlers to default */ signal(SIGTTOU, SIG_DFL); signal(SIGTTIN, SIG_DFL); signal(SIGTERM, SIG_DFL); signal(SIGTSTP, SIG_DFL); signal(SIGINT, SIG_DFL); signal(SIGCHLD, SIG_DFL); err = execvp(cmd, args); if(err == -1) { err = errno; if(err == ENOENT || err == ENOTDIR) // no file or dir for cmd write(STDOUT_FILENO, UNCMD_MSG, STRING_SIZE(UNCMD_MSG)); else perror("execvp"); free_list(job_list); free_list(msg_q); _exit(EXIT_FAILURE); } }
static YogHandle* make_initializer_name(YogEnv* env, YogHandle* pkg_name) { YogHandle* name = VAL2HDL(env, YogString_from_string(env, "YogInit_")); int_t pos = YogString_strrchr(env, HDL2VAL(pkg_name), '.'); if (pos < 0) { YogString_append(env, HDL2VAL(name), HDL2VAL(pkg_name)); return name; } uint_t len = STRING_SIZE(HDL2VAL(pkg_name)); YogVal s = YogString_slice(env, pkg_name, pos, len - pos); YogString_append(env, HDL2VAL(name), s); return name; }
static int string_copy(vm_thread_t *thread, obj_t *osrc) { #define STRING_SIZE(o) ((string_t*)PTR(o))->size SAFE_ASSERT(IS_STRING(*osrc)); int size = STRING_SIZE(*osrc); void *mem = heap_alloc(&thread->heap, size+sizeof(string_t), t_string); string_t *str = mem; str->str = mem+sizeof(string_t); str->size = size; str->allocated = 1; memcpy(str->str, CSTRING(*osrc), size); RETURN_OBJ(MAKE_HEAP_PTR(str)); }
YogVal YogEncoding_conv_to_yog(YogEnv* env, YogHandle* self, const char* begin, const char* end) { uint_t chars_num = count_chars(env, self, begin, end); YogVal s = YogString_of_size(env, chars_num); uint_t i; const char* pc = begin; for (i = 0; i < chars_num; i++) { YogChar c = HDL_AS(YogEncoding, self)->conv_char_to_yog(env, self, pc); STRING_CHARS(s)[i] = c; pc += HDL_AS(YogEncoding, self)->get_char_bytes(env, self, pc); } STRING_SIZE(s) = chars_num; return s; }
static void set_remote_branch(const char *name, const char *value, size_t valuelen) { if (!strcmp(name, ".remote")) { string_ncopy(repo.remote, value, valuelen); } else if (*repo.remote && !strcmp(name, ".merge")) { size_t from = strlen(repo.remote); if (!prefixcmp(value, "refs/heads/")) value += STRING_SIZE("refs/heads/"); if (!string_format_from(repo.remote, &from, "/%s", value)) repo.remote[0] = 0; } }
static YogVal group_num(YogEnv* env, YogHandle* self, int_t group) { int_t begin; int_t end; get_group_range(env, HDL2VAL(self), group, &begin, &end); if (begin < 0) { return YNIL; } uint_t size = end - begin; YogVal retval = YogString_of_size(env, size); YogVal s = HDL_AS(YogMatch, self)->str; uint_t bytes_num = sizeof(YogChar) * size; memcpy(STRING_CHARS(retval), STRING_CHARS(s) + begin, bytes_num); STRING_SIZE(retval) = size; return retval; }
static bool format_expand_arg(struct format_context *format, const char *name, const char *end) { struct format_var *vars = format->vars; int i; if (!prefixcmp(name, "%(prompt")) { const char *prompt = "Command argument: "; char msgbuf[SIZEOF_STR]; const char *value; const char *msgstart = name + STRING_SIZE("%(prompt"); int msglen = end - msgstart - 1; if (end && msglen > 0 && string_format(msgbuf, "%.*s", msglen, msgstart)) { const char *msg = msgbuf; while (isspace(*msg)) msg++; if (*msg) prompt = msg; } value = read_prompt(prompt); if (value == NULL) return FALSE; return string_format_from(format->buf, &format->bufpos, "%s", value); } for (i = 0; i < format->vars_size; i++) { const char *value; if (strncmp(name, vars[i].name, vars[i].namelen)) continue; if (vars[i].value == argv_env.file && !format->file_filter) return TRUE; value = *vars[i].value ? vars[i].value : vars[i].value_if_empty; if (!*value) return TRUE; return string_format_from(format->buf, &format->bufpos, "%s", value); } return FALSE; }
static int reload_refs(const char *git_dir, const char *remote_name, char *head, size_t headlen) { const char *head_argv[] = { "git", "symbolic-ref", "HEAD", NULL }; const char *ls_remote_argv[SIZEOF_ARG] = { "git", "ls-remote", git_dir, NULL }; static bool init = FALSE; struct ref_opt opt = { remote_name, head }; size_t i; if (!init) { if (!argv_from_env(ls_remote_argv, "TIG_LS_REMOTE")) return ERR; init = TRUE; } if (!*git_dir) return OK; if (!*head && io_run_buf(head_argv, head, headlen) && !prefixcmp(head, "refs/heads/")) { char *offset = head + STRING_SIZE("refs/heads/"); memmove(head, offset, strlen(offset) + 1); } refs_head = NULL; for (i = 0; i < refs_size; i++) refs[i]->valid = 0; done_ref_lists(); if (io_run_load(ls_remote_argv, "\t", read_ref, &opt) == ERR) return ERR; for (i = 0; i < refs_size; i++) if (!refs[i]->valid) refs[i]->id[0] = 0; qsort(refs, refs_size, sizeof(*refs), compare_refs); return OK; }
static enum status_code read_repo_info(char *name, size_t namelen, char *value, size_t valuelen, void *data) { struct repo_info_state *state = data; const char *arg = *state->argv ? *state->argv++ : ""; if (!strcmp(arg, REPO_INFO_GIT_DIR)) { string_ncopy(repo.git_dir, name, namelen); } else if (!strcmp(arg, REPO_INFO_WORK_TREE)) { /* This can be 3 different values depending on the * version of git being used. If git-rev-parse does not * understand --is-inside-work-tree it will simply echo * the option else either "true" or "false" is printed. * Default to true for the unknown case. */ repo.is_inside_work_tree = strcmp(name, "false") ? true : false; } else if (!strcmp(arg, REPO_INFO_SHOW_CDUP)) { string_ncopy(repo.cdup, name, namelen); } else if (!strcmp(arg, REPO_INFO_SHOW_PREFIX)) { /* Some versions of Git does not emit anything for --show-prefix * when the user is in the repository root directory. Try to detect * this special case by looking at the emitted value. If it looks * like a commit ID and there's no cdup path assume that no value * was emitted. */ if (!*repo.cdup && namelen == 40 && iscommit(name)) return read_repo_info(name, namelen, value, valuelen, data); string_ncopy(repo.prefix, name, namelen); } else if (!strcmp(arg, REPO_INFO_RESOLVED_HEAD)) { string_ncopy(repo.head_id, name, namelen); } else if (!strcmp(arg, REPO_INFO_SYMBOLIC_HEAD)) { if (!prefixcmp(name, "refs/heads/")) { const char *head = name + STRING_SIZE("refs/heads/"); string_ncopy(repo.head, head, strlen(head) + 1); add_ref(repo.head_id, name, repo.remote, repo.head); } state->argv++; } return SUCCESS; }
YogVal YogEncoding_conv_from_yog(YogEnv* env, YogHandle* self, YogHandle* s) { uint_t bytes_num = compute_bytes(env, self, s); YogVal bin = YogBinary_of_size(env, bytes_num + 1); char* begin = BINARY_CSTR(bin); char* pc = begin; uint_t size = STRING_SIZE(HDL2VAL(s)); uint_t i; for (i = 0; i < size; i++) { YogConvCharFromYog conv = HDL_AS(YogEncoding, self)->conv_char_from_yog; pc += conv(env, self, STRING_CHARS(HDL2VAL(s))[i], pc); } *pc = '\0'; BINARY_SIZE(bin) = pc - begin + 1; return bin; }
static int_t group_name2id(YogEnv* env, YogVal self, YogVal group) { YOG_ASSERT(env, IS_PTR(group), "invalid group (0x%x)", group); YOG_ASSERT(env, BASIC_OBJ_TYPE(group) == TYPE_STRING, "invalid group type (0x%x)", BASIC_OBJ_TYPE(group)); YogVal regexp = PTR_AS(YogMatch, self)->regexp; CorgiRegexp* corgi_regexp = PTR_AS(YogRegexp, regexp)->corgi_regexp; YogChar* begin = STRING_CHARS(group); YogChar* end = begin + STRING_SIZE(group); uint_t id; CorgiStatus status = corgi_group_name2id(corgi_regexp, begin, end, &id); if (status != CORGI_OK) { YogError_raise_IndexError(env, "No such group: %S", group); } return id + 1; }
struct Hjava_lang_Class* java_lang_VMClass_loadArrayClass(struct Hjava_lang_String* str, struct Hjava_lang_ClassLoader* loader) { errorInfo einfo; Hjava_lang_Class* clazz; Utf8Const *utf8buf; const char *buf; int jlen; jchar *js; /* * NB: internally, we store class names as path names (with slashes * instead of dots. However, we must also prevent calls to * "java/lang/Object" or "[[Ljava/lang/Object;" from succeeding. * Since class names cannot have slashes, we reject all attempts * to look up names that do. Awkward. Inefficient. */ js = STRING_DATA(str); jlen = STRING_SIZE(str); while (--jlen > 0) { if (*js++ == '/') { postExceptionMessage(&einfo, JAVA_LANG(ClassNotFoundException), "Cannot have slashes - use dots instead."); throwError(&einfo); } } /* Convert string to utf8, converting '.' to '/' */ utf8buf = checkPtr(stringJava2Utf8ConstReplace(str, '.', '/')); buf = utf8buf->data; clazz = loadArray(utf8buf, loader, &einfo); /* if an error occurred, throw an exception */ if (clazz == 0) { utf8ConstRelease(utf8buf); throwError(&einfo); } utf8ConstRelease(utf8buf); return clazz; }
static int read_repo_config_option(char *name, size_t namelen, char *value, size_t valuelen, void *data) { if (!strcmp(name, "i18n.commitencoding")) set_encoding(&default_encoding, value, FALSE); else if (!strcmp(name, "gui.encoding")) set_encoding(&default_encoding, value, TRUE); else if (!strcmp(name, "core.editor")) string_ncopy(opt_editor, value, valuelen); else if (!strcmp(name, "core.worktree")) set_work_tree(value); else if (!strcmp(name, "core.abbrev")) parse_int(&opt_id_width, value, 0, SIZEOF_REV - 1); else if (!prefixcmp(name, "tig.color.")) set_repo_config_option(name + 10, value, option_color_command); else if (!prefixcmp(name, "tig.bind.")) set_repo_config_option(name + 9, value, option_bind_command); else if (!prefixcmp(name, "tig.")) set_repo_config_option(name + 4, value, option_set_command); else if (!prefixcmp(name, "color.")) set_git_color_option(name + STRING_SIZE("color."), value); else if (*repo.head && !prefixcmp(name, "branch.") && !strncmp(name + 7, repo.head, strlen(repo.head))) set_remote_branch(name + 7 + strlen(repo.head), value, valuelen); else if (!strcmp(name, "diff.context")) { if (!find_option_info_by_value(&opt_diff_context)->seen) opt_diff_context = -atoi(value); } return OK; }
static bool branch_open_visitor(void *data, const struct ref *ref) { struct view *view = data; struct branch_state *state = view->private; struct branch *branch; bool is_all = ref == &branch_all; size_t ref_length; if (ref->tag || ref->ltag) return TRUE; if (!add_line_alloc(view, &branch, LINE_DEFAULT, 0, is_all)) return FALSE; ref_length = is_all ? STRING_SIZE(BRANCH_ALL_NAME) : strlen(ref->name); if (ref_length > state->max_ref_length) state->max_ref_length = ref_length; branch->ref = ref; return TRUE; }
const char * mkdate(const struct time *time, enum date date) { static char buf[STRING_SIZE("2006-04-29 14:21") + 1]; struct tm tm; const char *format; if (!date || !time || !time->sec) return ""; if (date == DATE_RELATIVE) return get_relative_date(time, buf, sizeof(buf)); if (date == DATE_LOCAL) { time_t date = time->sec + time->tz; localtime_r(&date, &tm); } else { gmtime_r(&time->sec, &tm); } format = date == DATE_SHORT ? "%Y-%m-%d" : "%Y-%m-%d %H:%M"; return strftime(buf, sizeof(buf), format, &tm) ? buf : NULL; }