move arg parser out of bootimage.cpp

This commit is contained in:
Joshua Warner 2013-02-17 11:19:07 -07:00 committed by Joshua Warner
parent 984f987e03
commit e9be3c4e07
4 changed files with 145 additions and 100 deletions

View File

@ -1041,7 +1041,7 @@ ifeq ($(continuations),true)
asmflags += -DAVIAN_CONTINUATIONS
endif
bootimage-generator-sources = $(src)/bootimage.cpp
bootimage-generator-sources = $(src)/bootimage.cpp $(src)/util/arg-parser.cpp
ifneq ($(lzma),)
bootimage-generator-sources += $(src)/lzma-encode.cpp
endif

View File

@ -19,12 +19,16 @@
#include "binaryToObject/tools.h"
#include "lzma.h"
#include "util/arg-parser.h"
#include "util/abort.h"
// since we aren't linking against libstdc++, we must implement this
// ourselves:
extern "C" void __cxa_pure_virtual(void) { abort(); }
using namespace vm;
using namespace avian::tools;
using namespace avian::util;
namespace {
@ -1714,105 +1718,6 @@ writeBootImage(Thread* t, uintptr_t* arguments)
return 1;
}
class Arg;
class ArgParser {
public:
Arg* first;
Arg** last;
ArgParser():
first(0),
last(&first) {}
bool parse(int ac, const char** av);
void printUsage(const char* exe);
};
class Arg {
public:
Arg* next;
bool required;
const char* name;
const char* desc;
const char* value;
Arg(ArgParser& parser, bool required, const char* name, const char* desc):
next(0),
required(required),
name(name),
desc(desc),
value(0)
{
*parser.last = this;
parser.last = &next;
}
};
bool ArgParser::parse(int ac, const char** av) {
Arg* state = 0;
for(int i = 1; i < ac; i++) {
if(state) {
if(state->value) {
fprintf(stderr, "duplicate parameter %s: '%s' and '%s'\n", state->name, state->value, av[i]);
return false;
}
state->value = av[i];
state = 0;
} else {
if(av[i][0] != '-') {
fprintf(stderr, "expected -parameter\n");
return false;
}
bool found = false;
for(Arg* arg = first; arg; arg = arg->next) {
if(::strcmp(arg->name, &av[i][1]) == 0) {
found = true;
if (arg->desc == 0) {
arg->value = "true";
} else {
state = arg;
}
}
}
if (not found) {
fprintf(stderr, "unrecognized parameter %s\n", av[i]);
return false;
}
}
}
if(state) {
fprintf(stderr, "expected argument after -%s\n", state->name);
return false;
}
for(Arg* arg = first; arg; arg = arg->next) {
if(arg->required && !arg->value) {
fprintf(stderr, "expected value for %s\n", arg->name);
return false;
}
}
return true;
}
void ArgParser::printUsage(const char* exe) {
fprintf(stderr, "usage:\n%s \\\n", exe);
for(Arg* arg = first; arg; arg = arg->next) {
const char* lineEnd = arg->next ? " \\" : "";
if(arg->required) {
fprintf(stderr, " -%s\t%s%s\n", arg->name, arg->desc, lineEnd);
} else if (arg->desc) {
fprintf(stderr, " [-%s\t%s]%s\n", arg->name, arg->desc, lineEnd);
} else {
fprintf(stderr, " [-%s]%s\n", arg->name, lineEnd);
}
}
}
char*
myStrndup(const char* src, unsigned length)
{

94
src/util/arg-parser.cpp Normal file
View File

@ -0,0 +1,94 @@
/* Copyright (c) 2008-2012, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
#include <stdio.h>
#include <string.h>
#include "util/arg-parser.h"
namespace avian {
namespace util {
Arg::Arg(ArgParser& parser, bool required, const char* name, const char* desc):
next(0),
required(required),
name(name),
desc(desc),
value(0)
{
*parser.last = this;
parser.last = &next;
}
bool ArgParser::parse(int ac, const char** av) {
Arg* state = 0;
for(int i = 1; i < ac; i++) {
if(state) {
if(state->value) {
fprintf(stderr, "duplicate parameter %s: '%s' and '%s'\n", state->name, state->value, av[i]);
return false;
}
state->value = av[i];
state = 0;
} else {
if(av[i][0] != '-') {
fprintf(stderr, "expected -parameter\n");
return false;
}
bool found = false;
for(Arg* arg = first; arg; arg = arg->next) {
if(strcmp(arg->name, &av[i][1]) == 0) {
found = true;
if (arg->desc == 0) {
arg->value = "true";
} else {
state = arg;
}
}
}
if (not found) {
fprintf(stderr, "unrecognized parameter %s\n", av[i]);
return false;
}
}
}
if(state) {
fprintf(stderr, "expected argument after -%s\n", state->name);
return false;
}
for(Arg* arg = first; arg; arg = arg->next) {
if(arg->required && !arg->value) {
fprintf(stderr, "expected value for %s\n", arg->name);
return false;
}
}
return true;
}
void ArgParser::printUsage(const char* exe) {
fprintf(stderr, "usage:\n%s \\\n", exe);
for(Arg* arg = first; arg; arg = arg->next) {
const char* lineEnd = arg->next ? " \\" : "";
if(arg->required) {
fprintf(stderr, " -%s\t%s%s\n", arg->name, arg->desc, lineEnd);
} else if (arg->desc) {
fprintf(stderr, " [-%s\t%s]%s\n", arg->name, arg->desc, lineEnd);
} else {
fprintf(stderr, " [-%s]%s\n", arg->name, lineEnd);
}
}
}
} // namespace util
} // namespace avian

46
src/util/arg-parser.h Normal file
View File

@ -0,0 +1,46 @@
/* Copyright (c) 2008-2011, Avian Contributors
Permission to use, copy, modify, and/or distribute this software
for any purpose with or without fee is hereby granted, provided
that the above copyright notice and this permission notice appear
in all copies.
There is NO WARRANTY for this software. See license.txt for
details. */
#ifndef AVIAN_UTIL_ARG_PARSER_H
#define AVIAN_UTIL_ARG_PARSER_H
namespace avian {
namespace util {
class Arg;
class ArgParser {
public:
Arg* first;
Arg** last;
ArgParser();
bool parse(int ac, const char** av);
void printUsage(const char* exe);
};
class Arg {
public:
Arg* next;
bool required;
const char* name;
const char* desc;
const char* value;
Arg(ArgParser& parser, bool required, const char* name, const char* desc);
};
} // namespace avian
} // namespace util
#endif // AVIAN_UTIL_ARG_PARSER_H