mirror of
https://github.com/akuker/RASCSI.git
synced 2024-06-10 17:29:35 +00:00
Reimplement ParseArgs() with getopt()
The command-line interface is intended to be equivalent. For example, consider this command: $ rascsi -ID0 zero.hda -ID1 one.hda This is no longer two pairs (ID0, zero.hda), (ID1, one.hda), but a sequence of commands: * -I: next disk is SCSI (not SASI) * -D 0: next disk is device 0 * zero.hda: set up disk * -I: next disk is SCSI (not SASI) * -D 1: next disk is device 1 * one.hda: set up disk Since SCSI is [now] the default, this could equivalently be: $ rascsi -d 0 zero.hda -d 1 one.hda
This commit is contained in:
parent
8b340fde89
commit
46e03a4026
BIN
src/raspberrypi/foo.hda
Normal file
BIN
src/raspberrypi/foo.hda
Normal file
Binary file not shown.
|
@ -606,6 +606,13 @@ BOOL ProcessCmd(FILE *fp, int id, int un, int cmd, int type, char *file)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool has_suffix(const char* string, const char* suffix) {
|
||||||
|
int string_len = strlen(string);
|
||||||
|
int suffix_len = strlen(suffix);
|
||||||
|
return (string_len >= suffix_len)
|
||||||
|
&& (xstrcasecmp(string + (string_len - suffix_len), suffix) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
//---------------------------------------------------------------------------
|
//---------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
// Argument Parsing
|
// Argument Parsing
|
||||||
|
@ -791,158 +798,94 @@ parse_error:
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
BOOL ParseArgument(int argc, char* argv[])
|
bool ParseArgument(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
int i;
|
int id = -1;
|
||||||
int id;
|
bool is_sasi = false;
|
||||||
int un;
|
int max_id = 7;
|
||||||
int type;
|
|
||||||
char *argID;
|
|
||||||
char *argPath;
|
|
||||||
int len;
|
|
||||||
char *ext;
|
|
||||||
|
|
||||||
// If the ID and path are not specified, the processing is interrupted
|
int opt;
|
||||||
if (argc < 3) {
|
while ((opt = getopt(argc, argv, "-IiHhD:d:")) != -1) {
|
||||||
return TRUE;
|
switch (opt) {
|
||||||
}
|
case 'I':
|
||||||
i = 1;
|
case 'i':
|
||||||
argc--;
|
is_sasi = false;
|
||||||
|
max_id = 7;
|
||||||
|
id = -1;
|
||||||
|
continue;
|
||||||
|
|
||||||
// Start Decoding
|
case 'H':
|
||||||
|
case 'h':
|
||||||
|
is_sasi = true;
|
||||||
|
max_id = 15;
|
||||||
|
id = -1;
|
||||||
|
continue;
|
||||||
|
|
||||||
while (TRUE) {
|
case 'D':
|
||||||
if (argc < 2) {
|
case 'd': {
|
||||||
break;
|
char* end;
|
||||||
}
|
id = strtol(optarg, &end, 10);
|
||||||
|
if (*end || (id < 0) || (max_id < id)) {
|
||||||
argc -= 2;
|
fprintf(stderr, "%s: invalid %s (0-%d)\n",
|
||||||
|
optarg, is_sasi ? "HD" : "ID", max_id);
|
||||||
// Get the ID and Path
|
return false;
|
||||||
argID = argv[i++];
|
}
|
||||||
argPath = argv[i++];
|
continue;
|
||||||
|
|
||||||
// Check if the argument is invalid
|
|
||||||
if (argID[0] != '-') {
|
|
||||||
FPRT(stderr,
|
|
||||||
"Error : Invalid argument(-IDn or -HDn) [%s]\n", argID);
|
|
||||||
goto parse_error;
|
|
||||||
}
|
|
||||||
argID++;
|
|
||||||
|
|
||||||
if (strlen(argID) == 3 && xstrncasecmp(argID, "id", 2) == 0) {
|
|
||||||
// ID or ID Format
|
|
||||||
|
|
||||||
// Check that the ID number is valid (0-7)
|
|
||||||
if (argID[2] < '0' || argID[2] > '7') {
|
|
||||||
FPRT(stderr,
|
|
||||||
"Error : Invalid argument(IDn n=0-7) [%c]\n", argID[2]);
|
|
||||||
goto parse_error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// The ID unit is good
|
default:
|
||||||
id = argID[2] - '0';
|
return false;
|
||||||
un = 0;
|
|
||||||
} else if (xstrncasecmp(argID, "hd", 2) == 0) {
|
|
||||||
// HD or HD format
|
|
||||||
|
|
||||||
if (strlen(argID) == 3) {
|
case 1:
|
||||||
// Check that the HD number is valid (0-9)
|
break;
|
||||||
if (argID[2] < '0' || argID[2] > '9') {
|
|
||||||
FPRT(stderr,
|
|
||||||
"Error : Invalid argument(HDn n=0-15) [%c]\n", argID[2]);
|
|
||||||
goto parse_error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// ID was confirmed
|
|
||||||
id = (argID[2] - '0') / UnitNum;
|
|
||||||
un = (argID[2] - '0') % UnitNum;
|
|
||||||
} else if (strlen(argID) == 4) {
|
|
||||||
// Check that the HD number is valid (10-15)
|
|
||||||
if (argID[2] != '1' || argID[3] < '0' || argID[3] > '5') {
|
|
||||||
FPRT(stderr,
|
|
||||||
"Error : Invalid argument(HDn n=0-15) [%c]\n", argID[2]);
|
|
||||||
goto parse_error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// The ID unit is good - create the id and unit number
|
|
||||||
id = ((argID[3] - '0') + 10) / UnitNum;
|
|
||||||
un = ((argID[3] - '0') + 10) % UnitNum;
|
|
||||||
} else {
|
|
||||||
FPRT(stderr,
|
|
||||||
"Error : Invalid argument(IDn or HDn) [%s]\n", argID);
|
|
||||||
goto parse_error;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
FPRT(stderr,
|
|
||||||
"Error : Invalid argument(IDn or HDn) [%s]\n", argID);
|
|
||||||
goto parse_error;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Skip if there is already an active device
|
if (id < 0) {
|
||||||
if (disk[id * UnitNum + un] &&
|
fprintf(stderr, "%s: ID not specified\n", optarg);
|
||||||
!disk[id * UnitNum + un]->IsNULL()) {
|
return false;
|
||||||
continue;
|
} else if (disk[id] && !disk[id]->IsNULL()) {
|
||||||
|
fprintf(stderr, "%d: duplicate ID\n", id);
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Initialize device type
|
char* path = optarg;
|
||||||
type = -1;
|
int type = -1;
|
||||||
|
if (has_suffix(path, ".hdf")
|
||||||
// Check ethernet and host bridge
|
|| has_suffix(path, ".hds")
|
||||||
if (xstrcasecmp(argPath, "bridge") == 0) {
|
|| has_suffix(path, ".hdn")
|
||||||
|
|| has_suffix(path, ".hdi")
|
||||||
|
|| has_suffix(path, ".hda")
|
||||||
|
|| has_suffix(path, ".nhd")) {
|
||||||
|
type = 0;
|
||||||
|
} else if (has_suffix(path, ".mos")) {
|
||||||
|
type = 2;
|
||||||
|
} else if (has_suffix(path, ".iso")) {
|
||||||
|
type = 3;
|
||||||
|
} else if (xstrcasecmp(path, "bridge") == 0) {
|
||||||
type = 4;
|
type = 4;
|
||||||
} else {
|
} else {
|
||||||
// Check the path length
|
// Cannot determine the file type
|
||||||
len = strlen(argPath);
|
fprintf(stderr,
|
||||||
if (len < 5) {
|
"%s: unknown file extension\n", path);
|
||||||
FPRT(stderr,
|
return false;
|
||||||
"Error : Invalid argument(File path is short) [%s]\n",
|
}
|
||||||
argPath);
|
|
||||||
goto parse_error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Does the file have an extension?
|
int un = 0;
|
||||||
if (argPath[len - 4] != '.') {
|
if (is_sasi) {
|
||||||
FPRT(stderr,
|
un = id % UnitNum;
|
||||||
"Error : Invalid argument(No extension) [%s]\n", argPath);
|
id /= UnitNum;
|
||||||
goto parse_error;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Figure out what the type is
|
|
||||||
ext = &argPath[len - 3];
|
|
||||||
if (xstrcasecmp(ext, "hdf") == 0 ||
|
|
||||||
xstrcasecmp(ext, "hds") == 0 ||
|
|
||||||
xstrcasecmp(ext, "hdn") == 0 ||
|
|
||||||
xstrcasecmp(ext, "hdi") == 0 || xstrcasecmp(ext, "nhd") == 0 ||
|
|
||||||
xstrcasecmp(ext, "hda") == 0) {
|
|
||||||
// HD(SASI/SCSI)
|
|
||||||
type = 0;
|
|
||||||
} else if (strcasecmp(ext, "mos") == 0) {
|
|
||||||
// MO
|
|
||||||
type = 2;
|
|
||||||
} else if (strcasecmp(ext, "iso") == 0) {
|
|
||||||
// CD
|
|
||||||
type = 3;
|
|
||||||
} else {
|
|
||||||
// Cannot determine the file type
|
|
||||||
FPRT(stderr,
|
|
||||||
"Error : Invalid argument(file type) [%s]\n", ext);
|
|
||||||
goto parse_error;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Execute the command
|
// Execute the command
|
||||||
if (!ProcessCmd(stderr, id, un, 0, type, argPath)) {
|
if (!ProcessCmd(stderr, id, un, 0, type, path)) {
|
||||||
goto parse_error;
|
return false;
|
||||||
}
|
}
|
||||||
|
id = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Display the device list
|
// Display the device list
|
||||||
ListDevice(stdout);
|
ListDevice(stdout);
|
||||||
return TRUE;
|
return true;
|
||||||
|
|
||||||
parse_error:
|
|
||||||
return FALSE;
|
|
||||||
}
|
}
|
||||||
#endif // BAREMETAL
|
#endif // BAREMETAL
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user