2 Commits

Author SHA1 Message Date
503325b68f fix again 2026-07-01 13:46:22 +03:00
566ca36af8 fixed little bug with long-only options 2026-07-01 11:57:07 +03:00
5 changed files with 44 additions and 25 deletions

View File

@@ -52,9 +52,11 @@ static glob_pars const Gdefault = {
* name has_arg flag val type argptr help
* BE carefull! The `help` field is mandatory! Omitting it equivalent of 'end_option'
*/
// if val < 33 || val > 127 we mean this like long-only option;
// you can repeat the same `val` for several long-only options without any problem
static sl_option_t cmdlnopts[] = {
// 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)")},
{"longonly",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`
@@ -71,7 +73,7 @@ static sl_option_t cmdlnopts[] = {
{"Int", MULT_PAR, NULL, 'I', arg_int, APTR(&G.intarr), _("integer parameter")},
{"Dbl", MULT_PAR, NULL, 'D', arg_double, APTR(&G.dblarr), _("double 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 (int)")},
{"long1", NEED_ARG, NULL, 0, arg_int, APTR(&G.lo1), _("only long arg 1 (int)")},
end_option
};

View File

@@ -93,9 +93,9 @@ int main(int argc, char *argv[]){
printf("String[%d]: \"%s\"\n", i, *p++);
}
}
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->lo2 != INT_MIN) printf("You set lo2 to %d\n", GP->lo2);
if(GP->lo0 != INT_MIN) printf("You set long 0 to %d\n", GP->lo0);
if(GP->lo1 != INT_MIN) printf("You set long 1 to %d\n", GP->lo1);
if(GP->lo2 != INT_MIN) printf("You set long 2 to %d\n", GP->lo2);
if(GP->so1){
sl_remove_quotes(GP->so1);
printf("String so1=%s\n", GP->so1);

View File

@@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-03-04 17:48+0300\n"
"POT-Creation-Date: 2026-03-31 11:35+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -36,7 +36,7 @@ msgstr ""
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:70
#, c-format
msgid ""
"\n"
@@ -44,11 +44,11 @@ msgid ""
msgstr ""
#. 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:95
msgid "Can't read self name"
msgstr ""
#: /home/eddy/Docs/SAO/C_diff/snippets_library/daemon.c:141
#: /home/eddy/Docs/SAO/C_diff/snippets_library/daemon.c:119
msgid "Can't open PID file"
msgstr ""

View File

@@ -7,7 +7,7 @@
msgid ""
msgstr "Project-Id-Version: PACKAGE VERSION\n"
"Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2026-03-04 17:30+0300\n"
"POT-Creation-Date: 2026-03-31 11:31+0300\n"
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
"Language-Team: LANGUAGE <LL@li.org>\n"
@@ -35,7 +35,7 @@ msgstr "sl_conf_showhelp():
msgid "Configuration file options (format: key=value):\n"
msgstr "ïÐÃÉÉ ËÏÎÆÉÇÕÒÁÃÉÏÎÎÏÇÏ ÆÁÊÌÁ (ÆÏÒÍÁÔ: ËÌÀÞ=ÚÎÁÞÅÎÉÅ):\n"
#: /home/eddy/Docs/SAO/C_diff/snippets_library/daemon.c:69
#: /home/eddy/Docs/SAO/C_diff/snippets_library/daemon.c:70
#, c-format
msgid "\n"
"Found running process (pid=%d), exit.\n"
@@ -43,11 +43,11 @@ msgstr "\n"
"ïÂÎÁÒÕÖÅÎ ÏÄÎÏÉÍÅÎÎÙÊ ÐÒÏÃÅÓÓ (pid=%d), ×ÙÈÏÄ.\n"
#. 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:95
msgid "Can't read self name"
msgstr "îÅ ÍÏÇÕ ÐÒÏÞÅÓÔØ ÉÍÑ ÐÒÏÃÅÓÓÁ"
#: /home/eddy/Docs/SAO/C_diff/snippets_library/daemon.c:141
#: /home/eddy/Docs/SAO/C_diff/snippets_library/daemon.c:119
msgid "Can't open PID file"
msgstr "îÅ ÍÏÇÕ ÏÔËÒÙÔØ PID ÆÁÊÌ"
@@ -236,5 +236,3 @@ msgstr "
#: /home/eddy/Docs/SAO/C_diff/snippets_library/usefull_macros.c:331
msgid "Can't setup console"
msgstr "îÅ ÍÏÇÕ ÎÁÓÔÒÏÉÔØ ËÏÎÓÏÌØ"
#, c-format

View File

@@ -30,6 +30,9 @@
#include <ctype.h> // isalpha
#include "usefull_macros.h"
// check `val` field: if it's <33 || >127 - it's just ordered number, not short option
#define CHKOPTVAL(Oval) ((Oval) > 32 && (Oval) < 128)
const char *helpstring = NULL; // will be inited later, can't init with gettext on this stage
/**
@@ -124,18 +127,33 @@ static int get_optind(const char *key, int opt, sl_option_t *options, void (*hel
int oind = 0, theopt = opt;
sl_option_t *opts = options;
assert(opts);
//printf("key: %s\n", key);
// `opt` should be ':' for "missed arguments", '?' for "not found" and short flag if found and checked
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(key[1] != '-'){ // search by unique short option
//printf("Short %c\n", theopt);
for(oind = 0; opts->help && opts->val != theopt; oind++, opts++){
DBG("cmp %c and %c", theopt, opts->val);
}
}else{ // search by long option
key += 2;
int l = strlen(key);
for(oind = 0; opts->help; oind++, opts++){
//printf("comp %s and %s\n", key, opts->name);
if(opts->name && 0 == strncmp(key, opts->name, l)) break;
}
}
if(!opts->help){
//printf("Not found\n");
return -1;
}
if(!opts->help) return -1;
if(opt == ':'){
fprintf(stderr, _("Parameter `%s` needs value\n"), key);
if(options[oind].name) fprintf(stderr, _("Parameter `--%s` needs value\n"), options[oind].name);
else fprintf(stderr, _("Parameter `-%c` needs value\n"), options[oind].val);
helpfun(oind, options);
return -1; // never reached until `helpfun` changed
}
@@ -249,7 +267,7 @@ void sl_parseargs_hf(int *argc, char ***argv, sl_option_t *options, void (*helpf
loptr->flag = opts->flag;
loptr->val = opts->val;
// fill short options if they are:
if(!opts->flag && opts->val){
if(!opts->flag && CHKOPTVAL(opts->val)){
shortlist[i] = (char) opts->val;
*soptr++ = opts->val;
if(loptr->has_arg) // add ':' if option has required argument
@@ -371,21 +389,22 @@ void sl_parseargs(int *argc, char ***argv, sl_option_t *options){
/**
* @brief argsort - compare function for qsort
* first - sort by short options; second - sort arguments without sort opts (by long options)
* first - sort by short options; second - sort arguments without short opts (by long options)
*/
static int argsort(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;
int s1 = o1->val, s2 = o2->val;
int chk1 = CHKOPTVAL(s1), chk2 = CHKOPTVAL(s2);
int *f1 = o1->flag, *f2 = o2->flag;
// check if both options has short arg
if(f1 == NULL && f2 == NULL && s1 && s2){ // both have short arg
if(f1 == NULL && f2 == NULL && chk1 && chk2){ // both have short arg
return (s1 - s2);
}else if((f1 != NULL || !s1) && (f2 != NULL || !s2)){ // both don't have short arg - sort by long
}else if((f1 != NULL || !chk1) && (f2 != NULL || !chk2)){ // 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);
}else{ // only one have short arg -- return it
if(f2 || !s2) return -1; // a1 have short - it is 'lesser'
if(f2 || !chk2) return -1; // a1 have short - it is 'lesser'
else return 1;
}
}
@@ -394,7 +413,7 @@ static int argsort(const void *a1, const void *a2){
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
if(!opt->flag && CHKOPTVAL(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
}