191 lines
4.0 KiB
C
191 lines
4.0 KiB
C
/*
|
|
* Command-line option parsing
|
|
*/
|
|
#include "vriscv.h"
|
|
|
|
#define OPTION_SEPARATOR "-"
|
|
|
|
uint64_t memory_size = 512 * 1024 * 1024;
|
|
char* file_path;
|
|
bool gdbstub = false;
|
|
|
|
static void print_usage();
|
|
static void print_help();
|
|
static void print_version();
|
|
|
|
static int parse_long_option(char* str, char* argq);
|
|
|
|
void parse_options(int argc, char** argv)
|
|
{
|
|
for(int i = 1; i < argc; i++)
|
|
{
|
|
// Start option parsing for argument 'i'
|
|
if(argv[i][0] != *OPTION_SEPARATOR) continue;
|
|
|
|
// Check for long options
|
|
if(argv[i][1] == *OPTION_SEPARATOR)
|
|
{
|
|
i += parse_long_option(argv[i] + 2, argv[i + 1]);
|
|
continue;
|
|
}
|
|
|
|
// Parse short options
|
|
int k = 1;
|
|
while(argv[i][k])
|
|
{
|
|
switch(argv[i][k])
|
|
{
|
|
case 'h':
|
|
case '?':
|
|
{
|
|
print_help();
|
|
exit(0);
|
|
}
|
|
case 'v':
|
|
{
|
|
print_version();
|
|
exit(0);
|
|
}
|
|
case 'm':
|
|
{
|
|
// First try to convert next chars into int (ex. -m512)
|
|
char* end;
|
|
memory_size = strtol(&argv[i][k + 1], &end, 10);
|
|
if(*end != '\0' || end == &argv[i][k + 1])
|
|
{
|
|
if(argv[i][k + 1])
|
|
{
|
|
fprintf(stderr, "Error: Option -m needs an argument, but you used -m in a group of options without an integer next to it\n");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
// Try to parse next arg as integer
|
|
if(argc <= i + 1)
|
|
{
|
|
fprintf(stderr, "Error: Option " OPTION_SEPARATOR "m needs an argument\n");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
memory_size = strtol(argv[i + 1], &end, 10);
|
|
if(*end != '\0')
|
|
{
|
|
fprintf(stderr, "Error: Invalid argument '%s' for option " OPTION_SEPARATOR "m\n", argv[i + 1]);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
else
|
|
{
|
|
i++;
|
|
k = strlen(argv[i]) - 1;
|
|
}
|
|
}
|
|
else k += (end - &argv[i][k + 1]);
|
|
|
|
if(memory_size <= 0)
|
|
{
|
|
fprintf(stderr, "Error: Memory size needs to be > 0\n");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
if(memory_size > 4096)
|
|
{
|
|
fprintf(stderr, "Error: Cannot address more than 4 GiB of memory on 32-bits !\n");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
memory_size *= 1024 * 1024;
|
|
|
|
break;
|
|
}
|
|
case 's':
|
|
{
|
|
gdbstub = true;
|
|
break;
|
|
}
|
|
default:
|
|
{
|
|
fprintf(stderr, "Error: Unknown short option -%c\n", argv[i][k]);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
}
|
|
k++;
|
|
}
|
|
}
|
|
|
|
if(argc <= 1)
|
|
{
|
|
print_usage();
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
else file_path = argv[argc - 1];
|
|
}
|
|
|
|
static int parse_long_option(char* str, char* argq)
|
|
{
|
|
if(strcmp(str, "help") == 0)
|
|
{
|
|
print_help();
|
|
exit(0);
|
|
}
|
|
else if(strcmp(str, "version") == 0)
|
|
{
|
|
print_version();
|
|
exit(0);
|
|
}
|
|
else if(strcmp(str, "memory") == 0)
|
|
{
|
|
if(argq == NULL)
|
|
{
|
|
fprintf(stderr, "Error: No argument given for option " OPTION_SEPARATOR "-memory\n");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
// Convert argument to integer
|
|
char* end;
|
|
memory_size = strtol(argq, &end, 10);
|
|
if(*end != '\0')
|
|
{
|
|
fprintf(stderr, "Error: Invalid argument '%s' for option " OPTION_SEPARATOR "-memory\n", argq);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
|
if(memory_size > 4096)
|
|
{
|
|
fprintf(stderr, "Error: Cannot address more than 4 GiB of memory on 32-bits !\n");
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
memory_size *= 1024 * 1024;
|
|
|
|
return 1;
|
|
}
|
|
else if(strcmp(str, "gdb-stub") == 0)
|
|
{
|
|
gdbstub = true;
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
fprintf(stderr, "Error: Unknown long option " OPTION_SEPARATOR OPTION_SEPARATOR "%s\n", str);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
}
|
|
|
|
static void print_usage()
|
|
{
|
|
printf("Usage: %s [options] <elf-file>\n", CURRENT_NAME);
|
|
}
|
|
|
|
static void print_help()
|
|
{
|
|
print_usage();
|
|
|
|
printf("Options:\n");
|
|
printf(" " OPTION_SEPARATOR "h, " OPTION_SEPARATOR "?, --help\t\tPrint this help message\n");
|
|
printf(" " OPTION_SEPARATOR "v, --version\t\t\tPrint version information\n");
|
|
printf(" " OPTION_SEPARATOR "m, --memory\t\t\tSet the simulated memory size, in MiB (max 4096)\n");
|
|
printf(" " OPTION_SEPARATOR "s, --gdb-stub\t\tLaunch a gdb stub server (remote gdb debugging)\n");
|
|
}
|
|
|
|
static void print_version()
|
|
{
|
|
printf("%s (%s) version %s\n", CURRENT_NAME, NAME, VERSION);
|
|
}
|