#include #include #include #include #include #include /* * Initial revision by JK */ static int print_value(option_help * o){ int pos = 0; if (o->arg == OPTION_OPTIONAL_ARGUMENT || o->arg == OPTION_REQUIRED_ARGUMENT){ assert(o->variable != NULL); switch(o->type){ case('F'):{ pos += printf("=%.14f ", *(double*) o->variable); break; } case('f'):{ pos += printf("=%.6f ", (double) *(float*) o->variable); break; } case('d'):{ pos += printf("=%d ", *(int*) o->variable); break; } case('H'): case('s'):{ if ( *(char**) o->variable != NULL && ((char**) o->variable)[0][0] != 0 ){ pos += printf("=%s", *(char**) o->variable); }else{ pos += printf("=STRING"); } break; } case('c'):{ pos += printf("=%c", *(char*) o->variable); break; } case('l'):{ pos += printf("=%lld", *(long long*) o->variable); break; } } } if (o->arg == OPTION_FLAG && (*(int*)o->variable) != 0){ pos += printf(" (%d)", (*(int*)o->variable)); } return pos; } static void print_help_section(option_help * args, option_value_type type, char * name){ int first; first = 1; option_help * o; for(o = args; o->shortVar != 0 || o->longVar != 0 || o->help != NULL ; o++){ if( o->shortVar == 0 && o->longVar == 0 && o->help != NULL){ printf("%-15s %s\n", "", o->help); continue; } if (o->arg == type){ if (first){ printf("\n%s\n", name); first = 0; } printf(" "); int pos = 0; if(o->shortVar != 0 && o->longVar != 0){ pos += printf("-%c, --%s", o->shortVar, o->longVar); }else if(o->shortVar != 0){ pos += printf("-%c", o->shortVar); }else if(o->longVar != 0){ pos += printf("--%s", o->longVar); } pos += print_value(o); if(o->help != NULL){ for(int i = 0 ; i < (30 - pos); i++){ printf(" "); } printf("%s", o->help); } printf("\n"); } } } void option_print_help(option_help * args, int is_plugin){ option_help * o; int optionalArgs = 0; for(o = args; o->shortVar != 0 || o->longVar != 0 ; o++){ if(o->arg != OPTION_REQUIRED_ARGUMENT){ optionalArgs = 1; } switch(o->arg){ case (OPTION_OPTIONAL_ARGUMENT): case (OPTION_FLAG):{ if(o->shortVar != 0){ printf("[-%c] ", o->shortVar); }else if(o->longVar != 0){ printf("[--%s] ", o->longVar); } break; }case (OPTION_REQUIRED_ARGUMENT):{ if(o->shortVar != 0){ printf("-%c ", o->shortVar); }else if(o->longVar != 0){ printf("--%s ", o->longVar); } break; } } } if (optionalArgs){ //printf(" [Optional Args]"); } if (! is_plugin){ printf(" -- \n"); } print_help_section(args, OPTION_REQUIRED_ARGUMENT, "Required arguments"); print_help_section(args, OPTION_FLAG, "Flags"); print_help_section(args, OPTION_OPTIONAL_ARGUMENT, "Optional arguments"); } static int print_option_value(option_help * o){ int pos = 0; if (o->arg == OPTION_OPTIONAL_ARGUMENT || o->arg == OPTION_REQUIRED_ARGUMENT){ assert(o->variable != NULL); switch(o->type){ case('F'):{ pos += printf("=%.14f ", *(double*) o->variable); break; } case('f'):{ pos += printf("=%.6f ", (double) *(float*) o->variable); break; } case('d'):{ pos += printf("=%d ", *(int*) o->variable); break; } case('H'):{ pos += printf("=HIDDEN"); break; } case('s'):{ if ( *(char**) o->variable != NULL && ((char**) o->variable)[0][0] != 0 ){ pos += printf("=%s", *(char**) o->variable); }else{ pos += printf("="); } break; } case('c'):{ pos += printf("=%c", *(char*) o->variable); break; } case('l'):{ pos += printf("=%lld", *(long long*) o->variable); break; } } }else{ //printf(" "); } return pos; } static void print_current_option_section(option_help * args, option_value_type type){ option_help * o; for(o = args; o->shortVar != 0 || o->longVar != 0 ; o++){ if (o->arg == type){ int pos = 0; if (o->arg == OPTION_FLAG && (*(int*)o->variable) == 0){ continue; } printf("\t"); if(o->shortVar != 0 && o->longVar != 0){ pos += printf("%s", o->longVar); }else if(o->shortVar != 0){ pos += printf("%c", o->shortVar); }else if(o->longVar != 0){ pos += printf("%s", o->longVar); } pos += print_option_value(o); printf("\n"); } } } void option_print_current(option_help * args){ print_current_option_section(args, OPTION_REQUIRED_ARGUMENT); print_current_option_section(args, OPTION_OPTIONAL_ARGUMENT); print_current_option_section(args, OPTION_FLAG); } int option_parse(int argc, char ** argv, option_help * args, int * printhelp){ int error = 0; int requiredArgsSeen = 0; int requiredArgsNeeded = 0; int i; for(option_help * o = args; o->shortVar != 0 || o->longVar != 0 ; o++ ){ if(o->arg == OPTION_REQUIRED_ARGUMENT){ requiredArgsNeeded++; } } for(i=1; i < argc; i++){ char * txt = argv[i]; int foundOption = 0; char * arg = strstr(txt, "="); if(arg != NULL){ arg[0] = 0; arg++; } if(strcmp(txt, "--") == 0){ // we found plugin options break; } // try to find matching option help for(option_help * o = args; o->shortVar != 0 || o->longVar != 0 || o->help != NULL ; o++ ){ if ( (strlen(txt) == 2 && txt[0] == '-' && o->shortVar == txt[1]) || (strlen(txt) > 2 && txt[0] == '-' && txt[1] == '-' && o->longVar != NULL && strcmp(txt + 2, o->longVar) == 0)){ foundOption = 1; if( o->shortVar == 0 && o->longVar == 0 && o->help != NULL){ // section continue; } // now process the option. switch(o->arg){ case (OPTION_FLAG):{ assert(o->type == 'd'); (*(int*) o->variable)++; break; } case (OPTION_OPTIONAL_ARGUMENT): case (OPTION_REQUIRED_ARGUMENT):{ // check if next is an argument if(arg == NULL){ // simply take the next value as argument i++; arg = argv[i]; } switch(o->type){ case('F'):{ *(double*) o->variable = atof(arg); break; } case('f'):{ *(float*) o->variable = atof(arg); break; } case('d'):{ *(int*) o->variable = atoi(arg); break; } case('H'): case('s'):{ (*(char **) o->variable) = strdup(arg); break; } case('c'):{ (*(char *)o->variable) = arg[0]; if(strlen(arg) > 1){ printf("Error, ignoring remainder of string for option %c (%s).\n", o->shortVar, o->longVar); } break; } case('l'):{ *(long long*) o->variable = atoll(arg); break; } } } } if(arg != NULL){ arg[-1] = '='; } if(o->arg == OPTION_REQUIRED_ARGUMENT){ requiredArgsSeen++; } break; } } if (! foundOption){ if(strcmp(txt, "-h") == 0 || strcmp(txt, "--help") == 0){ *printhelp=1; }else{ printf("Error invalid argument: %s\n", txt); error = 1; } } } if( requiredArgsSeen != requiredArgsNeeded ){ printf("Error: Missing some required arguments\n\n"); *printhelp = -1; } if(error != 0){ printf("Invalid options\n"); *printhelp = -1; } return i; }