Skip to content

Commit

Permalink
Added CmdArgs and -Override to the grammar, to allow setting some arg…
Browse files Browse the repository at this point in the history
…s there; Made cg-untrace protect ID and R tags
  • Loading branch information
TinoDidriksen committed Apr 18, 2024
1 parent 3ddbcba commit e87edf5
Show file tree
Hide file tree
Showing 20 changed files with 470 additions and 502 deletions.
287 changes: 96 additions & 191 deletions include/uoptions.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -19,69 +19,26 @@
#pragma once
#ifndef c6d28b7452ec699b_UOPTIONS_H__
#define c6d28b7452ec699b_UOPTIONS_H__
namespace Options {

/* This should usually be called before calling u_parseArgs */
/*#if defined(OS390) && (U_CHARSET_FAMILY == U_ASCII_FAMILY)*/
/* translate args from EBCDIC to ASCII */
/*# define U_MAIN_INIT_ARGS(argc, argv) __argvtoascii_a(argc, argv)*/
/*#elif defined(XP_MAC_CONSOLE)*/
#if defined(XP_MAC_CONSOLE)
# include <console.h>
/* Get the arguments from the GUI, since old Macs don't have a console Window. */
# define U_MAIN_INIT_ARGS(argc, argv) argc = ccommand((char***)&argv)
#else
/* Normally we do nothing. */
# define U_MAIN_INIT_ARGS(argc, argv)
#endif

#include <string.h>
#include <string>
#include <cstdint>


/* forward declarations for the function declaration */
struct UOption;
typedef struct UOption UOption;

/* function to be called for a command line option */
typedef int UOptionFn(void *context, UOption *option);
namespace Options {

/* values of UOption.hasArg */
enum { UOPT_NO_ARG, UOPT_REQUIRES_ARG, UOPT_OPTIONAL_ARG };
enum : uint8_t { UOPT_NO_ARG, UOPT_REQUIRES_ARG, UOPT_OPTIONAL_ARG };

/* structure describing a command line option */
struct UOption {
const char *longName; /* "foo" for --foo */
const char *value; /* output placeholder, will point to the argument string, if any */
UOptionFn *optionFn; /* function to be called when this option occurs */
void *context; /* parameter for the function */
char shortName; /* 'f' for -f */
char hasArg; /* enum value: option takes no/requires/may have argument */
char doesOccur; /* boolean for "this one occured" */
const char *description; /* description of the option (added by Tino Didriksen <mail@tinodidriksen.com>) */
const char *longName = nullptr; /* "foo" for --foo */
char shortName = 0; /* 'f' for -f */
uint8_t hasArg = UOPT_NO_ARG; /* enum value: option takes no/requires/may have argument */
std::string description; /* description of the option (added by Tino Didriksen <mail@tinodidriksen.com>) */
bool doesOccur = false; /* boolean for "this one occured" */
std::string value; /* output placeholder, will point to the argument string, if any */
};

/* macro for an entry in a declaration of UOption[] */
#define UOPTION_DEF(longName, shortName, hasArg) \
UOption{ longName, NULL, NULL, NULL, shortName, hasArg, 0, NULL}
/* added by Tino Didriksen <mail@tinodidriksen.com> */
#define UOPTION_DEF_D(longName, shortName, hasArg, desc) \
UOption{ longName, NULL, NULL, NULL, shortName, hasArg, 0, desc}

/* ICU Tools option definitions */
#define UOPTION_HELP_H UOPTION_DEF("help", 'h', UOPT_NO_ARG)
#define UOPTION_HELP_QUESTION_MARK UOPTION_DEF("help", '?', UOPT_NO_ARG)
#define UOPTION_VERBOSE UOPTION_DEF("verbose", 'v', UOPT_NO_ARG)
#define UOPTION_QUIET UOPTION_DEF("quiet", 'q', UOPT_NO_ARG)
#define UOPTION_VERSION UOPTION_DEF("version", 'V', UOPT_NO_ARG)
#define UOPTION_COPYRIGHT UOPTION_DEF("copyright", 'c', UOPT_NO_ARG)

#define UOPTION_DESTDIR UOPTION_DEF("destdir", 'd', UOPT_REQUIRES_ARG)
#define UOPTION_SOURCEDIR UOPTION_DEF("sourcedir", 's', UOPT_REQUIRES_ARG)
#define UOPTION_ENCODING UOPTION_DEF("encoding", 'e', UOPT_REQUIRES_ARG)
#define UOPTION_ICUDATADIR UOPTION_DEF("icudatadir", 'i', UOPT_REQUIRES_ARG)
#define UOPTION_WRITE_JAVA UOPTION_DEF("write-java", 'j', UOPT_OPTIONAL_ARG)
#define UOPTION_PACKAGE_NAME UOPTION_DEF("package-name", 'p', UOPT_REQUIRES_ARG)
#define UOPTION_BUNDLE_NAME UOPTION_DEF("bundle-name", 'b', UOPT_REQUIRES_ARG)

/**
* C Command line argument parser.
*
Expand Down Expand Up @@ -138,156 +95,104 @@ struct UOption {
* @param argv This parameter is modified
* @param options This parameter is modified
*/
int u_parseArgs(int argc, char* argv[],
int optionCount, UOption options[]);

#define uprv_strcpy(dst, src) U_STANDARD_CPP_NAMESPACE strcpy(dst, src)
#define uprv_strncpy(dst, src, size) U_STANDARD_CPP_NAMESPACE strncpy(dst, src, size)
#define uprv_strlen(str) U_STANDARD_CPP_NAMESPACE strlen(str)
#define uprv_strcmp(s1, s2) U_STANDARD_CPP_NAMESPACE strcmp(s1, s2)
#define uprv_strncmp(s1, s2, n) U_STANDARD_CPP_NAMESPACE strncmp(s1, s2, n)
#define uprv_strcat(dst, src) U_STANDARD_CPP_NAMESPACE strcat(dst, src)
#define uprv_strncat(dst, src, n) U_STANDARD_CPP_NAMESPACE strncat(dst, src, n)
#define uprv_strchr(s, c) U_STANDARD_CPP_NAMESPACE strchr(s, c)
#define uprv_strstr(s, c) U_STANDARD_CPP_NAMESPACE strstr(s, c)
#define uprv_strrchr(s, c) U_STANDARD_CPP_NAMESPACE strrchr(s, c)

#if U_CHARSET_FAMILY==U_ASCII_FAMILY
# define uprv_tolower uprv_asciitolower
#elif U_CHARSET_FAMILY==U_EBCDIC_FAMILY
# define uprv_tolower uprv_ebcdictolower
#else
# error U_CHARSET_FAMILY is not valid
#endif

#define uprv_strtod(source, end) U_STANDARD_CPP_NAMESPACE strtod(source, end)
#define uprv_strtoul(str, end, base) U_STANDARD_CPP_NAMESPACE strtoul(str, end, base)
#define uprv_strtol(str, end, base) U_STANDARD_CPP_NAMESPACE strtol(str, end, base)
#if !defined(uprv_stricmp) || !defined(uprv_strnicmp)
#ifdef U_WINDOWS
# if defined(__BORLANDC__)
# define uprv_stricmp(str1, str2) U_STANDARD_CPP_NAMESPACE stricmp(str1, str2)
# define uprv_strnicmp(str1, str2, n) U_STANDARD_CPP_NAMESPACE strnicmp(str1, str2, n)
# else
# define uprv_stricmp(str1, str2) U_STANDARD_CPP_NAMESPACE _stricmp(str1, str2)
# define uprv_strnicmp(str1, str2, n) U_STANDARD_CPP_NAMESPACE _strnicmp(str1, str2, n)
# endif
#elif defined(POSIX)
# define uprv_stricmp(str1, str2) U_STANDARD_CPP_NAMESPACE strcasecmp(str1, str2)
# define uprv_strnicmp(str1, str2, n) U_STANDARD_CPP_NAMESPACE strncasecmp(str1, str2, n)
#else
# define uprv_stricmp(str1, str2) T_CString_stricmp(str1, str2)
# define uprv_strnicmp(str1, str2, n) T_CString_strnicmp(str1, str2, n)
#endif
#endif

/* Conversion from a digit to the character with radix base from 2-19 */
/* May need to use U_UPPER_ORDINAL*/
#define T_CString_itosOffset(a) ((a)<=9?('0'+(a)):('A'+(a)-10))

inline int u_parseArgs(int argc, char* argv[], int optionCount, UOption options[]) {
char *arg;
int i = 1, remaining = 1;
char c, stopOptions = 0;

while (i < argc) {
arg = argv[i];
if (!stopOptions && *arg == '-' && (c = arg[1]) != 0) {
/* process an option */
UOption *option = NULL;
arg += 2;
if (c == '-') {
/* process a long option */
if (*arg == 0) {
/* stop processing options after "--" */
stopOptions = 1;
char *arg;
int i = 1, remaining = 1;
char c, stopOptions = 0;

while (i < argc) {
arg = argv[i];
if (!stopOptions && *arg == '-' && (c = arg[1]) != 0) {
/* process an option */
UOption *option = NULL;
arg += 2;
if (c == '-') {
/* process a long option */
if (*arg == 0) {
/* stop processing options after "--" */
stopOptions = 1;
}
else {
/* search for the option string */
int j;
for (j = 0; j < optionCount; ++j) {
if (options[j].longName && strcmp(arg, options[j].longName) == 0) {
option = options + j;
break;
}
}
if (option == NULL) {
/* no option matches */
return -i;
}
else {
/* search for the option string */
int j;
for (j = 0; j < optionCount; ++j) {
if (options[j].longName && uprv_strcmp(arg, options[j].longName) == 0) {
option = options + j;
break;
}
option->doesOccur = 1;

if (option->hasArg != UOPT_NO_ARG) {
/* parse the argument for the option, if any */
if (i + 1 < argc && !(argv[i + 1][0] == '-' && argv[i + 1][1] != 0)) {
/* argument in the next argv[], and there is not an option in there */
option->value = argv[++i];
}
if (option == NULL) {
/* no option matches */
else if (option->hasArg == UOPT_REQUIRES_ARG) {
/* there is no argument, but one is required: return with error */
return -i;
}
option->doesOccur = 1;

if (option->hasArg != UOPT_NO_ARG) {
/* parse the argument for the option, if any */
if (i + 1 < argc && !(argv[i + 1][0] == '-' && argv[i + 1][1] != 0)) {
/* argument in the next argv[], and there is not an option in there */
option->value = argv[++i];
}
else if (option->hasArg == UOPT_REQUIRES_ARG) {
/* there is no argument, but one is required: return with error */
return -i;
}
}
}
}
else {
/* process one or more short options */
do {
/* search for the option letter */
int j;
for (j = 0; j < optionCount; ++j) {
if (c == options[j].shortName) {
option = options + j;
break;
}
}
else {
/* process one or more short options */
do {
/* search for the option letter */
int j;
for (j = 0; j < optionCount; ++j) {
if (c == options[j].shortName) {
option = options + j;
break;
}
if (option == NULL) {
/* no option matches */
return -i;
}
if (option == NULL) {
/* no option matches */
return -i;
}
option->doesOccur = 1;

if (option->hasArg != UOPT_NO_ARG) {
/* parse the argument for the option, if any */
if (*arg != 0) {
/* argument following in the same argv[] */
option->value = arg;
/* do not process the rest of this arg as option letters */
break;
}
option->doesOccur = 1;

if (option->hasArg != UOPT_NO_ARG) {
/* parse the argument for the option, if any */
if (*arg != 0) {
/* argument following in the same argv[] */
option->value = arg;
/* do not process the rest of this arg as option letters */
break;
}
else if (i + 1 < argc && !(argv[i + 1][0] == '-' && argv[i + 1][1] != 0)) {
/* argument in the next argv[], and there is not an option in there */
option->value = argv[++i];
/* this break is redundant because we know that *arg==0 */
break;
}
else if (option->hasArg == UOPT_REQUIRES_ARG) {
/* there is no argument, but one is required: return with error */
return -i;
}
else if (i + 1 < argc && !(argv[i + 1][0] == '-' && argv[i + 1][1] != 0)) {
/* argument in the next argv[], and there is not an option in there */
option->value = argv[++i];
/* this break is redundant because we know that *arg==0 */
break;
}
else if (option->hasArg == UOPT_REQUIRES_ARG) {
/* there is no argument, but one is required: return with error */
return -i;
}
}

/* get the next option letter */
option = NULL;
c = *arg++;
} while (c != 0);
}

if (option != 0 && option->optionFn != 0 && option->optionFn(option->context, option) < 0) {
/* the option function was called and returned an error */
return -i;
}

/* go to next argv[] */
++i;
}
else {
/* move a non-option up in argv[] */
argv[remaining++] = arg;
++i;
/* get the next option letter */
option = NULL;
c = *arg++;
} while (c != 0);
}

/* go to next argv[] */
++i;
}
else {
/* move a non-option up in argv[] */
argv[remaining++] = arg;
++i;
}
return remaining;
}
return remaining;
}

}
Expand Down
2 changes: 2 additions & 0 deletions scripts/cg-untrace
Original file line number Diff line number Diff line change
Expand Up @@ -36,9 +36,11 @@ while (<STDIN>) {
}
# On readings only...
if (/^\s+"/) {
s/ (ID|R):/ x$1:/g;
# ...strip trace tags
while (s/ [-A-Z]+:[^"\s\n]+//g) {}
while (s/ (ADD|REM|SET)RELATIONS?\(\S+\):[^"\s\n]+//g) {}
s/ x(ID|R):/ $1:/g;
}
print;
}
1 change: 1 addition & 0 deletions src/AST.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ enum ASTType {
AST_Barrier,
AST_BarrierSafe,
AST_BeforeSections,
AST_CmdArgs,
AST_CompositeTag,
AST_Context,
AST_ContextMod,
Expand Down
2 changes: 1 addition & 1 deletion src/ApertiumApplicator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -848,7 +848,7 @@ void ApertiumApplicator::printReading(Reading* reading, std::ostream& output) {
break;
}
else {
uppercaseseen++;
++uppercaseseen;
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions src/BinaryGrammar.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ enum : uint32_t {
BINF_ADDCOHORT_ATTACH = (1 << 17),
};

constexpr uint32_t BIN_REV_ANCIENT = 10297;
constexpr uint32_t BIN_REV_CMDARGS = 13898;

class BinaryGrammar : public IGrammarParser {
public:
BinaryGrammar(Grammar& result, std::ostream& ux_err);
Expand Down
Loading

0 comments on commit e87edf5

Please sign in to comment.