int main(int argc, const char* argv[]) { char* full_filename = NULL; int err_num; int i; int name_value_count; editorconfig_handle eh; char** file_paths = NULL; int path_count; /* the count of path input*/ /* Will be a EditorConfig file name if -f is specified on command line */ const char* conf_filename = NULL; int version_major = -1; int version_minor = -1; int version_subminor = -1; /* File names read from stdin are put in this buffer temporarily */ char file_line_buffer[FILENAME_MAX + 1]; _Bool f_flag = 0; _Bool b_flag = 0; if (argc <= 1) { version(stderr); usage(stderr, argv[0]); exit(1); } for (i = 1; i < argc; ++i) { if (b_flag) { char* pos; int ver; int ver_pos = 0; char* argvi = strdup(argv[i]); b_flag = 0; /* convert the argument -b into a version number */ pos = strtok(argvi, "."); while (pos != NULL) { ver = atoi(pos); switch(ver_pos) { case 0: version_major = ver; break; case 1: version_minor = ver; break; case 2: version_subminor = ver; break; default: fprintf(stderr, "Invalid version number: %s\n", argv[i]); exit(1); } ++ ver_pos; pos = strtok(NULL, "."); } free(argvi); } else if (f_flag) { f_flag = 0; conf_filename = argv[i]; } else if (strcmp(argv[i], "--version") == 0 || strcmp(argv[i], "-v") == 0) { version(stdout); exit(0); } else if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) { version(stdout); usage(stdout, argv[0]); exit(0); } else if (strcmp(argv[i], "-b") == 0) b_flag = 1; else if (strcmp(argv[i], "-f") == 0) f_flag = 1; else if (i < argc) { /* If there are other args left, regard them as file names */ path_count = argc - i; file_paths = (char**) malloc(path_count * sizeof(char*)); for (; i < argc; ++i) { file_paths[path_count + i - argc] = strdup(argv[i]); if (file_paths[path_count - argc + i] == NULL) { fprintf(stderr, "Error: Unable to obtain the full path.\n"); exit(1); } } } else { usage(stderr, argv[0]); exit(1); } } if (!file_paths) { /* No filename is set */ usage(stderr, argv[0]); exit(1); } /* Go through all the files in the argument list */ for (i = 0; i < path_count; ++i) { int j; full_filename = file_paths[i]; /* Print the file path first, with [], if more than one file is * specified */ if (path_count > 1 && strcmp(full_filename, "-")) printf("[%s]\n", full_filename); if (!strcmp(full_filename, "-")) { int len; /* Read a line from stdin. If EOF encountered, continue */ if (!fgets(file_line_buffer, FILENAME_MAX + 1, stdin)) { if (!feof(stdin)) perror("Failed to read stdin"); free(full_filename); continue; } -- i; /* trim the trailing space characters */ len = strlen(file_line_buffer) - 1; while (len >= 0 && isspace(file_line_buffer[len])) -- len; if (len < 0) /* we meet a blank line */ continue; file_line_buffer[len + 1] = '\0'; full_filename = file_line_buffer; while (isspace(*full_filename)) ++ full_filename; full_filename = strdup(full_filename); printf("[%s]\n", full_filename); } /* Initialize the EditorConfig handle */ eh = editorconfig_handle_init(); /* Set conf file name */ if (conf_filename) editorconfig_handle_set_conf_file_name(eh, conf_filename); /* Set the version to be compatible with */ editorconfig_handle_set_version(eh, version_major, version_minor, version_subminor); /* parsing the editorconfig files */ err_num = editorconfig_parse(full_filename, eh); free(full_filename); if (err_num != 0) { /* print error message */ fputs(editorconfig_get_error_msg(err_num), stderr); if (err_num > 0) fprintf(stderr, "\"%s\"", editorconfig_handle_get_err_file(eh)); fprintf(stderr, "\n"); exit(1); } /* print the result */ name_value_count = editorconfig_handle_get_name_value_count(eh); for (j = 0; j < name_value_count; ++j) { const char* name; const char* value; editorconfig_handle_get_name_value(eh, j, &name, &value); printf("%s=%s\n", name, value); } if (editorconfig_handle_destroy(eh) != 0) { fprintf(stderr, "Failed to destroy editorconfig_handle.\n"); exit(1); } } free(file_paths); exit(0); }
GHashTable * editorconfig_glib_read (GFile *file, GCancellable *cancellable, GError **error) { editorconfig_handle handle = { 0 }; GHashTable *ret = NULL; gchar *filename = NULL; gint code; gint count; guint i; filename = g_file_get_path (file); if (!filename) { /* * This sucks, but we need to basically rewrite editorconfig library * to support this. Not out of the question, but it is for today. */ g_set_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, "only local files are currently supported"); return NULL; } handle = editorconfig_handle_init (); code = editorconfig_parse (filename, handle); switch (code) { case 0: break; case EDITORCONFIG_PARSE_NOT_FULL_PATH: case EDITORCONFIG_PARSE_MEMORY_ERROR: case EDITORCONFIG_PARSE_VERSION_TOO_NEW: default: g_set_error (error, G_IO_ERROR, G_IO_ERROR_FAILED, "Failed to parse editorconfig."); goto cleanup; } count = editorconfig_handle_get_name_value_count (handle); ret = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, _g_value_free); for (i = 0; i < count; i++) { GValue *value; const gchar *key = NULL; const gchar *valuestr = NULL; value = g_new0 (GValue, 1); editorconfig_handle_get_name_value (handle, i, &key, &valuestr); if ((g_strcmp0 (key, "tab_width") == 0) || (g_strcmp0 (key, "max_line_length") == 0) || (g_strcmp0 (key, "indent_size") == 0)) { g_value_init (value, G_TYPE_INT); g_value_set_int (value, g_ascii_strtoll (valuestr, NULL, 10)); } else if ((g_strcmp0 (key, "insert_final_newline") == 0) || (g_strcmp0 (key, "trim_trailing_whitespace") == 0)) { g_value_init (value, G_TYPE_BOOLEAN); g_value_set_boolean (value, g_str_equal (valuestr, "true")); } else { g_value_init (value, G_TYPE_STRING); g_value_set_string (value, valuestr); } g_hash_table_replace (ret, g_strdup (key), value); } cleanup: editorconfig_handle_destroy (handle); g_free (filename); return ret; }