// FIXME: ensure that the name is matched by the name regex, and by no other regex. static t3_config_t *load_map(int flags, t3_highlight_error_t *error) { t3_config_t *full_map = NULL, *map; char *xdg_map; if ((full_map = t3_config_new()) == NULL) { _t3_highlight_set_error_simple(error, T3_ERR_OUT_OF_MEMORY, flags); goto return_error; } if (!t3_config_add_plist(full_map, "lang", error == NULL ? NULL : &error->error)) goto return_error; xdg_map = t3_config_xdg_get_path(T3_CONFIG_XDG_DATA_HOME, "libt3highlight", strlen("lang.map")); if (xdg_map != NULL) { strcat(xdg_map, "/lang.map"); map = load_single_map(xdg_map, 0, NULL); free(xdg_map); if (map != NULL) merge(full_map, map); } if ((map = load_single_map(DATADIR "/" "lang.map", 0, error)) == NULL) goto return_error; merge(full_map, map); return full_map; return_error: t3_config_delete(full_map); return NULL; }
FILE *t3_config_xdg_open_read(t3_config_xdg_dirs_t xdg_dir, const char *program_dir, const char *file_name) { char *pathname; FILE *result; if (strchr(file_name, '/') != NULL) { errno = EINVAL; return NULL; } if ((pathname = t3_config_xdg_get_path(xdg_dir, program_dir, strlen(file_name))) == NULL) return NULL; strcat(pathname, "/"); strcat(pathname, file_name); result = fopen(pathname, "r"); free(pathname); return result; }
t3_config_write_file_t *t3_config_xdg_open_write(t3_config_xdg_dirs_t xdg_dir, const char *program_dir, const char *file_name) { t3_config_write_file_t *result; char *pathname; int fd; if (strchr(file_name, '/') != NULL) { errno = EINVAL; return NULL; } if ((pathname = t3_config_xdg_get_path(xdg_dir, program_dir, strlen(file_name) + 7)) == NULL) return NULL; if (!make_dirs(pathname)) { free(pathname); return NULL; } strcat(pathname, "/."); strcat(pathname, file_name); strcat(pathname, "XXXXXX"); if ((fd = mkstemp(pathname)) < 0) { free(pathname); return NULL; } if ((result = malloc(sizeof(t3_config_write_file_t))) == NULL || (result->file = fdopen(fd, "w")) == NULL) { close(fd); unlink(pathname); free(pathname); return NULL; } result->pathname = pathname; result->closed = t3_false; return result; }
t3_highlight_t *t3_highlight_load(const char *lang_file, int (*map_style)(void *, const char *), void *map_style_data, int flags, t3_highlight_error_t *error) { t3_config_opts_t opts; const char *path[] = { NULL, NULL, NULL }; char *xdg_path = NULL; t3_config_t *config = NULL; t3_config_error_t config_error; t3_highlight_t *result; FILE *file = NULL; /* Setup path. */ path[0] = xdg_path = t3_config_xdg_get_path(T3_CONFIG_XDG_DATA_HOME, "libt3highlight", 0); path[path[0] == NULL ? 0 : 1] = DATADIR; if (flags & T3_HIGHLIGHT_USE_PATH) { if ((file = t3_config_open_from_path(path, lang_file, 0)) == NULL) { _t3_highlight_set_error(error, T3_ERR_ERRNO, 0, lang_file, NULL, flags); goto return_error; } } else { if ((file = fopen(lang_file, "r")) == NULL) { _t3_highlight_set_error(error, T3_ERR_ERRNO, 0, lang_file, NULL, flags); goto return_error; } } opts.flags = T3_CONFIG_INCLUDE_DFLT | T3_CONFIG_ERROR_FILE_NAME; if (flags & T3_HIGHLIGHT_VERBOSE_ERROR) opts.flags |= T3_CONFIG_VERBOSE_ERROR; opts.include_callback.dflt.path = path; opts.include_callback.dflt.flags = 0; if ((config = t3_config_read_file(file, &config_error, &opts)) == NULL) { _t3_highlight_set_error(error, config_error.error, config_error.line_number, config_error.file_name == NULL ? lang_file : config_error.file_name, config_error.extra, flags); free(config_error.file_name); goto return_error; } free(xdg_path); xdg_path = NULL; fclose(file); file = NULL; if ((result = t3_highlight_new(config, map_style, map_style_data, flags, error)) == NULL) { if ((flags & T3_HIGHLIGHT_VERBOSE_ERROR) && error->file_name == NULL) error->file_name = _t3_highlight_strdup(lang_file); goto return_error; } if ((result->lang_file = _t3_highlight_strdup(lang_file)) == NULL) { _t3_highlight_set_error_simple(error, T3_ERR_OUT_OF_MEMORY, flags); goto return_error; } t3_config_delete(config); return result; return_error: t3_config_delete(config); free(xdg_path); if (file != NULL) { int save_errno = errno; fclose(file); errno = save_errno; } return NULL; }