/* CMDLINE.C number: {'$'|[{+|Ä}]['0'][{'x'|'X'}]}[digits][{'k'|'K'}] If the first character is 0 and the second character is not 'x' or 'X', the string is interpreted as an octal integer. Otherwise, it is interpreted as a decimal number. Beginnt die Zahl mit '$' oder '0x', wird die Basis 16 verwendet, bei '0' die Basis 8, sonst die Basis 10. Endet eine Zahl mit 'k' oder 'K' wird sie mit 1024 multipliziert. */ #include #include #include #include #include "cmdline.h" char cl_file_list[CL_FILE_MAX][_MAX_PATH]; int cl_file_cnt = 0; int cl_strcmp(s1, s2) char *s1; char *s2; { for(;;) { if ( *s1 == '\0' ) /* name aus der tabelle */ return 0; if ( *s2 == '\0' ) /* name von der commandline */ return -1; if ( toupper(*s1) < toupper(*s2) ) return -1; if ( toupper(*s1) > toupper(*s2) ) return 1; s1++; s2++; } } long cl_strtol( nptr, endptr ) char *nptr; char **endptr; { long res = 0L; while( isspace(*nptr) ) nptr++; if ( *nptr == '$' ) { nptr++; for(;;) { if ( *nptr >= '0' && *nptr <= '9' ) { res *= 16L; res += (long)(*nptr-'0'); } else if ( *nptr >= 'a' && *nptr <= 'f' ) { res *= 16L; res += (long)(*nptr-'a'); res += 10L; } else if ( *nptr >= 'A' && *nptr <= 'F' ) { res *= 16L; res += (long)(*nptr-'A'); res += 10L; } else { break; } nptr++; } } else { res = strtol( nptr, &nptr, 0 ); } if ( *nptr == 'k' || *nptr == 'K' ) { res *= 1024; nptr++; } if ( endptr != NULL ) *endptr = nptr; return res; } int cl_GetOptionNo(list, option) cl_entry_struct *list; char **option; { int i; if ( list == NULL || option == NULL ) return -3; while( isspace(**option) ) (*option)++; #ifdef UNIX if ( **option == '-' ) #else if ( **option == '/' || **option == '-' ) #endif { i = 0; while( list[i].typ != CL_TYP_NONE ) { if ( cl_strcmp(list[i].name, (*option)+1) == 0 ) { (*option) += 1 + strlen(list[i].name); return i; } i++; } } else { return -2; } return -1; } int cl_Convert(entry, option, is_string_space ) cl_entry_struct *entry; char **option; int is_string_space; { size_t i; switch(entry->typ) { case CL_TYP_NONE: return -1; case CL_TYP_ON: *(int *)entry->var_ptr = 1; return 1; case CL_TYP_OFF: *(int *)entry->var_ptr = 1; return 1; case CL_TYP_SET: *(long *)entry->var_ptr = (long)entry->var_size; return 1; case CL_TYP_LONG: if ( **option == '\0' ) return 0; *(long *)entry->var_ptr = cl_strtol( *option, option ); return 1; case CL_TYP_PATH: case CL_TYP_STRING: if ( **option == '\0' ) return 0; i = 0; /* if ( **option == '\"' ) (*option)++; */ for(;;) { if ( isspace(**option) && !is_string_space ) break; /* if ( **option == '\"' ) break; */ if ( **option == '\0' ) break; if ( i >= entry->var_size-1 ) break; ((char *)entry->var_ptr)[i] = **option; (*option)++; i++; } if ( i >= entry->var_size ) ((char *)entry->var_ptr)[entry->var_size-1] = '\0'; else ((char *)entry->var_ptr)[i] = '\0'; return 1; } return -1; } int cl_String(list, s) cl_entry_struct *list; char *s; { int n; if ( s == NULL ) return 0; while( *s != '\0' ) { while ( isspace(*s) ) s++; n = cl_GetOptionNo(list, &s); if ( n < 0 ) { while ( !isspace(*s) ) s++; } else { cl_Convert(list+n, &s, 1); } } return 1; } int cl_Do(list, argc, argv) cl_entry_struct *list; int argc; char **argv; { int i; int n; int ret = 1; char *s; i = 1; cl_file_cnt = 0; while( argv[i] != NULL ) { s = argv[i]; while( *s != '\0' ) { n = cl_GetOptionNo(list, &s); if ( n < 0 ) { if ( n == -2 && cl_file_cnt < CL_FILE_MAX ) { strcpy(cl_file_list[cl_file_cnt++], s); break; } else { ret = 0; /* unbekannte option */ break; } } switch( cl_Convert(list+n, &s, 0) ) { case -1: ret = 0; /* fehler */ break; case 1: break; case 0: i++; s = argv[i]; if ( s == NULL ) { ret = 0; /* fehler */ break; } if ( cl_Convert(list+n, &s, 1 ) != 1 ) { ret = 0; /* fehler */ break; } break; } if ( argv[i] == NULL ) break; } if ( argv[i] == NULL ) break; i++; if ( argv[i] == NULL ) break; } return ret; } /* #define cmdline_main_test */ #ifdef cmdline_main_test long com_port = -1; long port_adr = 0; int boolval = 0; long vmode = -1; cl_entry_struct cl_list[] = { { CL_TYP_SET, "25", &vmode, -2 }, { CL_TYP_SET, "43", &vmode, -3 }, { CL_TYP_SET, "50", &vmode, -4 }, { CL_TYP_SET, "d", &vmode, -1 }, { CL_TYP_LONG, "v", &vmode, 0 }, { CL_TYP_LONG, "com", &com_port, 0 }, { CL_TYP_LONG, "port", &port_adr, 0 }, { CL_TYP_ON, "on", &boolval, 0 }, CL_ENTRY_LAST }; void main(int argc, char *argv[]) { int i; /* printf("cl_Do: %d\n", cl_Do(cl_list, argc, argv)); */ cl_String(cl_list, "-com5 test -port"); printf("com_port: %ld\n", com_port); printf("port_adr: %ld\n", port_adr); printf("boolval: %d\n", boolval); for( i = 0; i < cl_file_cnt; i++ ) printf("%d.: %s\n", i, cl_file_list[i]); } #endif