mirror of
https://github.com/eddyem/snippets_library.git
synced 2025-12-06 02:35:20 +03:00
some useful fixes
This commit is contained in:
parent
82e66080b3
commit
9e285bbe34
@ -110,7 +110,7 @@ add_definitions(-DLOCALEDIR=\"${LOCALEDIR}\"
|
|||||||
-DMAJOR_VERSION=\"${MAJOR_VESION}\")
|
-DMAJOR_VERSION=\"${MAJOR_VESION}\")
|
||||||
|
|
||||||
# -l
|
# -l
|
||||||
target_link_libraries(${PROJ} ${${PROJ}_LIBRARIES})
|
target_link_libraries(${PROJ} ${${PROJ}_LIBRARIES} -lm)
|
||||||
|
|
||||||
set(PCFILE "${CMAKE_BINARY_DIR}/${PROJ}.pc")
|
set(PCFILE "${CMAKE_BINARY_DIR}/${PROJ}.pc")
|
||||||
configure_file("${PROJ}.pc.in" ${PCFILE} @ONLY)
|
configure_file("${PROJ}.pc.in" ${PCFILE} @ONLY)
|
||||||
@ -154,7 +154,7 @@ if(NOT DEFINED NOGETTEXT)
|
|||||||
# we need this to prevent ru.po & .mo from deleting by make clean
|
# we need this to prevent ru.po & .mo from deleting by make clean
|
||||||
add_custom_target(
|
add_custom_target(
|
||||||
RU_FILE
|
RU_FILE
|
||||||
COMMAND [ -f ${RU_FILE} ] && ${GETTEXT_MSGMERGE_EXECUTABLE} -Uis ${RU_FILE} ${PO_FILE} || cp ${PO_FILE} ${RU_FILE}
|
COMMAND [ -f ${RU_FILE} ] && ${GETTEXT_MSGMERGE_EXECUTABLE} -UiF ${RU_FILE} ${PO_FILE} || cp ${PO_FILE} ${RU_FILE}
|
||||||
DEPENDS ${PO_FILE} ${SOURCES}
|
DEPENDS ${PO_FILE} ${SOURCES}
|
||||||
)
|
)
|
||||||
add_custom_target(
|
add_custom_target(
|
||||||
|
|||||||
@ -1,3 +1,12 @@
|
|||||||
|
Wed Sep 10 14:19:24 MSK 2025
|
||||||
|
(still version 0.3.3: I forgot to add changelog last commits)
|
||||||
|
- fixed minor bugs and memory leaks
|
||||||
|
- use common way for parsing commandline arguments and content of configuration files, so now you can use arrays in configurations (several parameters with same name)
|
||||||
|
- add functions:
|
||||||
|
- - int sl_remove_quotes(char *string) - remove outern quotes (" and '), return amount of pairs found
|
||||||
|
- - void sl_conf_showhelp(int idx, sl_option_t *options) - show help for config file parameters (only long options, without '--' and without exit(1) at the end of function)
|
||||||
|
- - void sl_parseargs_hf(int *argc, char ***argv, sl_option_t *options, void (*helpfun)(int, sl_option_t*)) - now this funtion available for external using, parsing of arguments with user help function
|
||||||
|
|
||||||
Dec 16 2024
|
Dec 16 2024
|
||||||
|
|
||||||
VERSION 0.2.1:
|
VERSION 0.2.1:
|
||||||
|
|||||||
364
config.c
364
config.c
@ -24,6 +24,28 @@
|
|||||||
|
|
||||||
#include "usefull_macros.h"
|
#include "usefull_macros.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief sl_remove_quotes - remove all outern quotes - starting and trailng " and '
|
||||||
|
* @param (io) string to modify (if quotes found rest of string will be moved to head, tail will be zeroed)
|
||||||
|
* @return amount of quotation pair found
|
||||||
|
*/
|
||||||
|
int sl_remove_quotes(char *string){
|
||||||
|
if(!string) return 0;
|
||||||
|
int l = strlen(string);
|
||||||
|
if(l < 2) return 0;
|
||||||
|
int nq = 0, half = l/2;
|
||||||
|
for(; nq < half; ++nq){
|
||||||
|
char _1st = string[nq];
|
||||||
|
if(_1st != string[l-1-nq]) break;
|
||||||
|
if(_1st != '\'' && _1st != '"') break;
|
||||||
|
}
|
||||||
|
if(nq == 0) return 0;
|
||||||
|
l -= 2 * nq;
|
||||||
|
memmove(string, string + nq, l);
|
||||||
|
string[l] = 0;
|
||||||
|
return nq;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief sl_get_keyval - get key name and its value from string pair
|
* @brief sl_get_keyval - get key name and its value from string pair
|
||||||
* @param pair - empty string, `key = value` or just `key`
|
* @param pair - empty string, `key = value` or just `key`
|
||||||
@ -66,6 +88,7 @@ int sl_get_keyval(const char *pair, char key[SL_KEY_LEN], char value[SL_VAL_LEN]
|
|||||||
for(; kend < eq && !isspace(*kend); ++kend);
|
for(; kend < eq && !isspace(*kend); ++kend);
|
||||||
size_t l = SL_KEY_LEN - 1;
|
size_t l = SL_KEY_LEN - 1;
|
||||||
if(l > (size_t)(kend - kstart)) l = kend - kstart;
|
if(l > (size_t)(kend - kstart)) l = kend - kstart;
|
||||||
|
else if(l < (size_t)(kend - kstart)) WARNX(_("sl_get_keyval(): key would be trunkated to %d symbols"), l);
|
||||||
//DBG("kend=%c, kstart=%c, l=%zd", *kend, *kstart, l);
|
//DBG("kend=%c, kstart=%c, l=%zd", *kend, *kstart, l);
|
||||||
strncpy(key, kstart, l);
|
strncpy(key, kstart, l);
|
||||||
key[l] = 0;
|
key[l] = 0;
|
||||||
@ -90,13 +113,74 @@ static int read_key(FILE *file, char key[SL_KEY_LEN], char value[SL_VAL_LEN]){
|
|||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
// search `opt` record for given `key`
|
// print option value
|
||||||
static sl_option_t *opt_search(const char *key, sl_option_t *options){
|
static size_t pr_val(sl_argtype_e type, void *argptr, char **buffer, size_t *buflen, size_t pos){
|
||||||
while(options->name){
|
size_t maxlen = *buflen - pos - 1;
|
||||||
if(0 == strcmp(key, options->name)) return options;
|
char *buf = *buffer + pos;
|
||||||
++options;
|
switch(type){
|
||||||
|
case arg_none:
|
||||||
|
case arg_int:
|
||||||
|
DBG("int %d", *(int*) argptr);
|
||||||
|
return snprintf(buf, maxlen, "%d", *(int*) argptr);
|
||||||
|
case arg_longlong:
|
||||||
|
DBG("long long %lld", *(long long*) argptr);
|
||||||
|
return snprintf(buf, maxlen, "%lld", *(long long*)argptr);
|
||||||
|
case arg_float:
|
||||||
|
DBG("float %g", *(float*) argptr);
|
||||||
|
return snprintf(buf, maxlen, "%g", *(float*) argptr);
|
||||||
|
case arg_double:
|
||||||
|
DBG("double %g", *(double*) argptr);
|
||||||
|
return snprintf(buf, maxlen, "%g", *(double*) argptr);
|
||||||
|
case arg_string:
|
||||||
|
if(!argptr || !(*(char**)argptr)){
|
||||||
|
return snprintf(buf, maxlen, "(null)");
|
||||||
|
}else if(!(**(char**)argptr)){
|
||||||
|
return snprintf(buf, maxlen, "(empty)");
|
||||||
|
}
|
||||||
|
char *str = *(char**) argptr;
|
||||||
|
DBG("string %s", str);
|
||||||
|
size_t z = strlen(str);
|
||||||
|
while(pos + z > *buflen + 5){
|
||||||
|
*buflen += BUFSIZ;
|
||||||
|
*buffer = realloc(*buffer, *buflen);
|
||||||
|
if(!*buffer) ERRX("realloc()");
|
||||||
|
maxlen += BUFSIZ;
|
||||||
|
buf = *buffer + pos;
|
||||||
|
}
|
||||||
|
return snprintf(buf, maxlen, "\"%s\"", str);
|
||||||
|
default:
|
||||||
|
DBG("function");
|
||||||
|
return snprintf(buf, maxlen, "\"(unsupported)\"");
|
||||||
}
|
}
|
||||||
return NULL;
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// print one option
|
||||||
|
static size_t print_opt(sl_option_t *opt, char **buffer, size_t *buflen, size_t pos){
|
||||||
|
if((ssize_t)*buflen - pos < 3 *(SL_KEY_LEN + SL_VAL_LEN)){
|
||||||
|
*buflen += BUFSIZ;
|
||||||
|
*buffer = realloc(*buffer, *buflen);
|
||||||
|
if(!*buffer) ERR("realloc()");
|
||||||
|
}
|
||||||
|
char *buf = *buffer + pos;
|
||||||
|
size_t l = 0, maxlen = *buflen - pos - 1;
|
||||||
|
size_t got = snprintf(buf, maxlen, "%s = ", opt->name);
|
||||||
|
l = got; maxlen -= got; buf += got;
|
||||||
|
if(opt->flag){
|
||||||
|
DBG("got flag '%d'", *opt->flag);
|
||||||
|
l += snprintf(buf, maxlen, "%d\n", *opt->flag);
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
if(!opt->argptr){ // ERR!
|
||||||
|
l += snprintf(buf, maxlen, "\"(no argptr)\"\n");
|
||||||
|
WARNX("Parameter \"%s\" have no argptr!", opt->name);
|
||||||
|
return l;
|
||||||
|
}
|
||||||
|
DBG("type: %d", opt->type);
|
||||||
|
got = pr_val(opt->type, opt->argptr, buffer, buflen, pos + l);
|
||||||
|
l += got; maxlen -= got; buf += got;
|
||||||
|
l += snprintf(buf, maxlen, "\n");
|
||||||
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -108,156 +192,44 @@ static sl_option_t *opt_search(const char *key, sl_option_t *options){
|
|||||||
char *sl_print_opts(sl_option_t *opt, int showall){
|
char *sl_print_opts(sl_option_t *opt, int showall){
|
||||||
char *buf = MALLOC(char, BUFSIZ);
|
char *buf = MALLOC(char, BUFSIZ);
|
||||||
size_t L = BUFSIZ, l = 0;
|
size_t L = BUFSIZ, l = 0;
|
||||||
for(; opt->name; ++opt){
|
for(; opt->help; ++opt){
|
||||||
|
if(!opt->name) continue; // only show help - not config option!
|
||||||
DBG("check %s", opt->name);
|
DBG("check %s", opt->name);
|
||||||
if(!showall && opt->has_arg == NO_ARGS) continue; // show NO_ARGS only when `showall==TRUE`
|
if(!showall && opt->has_arg == NO_ARGS) continue; // show NO_ARGS only when `showall==TRUE`
|
||||||
if(!showall && opt->type == arg_string && !opt->argptr) continue; // empty string
|
if(!showall && opt->type == arg_string && !opt->argptr) continue; // empty string
|
||||||
if((ssize_t)L - l < SL_KEY_LEN + SL_VAL_LEN + 5){
|
if(opt->has_arg == MULT_PAR){
|
||||||
L += BUFSIZ;
|
sl_option_t tmpopt = *opt;
|
||||||
buf = realloc(buf, L);
|
DBG("type: %d", tmpopt.type);
|
||||||
if(!buf) ERR("realloc()");
|
if(!opt->argptr){ DBG("No pointer to array!"); continue; }
|
||||||
}
|
#if 0
|
||||||
l += sprintf(buf + l, "%s=", opt->name);
|
void ***pp = (void***)opt->argptr;
|
||||||
if(opt->flag){
|
if(!*(char***)pp){ DBG("Array is empty"); continue; }
|
||||||
DBG("got flag '%d'", *opt->flag);
|
while(**pp){
|
||||||
l += sprintf(buf + l, "%d\n", *opt->flag);
|
if(opt->type == arg_string){
|
||||||
continue;
|
DBG("str");
|
||||||
}
|
tmpopt.argptr = *pp; // string is pointer to pointer!
|
||||||
if(!opt->argptr){ // ERR!
|
}else tmpopt.argptr = **pp;
|
||||||
l += sprintf(buf + l, "\"(no argptr)\"\n");
|
if(!tmpopt.argptr){ DBG("null"); break; }
|
||||||
WARNX("Parameter \"%s\" have no argptr!", opt->name);
|
l += print_opt(&tmpopt, &buf, &L, l);
|
||||||
continue;
|
++(*pp);
|
||||||
}
|
}
|
||||||
int z = 0;
|
#endif
|
||||||
DBG("type: %d", opt->type);
|
void **pp = *(void***)opt->argptr;
|
||||||
switch(opt->type){
|
if(!(char**)pp){ DBG("Array is empty"); continue; }
|
||||||
case arg_none:
|
while(*pp){
|
||||||
case arg_int:
|
if(opt->type == arg_string){
|
||||||
DBG("int %d", *(int*) opt->argptr);
|
DBG("str");
|
||||||
l += sprintf(buf + l, "%d", *(int*) opt->argptr);
|
tmpopt.argptr = pp; // string is pointer to pointer!
|
||||||
break;
|
}else tmpopt.argptr = *pp;
|
||||||
case arg_longlong:
|
if(!tmpopt.argptr){ DBG("null"); break; }
|
||||||
DBG("long long %lld", *(long long*) opt->argptr);
|
l += print_opt(&tmpopt, &buf, &L, l);
|
||||||
l += sprintf(buf + l, "%lld", *(long long*) opt->argptr);
|
++(pp);
|
||||||
break;
|
}
|
||||||
case arg_float:
|
}else l += print_opt(opt, &buf, &L, l);
|
||||||
DBG("float %g", *(float*) opt->argptr);
|
|
||||||
l += sprintf(buf + l, "%g", *(float*) opt->argptr);
|
|
||||||
break;
|
|
||||||
case arg_double:
|
|
||||||
DBG("double %g", *(double*) opt->argptr);
|
|
||||||
l += sprintf(buf + l, "%g", *(double*) opt->argptr);
|
|
||||||
break;
|
|
||||||
case arg_string:
|
|
||||||
if(!opt->argptr || !(*(char*)opt->argptr)){
|
|
||||||
l += sprintf(buf + l, "(null)");
|
|
||||||
break;
|
|
||||||
}else if(!(**(char**)opt->argptr)){
|
|
||||||
l += sprintf(buf + l, "(empty)");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
DBG("string %s", *(char**) opt->argptr);
|
|
||||||
z = strlen(*(char**) opt->argptr);
|
|
||||||
while(l + z > L + 3){
|
|
||||||
L += BUFSIZ;
|
|
||||||
buf = realloc(buf, L);
|
|
||||||
}
|
|
||||||
l += sprintf(buf + l, "%s", *(char**) opt->argptr);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
DBG("function");
|
|
||||||
l += sprintf(buf + l, "\"(unsupported)\"");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
l += sprintf(buf + l, "\n");
|
|
||||||
}
|
}
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief sl_set_optval - convert `val` to `oval` parameter according to argument type
|
|
||||||
* @param oval (o) - value in int/long long/double/float
|
|
||||||
* @param opt (i) - record with options
|
|
||||||
* @param val (i) - new value
|
|
||||||
* @return FALSE if failed (or wrong data range)
|
|
||||||
*/
|
|
||||||
int sl_set_optval(sl_optval *oval, sl_option_t *opt, const char *val){
|
|
||||||
if(!oval || !opt || !val) return FALSE;
|
|
||||||
long long ll;
|
|
||||||
double d;
|
|
||||||
switch(opt->type){
|
|
||||||
case arg_none:
|
|
||||||
case arg_int:
|
|
||||||
case arg_longlong:
|
|
||||||
do{
|
|
||||||
if(!sl_str2ll(&ll, val)){
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(opt->type != arg_longlong){
|
|
||||||
if(ll > INT_MAX || ll < INT_MIN){
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
oval->ival = (int)ll;
|
|
||||||
}else oval->llval = ll;
|
|
||||||
return TRUE;
|
|
||||||
}while(0);
|
|
||||||
break;
|
|
||||||
case arg_double:
|
|
||||||
case arg_float:
|
|
||||||
do{
|
|
||||||
if(!sl_str2d(&d, val)){
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
if(opt->type == arg_double){
|
|
||||||
oval->dval = d;
|
|
||||||
}else{
|
|
||||||
if(d > FLT_MAX || d < FLT_MIN){
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
oval->fval = (float)d;
|
|
||||||
}
|
|
||||||
return TRUE;
|
|
||||||
}while(0);
|
|
||||||
break;
|
|
||||||
case arg_string:
|
|
||||||
return TRUE;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
WARNX(_("Unsupported option type"));
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
WARNX(_("Wrong number format '%s'"), val);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
// increment opt->argptr or set it to val
|
|
||||||
static void setoa(sl_option_t *opt, const char *val){
|
|
||||||
if(!opt || !opt->argptr || opt->type == arg_function) return;
|
|
||||||
sl_optval O;
|
|
||||||
if(!sl_set_optval(&O, opt, val)) return;
|
|
||||||
switch(opt->type){
|
|
||||||
case arg_none: // increment integer
|
|
||||||
*(int*) opt->argptr += O.ival;
|
|
||||||
break;
|
|
||||||
case arg_int:
|
|
||||||
*(int*) opt->argptr = O.ival;
|
|
||||||
break;
|
|
||||||
case arg_longlong:
|
|
||||||
*(long long*) opt->argptr = O.llval;
|
|
||||||
break;
|
|
||||||
case arg_double:
|
|
||||||
*(double*) opt->argptr = O.dval;
|
|
||||||
break;
|
|
||||||
case arg_float:
|
|
||||||
*(float*) opt->argptr = O.fval;
|
|
||||||
break;
|
|
||||||
case arg_string:
|
|
||||||
*(char**)opt->argptr = strdup(val);
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief sl_conf_readopts - simplest configuration:
|
* @brief sl_conf_readopts - simplest configuration:
|
||||||
@ -273,29 +245,85 @@ int sl_conf_readopts(const char *filename, sl_option_t *options){
|
|||||||
WARN(_("Can't open %s"), filename);
|
WARN(_("Can't open %s"), filename);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
int N = 0;
|
int argc = 1;
|
||||||
char key[SL_KEY_LEN], val[SL_VAL_LEN];
|
#define BUFSZ (SL_KEY_LEN+SL_VAL_LEN+8)
|
||||||
|
char key[SL_KEY_LEN], val[SL_VAL_LEN], obuf[BUFSZ];
|
||||||
|
int argvsize = 0;
|
||||||
|
char **argv = NULL;
|
||||||
do{
|
do{
|
||||||
int r = read_key(f, key, val);
|
int r = read_key(f, key, val);
|
||||||
if(r < 0) break;
|
if(r < 0) break;
|
||||||
if(r == 0) continue;
|
if(r == 0) continue;
|
||||||
sl_option_t *opt = opt_search(key, options);
|
DBG("key='%s', val='%s'", key, (r == 2) ? val : "(absent)");
|
||||||
if(!opt){
|
++argc;
|
||||||
WARNX(_("Wrong key: '%s'"), key);
|
if(argvsize <= argc){
|
||||||
continue;
|
argvsize += 256;
|
||||||
|
argv = realloc(argv, sizeof(char*) * argvsize);
|
||||||
|
if(!argv) ERRX("sl_conf_readopts: realloc() error");
|
||||||
}
|
}
|
||||||
if(opt->flag) *opt->flag = opt->val;
|
if(argc == 2) argv[0] = strdup(__progname); // all as should be
|
||||||
if(r == 1){ // only key
|
if(r == 2){
|
||||||
if(opt->has_arg != NO_ARGS && opt->has_arg != OPT_ARG){
|
// remove trailing/ending quotes
|
||||||
WARNX(_("Key '%s' need value"), opt->name);
|
sl_remove_quotes(val);
|
||||||
continue;
|
snprintf(obuf, BUFSZ-1, "--%s=%s", key, val);
|
||||||
}
|
}else snprintf(obuf, BUFSZ-1, "--%s", key);
|
||||||
if(opt->argptr) setoa(opt, "1");
|
DBG("next argv: '%s'", obuf);
|
||||||
}else{ // key + value
|
argv[argc-1] = strdup(obuf);
|
||||||
if(opt->argptr) setoa(opt, val);
|
|
||||||
else WARNX(_("Key '%s' have no argptr!"), opt->name);
|
|
||||||
}
|
|
||||||
++N;
|
|
||||||
}while(1);
|
}while(1);
|
||||||
return N;
|
if(!argc) return 0;
|
||||||
|
int N = argc; char **a = argv;
|
||||||
|
sl_parseargs_hf(&argc, &a, options, sl_conf_showhelp);
|
||||||
|
for(int n = 0; n < N; ++n) free(argv[n]);
|
||||||
|
free(argv);
|
||||||
|
return N - argc; // amount of recognized options
|
||||||
|
}
|
||||||
|
|
||||||
|
// sort only by long options
|
||||||
|
static int confsort(const void *a1, const void *a2){
|
||||||
|
const sl_option_t *o1 = (sl_option_t*)a1, *o2 = (sl_option_t*)a2;
|
||||||
|
const char *l1 = o1->name, *l2 = o2->name;
|
||||||
|
// move empty options to end of list
|
||||||
|
if(!l1 && !l2) return 1;
|
||||||
|
if(!l1) return 1;
|
||||||
|
if(!l2) return -1;
|
||||||
|
return strcmp(l1, l2);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void pr_helpstring(sl_option_t *opt){
|
||||||
|
if(!opt->name || !opt->help) return;
|
||||||
|
printf(" %s", opt->name);
|
||||||
|
if(opt->has_arg == NEED_ARG || opt->has_arg == MULT_PAR) // required argument
|
||||||
|
printf(" = arg");
|
||||||
|
else if(opt->has_arg == OPT_ARG) // optional argument
|
||||||
|
printf(" [= arg]");
|
||||||
|
printf(" -- %s", opt->help);
|
||||||
|
if(opt->has_arg == MULT_PAR) printf(" (can occur multiple times)");
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief sl_conf_showhelp - show help for config file
|
||||||
|
* (the same as `sl_showhelp`, but without "--", short opts and exit()
|
||||||
|
* @param options - config options (only long opts used)
|
||||||
|
*/
|
||||||
|
void sl_conf_showhelp(int idx, sl_option_t *options){
|
||||||
|
if(!options || !(*options).help) return;
|
||||||
|
// count amount of options
|
||||||
|
sl_option_t *opts = options;
|
||||||
|
int N; for(N = 0; opts->help; ++N, ++opts);
|
||||||
|
if(N == 0) exit(-2);
|
||||||
|
if(idx > -1){
|
||||||
|
if(idx >=N) WARNX(_("sl_conf_showhelp(): wrong index"));
|
||||||
|
else pr_helpstring(&options[idx]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
sl_option_t *tmpopts = MALLOC(sl_option_t, N);
|
||||||
|
memcpy(tmpopts, options, N*sizeof(sl_option_t));
|
||||||
|
printf(_("Configuration file options (format: key=value):\n"));
|
||||||
|
qsort(tmpopts, N, sizeof(sl_option_t), confsort);
|
||||||
|
for(int _ = 0; _ < N; ++_){
|
||||||
|
if(!tmpopts[_].name) continue;
|
||||||
|
pr_helpstring(&tmpopts[_]);
|
||||||
|
}
|
||||||
|
free(tmpopts);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -50,22 +50,28 @@ static glob_pars const Gdefault = {
|
|||||||
/*
|
/*
|
||||||
* Define command line options by filling structure:
|
* Define command line options by filling structure:
|
||||||
* name has_arg flag val type argptr help
|
* name has_arg flag val type argptr help
|
||||||
|
* BE carefull! The `help` field is mandatory! Omitting it equivalent of 'end_option'
|
||||||
*/
|
*/
|
||||||
static sl_option_t cmdlnopts[] = {
|
static sl_option_t cmdlnopts[] = {
|
||||||
{"lo0", NEED_ARG, NULL, 0, arg_int, APTR(&G.lo0), _("only long arg 0")},
|
// short option in only-long options should be zeroed, or you can add flag to set it to given value
|
||||||
|
{"lo0", NEED_ARG, NULL, 0, arg_int, APTR(&G.lo0), _("only long arg 0 (int)")},
|
||||||
|
// for short-only options long option can be NULL
|
||||||
|
{NULL, NEED_ARG, NULL, '0', arg_string, APTR(&G.so1), _("only short arg 1 (string)")},
|
||||||
|
// if you change `arg_int` to `arg_none`, value will be incremented each `-h`
|
||||||
{"help", NO_ARGS, NULL, 'h', arg_int, APTR(&help), _("show this help")},
|
{"help", NO_ARGS, NULL, 'h', arg_int, APTR(&help), _("show this help")},
|
||||||
// {"dup", NO_ARGS, NULL, 'h', arg_int, APTR(&help), _("show this help")},
|
|
||||||
{"device", NEED_ARG, NULL, 'd', arg_string, APTR(&G.device), _("serial device name")},
|
{"device", NEED_ARG, NULL, 'd', arg_string, APTR(&G.device), _("serial device name")},
|
||||||
{"lo2", NEED_ARG, NULL, 0, arg_int, APTR(&G.lo2), _("only long arg 2")},
|
// for short-only options long option can also be an empty string
|
||||||
|
{"", NEED_ARG, NULL, '1', arg_string, APTR(&G.so2), _("only short arg 2 (string)")},
|
||||||
|
{"lo2", NEED_ARG, NULL, 0, arg_int, APTR(&G.lo2), _("only long arg 2 (int)")},
|
||||||
{"speed", NEED_ARG, NULL, 's', arg_int, APTR(&G.speed), _("serial device speed (default: 9600)")},
|
{"speed", NEED_ARG, NULL, 's', arg_int, APTR(&G.speed), _("serial device speed (default: 9600)")},
|
||||||
{"logfile", NEED_ARG, NULL, 'l', arg_string, APTR(&G.logfile), _("file to save logs")},
|
{"logfile", NEED_ARG, NULL, 'l', arg_string, APTR(&G.logfile), _("file to save logs")},
|
||||||
{"pidfile", NEED_ARG, NULL, 'P', arg_string, APTR(&G.pidfile), _("pidfile (default: " DEFAULT_PIDFILE ")")},
|
{"pidfile", NEED_ARG, NULL, 'P', arg_string, APTR(&G.pidfile), _("pidfile (default: " DEFAULT_PIDFILE ")")},
|
||||||
{"exclusive",NO_ARGS, NULL, 'e', arg_int, APTR(&G.exclusive), _("open serial device exclusively")},
|
{"exclusive",NO_ARGS, NULL, 'e', arg_int, APTR(&G.exclusive), _("open serial device exclusively")},
|
||||||
// example of multiple options
|
// example of multiple options
|
||||||
{"Int", MULT_PAR, NULL, 'I', arg_int, APTR(&G.intarr), _("integer multiplying parameter")},
|
{"Int", MULT_PAR, NULL, 'I', arg_int, APTR(&G.intarr), _("integer parameter")},
|
||||||
{"Dbl", MULT_PAR, NULL, 'D', arg_double, APTR(&G.dblarr), _("double multiplying parameter")},
|
{"Dbl", MULT_PAR, NULL, 'D', arg_double, APTR(&G.dblarr), _("double parameter")},
|
||||||
{"Str", MULT_PAR, NULL, 'S', arg_string, APTR(&G.strarr), _("string multiplying parameter")},
|
{"Str", MULT_PAR, NULL, 'S', arg_string, APTR(&G.strarr), _("string parameter")},
|
||||||
{"lo1", NEED_ARG, NULL, 0, arg_int, APTR(&G.lo1), _("only long arg 1")},
|
{"lo1", NEED_ARG, NULL, 0, arg_int, APTR(&G.lo1), _("only long arg 1 (int)")},
|
||||||
end_option
|
end_option
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -38,6 +38,8 @@ typedef struct{
|
|||||||
int lo0; // only long options
|
int lo0; // only long options
|
||||||
int lo1;
|
int lo1;
|
||||||
int lo2;
|
int lo2;
|
||||||
|
char *so1; // only short options
|
||||||
|
char *so2;
|
||||||
int rest_pars_num; // number of rest parameters
|
int rest_pars_num; // number of rest parameters
|
||||||
char** rest_pars; // the rest parameters: array of char*
|
char** rest_pars; // the rest parameters: array of char*
|
||||||
} glob_pars;
|
} glob_pars;
|
||||||
|
|||||||
@ -23,12 +23,10 @@
|
|||||||
#include "usefull_macros.h"
|
#include "usefull_macros.h"
|
||||||
|
|
||||||
typedef struct{
|
typedef struct{
|
||||||
char *sp1;
|
char **sp;
|
||||||
char *sp2;
|
|
||||||
int ip1;
|
int ip1;
|
||||||
int ip2;
|
int ip2;
|
||||||
double dp1;
|
double **dp;
|
||||||
double dp2;
|
|
||||||
float fp1;
|
float fp1;
|
||||||
float fp2;
|
float fp2;
|
||||||
int help;
|
int help;
|
||||||
@ -36,66 +34,94 @@ typedef struct{
|
|||||||
char *confname;
|
char *confname;
|
||||||
} parameters;
|
} parameters;
|
||||||
|
|
||||||
static parameters G = {
|
static parameters G, parini = {
|
||||||
.ip1 = INT_MIN,
|
.ip1 = INT_MIN,
|
||||||
.ip2 = INT_MIN,
|
.ip2 = INT_MIN,
|
||||||
.dp1 = NAN,
|
|
||||||
.dp2 = NAN,
|
|
||||||
.fp1 = NAN,
|
.fp1 = NAN,
|
||||||
.fp2 = NAN
|
.fp2 = NAN
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define CONFOPTS \
|
||||||
|
{"string", MULT_PAR, NULL, 's', arg_string, APTR(&G.sp), "string array"}, \
|
||||||
|
{"int1", NEED_ARG, NULL, 'i', arg_int, APTR(&G.ip1), "integer one"}, \
|
||||||
|
{"int2", NEED_ARG, NULL, 'u', arg_int, APTR(&G.ip2), "integer two"}, \
|
||||||
|
{"double", MULT_PAR, NULL, 'd', arg_double, APTR(&G.dp), "double array"}, \
|
||||||
|
{"float1", NEED_ARG, NULL, 'f', arg_float, APTR(&G.fp1), "float one"}, \
|
||||||
|
{"float2", NEED_ARG, NULL, 'l', arg_float, APTR(&G.fp2), "float two"}, \
|
||||||
|
{"verbose", NO_ARGS, NULL, 'v', arg_none, APTR(&G.verbose),"verbose level (each -v adds 1)"},
|
||||||
|
|
||||||
static sl_option_t cmdlnopts[] = {
|
static sl_option_t cmdlnopts[] = {
|
||||||
{"help", NO_ARGS, NULL, 'h', arg_int, APTR(&G.help), "show this help"},
|
{"help", NO_ARGS, NULL, 'h', arg_int, APTR(&G.help), "show this help"},
|
||||||
{"string1", NEED_ARG, NULL, 's', arg_string, APTR(&G.sp1), "string one"},
|
CONFOPTS
|
||||||
{"string2", NEED_ARG, NULL, 'c', arg_string, APTR(&G.sp2), "string two"},
|
|
||||||
{"int1", NEED_ARG, NULL, 'i', arg_int, APTR(&G.ip1), "integer one"},
|
|
||||||
{"int2", NEED_ARG, NULL, 'u', arg_int, APTR(&G.ip2), "integer two"},
|
|
||||||
{"double1", NEED_ARG, NULL, 'd', arg_double, APTR(&G.dp1), "double one"},
|
|
||||||
{"double2", NEED_ARG, NULL, 'o', arg_double, APTR(&G.dp2), "double two"},
|
|
||||||
{"float1", NEED_ARG, NULL, 'f', arg_float, APTR(&G.fp1), "float one"},
|
|
||||||
{"float2", NEED_ARG, NULL, 'l', arg_float, APTR(&G.fp2), "float two"},
|
|
||||||
{"config", NEED_ARG, NULL, 'C', arg_string, APTR(&G.confname),"name of configuration file"},
|
{"config", NEED_ARG, NULL, 'C', arg_string, APTR(&G.confname),"name of configuration file"},
|
||||||
{"verbose", NO_ARGS, NULL, 'v', arg_none, APTR(&G.verbose),"verbose level (each -v adds 1)"},
|
end_option
|
||||||
|
};
|
||||||
|
// config options - without some unneed
|
||||||
|
static sl_option_t confopts[] = {
|
||||||
|
CONFOPTS
|
||||||
end_option
|
end_option
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char **argv){
|
int main(int argc, char **argv){
|
||||||
sl_init();
|
sl_init();
|
||||||
|
G = parini;
|
||||||
sl_parseargs(&argc, &argv, cmdlnopts);
|
sl_parseargs(&argc, &argv, cmdlnopts);
|
||||||
if(G.help) sl_showhelp(-1, cmdlnopts);
|
if(G.help) sl_showhelp(-1, cmdlnopts);
|
||||||
|
// if you will end main options with '--', you can write some additional options after and again run sl_parseargs with other sl_option_t array
|
||||||
|
if(argc) for(int i = 0; i < argc; ++i){
|
||||||
|
red("Extra arg: `%s`\n", argv[i]);
|
||||||
|
}
|
||||||
sl_loglevel_e lvl = G.verbose + LOGLEVEL_ERR;
|
sl_loglevel_e lvl = G.verbose + LOGLEVEL_ERR;
|
||||||
if(lvl >= LOGLEVEL_AMOUNT) lvl = LOGLEVEL_AMOUNT - 1;
|
if(lvl >= LOGLEVEL_AMOUNT) lvl = LOGLEVEL_AMOUNT - 1;
|
||||||
printf("verbose level: %d\n", lvl);
|
printf("verbose level: %d\n", lvl);
|
||||||
if(G.sp1){
|
if(G.sp){
|
||||||
printf("Parsing of string1: ");
|
char **s = G.sp;
|
||||||
char key[SL_KEY_LEN], val[SL_VAL_LEN];
|
while(*s){
|
||||||
int k = sl_get_keyval(G.sp1, key, val);
|
printf("Parsing of string: ");
|
||||||
switch(k){
|
char key[SL_KEY_LEN], val[SL_VAL_LEN];
|
||||||
case 0:
|
int k = sl_get_keyval(*s, key, val);
|
||||||
red("key not found\n");
|
switch(k){
|
||||||
break;
|
case 0:
|
||||||
case 1:
|
red("key not found\n");
|
||||||
green("got key='%s'\n", key);
|
break;
|
||||||
break;
|
case 1:
|
||||||
default:
|
green("got key='%s'\n", key);
|
||||||
green("got key='%s', value='%s'\n", key, val);
|
break;
|
||||||
|
default:
|
||||||
|
green("got key='%s', value='%s'\n", key, val);
|
||||||
|
}
|
||||||
|
++s;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
green("Starting parameters values:\n");
|
green("Starting parameters values:\n");
|
||||||
char *buf = sl_print_opts(cmdlnopts, TRUE);
|
char *buf = sl_print_opts(cmdlnopts, TRUE);
|
||||||
printf("%s\n", buf);
|
printf("%s\n", buf);
|
||||||
FREE(buf);
|
FREE(buf); // don't forget to `free` this buffer
|
||||||
if(G.confname){
|
if(G.confname){
|
||||||
int o = sl_conf_readopts(G.confname, cmdlnopts);
|
const char *confname = G.confname;
|
||||||
|
G = parini;
|
||||||
|
printf("now v=%d\n", G.verbose);
|
||||||
|
int o = sl_conf_readopts(confname, confopts);
|
||||||
if(o > 0){
|
if(o > 0){
|
||||||
printf("got %d options in '%s'\n", o, G.confname);
|
printf("got %d options in '%s'\n", o, confname);
|
||||||
green("And after reading of conffile:\n");
|
green("And after reading of conffile:\n");
|
||||||
buf = sl_print_opts(cmdlnopts, TRUE);
|
buf = sl_print_opts(confopts, TRUE);
|
||||||
printf("%s\n", buf);
|
printf("%s\n", buf);
|
||||||
FREE(buf);
|
FREE(buf);
|
||||||
}
|
}
|
||||||
|
// if we want to re-read conffile many times over program runs, don't forget to `free` old arrays like this:
|
||||||
|
if(G.dp){
|
||||||
|
DBG("Clear double array");
|
||||||
|
double **p = G.dp;
|
||||||
|
while(*p){ FREE(*p); ++p; }
|
||||||
|
FREE(G.dp);
|
||||||
|
}
|
||||||
|
if(G.sp){
|
||||||
|
DBG("Clear string array %s", *G.sp);
|
||||||
|
char **s = G.sp;
|
||||||
|
while(*s){ FREE(*s); ++s; }
|
||||||
|
FREE(G.sp);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -67,12 +67,6 @@ int main(int argc, char *argv[]){
|
|||||||
}
|
}
|
||||||
sl_check4running((char*)__progname, GP->pidfile);
|
sl_check4running((char*)__progname, GP->pidfile);
|
||||||
red("%s started, snippets library version is %s\n", __progname, sl_libversion());
|
red("%s started, snippets library version is %s\n", __progname, sl_libversion());
|
||||||
sl_setup_con();
|
|
||||||
signal(SIGTERM, signals); // kill (-15) - quit
|
|
||||||
signal(SIGHUP, SIG_IGN); // hup - ignore
|
|
||||||
signal(SIGINT, signals); // ctrl+C - quit
|
|
||||||
signal(SIGQUIT, signals); // ctrl+\ - quit
|
|
||||||
signal(SIGTSTP, SIG_IGN); // ignore ctrl+Z
|
|
||||||
if(GP->logfile) OPENLOG(GP->logfile, LOGLEVEL_ANY, 1);
|
if(GP->logfile) OPENLOG(GP->logfile, LOGLEVEL_ANY, 1);
|
||||||
LOGMSG("Start application...");
|
LOGMSG("Start application...");
|
||||||
if(GP->rest_pars_num){
|
if(GP->rest_pars_num){
|
||||||
@ -89,11 +83,22 @@ int main(int argc, char *argv[]){
|
|||||||
}
|
}
|
||||||
if(GP->strarr){
|
if(GP->strarr){
|
||||||
char **p = GP->strarr;
|
char **p = GP->strarr;
|
||||||
for(int i = 0; *p; ++i) printf("String[%d]: \"%s\"\n", i, *p++);
|
for(int i = 0; *p; ++i){
|
||||||
|
sl_remove_quotes(*p);
|
||||||
|
printf("String[%d]: \"%s\"\n", i, *p++);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(GP->lo0 != INT_MIN) printf("You set lo0 to %d\n", GP->lo0);
|
if(GP->lo0 != INT_MIN) printf("You set lo0 to %d\n", GP->lo0);
|
||||||
if(GP->lo1 != INT_MIN) printf("You set lo1 to %d\n", GP->lo1);
|
if(GP->lo1 != INT_MIN) printf("You set lo1 to %d\n", GP->lo1);
|
||||||
if(GP->lo2 != INT_MIN) printf("You set lo2 to %d\n", GP->lo2);
|
if(GP->lo2 != INT_MIN) printf("You set lo2 to %d\n", GP->lo2);
|
||||||
|
if(GP->so1){
|
||||||
|
sl_remove_quotes(GP->so1);
|
||||||
|
printf("String so1=%s\n", GP->so1);
|
||||||
|
}
|
||||||
|
if(GP->so2){
|
||||||
|
sl_remove_quotes(GP->so2);
|
||||||
|
printf("String so2=%s\n", GP->so2);
|
||||||
|
}
|
||||||
if(GP->device){
|
if(GP->device){
|
||||||
LOGDBG("Try to open serial %s", GP->device);
|
LOGDBG("Try to open serial %s", GP->device);
|
||||||
dev = sl_tty_new(GP->device, GP->speed, 4096);
|
dev = sl_tty_new(GP->device, GP->speed, 4096);
|
||||||
@ -103,7 +108,13 @@ int main(int argc, char *argv[]){
|
|||||||
signals(0);
|
signals(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if(!dev) return 0;
|
||||||
|
sl_setup_con();
|
||||||
|
signal(SIGTERM, signals); // kill (-15) - quit
|
||||||
|
signal(SIGHUP, SIG_IGN); // hup - ignore
|
||||||
|
signal(SIGINT, signals); // ctrl+C - quit
|
||||||
|
signal(SIGQUIT, signals); // ctrl+\ - quit
|
||||||
|
signal(SIGTSTP, SIG_IGN); // ignore ctrl+Z
|
||||||
// main stuff goes here
|
// main stuff goes here
|
||||||
long seed = sl_random_seed();
|
long seed = sl_random_seed();
|
||||||
green("Now I will sleep for 10 seconds after your last input.\n Do whatever you want. Random seed: %ld\n", seed);
|
green("Now I will sleep for 10 seconds after your last input.\n Do whatever you want. Random seed: %ld\n", seed);
|
||||||
|
|||||||
Binary file not shown.
@ -8,7 +8,7 @@ msgid ""
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: PACKAGE VERSION\n"
|
"Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2025-06-27 11:51+0300\n"
|
"POT-Creation-Date: 2025-09-10 12:08+0300\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
@ -17,33 +17,23 @@ msgstr ""
|
|||||||
"Content-Type: text/plain; charset=koi8-r\n"
|
"Content-Type: text/plain; charset=koi8-r\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/config.c:226
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/config.c:91
|
||||||
msgid "Unsupported option type"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/config.c:229
|
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Wrong number format '%s'"
|
msgid "sl_get_keyval(): key would be trunkated to %d symbols"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/config.c:273
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/config.c:245
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Can't open %s"
|
msgid "Can't open %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/config.c:284
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/config.c:316
|
||||||
#, c-format
|
msgid "sl_conf_showhelp(): wrong index"
|
||||||
msgid "Wrong key: '%s'"
|
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/config.c:290
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/config.c:322
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Key '%s' need value"
|
msgid "Configuration file options (format: key=value):\n"
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/config.c:296
|
|
||||||
#, c-format
|
|
||||||
msgid "Key '%s' have no argptr!"
|
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/daemon.c:69
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/daemon.c:69
|
||||||
@ -71,7 +61,19 @@ msgstr ""
|
|||||||
msgid "Integer out of range"
|
msgid "Integer out of range"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:166
|
#. `opt` should be ':' for "missed arguments", '?' for "not found" and short flag if found and checked
|
||||||
|
#. not found
|
||||||
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:129
|
||||||
|
#, c-format
|
||||||
|
msgid "No such parameter: `%s`\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:138
|
||||||
|
#, c-format
|
||||||
|
msgid "Parameter `%s` needs value\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:163
|
||||||
msgid "Can't use multiple args with arg_none!"
|
msgid "Can't use multiple args with arg_none!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@ -85,22 +87,32 @@ msgstr ""
|
|||||||
msgid "double short arguments: -%c"
|
msgid "double short arguments: -%c"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:332
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:343
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Need argument with %s type\n"
|
msgid "Need argument with %s type\n"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:486
|
#. print only one message
|
||||||
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:435
|
||||||
|
msgid "sl_showhelp(): option index out of range"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:441
|
||||||
|
#, c-format
|
||||||
|
msgid "Usage: %s [arguments]\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:528
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Wrong parameter: %s"
|
msgid "Wrong parameter: %s"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:490
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:532
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "%s: need argument!"
|
msgid "%s: need argument!"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:494
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:536
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Wrong argument \"%s\" of parameter \"%s\""
|
msgid "Wrong argument \"%s\" of parameter \"%s\""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@ -109,35 +121,35 @@ msgstr ""
|
|||||||
msgid "Server disconnected"
|
msgid "Server disconnected"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/socket.c:390
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/socket.c:385
|
||||||
msgid "Can't start server handlers thread"
|
msgid "Can't start server handlers thread"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/socket.c:459
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/socket.c:454
|
||||||
msgid "Limit of connections reached"
|
msgid "Limit of connections reached"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. check for RB overflow
|
#. check for RB overflow
|
||||||
#. -1 - buffer empty (can't be), -2 - buffer overflow
|
#. -1 - buffer empty (can't be), -2 - buffer overflow
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/socket.c:503
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/socket.c:498
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/socket.c:504
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/socket.c:499
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Server thread: ring buffer overflow for fd=%d"
|
msgid "Server thread: ring buffer overflow for fd=%d"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/socket.c:518
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/socket.c:513
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Server thread: can't write data to ringbuffer: overflow from fd=%d"
|
msgid "Server thread: can't write data to ringbuffer: overflow from fd=%d"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. buffer overflow
|
#. buffer overflow
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/socket.c:530
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/socket.c:525
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Server thread: buffer overflow from fd=%d"
|
msgid "Server thread: buffer overflow from fd=%d"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#. never reached
|
#. never reached
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/socket.c:620
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/socket.c:615
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Unsupported socket type %d"
|
msgid "Unsupported socket type %d"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@ -215,18 +227,3 @@ msgstr ""
|
|||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:347
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:347
|
||||||
msgid "Can't setup console"
|
msgid "Can't setup console"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:403
|
|
||||||
#, c-format
|
|
||||||
msgid "Wrong double number format '%s'"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:416
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:428
|
|
||||||
#, c-format
|
|
||||||
msgid "Wrong integer number format '%s'"
|
|
||||||
msgstr ""
|
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:432
|
|
||||||
msgid "Number out of integer limits"
|
|
||||||
msgstr ""
|
|
||||||
|
|||||||
293
locale/ru/ru.po
293
locale/ru/ru.po
@ -7,7 +7,7 @@
|
|||||||
msgid ""
|
msgid ""
|
||||||
msgstr "Project-Id-Version: PACKAGE VERSION\n"
|
msgstr "Project-Id-Version: PACKAGE VERSION\n"
|
||||||
"Report-Msgid-Bugs-To: \n"
|
"Report-Msgid-Bugs-To: \n"
|
||||||
"POT-Creation-Date: 2025-06-27 11:49+0300\n"
|
"POT-Creation-Date: 2025-09-10 12:08+0300\n"
|
||||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||||
@ -16,6 +16,25 @@ msgstr "Project-Id-Version: PACKAGE VERSION\n"
|
|||||||
"Content-Type: text/plain; charset=koi8-r\n"
|
"Content-Type: text/plain; charset=koi8-r\n"
|
||||||
"Content-Transfer-Encoding: 8bit\n"
|
"Content-Transfer-Encoding: 8bit\n"
|
||||||
|
|
||||||
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/config.c:91
|
||||||
|
#, c-format
|
||||||
|
msgid "sl_get_keyval(): key would be trunkated to %d symbols"
|
||||||
|
msgstr "sl_get_keyval(): ËÌÀÞ ÂÕÄÅÔ ÏÂÒÅÚÁÎ ÄÏ %d ÓÉÍ×ÏÌÏ×"
|
||||||
|
|
||||||
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/config.c:245
|
||||||
|
#, c-format
|
||||||
|
msgid "Can't open %s"
|
||||||
|
msgstr "îÅ ÍÏÇÕ ÏÔËÒÙÔØ %s"
|
||||||
|
|
||||||
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/config.c:316
|
||||||
|
msgid "sl_conf_showhelp(): wrong index"
|
||||||
|
msgstr "sl_conf_showhelp(): ÎÅ×ÅÒÎÙÊ ÉÎÄÅËÓ"
|
||||||
|
|
||||||
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/config.c:322
|
||||||
|
#, c-format
|
||||||
|
msgid "Configuration file options (format: key=value):\n"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/daemon.c:69
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/daemon.c:69
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "\n"
|
msgid "\n"
|
||||||
@ -23,159 +42,114 @@ msgid "\n"
|
|||||||
msgstr "\n"
|
msgstr "\n"
|
||||||
"ïÂÎÁÒÕÖÅÎ ÏÄÎÏÉÍÅÎÎÙÊ ÐÒÏÃÅÓÓ (pid=%d), ×ÙÈÏÄ.\n"
|
"ïÂÎÁÒÕÖÅÎ ÏÄÎÏÉÍÅÎÎÙÊ ÐÒÏÃÅÓÓ (pid=%d), ×ÙÈÏÄ.\n"
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:490
|
|
||||||
#, c-format
|
|
||||||
msgid "%s: need argument!"
|
|
||||||
msgstr "%s: ÎÅÏÂÈÏÄÉÍ ÁÒÇÕÍÅÎÔ!"
|
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/term2.c:119
|
|
||||||
msgid "Can't apply new TTY settings"
|
|
||||||
msgstr "îÅ ÍÏÇÕ ÓÍÅÎÉÔØ ÎÁÓÔÒÏÊËÉ ÐÏÒÔÁ"
|
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:266
|
|
||||||
msgid "Can't close mmap'ed file"
|
|
||||||
msgstr "îÅ ÍÏÇÕ ÚÁËÒÙÔØ mmap'ÎÕÔÙÊ ÆÁÊÌ"
|
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/term2.c:130
|
|
||||||
msgid "Can't do exclusive open"
|
|
||||||
msgstr "îÅ ÍÏÇÕ ÐÅÒÅ×ÅÓÔÉ ÐÏÒÔ × ÜËÓËÌÀÚÉ×ÎÙÊ ÒÅÖÉÍ"
|
|
||||||
|
|
||||||
#. Get settings
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/term2.c:106
|
|
||||||
msgid "Can't get old TTY settings"
|
|
||||||
msgstr "îÅ ÍÏÇÕ ÐÏÌÕÞÉÔØ ÄÅÊÓÔ×ÕÀÝÉÅ ÎÁÓÔÒÏÊËÉ ÐÏÒÔÁ"
|
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:279
|
|
||||||
msgid "Can't munmap"
|
|
||||||
msgstr "îÅ ÍÏÇÕ munmap"
|
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/config.c:273
|
|
||||||
#, c-format
|
|
||||||
msgid "Can't open %s"
|
|
||||||
msgstr "îÅ ÍÏÇÕ ÏÔËÒÙÔØ %s"
|
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:252
|
|
||||||
#, c-format
|
|
||||||
msgid "Can't open %s for reading"
|
|
||||||
msgstr "îÅ ÍÏÇÕ ÏÔËÒÙÔØ %s ÄÌÑ ÞÔÅÎÉÑ"
|
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:194
|
|
||||||
msgid "Can't open /dev/random"
|
|
||||||
msgstr "îÅ ÍÏÇÕ ÏÔËÒÙÔØ /dev/random"
|
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/daemon.c:141
|
|
||||||
msgid "Can't open PID file"
|
|
||||||
msgstr "îÅ ÍÏÇÕ ÏÔËÒÙÔØ PID ÆÁÊÌ"
|
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:198
|
|
||||||
msgid "Can't read /dev/random"
|
|
||||||
msgstr "îÅ ÍÏÇÕ ÐÒÏÞÅÓÔØ /dev/random"
|
|
||||||
|
|
||||||
#. error reading self name
|
#. error reading self name
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/daemon.c:117
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/daemon.c:117
|
||||||
msgid "Can't read self name"
|
msgid "Can't read self name"
|
||||||
msgstr "îÅ ÍÏÇÕ ÐÒÏÞÅÓÔØ ÉÍÑ ÐÒÏÃÅÓÓÁ"
|
msgstr "îÅ ÍÏÇÕ ÐÒÏÞÅÓÔØ ÉÍÑ ÐÒÏÃÅÓÓÁ"
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/term2.c:124
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/daemon.c:141
|
||||||
#, c-format
|
msgid "Can't open PID file"
|
||||||
msgid "Can't set speed %d, got ispeed=%d, ospeed=%d"
|
msgstr "îÅ ÍÏÇÕ ÏÔËÒÙÔØ PID ÆÁÊÌ"
|
||||||
msgstr "îÅ ÍÏÇÕ ÓÍÅÎÉÔØ ÓËÏÒÏÓÔØ ÎÁ %d; ispeed=%d, ospeed=%d"
|
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:347
|
#. amount of pcount and/or scount wrong
|
||||||
msgid "Can't setup console"
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:53
|
||||||
msgstr "îÅ ÍÏÇÕ ÎÁÓÔÒÏÉÔØ ËÏÎÓÏÌØ"
|
msgid "Wrong helpstring!"
|
||||||
|
msgstr "îÅÐÒÁ×ÉÌØÎÙÊ ÆÏÒÍÁÔ ÓÔÒÏËÉ ÐÏÍÏÝÉ"
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/socket.c:390
|
|
||||||
msgid "Can't start server handlers thread"
|
|
||||||
msgstr "îÅ ÍÏÇÕ ÚÁÐÕÓÔÉÔØ ÐÏÔÏË-ÏÂÒÁÂÏÔÞÉË ÓÅÒ×ÅÒÁ"
|
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:256
|
|
||||||
#, c-format
|
|
||||||
msgid "Can't stat %s"
|
|
||||||
msgstr "îÅ ÍÏÇÕ ×ÙÐÏÌÎÉÔØ stat %s"
|
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:166
|
|
||||||
msgid "Can't use multiple args with arg_none!"
|
|
||||||
msgstr "íÁÓÓÉ× ÐÁÒÁÍÅÔÒÏ× ÎÅ ÍÏÖÅÔ ÉÍÅÔØ ÔÉÐ arg_none!"
|
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/term2.c:102
|
|
||||||
#, c-format
|
|
||||||
msgid "Can't use port %s"
|
|
||||||
msgstr "îÅ ÍÏÇÕ ÉÓÐÏÌØÚÏ×ÁÔØ ÐÏÒÔ %s"
|
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:82
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:82
|
||||||
msgid "Integer out of range"
|
msgid "Integer out of range"
|
||||||
msgstr "ãÅÌÏÅ ×ÎÅ ÄÏÐÕÓÔÉÍÏÇÏ ÄÉÁÐÁÚÏÎÁ"
|
msgstr "ãÅÌÏÅ ×ÎÅ ÄÏÐÕÓÔÉÍÏÇÏ ÄÉÁÐÁÚÏÎÁ"
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/config.c:296
|
#. `opt` should be ':' for "missed arguments", '?' for "not found" and short flag if found and checked
|
||||||
|
#. not found
|
||||||
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:129
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Key '%s' have no argptr!"
|
msgid "No such parameter: `%s`\n"
|
||||||
msgstr "õ ËÌÀÞÁ '%s' ÎÅÔ ÕËÁÚÁÔÅÌÑ ÎÁ ÐÅÒÅÍÅÎÎÕÀ!"
|
msgstr "îÅÔ ÔÁËÏÇÏ ÐÁÒÁÍÅÔÒÁ: %s\n"
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/config.c:290
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:138
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Key '%s' need value"
|
msgid "Parameter `%s` needs value\n"
|
||||||
msgstr "ëÌÀÞ '%s' ÔÒÅÂÕÅÔ ÚÎÁÞÅÎÉÑ"
|
msgstr "ëÌÀÞ '%s' ÔÒÅÂÕÅÔ ÚÎÁÞÅÎÉÑ\n"
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/socket.c:459
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:163
|
||||||
msgid "Limit of connections reached"
|
msgid "Can't use multiple args with arg_none!"
|
||||||
msgstr "äÏÓÔÉÇÎÕÔ ÐÒÅÄÅÌ ÓÏÅÄÉÎÅÎÉÊ"
|
msgstr "íÁÓÓÉ× ÐÁÒÁÍÅÔÒÏ× ÎÅ ÍÏÖÅÔ ÉÍÅÔØ ÔÉÐ arg_none!"
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:262
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:267
|
||||||
msgid "Mmap error for input"
|
#, c-format
|
||||||
msgstr "ïÛÉÂËÁ mmap"
|
msgid "double long arguments: --%s"
|
||||||
|
msgstr "ÄÕÂÌÉÒÕÀÝÉÊÓÑ ÄÌÉÎÎÙÊ ÐÁÒÁÍÅÔÒ: --%s"
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:332
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:273
|
||||||
|
#, c-format
|
||||||
|
msgid "double short arguments: -%c"
|
||||||
|
msgstr "ÄÕÂÌÉÒÕÀÝÉÊÓÑ ËÏÒÏÔËÉÊ ÐÁÒÁÍÅÔÒ: -%c"
|
||||||
|
|
||||||
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:343
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Need argument with %s type\n"
|
msgid "Need argument with %s type\n"
|
||||||
msgstr "îÅÏÂÈÏÄÉÍ ÁÒÇÕÍÅÎÔ Ó ÔÉÐÏÍ %s\n"
|
msgstr "îÅÏÂÈÏÄÉÍ ÁÒÇÕÍÅÎÔ Ó ÔÉÐÏÍ %s\n"
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/term2.c:168
|
#. print only one message
|
||||||
msgid "Need non-zero buffer for TTY device"
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:435
|
||||||
msgstr "äÌÑ ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÇÏ ÕÓÔÒÏÊÓÔ×Á ÔÒÅÂÕÅÔÓÑ ÂÕÆÅÒ ÎÅÎÕÌÅ×ÏÇÏ ÒÁÚÍÅÒÁ"
|
msgid "sl_showhelp(): option index out of range"
|
||||||
|
msgstr "sl_showhelp(): ÉÎÄÅËÓ ÏÐÃÉÉ ×ÎÅ ÄÏÐÕÓÔÉÍÏÇÏ ÄÉÁÐÁÚÏÎÁ"
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:248
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:441
|
||||||
msgid "No filename given!"
|
#, c-format
|
||||||
msgstr "îÅ ÚÁÄÁÎÏ ÉÍÑ ÆÁÊÌÁ!"
|
msgid "Usage: %s [arguments]\n"
|
||||||
|
msgstr "éÓÐÏÌØÚÏ×ÁÎÉÅ: %s [ÁÒÇÕÍÅÎÔÙ]\n"
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:432
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:528
|
||||||
msgid "Number out of integer limits"
|
#, c-format
|
||||||
msgstr "þÉÓÌÏ ÚÁ ÐÒÅÄÅÌÁÍÉ int"
|
msgid "Wrong parameter: %s"
|
||||||
|
msgstr "îÅÐÒÁ×ÉÌØÎÙÊ ÐÁÒÁÍÅÔÒ: %s"
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/term2.c:162
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:532
|
||||||
msgid "Port name is missing"
|
#, c-format
|
||||||
msgstr "ïÔÓÕÔÓÔ×ÕÅÔ ÉÍÑ ÐÏÒÔÁ"
|
msgid "%s: need argument!"
|
||||||
|
msgstr "%s: ÎÅÏÂÈÏÄÉÍ ÁÒÇÕÍÅÎÔ!"
|
||||||
|
|
||||||
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:536
|
||||||
|
#, c-format
|
||||||
|
msgid "Wrong argument \"%s\" of parameter \"%s\""
|
||||||
|
msgstr "îÅÐÒÁ×ÉÌØÎÙÊ ÁÒÇÕÍÅÎÔ \"%s\" ÐÁÒÁÍÅÔÒÁ \"%s\""
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/socket.c:147
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/socket.c:147
|
||||||
msgid "Server disconnected"
|
msgid "Server disconnected"
|
||||||
msgstr "óÅÒ×ÅÒ ÏÔËÌÀÞÅÎ"
|
msgstr "óÅÒ×ÅÒ ÏÔËÌÀÞÅÎ"
|
||||||
|
|
||||||
#. buffer overflow
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/socket.c:385
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/socket.c:530
|
msgid "Can't start server handlers thread"
|
||||||
#, c-format
|
msgstr "îÅ ÍÏÇÕ ÚÁÐÕÓÔÉÔØ ÐÏÔÏË-ÏÂÒÁÂÏÔÞÉË ÓÅÒ×ÅÒÁ"
|
||||||
msgid "Server thread: buffer overflow from fd=%d"
|
|
||||||
msgstr "ðÏÔÏË ÓÅÒ×ÅÒÁ: ÐÅÒÅÐÏÌÎÅÎÉÅ ÂÕÆÅÒÁ ÏÔ fd=%d"
|
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/socket.c:518
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/socket.c:454
|
||||||
#, fuzzy, c-format
|
msgid "Limit of connections reached"
|
||||||
msgid "Server thread: can't write data to ringbuffer: overflow from fd=%d"
|
msgstr "äÏÓÔÉÇÎÕÔ ÐÒÅÄÅÌ ÓÏÅÄÉÎÅÎÉÊ"
|
||||||
msgstr "ðÏÔÏË ÓÅÒ×ÅÒÁ: ÎÅ ÍÏÇÕ ÓÏÈÒÁÎÉÔØ ÄÁÎÎÙÅ × ËÏÌØÃÅ×ÏÍ ÂÕÆÅÒÅ, "
|
|
||||||
"ÐÅÒÅÐÏÌÎÅÎÉÅ ÏÔ fd=%d"
|
|
||||||
|
|
||||||
#. check for RB overflow
|
#. check for RB overflow
|
||||||
#. -1 - buffer empty (can't be), -2 - buffer overflow
|
#. -1 - buffer empty (can't be), -2 - buffer overflow
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/socket.c:503
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/socket.c:498
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/socket.c:504
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/socket.c:499
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Server thread: ring buffer overflow for fd=%d"
|
msgid "Server thread: ring buffer overflow for fd=%d"
|
||||||
msgstr "ðÏÔÏË ÓÅÒ×ÅÒÁ: ÐÅÒÅÐÏÌÎÅÎÉÅ ÂÕÆÅÒÁ ÏÔ fd=%d"
|
msgstr "ðÏÔÏË ÓÅÒ×ÅÒÁ: ÐÅÒÅÐÏÌÎÅÎÉÅ ÂÕÆÅÒÁ ÏÔ fd=%d"
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/config.c:226
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/socket.c:513
|
||||||
msgid "Unsupported option type"
|
#, c-format
|
||||||
msgstr "îÅÐÏÄÄÅÒÖÉ×ÁÅÍÙÊ ÔÉÐ ÏÐÃÉÉ"
|
msgid "Server thread: can't write data to ringbuffer: overflow from fd=%d"
|
||||||
|
msgstr "ðÏÔÏË ÓÅÒ×ÅÒÁ: ÎÅ ÍÏÇÕ ÓÏÈÒÁÎÉÔØ ÄÁÎÎÙÅ × ËÏÌØÃÅ×ÏÍ ÂÕÆÅÒÅ, "
|
||||||
|
"ÐÅÒÅÐÏÌÎÅÎÉÅ ÏÔ fd=%d"
|
||||||
|
|
||||||
|
#. buffer overflow
|
||||||
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/socket.c:525
|
||||||
|
#, c-format
|
||||||
|
msgid "Server thread: buffer overflow from fd=%d"
|
||||||
|
msgstr "ðÏÔÏË ÓÅÒ×ÅÒÁ: ÐÅÒÅÐÏÌÎÅÎÉÅ ÂÕÆÅÒÁ ÏÔ fd=%d"
|
||||||
|
|
||||||
#. never reached
|
#. never reached
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/socket.c:620
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/socket.c:615
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Unsupported socket type %d"
|
msgid "Unsupported socket type %d"
|
||||||
msgstr "îÅÐÏÄÄÅÒÖÉ×ÁÅÍÙÊ ÔÉÐ ÓÏËÅÔÁ %d"
|
msgstr "îÅÐÏÄÄÅÒÖÉ×ÁÅÍÙÊ ÔÉÐ ÓÏËÅÔÁ %d"
|
||||||
@ -187,48 +161,71 @@ msgid "Wrong USART format \"%s\"; use NPS, where N: 5..8; P: N/E/O/1/0, S: "
|
|||||||
msgstr "îÅÐÒÁ×ÉÌØÎÙÊ ÆÏÒÍÁÔ USART \"%s\"; ÎÕÖÅÎ NPS, ÇÄÅ N: 5..8; P: N/E/O/"
|
msgstr "îÅÐÒÁ×ÉÌØÎÙÊ ÆÏÒÍÁÔ USART \"%s\"; ÎÕÖÅÎ NPS, ÇÄÅ N: 5..8; P: N/E/O/"
|
||||||
"1/0, S: 1/2"
|
"1/0, S: 1/2"
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:494
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/term2.c:102
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Wrong argument \"%s\" of parameter \"%s\""
|
msgid "Can't use port %s"
|
||||||
msgstr "îÅÐÒÁ×ÉÌØÎÙÊ ÁÒÇÕÍÅÎÔ \"%s\" ÐÁÒÁÍÅÔÒÁ \"%s\""
|
msgstr "îÅ ÍÏÇÕ ÉÓÐÏÌØÚÏ×ÁÔØ ÐÏÒÔ %s"
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:403
|
#. Get settings
|
||||||
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/term2.c:106
|
||||||
|
msgid "Can't get old TTY settings"
|
||||||
|
msgstr "îÅ ÍÏÇÕ ÐÏÌÕÞÉÔØ ÄÅÊÓÔ×ÕÀÝÉÅ ÎÁÓÔÒÏÊËÉ ÐÏÒÔÁ"
|
||||||
|
|
||||||
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/term2.c:119
|
||||||
|
msgid "Can't apply new TTY settings"
|
||||||
|
msgstr "îÅ ÍÏÇÕ ÓÍÅÎÉÔØ ÎÁÓÔÒÏÊËÉ ÐÏÒÔÁ"
|
||||||
|
|
||||||
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/term2.c:124
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Wrong double number format '%s'"
|
msgid "Can't set speed %d, got ispeed=%d, ospeed=%d"
|
||||||
msgstr "îÅÐÒÁ×ÉÌØÎÙÊ ÆÏÒÍÁÔ double: %s"
|
msgstr "îÅ ÍÏÇÕ ÓÍÅÎÉÔØ ÓËÏÒÏÓÔØ ÎÁ %d; ispeed=%d, ospeed=%d"
|
||||||
|
|
||||||
#. amount of pcount and/or scount wrong
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/term2.c:130
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:53
|
msgid "Can't do exclusive open"
|
||||||
msgid "Wrong helpstring!"
|
msgstr "îÅ ÍÏÇÕ ÐÅÒÅ×ÅÓÔÉ ÐÏÒÔ × ÜËÓËÌÀÚÉ×ÎÙÊ ÒÅÖÉÍ"
|
||||||
msgstr "îÅÐÒÁ×ÉÌØÎÙÊ ÆÏÒÍÁÔ ÓÔÒÏËÉ ÐÏÍÏÝÉ"
|
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:416
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/term2.c:162
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:428
|
msgid "Port name is missing"
|
||||||
|
msgstr "ïÔÓÕÔÓÔ×ÕÅÔ ÉÍÑ ÐÏÒÔÁ"
|
||||||
|
|
||||||
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/term2.c:168
|
||||||
|
msgid "Need non-zero buffer for TTY device"
|
||||||
|
msgstr "äÌÑ ÐÏÓÌÅÄÏ×ÁÔÅÌØÎÏÇÏ ÕÓÔÒÏÊÓÔ×Á ÔÒÅÂÕÅÔÓÑ ÂÕÆÅÒ ÎÅÎÕÌÅ×ÏÇÏ ÒÁÚÍÅÒÁ"
|
||||||
|
|
||||||
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:194
|
||||||
|
msgid "Can't open /dev/random"
|
||||||
|
msgstr "îÅ ÍÏÇÕ ÏÔËÒÙÔØ /dev/random"
|
||||||
|
|
||||||
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:198
|
||||||
|
msgid "Can't read /dev/random"
|
||||||
|
msgstr "îÅ ÍÏÇÕ ÐÒÏÞÅÓÔØ /dev/random"
|
||||||
|
|
||||||
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:248
|
||||||
|
msgid "No filename given!"
|
||||||
|
msgstr "îÅ ÚÁÄÁÎÏ ÉÍÑ ÆÁÊÌÁ!"
|
||||||
|
|
||||||
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:252
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Wrong integer number format '%s'"
|
msgid "Can't open %s for reading"
|
||||||
msgstr "îÅÐÒÁ×ÉÌØÎÙÊ ÆÏÒÍÁÔ ÃÅÌÏÇÏ: %s"
|
msgstr "îÅ ÍÏÇÕ ÏÔËÒÙÔØ %s ÄÌÑ ÞÔÅÎÉÑ"
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/config.c:284
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:256
|
||||||
#, c-format
|
#, c-format
|
||||||
msgid "Wrong key: '%s'"
|
msgid "Can't stat %s"
|
||||||
msgstr "îÅÐÒÁ×ÉÌØÎÙÊ ËÌÀÞ: %s"
|
msgstr "îÅ ÍÏÇÕ ×ÙÐÏÌÎÉÔØ stat %s"
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/config.c:229
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:262
|
||||||
#, c-format
|
msgid "Mmap error for input"
|
||||||
msgid "Wrong number format '%s'"
|
msgstr "ïÛÉÂËÁ mmap"
|
||||||
msgstr "îÅÐÒÁ×ÉÌØÎÙÊ ÆÏÒÍÁÔ ÞÉÓÌÁ: %s"
|
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:486
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:266
|
||||||
#, c-format
|
msgid "Can't close mmap'ed file"
|
||||||
msgid "Wrong parameter: %s"
|
msgstr "îÅ ÍÏÇÕ ÚÁËÒÙÔØ mmap'ÎÕÔÙÊ ÆÁÊÌ"
|
||||||
msgstr "îÅÐÒÁ×ÉÌØÎÙÊ ÐÁÒÁÍÅÔÒ: %s"
|
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:267
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:279
|
||||||
#, c-format
|
msgid "Can't munmap"
|
||||||
msgid "double long arguments: --%s"
|
msgstr "îÅ ÍÏÇÕ munmap"
|
||||||
msgstr "ÄÕÂÌÉÒÕÀÝÉÊÓÑ ÄÌÉÎÎÙÊ ÐÁÒÁÍÅÔÒ: --%s"
|
|
||||||
|
|
||||||
#: /home/eddy/Docs/SAO/C_diff/snippets_library/parseargs.c:273
|
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:347
|
||||||
#, c-format
|
msgid "Can't setup console"
|
||||||
msgid "double short arguments: -%c"
|
msgstr "îÅ ÍÏÇÕ ÎÁÓÔÒÏÉÔØ ËÏÎÓÏÌØ"
|
||||||
msgstr "ÄÕÂÌÉÒÕÀÝÉÊÓÑ ËÏÒÏÔËÉÊ ÐÁÒÁÍÅÔÒ: -%c"
|
|
||||||
|
|||||||
226
parseargs.c
226
parseargs.c
@ -30,7 +30,7 @@
|
|||||||
#include <ctype.h> // isalpha
|
#include <ctype.h> // isalpha
|
||||||
#include "usefull_macros.h"
|
#include "usefull_macros.h"
|
||||||
|
|
||||||
char *helpstring = "%s\n";
|
const char *helpstring = NULL; // will be inited later, can't init with gettext on this stage
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief sl_helpstring - change standard help header
|
* @brief sl_helpstring - change standard help header
|
||||||
@ -115,36 +115,33 @@ static int myatod(void *num, const char *str, sl_argtype_e t){
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief get_optind - get index of current option in array options
|
* @brief get_optind - get index of current option in array options
|
||||||
|
* @param key (i) - original key (short or long)
|
||||||
* @param opt (i) - returning val of getopt_long
|
* @param opt (i) - returning val of getopt_long
|
||||||
* @param options (i) - array of options
|
* @param options (i) - array of options
|
||||||
* @return index in array
|
* @return index in array
|
||||||
*/
|
*/
|
||||||
static int get_optind(int opt, sl_option_t *options){
|
static int get_optind(const char *key, int opt, sl_option_t *options, void (*helpfun)(int, sl_option_t*)){
|
||||||
int oind;
|
int oind = 0, theopt = opt;
|
||||||
sl_option_t *opts = options;
|
sl_option_t *opts = options;
|
||||||
assert(opts);
|
assert(opts);
|
||||||
for(oind = 0; opts->name && opts->val != opt; oind++, opts++){
|
// `opt` should be ':' for "missed arguments", '?' for "not found" and short flag if found and checked
|
||||||
DBG("cmp %c and %c", opt, opts->val);
|
if(opt == '?'){ // not found
|
||||||
|
fprintf(stderr, _("No such parameter: `%s`\n"), key);
|
||||||
|
helpfun(-1, options);
|
||||||
|
return -1; // never reached until `helpfun` changed
|
||||||
|
}else if(opt == ':') theopt = optopt; // search to show helpstring "need parameter"
|
||||||
|
for(oind = 0; opts->help && opts->val != theopt; oind++, opts++){
|
||||||
|
DBG("cmp %c and %c", theopt, opts->val);
|
||||||
|
}
|
||||||
|
if(!opts->help) return -1;
|
||||||
|
if(opt == ':'){
|
||||||
|
fprintf(stderr, _("Parameter `%s` needs value\n"), key);
|
||||||
|
helpfun(oind, options);
|
||||||
|
return -1; // never reached until `helpfun` changed
|
||||||
}
|
}
|
||||||
if(!opts->name || opts->val != opt) // no such parameter
|
|
||||||
sl_showhelp(-1, options);
|
|
||||||
return oind;
|
return oind;
|
||||||
}
|
}
|
||||||
#if 0
|
|
||||||
static int get_optindl(struct option *opt, sl_option_t *options){
|
|
||||||
int oind;
|
|
||||||
sl_option_t *opts = options;
|
|
||||||
assert(opts);
|
|
||||||
for(oind = 0; opts->name; ){
|
|
||||||
DBG("cmp '%s' and '%s'", opt->name, opts->name);
|
|
||||||
if(0 == strcmp(opt->name, opts->name)) break;
|
|
||||||
oind++, opts++;
|
|
||||||
}
|
|
||||||
if(!opts->name || strcmp(opt->name, opts->name)) // no such parameter
|
|
||||||
sl_showhelp(-1, options);
|
|
||||||
return oind;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief get_aptr - reallocate new value in array of multiple repeating arguments
|
* @brief get_aptr - reallocate new value in array of multiple repeating arguments
|
||||||
@ -194,41 +191,38 @@ void *get_aptr(void *paptr, sl_argtype_e type){
|
|||||||
return aptr[i - 1];
|
return aptr[i - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief sl_parseargs - parse command line arguments
|
* @brief sl_parseargs_hf - parse arguments with user help funtion
|
||||||
* ! If arg is string, then value will be strdup'ed!
|
* @param argc - amount of arguments
|
||||||
*
|
* @param argv - arguments
|
||||||
* @param argc (io) - address of argc of main(), return value of argc stay after `getopt`
|
* @param options - array with opts
|
||||||
* @param argv (io) - address of argv of main(), return pointer to argv stay after `getopt`
|
* @param helpfun - function called in case of wrong arg
|
||||||
* BE CAREFUL! if you wanna use full argc & argv, save their original values before
|
*/
|
||||||
* calling this function
|
void sl_parseargs_hf(int *argc, char ***argv, sl_option_t *options, void (*helpfun)(int, sl_option_t*)){
|
||||||
* @param options (i) - array of `myoption` for arguments parcing
|
|
||||||
*
|
|
||||||
* @exit: in case of error this function show help & make `exit(-1)`
|
|
||||||
*/
|
|
||||||
void sl_parseargs(int *argc, char ***argv, sl_option_t *options){
|
|
||||||
char *short_options, *soptr;
|
char *short_options, *soptr;
|
||||||
struct option *long_options, *loptr;
|
struct option *long_options, *loptr;
|
||||||
size_t optsize, i;
|
int optsize = 0;
|
||||||
sl_option_t *opts = options;
|
sl_option_t *opts = options;
|
||||||
// check whether there is at least one options
|
// check whether there is at least one options
|
||||||
assert(opts);
|
assert(opts);
|
||||||
assert(opts[0].name);
|
//assert(opts[0].name);
|
||||||
// first we count how much values are in opts
|
// first we count how much values are in opts
|
||||||
for(optsize = 0; opts->name; optsize++, opts++);
|
for(optsize = 0; opts->help; optsize++, opts++);
|
||||||
// now we can allocate memory
|
// now we can allocate memory
|
||||||
short_options = calloc(optsize * 3 + 1, 1); // multiply by three for '::' in case of args in opts
|
// TODO: FREE all unneeded memory at end of function
|
||||||
|
short_options = calloc(optsize * 3 + 2, 1); // multiply by three for '::' in case of args in opts, add 1 for starting ':'
|
||||||
long_options = calloc(optsize + 1, sizeof(struct option));
|
long_options = calloc(optsize + 1, sizeof(struct option));
|
||||||
opts = options; loptr = long_options; soptr = short_options;
|
opts = options; loptr = long_options; soptr = short_options;
|
||||||
|
*soptr++ = ':';
|
||||||
// check the parameters are not repeated
|
// check the parameters are not repeated
|
||||||
char **longlist = MALLOC(char*, optsize);
|
char **longlist = MALLOC(char*, optsize);
|
||||||
char *shortlist = MALLOC(char, optsize);
|
char *shortlist = MALLOC(char, optsize);
|
||||||
// fill short/long parameters and make a simple checking
|
// fill short/long parameters and make a simple checking
|
||||||
for(i = 0; i < optsize; i++, loptr++, opts++){
|
for(int i = 0; i < optsize; i++, loptr++, opts++){
|
||||||
// check
|
// check
|
||||||
assert(opts->name); // check name
|
//assert(opts->name); // check name
|
||||||
longlist[i] = strdup(opts->name);
|
DBG("opts: val=%c, name=%s", opts->val, opts->name);
|
||||||
|
longlist[i] = opts->name ? strdup(opts->name) : NULL;
|
||||||
if(opts->has_arg){
|
if(opts->has_arg){
|
||||||
assert(opts->type != arg_none); // check error with arg type
|
assert(opts->type != arg_none); // check error with arg type
|
||||||
assert(opts->argptr); // check pointer
|
assert(opts->argptr); // check pointer
|
||||||
@ -237,7 +231,7 @@ void sl_parseargs(int *argc, char ***argv, sl_option_t *options){
|
|||||||
assert(opts->argptr);
|
assert(opts->argptr);
|
||||||
// fill long_options
|
// fill long_options
|
||||||
// don't do memcmp: what if there would be different alignment?
|
// don't do memcmp: what if there would be different alignment?
|
||||||
loptr->name = opts->name;
|
loptr->name = opts->name ? opts->name : "";
|
||||||
loptr->has_arg = (opts->has_arg < MULT_PAR) ? opts->has_arg : 1;
|
loptr->has_arg = (opts->has_arg < MULT_PAR) ? opts->has_arg : 1;
|
||||||
loptr->flag = opts->flag;
|
loptr->flag = opts->flag;
|
||||||
loptr->val = opts->val;
|
loptr->val = opts->val;
|
||||||
@ -253,7 +247,12 @@ void sl_parseargs(int *argc, char ***argv, sl_option_t *options){
|
|||||||
}
|
}
|
||||||
// sort all lists & check for repeating
|
// sort all lists & check for repeating
|
||||||
int cmpstringp(const void *p1, const void *p2){
|
int cmpstringp(const void *p1, const void *p2){
|
||||||
return strcmp(* (char * const *) p1, * (char * const *) p2);
|
if(!p1 || !p2) return 0;
|
||||||
|
const char *str1 = * (char * const *) p1, *str2 = * (char * const *) p2;
|
||||||
|
if(!str1 && !str2) return 0;
|
||||||
|
else if(!str1) return 1;
|
||||||
|
else if(!str2) return -1;
|
||||||
|
return strcmp(str1, str2);
|
||||||
}
|
}
|
||||||
int cmpcharp(const void *p1, const void *p2){
|
int cmpcharp(const void *p1, const void *p2){
|
||||||
return (int)(*(char * const)p1 - *(char *const)p2);
|
return (int)(*(char * const)p1 - *(char *const)p2);
|
||||||
@ -261,8 +260,9 @@ void sl_parseargs(int *argc, char ***argv, sl_option_t *options){
|
|||||||
qsort(longlist, optsize, sizeof(char *), cmpstringp);
|
qsort(longlist, optsize, sizeof(char *), cmpstringp);
|
||||||
qsort(shortlist,optsize, sizeof(char), cmpcharp);
|
qsort(shortlist,optsize, sizeof(char), cmpcharp);
|
||||||
char *prevl = longlist[0], prevshrt = shortlist[0];
|
char *prevl = longlist[0], prevshrt = shortlist[0];
|
||||||
for(i = 1; i < optsize; ++i){
|
// check for repeated args
|
||||||
if(longlist[i]){
|
for(int i = 1; i < optsize; ++i){
|
||||||
|
if(longlist[i] && *longlist[i]){
|
||||||
if(prevl){
|
if(prevl){
|
||||||
if(strcmp(prevl, longlist[i]) == 0) ERRX(_("double long arguments: --%s"), prevl);
|
if(strcmp(prevl, longlist[i]) == 0) ERRX(_("double long arguments: --%s"), prevl);
|
||||||
}
|
}
|
||||||
@ -275,21 +275,32 @@ void sl_parseargs(int *argc, char ***argv, sl_option_t *options){
|
|||||||
prevshrt = shortlist[i];
|
prevshrt = shortlist[i];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
FREE(longlist); FREE(shortlist);
|
||||||
|
#ifdef EBUG
|
||||||
|
DBG("Argc=%d, argv[0]=%s, argv[1]=%s, short=%s", *argc, (*argv)[0], (*argv)[1], short_options);
|
||||||
|
for(int _ = 0; _ <= optsize; ++_) fprintf(stderr, "\tlo[%d]='%s'\n", _, long_options[_].name);
|
||||||
|
DBG("AND argv:");
|
||||||
|
for(int _ = 0; _ < *argc; ++_) fprintf(stderr, "\t[%d]='%s'\n", _ ,(*argv)[_]);
|
||||||
|
#endif
|
||||||
|
// reinit global `optind` for ability of sequentional run
|
||||||
|
optind = 1;
|
||||||
// now we have both long_options & short_options and can parse `getopt_long`
|
// now we have both long_options & short_options and can parse `getopt_long`
|
||||||
while(1){
|
while(1){
|
||||||
int opt;
|
int opt;
|
||||||
int /*oindex = -1,*/ optind = -1; // oindex - number of option in long_options, optind - number in options[]
|
int /*oindex = -1,*/ loptind = -1; // oindex - number of option in long_options, optind - number in options[]
|
||||||
if((opt = getopt_long(*argc, *argv, short_options, long_options, &optind)) == -1) break;
|
DBG("optind=%d", optind);
|
||||||
DBG("%c(%d) = getopt_long(argc, argv, %s, long_options, &%d); optopt=%c(%d), errno=%d", opt, opt, short_options, optind, optopt, optopt, errno);
|
const char *curopt = (*argv)[optind];
|
||||||
if(optind < 0 ) optind = get_optind(opt, options); // find short option -> need to know index of long
|
if((opt = getopt_long(*argc, *argv, short_options, long_options, &loptind)) == -1) break;
|
||||||
|
DBG("search `%s`, %c(%d) = getopt_long(argc, argv, %s, long_options, &%d); optopt=%c(%d), errno=%d", curopt, opt, opt, short_options, loptind, optopt, optopt, errno);
|
||||||
|
if(loptind < 0 ) loptind = get_optind(curopt, opt, options, helpfun); // find short option -> need to know index of long
|
||||||
|
if(loptind < 0 || loptind >= optsize) continue;
|
||||||
// be careful with "-?" flag: all wrong or ambiguous flags will be interpreted as this!
|
// be careful with "-?" flag: all wrong or ambiguous flags will be interpreted as this!
|
||||||
DBG("index=%d", optind);
|
DBG("index=%d", loptind);
|
||||||
opts = &options[optind];
|
opts = &options[loptind];
|
||||||
DBG("Got option %s", opts->name);
|
DBG("Got option %s (%c)", opts->name, opts->val);
|
||||||
|
|
||||||
// now check option
|
// now check option
|
||||||
if(opts->has_arg == NEED_ARG || opts->has_arg == MULT_PAR)
|
if(opts->has_arg == NEED_ARG || opts->has_arg == MULT_PAR)
|
||||||
if(!optarg) sl_showhelp(optind, options); // need argument
|
if(!optarg) helpfun(loptind, options); // need argument
|
||||||
void *aptr;
|
void *aptr;
|
||||||
if(opts->has_arg == MULT_PAR){
|
if(opts->has_arg == MULT_PAR){
|
||||||
aptr = get_aptr(opts->argptr, opts->type);
|
aptr = get_aptr(opts->argptr, opts->type);
|
||||||
@ -303,39 +314,55 @@ void sl_parseargs(int *argc, char ***argv, sl_option_t *options){
|
|||||||
default:
|
default:
|
||||||
case arg_none:
|
case arg_none:
|
||||||
if(opts->argptr) *((int*)aptr) += 1; // increment value
|
if(opts->argptr) *((int*)aptr) += 1; // increment value
|
||||||
break;
|
break;
|
||||||
case arg_int:
|
case arg_int:
|
||||||
result = myatoll(aptr, optarg, arg_int);
|
result = myatoll(aptr, optarg, arg_int);
|
||||||
type = "integer";
|
type = "integer";
|
||||||
break;
|
break;
|
||||||
case arg_longlong:
|
case arg_longlong:
|
||||||
result = myatoll(aptr, optarg, arg_longlong);
|
result = myatoll(aptr, optarg, arg_longlong);
|
||||||
type = "long long";
|
type = "long long";
|
||||||
break;
|
break;
|
||||||
case arg_double:
|
case arg_double:
|
||||||
result = myatod(aptr, optarg, arg_double);
|
result = myatod(aptr, optarg, arg_double);
|
||||||
type = "double";
|
type = "double";
|
||||||
break;
|
break;
|
||||||
case arg_float:
|
case arg_float:
|
||||||
result = myatod(aptr, optarg, arg_float);
|
result = myatod(aptr, optarg, arg_float);
|
||||||
type = "float";
|
type = "float";
|
||||||
break;
|
break;
|
||||||
case arg_string:
|
case arg_string:
|
||||||
result = (*((void**)aptr) = (void*)strdup(optarg)) != NULL;
|
result = (*((void**)aptr) = (void*)strdup(optarg)) != NULL;
|
||||||
type = "string";
|
type = "string";
|
||||||
break;
|
break;
|
||||||
case arg_function:
|
case arg_function:
|
||||||
result = ((sl_argfn_t)aptr)(optarg);
|
result = ((sl_argfn_t)aptr)(optarg);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(!result){
|
if(!result){
|
||||||
if(type) fprintf(stderr, _("Need argument with %s type\n"), type);
|
if(type) fprintf(stderr, _("Need argument with %s type\n"), type);
|
||||||
sl_showhelp(optind, options);
|
helpfun(loptind, options);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
FREE(short_options); FREE(long_options);
|
||||||
*argc -= optind;
|
*argc -= optind;
|
||||||
*argv += optind;
|
*argv += optind;
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* @brief sl_parseargs - parse command line arguments
|
||||||
|
* ! If arg is string, then value will be strdup'ed!
|
||||||
|
*
|
||||||
|
* @param argc (io) - address of argc of main(), return value of argc stay after `getopt`
|
||||||
|
* @param argv (io) - address of argv of main(), return pointer to argv stay after `getopt`
|
||||||
|
* BE CAREFUL! if you wanna use full argc & argv, save their original values before
|
||||||
|
* calling this function
|
||||||
|
* @param options (i) - array of `myoption` for arguments parcing
|
||||||
|
*
|
||||||
|
* @exit: in case of error this function show help & make `exit(-1)`
|
||||||
|
*/
|
||||||
|
void sl_parseargs(int *argc, char ***argv, sl_option_t *options){
|
||||||
|
sl_parseargs_hf(argc, argv, options, sl_showhelp);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief argsort - compare function for qsort
|
* @brief argsort - compare function for qsort
|
||||||
@ -350,6 +377,7 @@ static int argsort(const void *a1, const void *a2){
|
|||||||
if(f1 == NULL && f2 == NULL && s1 && s2){ // both have short arg
|
if(f1 == NULL && f2 == NULL && s1 && s2){ // both have short arg
|
||||||
return (s1 - s2);
|
return (s1 - s2);
|
||||||
}else if((f1 != NULL || !s1) && (f2 != NULL || !s2)){ // both don't have short arg - sort by long
|
}else if((f1 != NULL || !s1) && (f2 != NULL || !s2)){ // both don't have short arg - sort by long
|
||||||
|
assert(l1); assert(l2); // no way to omit long option if short is absent
|
||||||
return strcmp(l1, l2);
|
return strcmp(l1, l2);
|
||||||
}else{ // only one have short arg -- return it
|
}else{ // only one have short arg -- return it
|
||||||
if(f2 || !s2) return -1; // a1 have short - it is 'lesser'
|
if(f2 || !s2) return -1; // a1 have short - it is 'lesser'
|
||||||
@ -357,6 +385,34 @@ static int argsort(const void *a1, const void *a2){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// print one string of help
|
||||||
|
static void pr_helpstring(sl_option_t *opt, char *buf, int indent, size_t bufsz){
|
||||||
|
size_t p = sprintf(buf, " "); // a little indent
|
||||||
|
int havelongopt = opt->name && *opt->name;
|
||||||
|
if(!opt->flag && opt->val){ // .val is short argument
|
||||||
|
p += snprintf(buf+p, bufsz-p, "-%c", opt->val);
|
||||||
|
if(havelongopt) p += snprintf(buf+p, bufsz-p, ", "); // show comma only it there's shor arg
|
||||||
|
}
|
||||||
|
if(havelongopt){
|
||||||
|
p += snprintf(buf+p, bufsz-p, "--%s", opt->name);
|
||||||
|
if(opt->has_arg == NEED_ARG || opt->has_arg == MULT_PAR) // required argument
|
||||||
|
p += snprintf(buf+p, bufsz-p, "=arg");
|
||||||
|
else if(opt->has_arg == OPT_ARG) // optional argument
|
||||||
|
p += snprintf(buf+p, bufsz-p, "[=arg]");
|
||||||
|
}else{
|
||||||
|
if(opt->has_arg == NEED_ARG || opt->has_arg == MULT_PAR)
|
||||||
|
p += snprintf(buf+p, bufsz-p, " arg");
|
||||||
|
else if(opt->has_arg == OPT_ARG)
|
||||||
|
p += snprintf(buf+p, bufsz-p, " [arg]");
|
||||||
|
}
|
||||||
|
if(indent > 0){
|
||||||
|
assert(p < (size_t)indent);
|
||||||
|
printf("%-*s%s", indent+1, buf, _(opt->help)); // write options & at least 2 spaces after
|
||||||
|
}else printf("%s %s", buf, _(opt->help));
|
||||||
|
if(opt->has_arg == MULT_PAR) printf(" (can occur multiple times)");
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief sl_showhelp - show help information based on sl_option_t->help values
|
* @brief sl_showhelp - show help information based on sl_option_t->help values
|
||||||
* @param oindex (i) - if non-negative, show only help by sl_option_t[oindex].help
|
* @param oindex (i) - if non-negative, show only help by sl_option_t[oindex].help
|
||||||
@ -370,49 +426,35 @@ void sl_showhelp(int oindex, sl_option_t *options){
|
|||||||
char buf[bufsz+1];
|
char buf[bufsz+1];
|
||||||
sl_option_t *opts = options;
|
sl_option_t *opts = options;
|
||||||
assert(opts);
|
assert(opts);
|
||||||
assert(opts[0].name); // check whether there is at least one options
|
assert(opts[0].help); // check whether there is at least one options
|
||||||
|
// count amount of options
|
||||||
|
int N; for(N = 0; opts->help; ++N, ++opts);
|
||||||
|
if(N == 0) exit(-2);
|
||||||
|
DBG("got %d options, oindex=%d", N, oindex);
|
||||||
if(oindex > -1){ // print only one message
|
if(oindex > -1){ // print only one message
|
||||||
opts = &options[oindex];
|
if(oindex >= N || oindex < 0) ERRX(_("sl_showhelp(): option index out of range"));
|
||||||
printf(" ");
|
pr_helpstring(&options[oindex], buf, 0, bufsz);
|
||||||
if(!opts->flag && isalpha(opts->val)) printf("-%c, ", opts->val);
|
|
||||||
printf("--%s", opts->name);
|
|
||||||
if(opts->has_arg == 1) printf("=arg");
|
|
||||||
else if(opts->has_arg == 2) printf("[=arg]");
|
|
||||||
printf(" %s\n", _(opts->help));
|
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
// header, by default is just "progname\n"
|
// header, by default is just "progname\n"
|
||||||
printf("\n");
|
printf("\n");
|
||||||
|
if(!helpstring) helpstring = _("Usage: %s [arguments]\n");
|
||||||
if(strstr(helpstring, "%s")) // print progname
|
if(strstr(helpstring, "%s")) // print progname
|
||||||
printf(helpstring, __progname);
|
printf(helpstring, __progname);
|
||||||
else // only text
|
else // only text
|
||||||
printf("%s", helpstring);
|
printf("%s", helpstring);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
// count max_opt_len
|
// count max_opt_len
|
||||||
do{
|
for(int _ = 0; _ < N; ++_){
|
||||||
int L = strlen(opts->name);
|
if(!options[_].name) continue;
|
||||||
|
int L = strlen(options[_].name);
|
||||||
if(max_opt_len < L) max_opt_len = L;
|
if(max_opt_len < L) max_opt_len = L;
|
||||||
}while((++opts)->name);
|
}
|
||||||
max_opt_len += 14; // format: '-S , --long[=arg]' - get addition 13 symbols
|
max_opt_len += 14; // format: '-S, --long[=arg]' - get addition 13 symbols
|
||||||
opts = options;
|
|
||||||
// count amount of options
|
|
||||||
int N; for(N = 0; opts->name; ++N, ++opts);
|
|
||||||
if(N == 0) exit(-2);
|
|
||||||
// Now print all help (sorted)
|
// Now print all help (sorted)
|
||||||
opts = options;
|
qsort(options, N, sizeof(sl_option_t), argsort);
|
||||||
qsort(opts, N, sizeof(sl_option_t), argsort);
|
|
||||||
do{
|
do{
|
||||||
int p = sprintf(buf, " "); // a little indent
|
pr_helpstring(options++, buf, max_opt_len, bufsz);
|
||||||
if(!opts->flag && opts->val) // .val is short argument
|
|
||||||
p += snprintf(buf+p, bufsz-p, "-%c, ", opts->val);
|
|
||||||
p += snprintf(buf+p, bufsz-p, "--%s", opts->name);
|
|
||||||
if(opts->has_arg == 1) // required argument
|
|
||||||
p += snprintf(buf+p, bufsz-p, "=arg");
|
|
||||||
else if(opts->has_arg == 2) // optional argument
|
|
||||||
p += snprintf(buf+p, bufsz-p, "[=arg]");
|
|
||||||
assert(p < max_opt_len); // there would be magic if p >= max_opt_len
|
|
||||||
printf("%-*s%s\n", max_opt_len+1, buf, _(opts->help)); // write options & at least 2 spaces after
|
|
||||||
++opts;
|
|
||||||
}while(--N);
|
}while(--N);
|
||||||
printf("\n\n");
|
printf("\n\n");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
|
|||||||
@ -326,6 +326,7 @@ typedef struct{
|
|||||||
extern const char *__progname;
|
extern const char *__progname;
|
||||||
|
|
||||||
void sl_showhelp(int oindex, sl_option_t *options);
|
void sl_showhelp(int oindex, sl_option_t *options);
|
||||||
|
void sl_parseargs_hf(int *argc, char ***argv, sl_option_t *options, void (*helpfun)(int, sl_option_t*));
|
||||||
void sl_parseargs(int *argc, char ***argv, sl_option_t *options);
|
void sl_parseargs(int *argc, char ***argv, sl_option_t *options);
|
||||||
/**
|
/**
|
||||||
* @brief sl_helpstring - change standard help header
|
* @brief sl_helpstring - change standard help header
|
||||||
@ -374,16 +375,18 @@ void *sl_list_pop(sl_list_t **lst);
|
|||||||
#define SL_COMMENT_CHAR '#'
|
#define SL_COMMENT_CHAR '#'
|
||||||
|
|
||||||
// option or simple configuration value (don't work for functions)
|
// option or simple configuration value (don't work for functions)
|
||||||
typedef struct{
|
/*typedef struct{
|
||||||
union{
|
union{
|
||||||
int ival; long long llval; double dval; float fval;
|
int ival; long long llval; double dval; float fval;
|
||||||
};
|
};
|
||||||
sl_argtype_e type;
|
sl_argtype_e type;
|
||||||
} sl_optval;
|
} sl_optval;*/
|
||||||
|
|
||||||
int sl_get_keyval(const char *pair, char key[SL_KEY_LEN], char value[SL_VAL_LEN]);
|
int sl_get_keyval(const char *pair, char key[SL_KEY_LEN], char value[SL_VAL_LEN]);
|
||||||
char *sl_print_opts(sl_option_t *opt, int showall);
|
char *sl_print_opts(sl_option_t *opt, int showall);
|
||||||
int sl_conf_readopts(const char *filename, sl_option_t *options);
|
int sl_conf_readopts(const char *filename, sl_option_t *options);
|
||||||
|
void sl_conf_showhelp(int idx, sl_option_t *options);
|
||||||
|
int sl_remove_quotes(char *string);
|
||||||
|
|
||||||
/******************************************************************************\
|
/******************************************************************************\
|
||||||
The original ringbuffer.h
|
The original ringbuffer.h
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user