blob: da4b5e6db1caa4b70709bd959910042bbf8ef99b [file] [log] [blame]
/*
* *****************************************************************************
*
* Copyright 2018 Gavin D. Howard
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
* REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
* AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
* LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
* OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
* PERFORMANCE OF THIS SOFTWARE.
*
* *****************************************************************************
*
* Code for processing command-line arguments.
*
*/
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <getopt.h>
#include <status.h>
#include <vector.h>
#include <vm.h>
#include <bc.h>
#include <args.h>
const struct option bc_args_opts[] = {
{ "help", no_argument, NULL, 'h' },
{ "interactive", no_argument, NULL, 'i' },
{ "mathlib", no_argument, NULL, 'l' },
{ "quiet", no_argument, NULL, 'q' },
{ "standard", no_argument, NULL, 's' },
{ "version", no_argument, NULL, 'v' },
{ "warn", no_argument, NULL, 'w' },
{ 0, 0, 0, 0 },
};
const char* const bc_args_short_opts = "hilqsvw";
const char* const bc_args_env_name = "BC_ENV_ARGS";
BcStatus bc_args(int argc, char *argv[], unsigned int *flags, BcVec *files) {
BcStatus status;
int c, i, opt_idx;
bool do_exit;
do_exit = false;
opt_idx = c = 0;
status = BC_STATUS_SUCCESS;
optind = 1;
do {
switch (c) {
case 0:
{
// This is the case when a long option is
// found, so we don't need to do anything.
break;
}
case 'h':
{
if (printf(bc_help, argv[0]) < 0) return BC_STATUS_IO_ERR;
do_exit = true;
break;
}
case 'i':
{
(*flags) |= BC_VM_FLAG_I;
break;
}
case 'l':
{
(*flags) |= BC_VM_FLAG_L;
break;
}
case 'q':
{
(*flags) |= BC_VM_FLAG_Q;
break;
}
case 's':
{
(*flags) |= BC_VM_FLAG_S;
break;
}
case 'v':
{
if (printf("%s", bc_vm_header) < 0) return BC_STATUS_IO_ERR;
do_exit = true;
break;
}
case 'w':
{
(*flags) |= BC_VM_FLAG_W;
break;
}
// Getopt printed an error message, but we should exit.
case '?':
default:
{
return BC_STATUS_INVALID_OPTION;
}
}
c = getopt_long(argc, argv, bc_args_short_opts, bc_args_opts, &opt_idx);
} while (c != -1);
if (do_exit) exit((int) status);
if (argv[optind] && strcmp(argv[optind], "--") == 0) ++optind;
for (i = optind; !status && i < argc; ++i)
status = bc_vec_push(files, 1, argv + i);
return status;
}