Example #1
0
static int handle_options(int argc,  char *argv[], int *force)
{
  static struct option long_options[] = {
    {"force", 0, NULL, 'f'},
    {"help", 0, NULL, 'h'},
    {0, 0, 0, 0}
  };

  int option_index = 0;
  int c;

  *force = 0;
  opterr = 0;
  while (1) {
    c = getopt_long (argc, argv, "fh?", long_options, &option_index);
    if (c == -1)
      break;
    switch (c) {
    case 'f':
      *force = 1;
      break;
    case 'h':
      main_usage(argv[0]);
    case '?':
    default:
      carmen_warn("\nUnknown option character %c", optopt);
      if (isdigit(optopt) || optopt == '.')
	carmen_die("\n\nThis looks like a negative numeric value. "
		   "If you want to pass a negative \nvalue, you need "
		   "to suppress option parsing by using -- after the "
		   "command.\n Any options before -- will be parsed, but "
		   "nothing after. For example:\n\n"
		   "%% maptool add_offset -- map.cmf -1 -1 0\n\n"
		   "works where \n\n"
		   "%% maptool add_offset map.cmf -1 -1 0\n\n"
		   "does not.\n");
      else
	main_usage(argv[0]);
      break;
    }
  }

  return optind;
}
Example #2
0
int main(int argc, char **argv)
{
  char *action;

  if (argc < 2) 
    main_usage(argv[0]);
  
  action = argv[1];
  
  if (carmen_strcasecmp(action, "-h") == 0 || 
      carmen_strcasecmp(action, "--help") == 0) 
    main_usage(argv[0]);
  if (carmen_strcasecmp(action, "help") == 0) {
    help(argc, argv);
    return 0;
  }

  if (carmen_strcasecmp(action, "toppm") == 0)
    toppm(argc, argv);
#ifndef NO_GRAPHICS
  else if (carmen_strcasecmp(action, "tomap") == 0)
    tomap(argc, argv);
#endif
  else if (carmen_strcasecmp(action, "rotate") == 0)
    rotate(argc, argv);
  else if (carmen_strcasecmp(action, "minimize") == 0)
    minimize(argc, argv);
  else if (carmen_strcasecmp(action, "add_place") == 0)
    add_place(argc, argv);
  else if (carmen_strcasecmp(action, "add_offset") == 0)
    add_offset(argc, argv);
  else if (carmen_strcasecmp(action, "strip") == 0)
    strip(argc, argv);
  else if (carmen_strcasecmp(action, "info") == 0)
    info(argc, argv);
  else {
    carmen_warn("\nUnrecognized action %s\n", argv[1]);
    main_usage(argv[0]);
  }

  return 0;
}
Example #3
0
static char sep_from_arg(char* arg, char* argv0) {
	if (streq(arg, "tab"))
		return '\t';
	if (streq(arg, "space"))
		return ' ';
	if (streq(arg, "comma"))
		return ',';
	if (streq(arg, "newline"))
		return '\n';
	if (streq(arg, "pipe"))
		return '|';
	if (streq(arg, "slash"))
		return '/';
	if (streq(arg, "colon"))
		return ':';
	if (streq(arg, "semicolon"))
		return '|';
	if (streq(arg, "equals"))
		return '=';
	if (strlen(arg) != 1)
		main_usage(argv0, 1);
	return arg[0];
}
Example #4
0
int main(int argc, char** argv)
{
    char progsub[256];

    if (stxxl::check_library_version() != 0)
        STXXL_ERRMSG("version mismatch between headers and library");

    if (argc > 1)
    {
        for (unsigned int i = 0; subtools[i].name; ++i)
        {
            if (strcmp(subtools[i].name, argv[1]) == 0)
            {
                // replace argv[1] with call string of subtool.
                snprintf(progsub, sizeof(progsub), "%s %s", argv[0], argv[1]);
                argv[1] = progsub;
                return subtools[i].func(argc - 1, argv + 1);
            }
        }
        std::cout << "Unknown subtool '" << argv[1] << "'" << std::endl;
    }

    return main_usage(argv[0]);
}
Example #5
0
static void help(int argc, char **argv)
{
  char *action;

  if (argc < 3 || argc > 3) 
    main_usage(argv[0]);

  action = argv[2];
  if (carmen_strcasecmp(action, "info") == 0)
    carmen_die("\nUsage: %s info <map filename>\n\n", 
	       argv[0]); 
  else if (carmen_strcasecmp(action, "toppm") == 0)
    carmen_die("\nUsage: %s toppm <map filename> <ppm filename>\n\n", 
	       argv[0]); 
  else if (carmen_strcasecmp(action, "tomap") == 0)
    carmen_die("\nUsage: %s tomap <resolution> <image file> "
	       "<map filename>\n\nThe image file can be in most standard "
	       "formats such as gif, png, jpeg, etc.\n\n", argv[0]); 
  else if (carmen_strcasecmp(action, "rotate") == 0)
    carmen_die("\nUsage: %s rotate <rotation in degrees> <in map filename> "
	       "<out map filename>\n\nThe rotation angle must be in multiples "
	       "of 90degrees -- arbitrary rotations are not\nyet supported."
	       "\n\n", argv[0]);
  else if (carmen_strcasecmp(action, "minimize") == 0)
    carmen_die("\nUsage: %s minimize <in map filename> <out map filename>\n\n",
	       argv[0]);
  else if (carmen_strcasecmp(action, "add_place") == 0) {
    fprintf(stderr, "\nUsage: %s <mapfilename> <placename> <place params>\n",
	    argv[0]);
    fprintf(stderr, "       2, 3, or 6 place parameters can be given.\n");
    fprintf(stderr, "       2 parameters - named position (x, y)\n");
    fprintf(stderr, "       3 parameters - named pose (x, y, theta)\n");
    fprintf(stderr, "       6 parameters - initialization position\n");
    fprintf(stderr, "                      (x, y, theta, std_x, std_y, "
	    "std_theta)\n");
    fprintf(stderr, "\nRemember: The x/y/std_x/std_y co-ordinates are in "
	    "%sMETRES%s, not in\n", carmen_red_code, carmen_normal_code);
    fprintf(stderr, "grid cells. \n");
    fprintf(stderr, "\nAlso: theta is in %sDEGREES%s. I will print out the "
	    "conversion to radians\n", carmen_red_code, carmen_normal_code);
    fprintf(stderr, "automatically for you.\n\n");
    fprintf(stderr, "Note that unlike rotate, minimize, etc., add_place "
	    "performs an in-place edit\nto the map, and creates a backup "
	    "copy.\n\n");
    exit(0);
  } else if (carmen_strcasecmp(action, "add_offset") == 0) {
    carmen_warn("\nUsage: %s <mapfilename> <x> <y> <theta>\n",
		argv[0]);
    carmen_warn("       <theta> should be given in degrees.\n");
    exit(0);
  } else if (carmen_strcasecmp(action, "strip") == 0) {
    fprintf(stderr, "\nUsage: %s strip <in map filename> <in map filename> "
	    "<chunk type>\n\n", argv[0]);
    fprintf(stderr, "If the map file contains a data chunk of this type, "
	    "it will\nbe removed on output. All other chunks will be "
	    "passed through untouched.\n");
    fprintf(stderr, "<chunk type> can be one of \"laserscans\", "
	    "\"places\", \"gridmap\", \"offlimits\", ");
    fprintf(stderr, "                                \"expected\".\n\n");

    exit(0);
  }

  carmen_warn("\nUnrecognized command %s\n", action);
  main_usage(argv[0]);
}
Example #6
0
/*
 * Main entry point.
 */
