/* This file is part of Eclat. Copyright (C) 2012-2014 Sergey Poznyakoff. Eclat is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. Eclat is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with Eclat. If not, see . */ #ifdef HAVE_GETOPT_H # include #endif static char *pp_cmd_buffer; static size_t pp_cmd_bufsize; static size_t pp_cmd_buflevel; struct replvar { union { char **strptr; int *intptr; } r_pointer; #define s_ptr r_pointer.strptr #define i_ptr r_pointer.intptr union { char *strval; int intval; } r_value; #define s_val r_value.strval #define i_val r_value.intval }; int replace_string_var(void *p) { struct replvar *rv = p; *rv->s_ptr = rv->s_val; return 0; } int replace_int_var(void *p) { struct replvar *rv = p; *rv->i_ptr = rv->i_val; return 0; } OPTIONS_BEGIN("eclat", [], [], [], [], [], [],[]) GROUP(Selecting program mode) OPTION(lint,t,, []) BEGIN lint_mode = 1; END OPTION(,E,, []) BEGIN preprocess_only = 1; END OPTION(match-commands,m,, []) BEGIN match_command_mode = 1; END OPTION(list-commands,l,FMT, []) BEGIN listcmd(optarg); exit(0); END GROUP(Modifiers) OPTION(config-file,c,FILE, []) BEGIN conffile = optarg; END OPTION(region,,NAME, []) BEGIN struct replvar *rv = grecs_malloc(sizeof(*rv)); rv->s_ptr = ®ion_name; rv->s_val = optarg; add_config_finish_hook(replace_string_var, rv); END OPTION(access-file,a,NAME, []) BEGIN struct replvar *rv = grecs_malloc(sizeof(*rv)); rv->s_ptr = &access_file_name; rv->s_val = optarg; add_config_finish_hook(replace_string_var, rv); END OPTION(access-key,O,[], []) BEGIN access_key = optarg; END OPTION(secret-key,W,[], []) BEGIN secret_key = optarg; END OPTION(ssl,,, []) BEGIN struct replvar *rv = grecs_malloc(sizeof(*rv)); rv->i_ptr = &use_ssl; rv->i_val = 1; add_config_finish_hook(replace_int_var, rv); END OPTION(format,H,NAME, []) BEGIN format_name_option = optarg; END OPTION(format-expression,e,EXPR, []) BEGIN format_expr_option = optarg; END OPTION(format-file,F,FILE, []) ALIAS(formfile) BEGIN format_file_option = optarg; END OPTION(sort,s,, []) BEGIN sort_option = 1; END OPTION(yes,Y,, []) BEGIN confirm_mode = eclat_confirm_positive; END OPTION(no,N,, []) BEGIN confirm_mode = eclat_confirm_negative; END GROUP(Identifier translation) OPTION(translate,x,, []) BEGIN translate_option = 1; END OPTION(no-translate,X,, []) BEGIN translate_option = 0; END OPTION(map,M,[], []) BEGIN custom_map = optarg; translate_option = 1; END OPTION(test-map,,[], []) BEGIN test_map_name = optarg; translate_option = 1; END GROUP(Preprocessor control) OPTION(include-directory,I,DIR, []) BEGIN grecs_preproc_add_include_dir(optarg); END OPTION(define,D,SYMBOL[=VALUE], []) BEGIN size_t len; char *p; len = 5; for (p = optarg; *p; p++) { if (*p == '\\' || *p == '"') len++; len++; } if (pp_cmd_buflevel + len + 1 > pp_cmd_bufsize) { pp_cmd_bufsize = pp_cmd_buflevel + len + 1; pp_cmd_buffer = grecs_realloc(pp_cmd_buffer, pp_cmd_bufsize); } memcpy(pp_cmd_buffer + pp_cmd_buflevel, " \"-D", 4); pp_cmd_buflevel += 4; for (p = optarg; *p; p++) { if (*p == '\\' || *p == '"') pp_cmd_buffer[pp_cmd_buflevel++] = '\\'; pp_cmd_buffer[pp_cmd_buflevel++] = *p; } pp_cmd_buffer[pp_cmd_buflevel++] = '"'; pp_cmd_buffer[pp_cmd_buflevel] = 0; END OPTION(preprocessor,,COMMAND, []) BEGIN grecs_preprocessor = optarg; END OPTION(no-preprocessor,,, []) BEGIN grecs_preprocessor = NULL; END GROUP(Debugging) OPTION(dry-run,n,, []) BEGIN dry_run_mode = 1; parse_debug_level("main.1"); parse_debug_level("curl.1"); END OPTION(dump-grammar-trace,,, []) BEGIN grecs_gram_trace (1); END OPTION(dump-lex-trace,,, []) BEGIN grecs_lex_trace (1); END OPTION(debug,d,CAT[.LEVEL], []) BEGIN if (parse_debug_level(optarg)) { die(EX_USAGE, "invalid debugging category or level"); } END GROUP([]) OPTION(config-help,,, []) BEGIN config_help(); exit(0); END OPTIONS_END static void parse_options(int *pargc, char **pargv[]) { int index; int argc; char **argv; char *p; argc = *pargc; argv = *pargv; p = getenv("ECLAT_OPTIONS"); if (p) { struct wordsplit ws; int i, j; ws.ws_offs = argc; if (wordsplit(p, &ws, WRDSF_DEFFLAGS|WRDSF_DOOFFS)) die(EX_SOFTWARE, "wordsplit failed at \"%s\": %s", p, wordsplit_strerror(&ws)); memmove(ws.ws_wordv + 1, ws.ws_wordv + ws.ws_offs, sizeof(ws.ws_wordv[0])*ws.ws_wordc); ws.ws_wordv[0] = argv[0]; for (i = 1, j = ws.ws_wordc + 1; i < argc; i++, j++) ws.ws_wordv[j] = argv[i]; argc += ws.ws_wordc; argv = ws.ws_wordv; } GETOPT(argc, argv, index, exit(EX_USAGE)) if (pp_cmd_buffer && grecs_preprocessor) { char *cmd = grecs_malloc(strlen(grecs_preprocessor) + pp_cmd_buflevel + 1); strcpy(cmd, grecs_preprocessor); strcat(cmd, pp_cmd_buffer); grecs_preprocessor = cmd; free(pp_cmd_buffer); } *pargc = argc - index; *pargv = argv + index; }