int
main(int argc, char *argv[])
{
	const char *argv0;
	int ch;
	opts_t *opts;
	char *natengine;
	int pidfd = -1;
	int rv = EXIT_FAILURE;

	argv0 = argv[0];
	opts = opts_new();
	natengine = strdup(nat_getdefaultname());

	while ((ch = getopt(argc, argv, OPT_g OPT_G OPT_Z
	                    "k:c:C:K:t:OPs:e:Eu:j:p:l:L:S:dDVh")) != -1) {
		switch (ch) {
			case 'c':
				if (opts->cacrt)
					X509_free(opts->cacrt);
				opts->cacrt = ssl_x509_load(optarg);
				if (!opts->cacrt) {
					fprintf(stderr, "%s: error loading CA "
					                "cert from '%s':\n",
					                argv0, optarg);
					if (errno) {
						fprintf(stderr, "%s\n",
						        strerror(errno));
					} else {
						ERR_print_errors_fp(stderr);
					}
					exit(EXIT_FAILURE);
				}
				ssl_x509_refcount_inc(opts->cacrt);
				sk_X509_insert(opts->chain, opts->cacrt, 0);
				if (!opts->cakey) {
					opts->cakey = ssl_key_load(optarg);
				}
#ifndef OPENSSL_NO_DH
				if (!opts->dh) {
					opts->dh = ssl_dh_load(optarg);
				}
#endif /* !OPENSSL_NO_DH */
				break;
			case 'k':
				if (opts->cakey)
					EVP_PKEY_free(opts->cakey);
				opts->cakey = ssl_key_load(optarg);
				if (!opts->cakey) {
					fprintf(stderr, "%s: error loading CA "
					                "key from '%s':\n",
					                argv0, optarg);
					if (errno) {
						fprintf(stderr, "%s\n",
						        strerror(errno));
					} else {
						ERR_print_errors_fp(stderr);
					}
					exit(EXIT_FAILURE);
				}
				if (!opts->cacrt) {
					opts->cacrt = ssl_x509_load(optarg);
					if (opts->cacrt) {
						ssl_x509_refcount_inc(
						               opts->cacrt);
						sk_X509_insert(opts->chain,
						               opts->cacrt, 0);
					}
				}
#ifndef OPENSSL_NO_DH
				if (!opts->dh) {
					opts->dh = ssl_dh_load(optarg);
				}
#endif /* !OPENSSL_NO_DH */
				break;
			case 'C':
				if (ssl_x509chain_load(NULL, &opts->chain,
				                       optarg) == -1) {
					fprintf(stderr, "%s: error loading "
					                "chain from '%s':\n",
					                argv0, optarg);
					if (errno) {
						fprintf(stderr, "%s\n",
						        strerror(errno));
					} else {
						ERR_print_errors_fp(stderr);
					}
					exit(EXIT_FAILURE);
				}
				break;
			case 'K':
				if (opts->key)
					EVP_PKEY_free(opts->key);
				opts->key = ssl_key_load(optarg);
				if (!opts->key) {
					fprintf(stderr, "%s: error loading lea"
					                "f key from '%s':\n",
					                argv0, optarg);
					if (errno) {
						fprintf(stderr, "%s\n",
						        strerror(errno));
					} else {
						ERR_print_errors_fp(stderr);
					}
					exit(EXIT_FAILURE);
				}
#ifndef OPENSSL_NO_DH
				if (!opts->dh) {
					opts->dh = ssl_dh_load(optarg);
				}
#endif /* !OPENSSL_NO_DH */
				break;
			case 't':
				if (!sys_isdir(optarg)) {
					fprintf(stderr, "%s: '%s' is not a "
					                "directory\n",
					                argv0, optarg);
					exit(EXIT_FAILURE);
				}
				if (opts->tgcrtdir)
					free(opts->tgcrtdir);
				opts->tgcrtdir = strdup(optarg);
				break;
			case 'O':
				opts->deny_ocsp = 1;
				break;
			case 'P':
				opts->passthrough = 1;
				break;
#ifndef OPENSSL_NO_DH
			case 'g':
				if (opts->dh)
					DH_free(opts->dh);
				opts->dh = ssl_dh_load(optarg);
				if (!opts->dh) {
					fprintf(stderr, "%s: error loading DH "
					                "params from '%s':\n",
					                argv0, optarg);
					if (errno) {
						fprintf(stderr, "%s\n",
						        strerror(errno));
					} else {
						ERR_print_errors_fp(stderr);
					}
					exit(EXIT_FAILURE);
				}
				break;
#endif /* !OPENSSL_NO_DH */
#ifndef OPENSSL_NO_ECDH
			case 'G':
			{
				EC_KEY *ec;
				if (opts->ecdhcurve)
					free(opts->ecdhcurve);
				if (!(ec = ssl_ec_by_name(optarg))) {
					fprintf(stderr, "%s: unknown curve "
					                "'%s'\n",
					                argv0, optarg);
					exit(EXIT_FAILURE);
				}
				EC_KEY_free(ec);
				opts->ecdhcurve = strdup(optarg);
				break;
			}
#endif /* !OPENSSL_NO_ECDH */
#ifdef SSL_OP_NO_COMPRESSION
			case 'Z':
				opts->sslcomp = 0;
				break;
#endif /* SSL_OP_NO_COMPRESSION */
			case 's':
				if (opts->ciphers)
					free(opts->ciphers);
				opts->ciphers = strdup(optarg);
				break;
			case 'e':
				free(natengine);
				natengine = strdup(optarg);
				break;
			case 'E':
				nat_list_engines();
				exit(EXIT_SUCCESS);
				break;
			case 'u':
				if (opts->dropuser)
					free(opts->dropuser);
				opts->dropuser = strdup(optarg);
				break;
			case 'p':
				if (opts->pidfile)
					free(opts->pidfile);
				opts->pidfile = strdup(optarg);
				break;
			case 'j':
				if (opts->jaildir)
					free(opts->jaildir);
				opts->jaildir = strdup(optarg);
				break;
			case 'l':
				if (opts->connectlog)
					free(opts->connectlog);
				opts->connectlog = strdup(optarg);
				break;
			case 'L':
				if (opts->contentlog)
					free(opts->contentlog);
				opts->contentlog = strdup(optarg);
				opts->contentlogdir = 0;
				break;
			case 'S':
				if (opts->contentlog)
					free(opts->contentlog);
				opts->contentlog = strdup(optarg);
				opts->contentlogdir = 1;
				break;
			case 'd':
				opts->detach = 1;
				break;
			case 'D':
				log_dbg_mode(LOG_DBG_MODE_ERRLOG);
				opts->debug = 1;
				break;
			case 'V':
				main_version();
				exit(EXIT_SUCCESS);
			case 'h':
				main_usage();
				exit(EXIT_SUCCESS);
			case '?':
				exit(EXIT_FAILURE);
			default:
				main_usage();
				exit(EXIT_FAILURE);
		}
	}
	argc -= optind;
	argv += optind;
	opts->spec = proxyspec_parse(&argc, &argv, natengine);

	/* usage checks */
	if (opts->detach && OPTS_DEBUG(opts)) {
		fprintf(stderr, "%s: -d and -D are mutually exclusive.\n",
		                argv0);
		exit(EXIT_FAILURE);
	}
	if (!opts->spec) {
		fprintf(stderr, "%s: no proxyspec specified.\n", argv0);
		exit(EXIT_FAILURE);
	}
	for (proxyspec_t *spec = opts->spec; spec; spec = spec->next) {
		if (spec->connect_addrlen || spec->sni_port)
			continue;
		if (!spec->natengine) {
			fprintf(stderr, "%s: no supported NAT engines "
			                "on this platform.\n"
			                "Only static addr and SNI proxyspecs "
			                "supported.\n", argv0);
			exit(EXIT_FAILURE);
		}
		if (spec->listen_addr.ss_family == AF_INET6 &&
		    !nat_ipv6ready(spec->natengine)) {
			fprintf(stderr, "%s: IPv6 not supported by '%s'\n",
			                argv0, spec->natengine);
			exit(EXIT_FAILURE);
		}
		spec->natlookup = nat_getlookupcb(spec->natengine);
		spec->natsocket = nat_getsocketcb(spec->natengine);
	}
	if (opts_has_ssl_spec(opts)) {
		if ((opts->cacrt || !opts->tgcrtdir) && !opts->cakey) {
			fprintf(stderr, "%s: no CA key specified (-k).\n",
			                argv0);
			exit(EXIT_FAILURE);
		}
		if (opts->cakey && !opts->cacrt) {
			fprintf(stderr, "%s: no CA cert specified (-c).\n",
			                argv0);
			exit(EXIT_FAILURE);
		}
		if (opts->cakey && opts->cacrt &&
		    (X509_check_private_key(opts->cacrt, opts->cakey) != 1)) {
			fprintf(stderr, "%s: CA cert does not match key.\n",
			                argv0);
			ERR_print_errors_fp(stderr);
			exit(EXIT_FAILURE);
		}
	}

	/* prevent multiple instances running */
	if (opts->pidfile) {
		pidfd = sys_pidf_open(opts->pidfile);
		if (pidfd == -1) {
			fprintf(stderr, "%s: cannot open PID file '%s' "
			                "- process already running?\n",
			                argv0, opts->pidfile);
			exit(EXIT_FAILURE);
		}
	}

	/* dynamic defaults */
	if (!opts->ciphers) {
		opts->ciphers = strdup("ALL:-aNULL");
		if (!opts->ciphers) {
			fprintf(stderr, "%s: out of memory.\n", argv0);
			exit(EXIT_FAILURE);
		}
	}
	if (!opts->jaildir && (geteuid() == 0) && !opts->contentlogdir) {
		opts->jaildir = strdup("/var/empty");
	}
	if (!opts->dropuser && !geteuid() && !getuid() &&
	    !opts->contentlogdir) {
		opts->dropuser = strdup("nobody");
	}
	if (opts_has_ssl_spec(opts) && !opts->key) {
		opts->key = ssl_key_genrsa(1024);
		if (!opts->key) {
			fprintf(stderr, "%s: error generating RSA key:\n",
			                argv0);
			ERR_print_errors_fp(stderr);
			exit(EXIT_FAILURE);
		}
		if (OPTS_DEBUG(opts)) {
			log_dbg_printf("Generated RSA key for leaf certs.\n");
		}
	}

	/* debugging */
	if (OPTS_DEBUG(opts)) {
		main_version();
		log_dbg_printf("proxyspecs:\n");
		for (proxyspec_t *spec = opts->spec; spec; spec = spec->next) {
			char *lbuf, *cbuf = NULL;
			lbuf = sys_sockaddr_str((struct sockaddr *)
			                        &spec->listen_addr,
			                        spec->listen_addrlen);
			if (spec->connect_addrlen) {
				cbuf = sys_sockaddr_str((struct sockaddr *)
				                        &spec->connect_addr,
				                        spec->connect_addrlen);
			}
			if (spec->sni_port) {
				asprintf(&cbuf, "sni %i", spec->sni_port);
			}
			log_dbg_printf("- %s %s %s %s\n", lbuf,
			               (spec->ssl ? "ssl" : "tcp"),
			               (spec->http ? "http" : "plain"),
			               (spec->natengine ? spec->natengine
			                                : cbuf));
			if (lbuf)
				free(lbuf);
			if (cbuf)
				free(cbuf);
		}
		if (opts->cacrt) {
			char *subj = ssl_x509_subject(opts->cacrt);
			log_dbg_printf("Loaded CA: '%s'\n", subj);
			free(subj);
#ifdef DEBUG_CERTIFICATE
			log_dbg_print_free(ssl_x509_to_str(opts->cacrt));
			log_dbg_print_free(ssl_x509_to_pem(opts->cacrt));
#endif /* DEBUG_CERTIFICATE */
		} else {
			log_dbg_printf("No CA loaded.\n");
		}
	}

	/*
	 * Initialize as much as possible before daemon() in order to be
	 * able to provide direct feedback to the user when failing.
	 */
	if (cachemgr_preinit() == -1) {
		fprintf(stderr, "%s: failed to preinit cachemgr.\n", argv0);
		exit(EXIT_FAILURE);
	}
	if (log_preinit(opts) == -1) {
		fprintf(stderr, "%s: failed to preinit logging.\n", argv0);
		exit(EXIT_FAILURE);
	}
	if (nat_preinit() == -1) {
		fprintf(stderr, "%s: failed to preinit NAT lookup.\n", argv0);
		exit(EXIT_FAILURE);
	}

	/* Bind listeners before dropping privileges */
	proxy_ctx_t *proxy = proxy_new(opts);
	if (!proxy) {
		fprintf(stderr, "%s: failed to initialize proxy.\n", argv0);
		exit(EXIT_FAILURE);
	}

	/* Drop privs, chroot, detach from TTY */
	if (sys_privdrop(opts->dropuser, opts->jaildir) == -1) {
		fprintf(stderr, "%s: failed to drop privileges: %s\n",
		                argv0, strerror(errno));
		exit(EXIT_FAILURE);
	}
	if (opts->detach) {
		if (OPTS_DEBUG(opts)) {
			log_dbg_printf("Detaching from TTY, see syslog for "
			               "errors after this point\n");
		}
		if (daemon(1, 0) == -1) {
			fprintf(stderr, "%s: failed to detach from TTY: %s\n",
			                argv0, strerror(errno));
			exit(EXIT_FAILURE);
		}
		log_err_mode(LOG_ERR_MODE_SYSLOG);
		ssl_reinit();
	}

	/* Post-privdrop/chroot/detach initialization, thread spawning */
	if (log_init(opts) == -1) {
		fprintf(stderr, "%s: failed to init log facility.\n", argv0);
		goto out_log_failed;
	}
	if (opts->pidfile && (sys_pidf_write(pidfd) == -1)) {
		log_err_printf("Failed to write PID to PID file '%s': %s\n",
		               opts->pidfile, strerror(errno));
		goto out_pidwrite_failed;
	}
	if (cachemgr_init() == -1) {
		log_err_printf("Failed to init cache manager.\n");
		goto out_cachemgr_failed;
	}
	if (nat_init() == -1) {
		log_err_printf("Failed to init NAT state table lookup.\n");
		goto out_nat_failed;
	}

	if (opts->tgcrtdir) {
		sys_dir_eachfile(opts->tgcrtdir, main_loadtgcrt, opts);
	}

	rv = EXIT_SUCCESS;

	proxy_run(proxy);
	proxy_free(proxy);
	nat_fini();
out_nat_failed:
	cachemgr_fini();
out_cachemgr_failed:
	if (opts->pidfile) {
		sys_pidf_close(pidfd, opts->pidfile);
	}
out_pidwrite_failed:
	log_fini();
out_log_failed:
	opts_free(opts);
	ssl_fini();
	return rv;
}
Example #7
0
// ----------------------------------------------------------------
cli_opts_t* parse_command_line(int argc, char** argv) {
	cli_opts_t* popts = mlr_malloc_or_die(sizeof(cli_opts_t));
	memset(popts, 0, sizeof(*popts));

	popts->irs               = NULL;
	popts->ifs               = NULL;
	popts->ips               = NULL;
	popts->allow_repeat_ifs  = NEITHER_TRUE_NOR_FALSE;
	popts->allow_repeat_ips  = NEITHER_TRUE_NOR_FALSE;
	popts->use_implicit_csv_header = FALSE;
	popts->headerless_csv_output   = FALSE;

	popts->ors               = NULL;
	popts->ofs               = NULL;
	popts->ops               = NULL;

	popts->right_justify_xtab_value       = FALSE;
	popts->stack_json_output_vertically   = FALSE;
	popts->wrap_json_output_in_outer_list = FALSE;
	popts->quote_json_values_always       = FALSE;
	popts->json_flatten_separator         = DEFAULT_JSON_FLATTEN_SEPARATOR;

	popts->ofmt              = DEFAULT_OFMT;
	popts->oquoting          = DEFAULT_OQUOTING;

	popts->plrec_reader      = NULL;
	popts->plrec_writer      = NULL;

	popts->prepipe           = NULL;
	popts->filenames         = NULL;

	popts->ifile_fmt         = "dkvp";
	popts->ofile_fmt         = "dkvp";

	popts->use_mmap_for_read = TRUE;
	int left_align_pprint    = TRUE;

	int have_rand_seed       = FALSE;
	unsigned rand_seed       = 0;

	int argi = 1;
	for (; argi < argc; argi++) {
		if (argv[argi][0] != '-') {
			break;

		} else if (streq(argv[argi], "--version")) {
#ifdef HAVE_CONFIG_H
			printf("Miller %s\n", PACKAGE_VERSION);
#else
			printf("Miller %s\n", MLR_VERSION);
#endif // HAVE_CONFIG_H
			exit(0);
		} else if (streq(argv[argi], "-h")) {
			main_usage(stdout, argv[0]);
			exit(0);
		} else if (streq(argv[argi], "--help")) {
			main_usage(stdout, argv[0]);
			exit(0);
		} else if (streq(argv[argi], "--help-all-verbs")) {
			usage_all_verbs(argv[0]);
		} else if (streq(argv[argi], "--list-all-verbs") || streq(argv[argi], "-l")) {
			list_all_verbs(stdout, "");
			exit(0);
		} else if (streq(argv[argi], "--list-all-verbs-raw")) {
			list_all_verbs_raw(stdout);
			exit(0);
		} else if (streq(argv[argi], "--list-all-functions-raw")) {
			lrec_evaluator_list_all_functions_raw(stdout);
			exit(0);
		} else if (streq(argv[argi], "--help-all-functions") || streq(argv[argi], "-f")) {
			lrec_evaluator_function_usage(stdout, NULL);
			exit(0);

		} else if (streq(argv[argi], "--help-function") || streq(argv[argi], "--hf")) {
			check_arg_count(argv, argi, argc, 2);
			lrec_evaluator_function_usage(stdout, argv[argi+1]);
			exit(0);

		// main-usage subsections, individually accessible for the benefit of
		// the manpage-autogenerator
		} else if (streq(argv[argi], "--usage-synopsis")) {
			main_usage_synopsis(stdout, argv[0]);
			exit(0);
		} else if (streq(argv[argi], "--usage-examples")) {
			main_usage_examples(stdout, argv[0], "");
			exit(0);
		} else if (streq(argv[argi], "--usage-list-all-verbs")) {
			list_all_verbs(stdout, "");
			exit(0);
		} else if (streq(argv[argi], "--usage-help-options")) {
			main_usage_help_options(stdout, argv[0]);
			exit(0);
		} else if (streq(argv[argi], "--usage-functions")) {
			main_usage_functions(stdout, argv[0], "");
			exit(0);
		} else if (streq(argv[argi], "--usage-data-format-examples")) {
			main_usage_data_format_examples(stdout, argv[0]);
			exit(0);
		} else if (streq(argv[argi], "--usage-data-format-options")) {
			main_usage_data_format_options(stdout, argv[0]);
			exit(0);
		} else if (streq(argv[argi], "--usage-compressed-data-options")) {
			main_usage_compressed_data_options(stdout, argv[0]);
			exit(0);
		} else if (streq(argv[argi], "--usage-separator-options")) {
			main_usage_separator_options(stdout, argv[0]);
			exit(0);
		} else if (streq(argv[argi], "--usage-csv-options")) {
			main_usage_csv_options(stdout, argv[0]);
			exit(0);
		} else if (streq(argv[argi], "--usage-double-quoting")) {
			main_usage_double_quoting(stdout, argv[0]);
			exit(0);
		} else if (streq(argv[argi], "--usage-numerical-formatting")) {
			main_usage_numerical_formatting(stdout, argv[0]);
			exit(0);
		} else if (streq(argv[argi], "--usage-other-options")) {
			main_usage_other_options(stdout, argv[0]);
			exit(0);
		} else if (streq(argv[argi], "--usage-then-chaining")) {
			main_usage_then_chaining(stdout, argv[0]);
			exit(0);
		} else if (streq(argv[argi], "--usage-see-also")) {
			main_usage_see_also(stdout, argv[0]);
			exit(0);

		} else if (streq(argv[argi], "--rs")) {
			check_arg_count(argv, argi, argc, 2);
			popts->ors = sep_from_arg(argv[argi+1], argv[0]);
			popts->irs = sep_from_arg(argv[argi+1], argv[0]);
			argi++;
		} else if (streq(argv[argi], "--irs")) {
			check_arg_count(argv, argi, argc, 2);
			popts->irs = sep_from_arg(argv[argi+1], argv[0]);
			argi++;
		} else if (streq(argv[argi], "--ors")) {
			check_arg_count(argv, argi, argc, 2);
			popts->ors = sep_from_arg(argv[argi+1], argv[0]);
			argi++;

		} else if (streq(argv[argi], "--fs")) {
			check_arg_count(argv, argi, argc, 2);
			popts->ofs = sep_from_arg(argv[argi+1], argv[0]);
			popts->ifs = sep_from_arg(argv[argi+1], argv[0]);
			argi++;
		} else if (streq(argv[argi], "--ifs")) {
			check_arg_count(argv, argi, argc, 2);
			popts->ifs = sep_from_arg(argv[argi+1], argv[0]);
			argi++;
		} else if (streq(argv[argi], "--ofs")) {
			check_arg_count(argv, argi, argc, 2);
			popts->ofs = sep_from_arg(argv[argi+1], argv[0]);
			argi++;
		} else if (streq(argv[argi], "--repifs")) {
			popts->allow_repeat_ifs = TRUE;
		} else if (streq(argv[argi], "--implicit-csv-header")) {
			popts->use_implicit_csv_header = TRUE;
		} else if (streq(argv[argi], "--headerless-csv-output")) {
			popts->headerless_csv_output = TRUE;

		} else if (streq(argv[argi], "-p")) {
			popts->ifile_fmt = "nidx";
			popts->ofile_fmt = "nidx";
			popts->ifs = " ";
			popts->ofs = " ";
			popts->allow_repeat_ifs = TRUE;

		} else if (streq(argv[argi], "--ps")) {
			check_arg_count(argv, argi, argc, 2);
			popts->ops = sep_from_arg(argv[argi+1], argv[0]);
			popts->ips = sep_from_arg(argv[argi+1], argv[0]);
			argi++;
		} else if (streq(argv[argi], "--ips")) {
			check_arg_count(argv, argi, argc, 2);
			popts->ips = sep_from_arg(argv[argi+1], argv[0]);
			argi++;
		} else if (streq(argv[argi], "--ops")) {
			check_arg_count(argv, argi, argc, 2);
			popts->ops = sep_from_arg(argv[argi+1], argv[0]);
			argi++;

		} else if (streq(argv[argi], "--xvright")) {
			popts->right_justify_xtab_value = TRUE;

		} else if (streq(argv[argi], "--jvstack")) {
			popts->stack_json_output_vertically = TRUE;
		} else if (streq(argv[argi], "--jlistwrap")) {
			popts->wrap_json_output_in_outer_list = TRUE;
		} else if (streq(argv[argi], "--jquoteall")) {
			popts->quote_json_values_always = TRUE;
		} else if (streq(argv[argi], "--jflatsep")) {
			check_arg_count(argv, argi, argc, 2);
			popts->json_flatten_separator = sep_from_arg(argv[argi+1], argv[0]);
			argi++;

		} else if (streq(argv[argi], "--csv"))      { popts->ifile_fmt = popts->ofile_fmt = "csv";
		} else if (streq(argv[argi], "--icsv"))     { popts->ifile_fmt = "csv";
		} else if (streq(argv[argi], "--ocsv"))     { popts->ofile_fmt = "csv";

		} else if (streq(argv[argi], "--csvlite"))  { popts->ifile_fmt = popts->ofile_fmt = "csvlite";
		} else if (streq(argv[argi], "--icsvlite")) { popts->ifile_fmt = "csvlite";
		} else if (streq(argv[argi], "--ocsvlite")) { popts->ofile_fmt = "csvlite";

		} else if (streq(argv[argi], "--dkvp"))     { popts->ifile_fmt = popts->ofile_fmt = "dkvp";
		} else if (streq(argv[argi], "--idkvp"))    { popts->ifile_fmt = "dkvp";
		} else if (streq(argv[argi], "--odkvp"))    { popts->ofile_fmt = "dkvp";

		} else if (streq(argv[argi], "--json"))     { popts->ifile_fmt = popts->ofile_fmt = "json";
		} else if (streq(argv[argi], "--ijson"))    { popts->ifile_fmt = "json";
		} else if (streq(argv[argi], "--ojson"))    { popts->ofile_fmt = "json";

		} else if (streq(argv[argi], "--nidx"))     { popts->ifile_fmt = popts->ofile_fmt = "nidx";
		} else if (streq(argv[argi], "--inidx"))    { popts->ifile_fmt = "nidx";
		} else if (streq(argv[argi], "--onidx"))    { popts->ofile_fmt = "nidx";

		} else if (streq(argv[argi], "--xtab"))     { popts->ifile_fmt = popts->ofile_fmt = "xtab";
		} else if (streq(argv[argi], "--ixtab"))    { popts->ifile_fmt = "xtab";
		} else if (streq(argv[argi], "--oxtab"))    { popts->ofile_fmt = "xtab";

		} else if (streq(argv[argi], "--ipprint")) {
			popts->ifile_fmt        = "csvlite";
			popts->ifs              = " ";
			popts->allow_repeat_ifs = TRUE;

		} else if (streq(argv[argi], "--opprint")) {
			popts->ofile_fmt = "pprint";
		} else if (streq(argv[argi], "--pprint")) {
			popts->ifile_fmt        = "csvlite";
			popts->ifs              = " ";
			popts->allow_repeat_ifs = TRUE;
			popts->ofile_fmt        = "pprint";
		} else if (streq(argv[argi], "--right"))   {
			left_align_pprint = FALSE;

		} else if (streq(argv[argi], "--ofmt")) {
			check_arg_count(argv, argi, argc, 2);
			popts->ofmt = argv[argi+1];
			argi++;

		} else if (streq(argv[argi], "--quote-all"))     { popts->oquoting = QUOTE_ALL;
		} else if (streq(argv[argi], "--quote-none"))    { popts->oquoting = QUOTE_NONE;
		} else if (streq(argv[argi], "--quote-minimal")) { popts->oquoting = QUOTE_MINIMAL;
		} else if (streq(argv[argi], "--quote-numeric")) { popts->oquoting = QUOTE_NUMERIC;

		} else if (streq(argv[argi], "--mmap")) {
			popts->use_mmap_for_read = TRUE;
		} else if (streq(argv[argi], "--no-mmap")) {
			popts->use_mmap_for_read = FALSE;

		} else if (streq(argv[argi], "--seed")) {
			check_arg_count(argv, argi, argc, 2);
			if (sscanf(argv[argi+1], "0x%x", &rand_seed) == 1) {
				have_rand_seed = TRUE;
			} else if (sscanf(argv[argi+1], "%u", &rand_seed) == 1) {
				have_rand_seed = TRUE;
			} else {
				main_usage(stderr, argv[0]);
				exit(1);
			}
			argi++;

		} else if (streq(argv[argi], "--prepipe")) {
			check_arg_count(argv, argi, argc, 2);
			popts->prepipe = argv[argi+1];
			popts->use_mmap_for_read = FALSE;
			argi++;

		} else {
			usage_unrecognized_verb(argv[0], argv[argi]);
		}
	}

	lhmss_t* default_rses = get_default_rses();
	lhmss_t* default_fses = get_default_fses();
	lhmss_t* default_pses = get_default_pses();
	lhmsi_t* default_repeat_ifses = get_default_repeat_ifses();
	lhmsi_t* default_repeat_ipses = get_default_repeat_ipses();

	if (popts->irs == NULL)
		popts->irs = lhmss_get(default_rses, popts->ifile_fmt);
	if (popts->ifs == NULL)
		popts->ifs = lhmss_get(default_fses, popts->ifile_fmt);
	if (popts->ips == NULL)
		popts->ips = lhmss_get(default_pses, popts->ifile_fmt);

	if (popts->allow_repeat_ifs == NEITHER_TRUE_NOR_FALSE)
		popts->allow_repeat_ifs = lhmsi_get(default_repeat_ifses, popts->ifile_fmt);
	if (popts->allow_repeat_ips == NEITHER_TRUE_NOR_FALSE)
		popts->allow_repeat_ips = lhmsi_get(default_repeat_ipses, popts->ifile_fmt);

	if (popts->ors == NULL)
		popts->ors = lhmss_get(default_rses, popts->ofile_fmt);
	if (popts->ofs == NULL)
		popts->ofs = lhmss_get(default_fses, popts->ofile_fmt);
	if (popts->ops == NULL)
		popts->ops = lhmss_get(default_pses, popts->ofile_fmt);

	if (popts->irs == NULL) {
		fprintf(stderr, "%s: internal coding error detected in file %s at line %d.\n", argv[0], __FILE__, __LINE__);
		exit(1);
	}
	if (popts->ifs == NULL) {
		fprintf(stderr, "%s: internal coding error detected in file %s at line %d.\n", argv[0], __FILE__, __LINE__);
		exit(1);
	}
	if (popts->ips == NULL) {
		fprintf(stderr, "%s: internal coding error detected in file %s at line %d.\n", argv[0], __FILE__, __LINE__);
		exit(1);
	}

	if (popts->allow_repeat_ifs == NEITHER_TRUE_NOR_FALSE) {
		fprintf(stderr, "%s: internal coding error detected in file %s at line %d.\n", argv[0], __FILE__, __LINE__);
		exit(1);
	}
	if (popts->allow_repeat_ips == NEITHER_TRUE_NOR_FALSE) {
		fprintf(stderr, "%s: internal coding error detected in file %s at line %d.\n", argv[0], __FILE__, __LINE__);
		exit(1);
	}

	if (popts->ors == NULL) {
		fprintf(stderr, "%s: internal coding error detected in file %s at line %d.\n", argv[0], __FILE__, __LINE__);
		exit(1);
	}
	if (popts->ofs == NULL) {
		fprintf(stderr, "%s: internal coding error detected in file %s at line %d.\n", argv[0], __FILE__, __LINE__);
		exit(1);
	}
	if (popts->ops == NULL) {
		fprintf(stderr, "%s: internal coding error detected in file %s at line %d.\n", argv[0], __FILE__, __LINE__);
		exit(1);
	}

	if (streq(popts->ofile_fmt, "pprint") && strlen(popts->ofs) != 1) {
		fprintf(stderr, "%s: OFS for PPRINT format must be single-character; got \"%s\".\n",
			argv[0], popts->ofs);
		return NULL;
	}
	if      (streq(popts->ofile_fmt, "dkvp"))
		popts->plrec_writer = lrec_writer_dkvp_alloc(popts->ors, popts->ofs, popts->ops);
	else if (streq(popts->ofile_fmt, "json"))
		popts->plrec_writer = lrec_writer_json_alloc(popts->stack_json_output_vertically,
			popts->wrap_json_output_in_outer_list, popts->quote_json_values_always, popts->json_flatten_separator);
	else if (streq(popts->ofile_fmt, "csv"))
		popts->plrec_writer = lrec_writer_csv_alloc(popts->ors, popts->ofs, popts->oquoting,
			popts->headerless_csv_output);
	else if (streq(popts->ofile_fmt, "csvlite"))
		popts->plrec_writer = lrec_writer_csvlite_alloc(popts->ors, popts->ofs, popts->headerless_csv_output);
	else if (streq(popts->ofile_fmt, "nidx"))
		popts->plrec_writer = lrec_writer_nidx_alloc(popts->ors, popts->ofs);
	else if (streq(popts->ofile_fmt, "xtab"))
		popts->plrec_writer = lrec_writer_xtab_alloc(popts->ofs, popts->ops, popts->right_justify_xtab_value);
	else if (streq(popts->ofile_fmt, "pprint"))
		popts->plrec_writer = lrec_writer_pprint_alloc(popts->ors, popts->ofs[0], left_align_pprint);
	else {
		main_usage(stderr, argv[0]);
		exit(1);
	}

	if ((argc - argi) < 1) {
		main_usage(stderr, argv[0]);
		exit(1);
	}

	popts->pmapper_list = sllv_alloc();
	while (TRUE) {
		check_arg_count(argv, argi, argc, 1);
		char* verb = argv[argi];

		mapper_setup_t* pmapper_setup = look_up_mapper_setup(verb);
		if (pmapper_setup == NULL) {
			fprintf(stderr, "%s: verb \"%s\" not found. Please use \"%s --help\" for a list.\n",
				argv[0], verb, argv[0]);
			exit(1);
		}

		if ((argc - argi) >= 2) {
			if (streq(argv[argi+1], "-h") || streq(argv[argi+1], "--help")) {
				pmapper_setup->pusage_func(stdout, argv[0], verb);
				exit(0);
			}
		}

		// It's up to the parse func to print its usage on CLI-parse failure.
		mapper_t* pmapper = pmapper_setup->pparse_func(&argi, argc, argv);
		if (pmapper == NULL) {
			exit(1);
		}
		sllv_append(popts->pmapper_list, pmapper);

		if (argi >= argc || !streq(argv[argi], "then"))
			break;
		argi++;
	}

	popts->filenames = &argv[argi];

	// No filenames means read from standard input, and standard input cannot be mmapped.
	if (argi == argc)
		popts->use_mmap_for_read = FALSE;

	popts->plrec_reader = lrec_reader_alloc(popts->ifile_fmt, popts->use_mmap_for_read,
		popts->irs, popts->ifs, popts->allow_repeat_ifs, popts->ips, popts->allow_repeat_ips,
		popts->use_implicit_csv_header, popts->json_flatten_separator);
	if (popts->plrec_reader == NULL) {
		main_usage(stderr, argv[0]);
		exit(1);
	}

	if (have_rand_seed) {
		mtrand_init(rand_seed);
	} else {
		mtrand_init_default();
	}

	return popts;
}
Example #8
0
static void check_arg_count(char** argv, int argi, int argc, int n) {
	if ((argc - argi) < n) {
		main_usage(stderr, argv[0]);
		exit(1);
	}
}
Example #9
0
static void usage_unrecognized_verb(char* argv0, char* arg) {
	fprintf(stderr, "%s: option \"%s\" not recognized.\n", argv0, arg);
	fprintf(stderr, "\n");
	main_usage(stderr, argv0);
	exit(1);
}
Example #10
0
// ----------------------------------------------------------------
int main(int argc, char** argv)
{
	STRANDOM(); // Seed the random-number generator.

	// If the user invoked us with no arguments, give them a usage message.

	if (argc < 2)
		main_usage(argv[0]);

	// Invoke the appropriate subroutine (if any) for the first argument the
	// user typed, passing all remaining arguments along to that subroutine.
	// If the first argument is unrecognized, give them a usage message.
	//
	// Sample command line:  "./perco2 print p=0.6 M=8 N=16".

	if      (strcmp(argv[1], "print") == 0)
		test_print_lattice(argc, argv);
	else if (strcmp(argv[1], "plot") == 0)
		test_plot_lattice(argc, argv);

	else if (strcmp(argv[1], "nei") == 0)
		test_get_bonded_neighbors(argc, argv);

	else if (strcmp(argv[1], "cluster") == 0)
		test_cluster(argc, argv);
	else if (strcmp(argv[1], "plotcluster") == 0)
		test_plot_cluster(argc, argv);
	else if (strcmp(argv[1], "meanC0size") == 0)
		test_mean_C0_size(argc, argv);
	else if (strcmp(argv[1], "meanfC0size") == 0)
		test_mean_finite_C0_size(argc, argv);
	else if (strcmp(argv[1], "corrlen") == 0)
		test_corrlen(argc, argv);

	else if (strcmp(argv[1], "1o2") == 0)
		test_A1_oo_A2(argc, argv);
	else if (strcmp(argv[1], "P1o2") == 0) // This is tau(p) in greeks.sh.
		test_P_A1_oo_A2(argc, argv);

	else if (strcmp(argv[1], "clnos") == 0)
		test_cluster_numbers(argc, argv);
	else if (strcmp(argv[1], "plotclusters") == 0)
		test_plot_clusters(argc, argv);
	else if (strcmp(argv[1], "clszs") == 0)
		test_cluster_sizes(argc, argv);

	else if (strcmp(argv[1], "AinC") == 0)
		test_A_in_C(argc, argv);
	else if (strcmp(argv[1], "PAinC") == 0) // This is theta(p) in greeks.sh.
		test_P_A_in_C(argc, argv);

	else if (strcmp(argv[1], "U2inC") == 0)
		test_A1_or_A2_in_C(argc, argv);
	else if (strcmp(argv[1], "PU2inC") == 0) // This is sigma(p) in greeks.sh.
		test_P_A1_or_A2_in_C(argc, argv);

	else
		main_usage(argv[0]);

	return 0;
}
Example #11
0
// ----------------------------------------------------------------
cli_opts_t* parse_command_line(int argc, char** argv) {
	cli_opts_t* popts = mlr_malloc_or_die(sizeof(cli_opts_t));
	memset(popts, 0, sizeof(*popts));

	popts->irs  = DEFAULT_RS;
	popts->ifs  = DEFAULT_FS;
	popts->ips  = DEFAULT_PS;
	popts->allow_repeat_ifs = FALSE;
	popts->allow_repeat_ips = FALSE;

	popts->ors  = DEFAULT_RS;
	popts->ofs  = DEFAULT_FS;
	popts->ops  = DEFAULT_PS;
	popts->ofmt = DEFAULT_OFMT;

	popts->plrec_reader = NULL;
	popts->plrec_writer = NULL;
	popts->filenames    = NULL;

	popts->ifmt = "dkvp";
	char* ofmt  = "dkvp";

	popts->use_mmap_for_read = TRUE;
	int left_align_pprint    = TRUE;

	int have_rand_seed = FALSE;
	unsigned rand_seed = 0;

	int argi = 1;
	for (; argi < argc; argi++) {
		if (argv[argi][0] != '-')
			break;

		else if (streq(argv[argi], "-h"))
			main_usage(argv[0], 0);
		else if (streq(argv[argi], "--help"))
			main_usage(argv[0], 0);
		else if (streq(argv[argi], "--help-all-verbs"))
			usage_all_verbs(argv[0]);
		else if (streq(argv[argi], "--help-all-functions") || streq(argv[argi], "-f")) {
			lrec_evaluator_function_usage(stdout, NULL);
			exit(0);
		}

		else if (streq(argv[argi], "--help-function") || streq(argv[argi], "--hf")) {
			check_arg_count(argv, argi, argc, 2);
			lrec_evaluator_function_usage(stdout, argv[argi+1]);
			exit(0);
		}

		else if (streq(argv[argi], "--rs")) {
			check_arg_count(argv, argi, argc, 2);
			popts->ors = popts->irs = sep_from_arg(argv[argi+1], argv[0]);
			argi++;
		}
		else if (streq(argv[argi], "--irs")) {
			check_arg_count(argv, argi, argc, 2);
			popts->irs = sep_from_arg(argv[argi+1], argv[0]);
			argi++;
		}
		else if (streq(argv[argi], "--ors")) {
			check_arg_count(argv, argi, argc, 2);
			popts->ors = sep_from_arg(argv[argi+1], argv[0]);
			argi++;
		}

		else if (streq(argv[argi], "--fs")) {
			check_arg_count(argv, argi, argc, 2);
			popts->ofs = popts->ifs = sep_from_arg(argv[argi+1], argv[0]);
			argi++;
		}
		else if (streq(argv[argi], "--ifs")) {
			check_arg_count(argv, argi, argc, 2);
			popts->ifs = sep_from_arg(argv[argi+1], argv[0]);
			argi++;
		}
		else if (streq(argv[argi], "--ofs")) {
			check_arg_count(argv, argi, argc, 2);
			popts->ofs = sep_from_arg(argv[argi+1], argv[0]);
			argi++;
		}
		else if (streq(argv[argi], "--repifs")) {
			popts->allow_repeat_ifs = TRUE;
		}

		else if (streq(argv[argi], "-p")) {
			popts->ifmt = "nidx";
			ofmt = "nidx";
			popts->ifs = ' ';
			popts->ofs = ' ';
			popts->allow_repeat_ifs = TRUE;
		}

		else if (streq(argv[argi], "--ps")) {
			check_arg_count(argv, argi, argc, 2);
			popts->ops = popts->ips = sep_from_arg(argv[argi+1], argv[0]);
			argi++;
		}
		else if (streq(argv[argi], "--ips")) {
			check_arg_count(argv, argi, argc, 2);
			popts->ips = sep_from_arg(argv[argi+1], argv[0]);
			argi++;
		}
		else if (streq(argv[argi], "--ops")) {
			check_arg_count(argv, argi, argc, 2);
			popts->ops = sep_from_arg(argv[argi+1], argv[0]);
			argi++;
		}

		else if (streq(argv[argi], "--dkvp"))    { popts->ifmt = ofmt = "dkvp"; }
		else if (streq(argv[argi], "--idkvp"))   { popts->ifmt = "dkvp"; }
		else if (streq(argv[argi], "--odkvp"))   { ofmt = "dkvp"; }

		else if (streq(argv[argi], "--csv"))     { popts->ifmt = ofmt = "csv";  }
		else if (streq(argv[argi], "--icsv"))    { popts->ifmt = "csv";  }
		else if (streq(argv[argi], "--ocsv"))    { ofmt = "csv";  }

		else if (streq(argv[argi], "--nidx"))    { popts->ifmt = ofmt = "nidx"; }
		else if (streq(argv[argi], "--inidx"))   { popts->ifmt = "nidx"; }
		else if (streq(argv[argi], "--onidx"))   { ofmt = "nidx"; }

		else if (streq(argv[argi], "--xtab"))    { popts->ifmt = ofmt = "xtab"; }
		else if (streq(argv[argi], "--ixtab"))   { popts->ifmt = "xtab"; }
		else if (streq(argv[argi], "--oxtab"))   { ofmt = "xtab"; }

		else if (streq(argv[argi], "--ipprint")) {
			popts->ifmt             = "csv";
			popts->ifs              = ' ';
			popts->allow_repeat_ifs = TRUE;

		}
		else if (streq(argv[argi], "--opprint")) {
			ofmt = "pprint";
		}
		else if (streq(argv[argi], "--pprint")) {
			popts->ifmt             = "csv";
			popts->ifs              = ' ';
			popts->allow_repeat_ifs = TRUE;
			ofmt                    = "pprint";
		}
		else if (streq(argv[argi], "--right"))   {
			left_align_pprint = FALSE;
		}

		else if (streq(argv[argi], "--ofmt")) {
			check_arg_count(argv, argi, argc, 2);
			popts->ofmt = argv[argi+1];
			argi++;
		}

		// xxx put into online help.
		else if (streq(argv[argi], "--mmap")) {
			popts->use_mmap_for_read = TRUE;
		}
		else if (streq(argv[argi], "--no-mmap")) {
			popts->use_mmap_for_read = FALSE;
		}
		else if (streq(argv[argi], "--seed")) {
			check_arg_count(argv, argi, argc, 2);
			if (sscanf(argv[argi+1], "0x%x", &rand_seed) == 1) {
				have_rand_seed = TRUE;
			} else if (sscanf(argv[argi+1], "%u", &rand_seed) == 1) {
				have_rand_seed = TRUE;
			} else {
				main_usage(argv[0], 1);
			}
			argi++;
		}

		else
			nusage(argv[0], argv[argi]);
	}

	if      (streq(ofmt, "dkvp"))   popts->plrec_writer = lrec_writer_dkvp_alloc(popts->ors, popts->ofs, popts->ops);
	else if (streq(ofmt, "csv"))    popts->plrec_writer = lrec_writer_csv_alloc(popts->ors, popts->ofs);
	else if (streq(ofmt, "nidx"))   popts->plrec_writer = lrec_writer_nidx_alloc(popts->ors, popts->ofs);
	else if (streq(ofmt, "xtab"))   popts->plrec_writer = lrec_writer_xtab_alloc();
	else if (streq(ofmt, "pprint")) popts->plrec_writer = lrec_writer_pprint_alloc(left_align_pprint);
	else {
		main_usage(argv[0], 1);
	}

	if ((argc - argi) < 1) {
		main_usage(argv[0], 1);
	}

	popts->pmapper_list = sllv_alloc();
	while (TRUE) {
		check_arg_count(argv, argi, argc, 1);
		char* verb = argv[argi];

		mapper_setup_t* pmapper_setup = look_up_mapper_setup(verb);
		if (pmapper_setup == NULL) {
			fprintf(stderr, "%s: verb \"%s\" not found. Please use \"%s --help\" for a list.\n",
				argv[0], verb, argv[0]);
			exit(1);
		}

		if ((argc - argi) >= 2) {
			if (streq(argv[argi+1], "-h") || streq(argv[argi+1], "--help")) {
				pmapper_setup->pusage_func(argv[0], verb);
				exit(0);
			}
		}

		// It's up to the parse func to print its usage on CLI-parse failure.
		mapper_t* pmapper = pmapper_setup->pparse_func(&argi, argc, argv);
		if (pmapper == NULL) {
			exit(1);
		}
		sllv_add(popts->pmapper_list, pmapper);

		// xxx cmt
		if (argi >= argc || !streq(argv[argi], "then"))
			break;
		argi++;
	}

	popts->filenames = &argv[argi];

	// No filenames means read from standard input, and standard input cannot be mmapped.
	if (argi == argc)
		popts->use_mmap_for_read = FALSE;

	popts->plrec_reader = lrec_reader_alloc(popts->ifmt, popts->use_mmap_for_read,
		popts->irs, popts->ifs, popts->allow_repeat_ifs, popts->ips, popts->allow_repeat_ips);
	if (popts->plrec_reader == NULL)
		main_usage(argv[0], 1);

	if (have_rand_seed) {
		mtrand_init(rand_seed);
	} else {
		mtrand_init_default();
	}

	return popts;
}
Example #12
0
static void check_arg_count(char** argv, int argi, int argc, int n) {
	if ((argc - argi) < n) {
		main_usage(argv[0], 1);
	}
}
Example #13
0
static void nusage(char* argv0, char* arg) {
	fprintf(stdout, "%s: option \"%s\" not recognized.\n", argv0, arg);
	fprintf(stdout, "\n");
	main_usage(argv0, 1);
}
Example #14
0
// ----------------------------------------------------------------
cli_opts_t* parse_command_line(int argc, char** argv) {
	cli_opts_t* popts = mlr_malloc_or_die(sizeof(cli_opts_t));
	memset(popts, 0, sizeof(*popts));

	popts->irs               = NULL;
	popts->ifs               = NULL;
	popts->ips               = NULL;
	popts->allow_repeat_ifs  = NEITHER_TRUE_NOR_FALSE;
	popts->allow_repeat_ips  = NEITHER_TRUE_NOR_FALSE;

	popts->ors               = NULL;
	popts->ofs               = NULL;
	popts->ops               = NULL;
	popts->ofmt              = DEFAULT_OFMT;
	popts->oquoting          = DEFAULT_OQUOTING;

	popts->plrec_reader      = NULL;
	popts->plrec_writer      = NULL;
	popts->filenames         = NULL;

	popts->ifile_fmt         = "dkvp";
	popts->ofile_fmt          = "dkvp";

	popts->use_mmap_for_read = TRUE;
	int left_align_pprint    = TRUE;

	int have_rand_seed       = FALSE;
	unsigned rand_seed       = 0;

	int argi = 1;
	for (; argi < argc; argi++) {
		if (argv[argi][0] != '-')
			break;

		else if (streq(argv[argi], "--version")) {
#ifdef HAVE_CONFIG_H
			printf("Miller version >= %s.\n", PACKAGE_VERSION);
#else
			printf("Miller version >= %s.\n", MLR_VERSION);
#endif // HAVE_CONFIG_H
			exit(0);
		} else if (streq(argv[argi], "-h"))
			main_usage(argv[0], 0);
		else if (streq(argv[argi], "--help"))
			main_usage(argv[0], 0);
		else if (streq(argv[argi], "--help-all-verbs"))
			usage_all_verbs(argv[0]);
		else if (streq(argv[argi], "--help-all-functions") || streq(argv[argi], "-f")) {
			lrec_evaluator_function_usage(stdout, NULL);
			exit(0);
		}

		else if (streq(argv[argi], "--help-function") || streq(argv[argi], "--hf")) {
			check_arg_count(argv, argi, argc, 2);
			lrec_evaluator_function_usage(stdout, argv[argi+1]);
			exit(0);
		}

		else if (streq(argv[argi], "--rs")) {
			check_arg_count(argv, argi, argc, 2);
			popts->ors = sep_from_arg(argv[argi+1], argv[0]);
			popts->irs = sep_from_arg(argv[argi+1], argv[0]);
			argi++;
		}
		else if (streq(argv[argi], "--irs")) {
			check_arg_count(argv, argi, argc, 2);
			popts->irs = sep_from_arg(argv[argi+1], argv[0]);
			argi++;
		}
		else if (streq(argv[argi], "--ors")) {
			check_arg_count(argv, argi, argc, 2);
			popts->ors = sep_from_arg(argv[argi+1], argv[0]);
			argi++;
		}

		else if (streq(argv[argi], "--fs")) {
			check_arg_count(argv, argi, argc, 2);
			popts->ofs = sep_from_arg(argv[argi+1], argv[0]);
			popts->ifs = sep_from_arg(argv[argi+1], argv[0]);
			argi++;
		}
		else if (streq(argv[argi], "--ifs")) {
			check_arg_count(argv, argi, argc, 2);
			popts->ifs = sep_from_arg(argv[argi+1], argv[0]);
			argi++;
		}
		else if (streq(argv[argi], "--ofs")) {
			check_arg_count(argv, argi, argc, 2);
			popts->ofs = sep_from_arg(argv[argi+1], argv[0]);
			argi++;
		}
		else if (streq(argv[argi], "--repifs")) {
			popts->allow_repeat_ifs = TRUE;
		}

		else if (streq(argv[argi], "-p")) {
			popts->ifile_fmt = "nidx";
			popts->ofile_fmt = "nidx";
			popts->ifs = " ";
			popts->ofs = " ";
			popts->allow_repeat_ifs = TRUE;
		}

		else if (streq(argv[argi], "--ps")) {
			check_arg_count(argv, argi, argc, 2);
			popts->ops = sep_from_arg(argv[argi+1], argv[0]);
			popts->ips = sep_from_arg(argv[argi+1], argv[0]);
			argi++;
		}
		else if (streq(argv[argi], "--ips")) {
			check_arg_count(argv, argi, argc, 2);
			popts->ips = sep_from_arg(argv[argi+1], argv[0]);
			argi++;
		}
		else if (streq(argv[argi], "--ops")) {
			check_arg_count(argv, argi, argc, 2);
			popts->ops = sep_from_arg(argv[argi+1], argv[0]);
			argi++;
		}

		else if (streq(argv[argi], "--csv"))      { popts->ifile_fmt = popts->ofile_fmt = "csv";  }
		else if (streq(argv[argi], "--icsv"))     { popts->ifile_fmt = "csv";  }
		else if (streq(argv[argi], "--ocsv"))     { popts->ofile_fmt = "csv";  }

		else if (streq(argv[argi], "--csvlite"))  { popts->ifile_fmt = popts->ofile_fmt = "csvlite";  }
		else if (streq(argv[argi], "--icsvlite")) { popts->ifile_fmt = "csvlite";  }
		else if (streq(argv[argi], "--ocsvlite")) { popts->ofile_fmt = "csvlite";  }

		else if (streq(argv[argi], "--dkvp"))     { popts->ifile_fmt = popts->ofile_fmt = "dkvp"; }
		else if (streq(argv[argi], "--idkvp"))    { popts->ifile_fmt = "dkvp"; }
		else if (streq(argv[argi], "--odkvp"))    { popts->ofile_fmt = "dkvp"; }

		else if (streq(argv[argi], "--nidx"))     { popts->ifile_fmt = popts->ofile_fmt = "nidx"; }
		else if (streq(argv[argi], "--inidx"))    { popts->ifile_fmt = "nidx"; }
		else if (streq(argv[argi], "--onidx"))    { popts->ofile_fmt = "nidx"; }

		else if (streq(argv[argi], "--xtab"))     { popts->ifile_fmt = popts->ofile_fmt = "xtab"; }
		else if (streq(argv[argi], "--ixtab"))    { popts->ifile_fmt = "xtab"; }
		else if (streq(argv[argi], "--oxtab"))    { popts->ofile_fmt = "xtab"; }

		else if (streq(argv[argi], "--ipprint")) {
			popts->ifile_fmt        = "csvlite";
			popts->ifs              = " ";
			popts->allow_repeat_ifs = TRUE;

		}
		else if (streq(argv[argi], "--opprint")) {
			popts->ofile_fmt = "pprint";
		}
		else if (streq(argv[argi], "--pprint")) {
			popts->ifile_fmt        = "csvlite";
			popts->ifs              = " ";
			popts->allow_repeat_ifs = TRUE;
			popts->ofile_fmt        = "pprint";
		}
		else if (streq(argv[argi], "--right"))   {
			left_align_pprint = FALSE;
		}

		else if (streq(argv[argi], "--ofmt")) {
			check_arg_count(argv, argi, argc, 2);
			popts->ofile_fmt = argv[argi+1];
			argi++;
		}

		else if (streq(argv[argi], "--quote-all"))     { popts->oquoting = QUOTE_ALL;     }
		else if (streq(argv[argi], "--quote-none"))    { popts->oquoting = QUOTE_NONE;    }
		else if (streq(argv[argi], "--quote-minimal")) { popts->oquoting = QUOTE_MINIMAL; }
		else if (streq(argv[argi], "--quote-numeric")) { popts->oquoting = QUOTE_NUMERIC; }

		// xxx put into online help.
		else if (streq(argv[argi], "--mmap")) {
			popts->use_mmap_for_read = TRUE;
		}
		else if (streq(argv[argi], "--no-mmap")) {
			popts->use_mmap_for_read = FALSE;
		}
		else if (streq(argv[argi], "--seed")) {
			check_arg_count(argv, argi, argc, 2);
			if (sscanf(argv[argi+1], "0x%x", &rand_seed) == 1) {
				have_rand_seed = TRUE;
			} else if (sscanf(argv[argi+1], "%u", &rand_seed) == 1) {
				have_rand_seed = TRUE;
			} else {
				main_usage(argv[0], 1);
			}
			argi++;
		}

		else
			nusage(argv[0], argv[argi]);
	}

	lhmss_t* default_rses = get_default_rses();
	lhmss_t* default_fses = get_default_fses();
	lhmss_t* default_pses = get_default_pses();
	lhmsi_t* default_repeat_ifses = get_default_repeat_ifses();
	lhmsi_t* default_repeat_ipses = get_default_repeat_ipses();

	if (popts->irs == NULL)
		popts->irs = lhmss_get(default_rses, popts->ifile_fmt);
	if (popts->ifs == NULL)
		popts->ifs = lhmss_get(default_fses, popts->ifile_fmt);
	if (popts->ips == NULL)
		popts->ips = lhmss_get(default_pses, popts->ifile_fmt);

	if (popts->allow_repeat_ifs == NEITHER_TRUE_NOR_FALSE)
		popts->allow_repeat_ifs = lhmsi_get(default_repeat_ifses, popts->ifile_fmt);
	if (popts->allow_repeat_ips == NEITHER_TRUE_NOR_FALSE)
		popts->allow_repeat_ips = lhmsi_get(default_repeat_ipses, popts->ifile_fmt);

	if (popts->ors == NULL)
		popts->ors = lhmss_get(default_rses, popts->ofile_fmt);
	if (popts->ofs == NULL)
		popts->ofs = lhmss_get(default_fses, popts->ofile_fmt);
	if (popts->ops == NULL)
		popts->ops = lhmss_get(default_pses, popts->ofile_fmt);

	if (popts->irs == NULL) {
		fprintf(stderr, "%s: internal coding error detected in file %s at line %d.\n", argv[0], __FILE__, __LINE__);
		exit(1);
	}
	if (popts->ifs == NULL) {
		fprintf(stderr, "%s: internal coding error detected in file %s at line %d.\n", argv[0], __FILE__, __LINE__);
		exit(1);
	}
	if (popts->ips == NULL) {
		fprintf(stderr, "%s: internal coding error detected in file %s at line %d.\n", argv[0], __FILE__, __LINE__);
		exit(1);
	}

	if (popts->allow_repeat_ifs == NEITHER_TRUE_NOR_FALSE) {
		fprintf(stderr, "%s: internal coding error detected in file %s at line %d.\n", argv[0], __FILE__, __LINE__);
		exit(1);
	}
	if (popts->allow_repeat_ips == NEITHER_TRUE_NOR_FALSE) {
		fprintf(stderr, "%s: internal coding error detected in file %s at line %d.\n", argv[0], __FILE__, __LINE__);
		exit(1);
	}

	if (popts->ors == NULL) {
		fprintf(stderr, "%s: internal coding error detected in file %s at line %d.\n", argv[0], __FILE__, __LINE__);
		exit(1);
	}
	if (popts->ofs == NULL) {
		fprintf(stderr, "%s: internal coding error detected in file %s at line %d.\n", argv[0], __FILE__, __LINE__);
		exit(1);
	}
	if (popts->ops == NULL) {
		fprintf(stderr, "%s: internal coding error detected in file %s at line %d.\n", argv[0], __FILE__, __LINE__);
		exit(1);
	}

	if (streq(popts->ofile_fmt, "pprint") && strlen(popts->ofs) != 1) {
		fprintf(stderr, "%s: OFS for PPRINT format must be single-character; got \"%s\".\n",
			argv[0], popts->ofs);
		return NULL;
	}
	if      (streq(popts->ofile_fmt, "dkvp"))
		popts->plrec_writer = lrec_writer_dkvp_alloc(popts->ors, popts->ofs, popts->ops);
	else if (streq(popts->ofile_fmt, "csv"))
		popts->plrec_writer = lrec_writer_csv_alloc(popts->ors, popts->ofs, popts->oquoting);
	else if (streq(popts->ofile_fmt, "csvlite"))
		popts->plrec_writer = lrec_writer_csvlite_alloc(popts->ors, popts->ofs);
	else if (streq(popts->ofile_fmt, "nidx"))
		popts->plrec_writer = lrec_writer_nidx_alloc(popts->ors, popts->ofs);
	else if (streq(popts->ofile_fmt, "xtab"))
		popts->plrec_writer = lrec_writer_xtab_alloc(popts->ofs, popts->ops);
	else if (streq(popts->ofile_fmt, "pprint"))
		popts->plrec_writer = lrec_writer_pprint_alloc(popts->ors, popts->ofs[0], left_align_pprint);
	else {
		main_usage(argv[0], 1);
	}

	if ((argc - argi) < 1) {
		main_usage(argv[0], 1);
	}

	popts->pmapper_list = sllv_alloc();
	while (TRUE) {
		check_arg_count(argv, argi, argc, 1);
		char* verb = argv[argi];

		mapper_setup_t* pmapper_setup = look_up_mapper_setup(verb);
		if (pmapper_setup == NULL) {
			fprintf(stderr, "%s: verb \"%s\" not found. Please use \"%s --help\" for a list.\n",
				argv[0], verb, argv[0]);
			exit(1);
		}

		if ((argc - argi) >= 2) {
			if (streq(argv[argi+1], "-h") || streq(argv[argi+1], "--help")) {
				pmapper_setup->pusage_func(argv[0], verb);
				exit(0);
			}
		}

		// It's up to the parse func to print its usage on CLI-parse failure.
		mapper_t* pmapper = pmapper_setup->pparse_func(&argi, argc, argv);
		if (pmapper == NULL) {
			exit(1);
		}
		sllv_add(popts->pmapper_list, pmapper);

		// xxx cmt
		if (argi >= argc || !streq(argv[argi], "then"))
			break;
		argi++;
	}

	popts->filenames = &argv[argi];

	// No filenames means read from standard input, and standard input cannot be mmapped.
	if (argi == argc)
		popts->use_mmap_for_read = FALSE;

	popts->plrec_reader = lrec_reader_alloc(popts->ifile_fmt, popts->use_mmap_for_read,
		popts->irs, popts->ifs, popts->allow_repeat_ifs, popts->ips, popts->allow_repeat_ips);
	if (popts->plrec_reader == NULL)
		main_usage(argv[0], 1);

	if (have_rand_seed) {
		mtrand_init(rand_seed);
	} else {
		mtrand_init_default();
	}

	return popts;
}