[Progetto] C Library for parsing command line arguments

Iniziative e progetti della comunità legati a Ubuntu.
Regole della sezione
Questa sezione ha lo scopo di raccogliere le iniziative/progetti della nostra Comunità legati ad Ubuntu. I progetti ospitati nascono da iniziative degli utenti o gruppi di utenti. In futuro i progetti potrebbero rimanere iniziative "personali" o essere integrate nella distribuzione, sponsorizzate da Ubuntu o da Canonical a discrezione dei responsabili. All'interno di essa sarà possibile inserire delle discussioni che hanno la funzione di pubblicizzare avvenimenti, iniziative e progetti software su Ubuntu e GNU/Linux in generale. Sarà inoltre possibile per gli utenti proporre lo sviluppo di nuovi software e in questo caso la discussione di richiesta avrà la funzione di generare un requisito funzionale del prodotto da sviluppare.

Sezione I - Iniziative
  • Fanno parte di iniziative, ad esempio, le seguenti categorie: corsi, progetti editoriali, libri.
  • La segnalazione di un'iniziativa avviene creando una discussione con l'annuncio.
  • Una volta effettuata la segnalazione, la discussione viene chiusa dal Gruppo Forum.
  • Se l'iniziativa esposta comporta un costo di adesione o fruizione, questo deve essere esplicitamente riportato all'interno della discussione.
  • È obbligatorio segnalare all'interno della discussione i riferimenti per poter contattare/partecipare all'iniziativa.
Sezione II - Progetti
  • La segnalazione di un progetto software, come per le iniziative, avviene e si sviluppa all'interno di una singola discussione.
  • Sarà consentito l'inserimento di software solo se rilasciati sotto licenza GPL (in tutte le sue versioni) o equivalente FOSS, tale da garantire agli utenti l'utilizzo del prodotto senza restrizioni e agli sviluppatori la proprietà intellettuale del codice prodotto.
  • Nell'oggetto della discussione dovrà essere riportata la categoria (es. [Iniziativa], [Progetto] o [Proposta]) e una semplice descrizione del progetto.
  • Se il progetto ha già un sito che lo ospita sarà a discrezione del Gruppo Forum chiuderla come segnalazione o lasciarla aperta.
  • Se il progetto non ha un sito che lo ospita si potranno aprire due discussioni, una per proporre modifiche/implementazioni (dove nel titolo occorre specificare [sviluppo]) ed una per segnalare problemi (e nel titolo dovrà comparire [supporto]).
  • Non è consentita l'apertura di nuove discussioni in riferimento a versioni superiori o modificate di un prodotto già riportato in precedenza.
  • Se il software oggetto del progetto ha una dimensione non superiore ai 128 kB, per prodotti che non hanno un sito che li ospita, sarà possibile allegarlo alla discussione.
Sezione III - Proposte
  • Una proposta deve essere eseguita e si svilupperà all'interno di una singola discussione.
  • Le proposte dovranno essere inserite direttamente nella sezione "Progetti della Comunità".
  • Dovranno essere specificate le funzionalità che devono essere sviluppate.
  • Non dovranno essere riportate diciture tipo "...deve fare come questo software...", ma indicare nel miglior modo possibile i requisiti.
  • Una volta segnalata la discussione resterà aperta per consentire uno scambio di idee su come sviluppare il codice o finché gli sviluppatori non forniranno una soluzione (da pubblicizzare poi, come visto prima, nella sezione Progetti) che ne soddisfi il requisito.
Per quanto non esposto sopra, si fa comunque riferimento al Regolamento del forum ed al Codice di Condotta della Comunità.
Avatar utente
Vincenzo1968
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 450
Iscrizione: lunedì 14 gennaio 2013, 14:21
Desktop: Unity
Distribuzione: Ubuntu 18.04.3 LTS x86_64
Località: Villabate(PA)
Contatti:

[Progetto] C Library for parsing command line arguments

Messaggio da Vincenzo1968 »

In seguito a questo thread:

http://forum.ubuntu-it.org/viewtopic.php?f=33&t=556461

ho scritto una libreria C per il parsing degli argomenti dalla linea di comando.

I sorgenti possono essere scaricati da qui:

https://github.com/Vincenzo1968/myoptParser

La documentazione:

https://github.com/Vincenzo1968/myoptPa ... mpilare.md

https://github.com/Vincenzo1968/myoptPa ... _si_usa.md


Il parser costruisce automaticamente il messaggio di help partendo dai parametri passati alla funzione myopt_Parser.
È possibile specificare quanti argomenti un'opzione può accettare e di che tipo: stringa, numero intero o numero in virgola mobile.
Anche per gli argomenti posizionali è possibile specificare numero e tipo(di default il parser accetta zero o più argomenti posizionali, tutti di tipo stringa).
C'è la possibilità di specificare gruppi di opzioni mutualmente esclusive.

È possibile installare la libreria con i comandi usuali configure/make/make install:
$ ./configure
$ make
$ sudo make install
Se volete contribuire allo sviluppo del progetto potete effettuare una pull request all'indirizzo sopra specificato. Oppure si può effettuare una fork. La libreria è rilasciata con licenza GPL3.

Un esempio:

Codice: Seleziona tutto

/*
   Copyright (C) 2013 Vincenzo Lo Cicero

   Author: Vincenzo Lo Cicero.
    
   From an idea by Leonardo Pozzati.
   
   Special thanks to Francesco Baro for code review and bug fixing.
   
   This file use myoptParserLib.

   myoptParserLib is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   myoptParserLib is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with myoptParserLib.  If not, see <http://www.gnu.org/licenses/>.
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>
#include <stdbool.h>
#include <stdint.h>

#include "myoptParser.h"

int main(int argc, char* argv[])
{
	myopt_Parser_t parser;
	int x;
	char strDescr[MAX_LEN_STR + 1];
	int32_t idGroup;
	int32_t idOption;
	double num;
	bool bParse;
		
	parser = myopt_InitParser();
	if ( !parser )
		return -1;

	idGroup = myopt_AddGroup(parser, "Gruppo 0", true, true);
	
	strcpy(strDescr, "Print this message and exit");
	myopt_AddOption(parser, idGroup, 'h', "help", strDescr, false, MOB_OVERRIDE, 0, 0, "");	

	strcpy(strDescr, "Accumulator: print sum of positionals arguments");
	myopt_AddOption(parser, idGroup, 'a', "accumulate", strDescr, true, MOB_OVERRIDE, 0, 0, "");
	
	strcpy(strDescr, "Max: print the maximum of the positional arguments");	
	myopt_AddOption(parser, idGroup, 'm', "max", strDescr, false, MOB_OVERRIDE, 0, 0, "");
		
	myopt_SetPositionalArgsParams(parser, "NUMS", 1, OR_MORE, "float");
		
	bParse = myopt_ParseArray(parser, argc, argv);
	
	if ( parser->countInternalErrors > 0 )
	{
		printf("Internal errors:\n");
		printf(parser->strInternalErrors);
		return -1;
	}		
	
	idOption = myopt_LookupShort(parser, 'h');
	//idOption = myopt_LookupLong(parser, "help");
	if ( idOption >= 0 && parser->arrayOptArgs[idOption].countOccurrences > 0 )
	{
		printf(parser->strUsage);
		myopt_FreeParser(parser);
		return 0;
	}	
	
	if ( !bParse )
	{
		printf(parser->strUsage);
		printf(parser->strErrors);
		myopt_FreeParser(parser);
		return -1;		
	}
	
	idOption = myopt_LookupShort(parser, 'a');
	//idOption = myopt_LookupLong(parser, "accumulate");
	if ( idOption >= 0 && parser->arrayOptArgs[idOption].countOccurrences > 0 )
	{
		num = 0;
		for ( x = 0; x < parser->countPosArgs; x++ )
			num += parser->arrayPosArgs[x].floatValue;
		printf("\nThe sum is: %f\n", num);
	}
	
	idOption = myopt_LookupShort(parser, 'm');
	//idOption = myopt_LookupLong(parser, "max");
	if ( idOption >= 0 && parser->arrayOptArgs[idOption].countOccurrences > 0 )
	{
		num = 0;
		if ( parser->countPosArgs > 0 )
			num = parser->arrayPosArgs[0].floatValue;			
		for ( x = 0; x < parser->countPosArgs; x++ )
			if ( parser->arrayPosArgs[x].floatValue > num )
				num = parser->arrayPosArgs[x].floatValue;
		printf("\nThe maximum is: %g\n", num);		
	}
		
	myopt_FreeParser(parser);
	
	return 0;
}

Immagine

Immagine
Ultima modifica di Vincenzo1968 il domenica 15 settembre 2013, 20:34, modificato 1 volta in totale.
È ormai difficile incontrare un cretino che non sia intelligente e un intelligente che non sia un cretino. [...] Oh i bei cretini di una volta! Genuini, integrali. Come il pane di casa. Come l'olio e il vino dei contadini. (da "Nero su nero" di Leonardo Sciascia)
melfnt
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1312
Iscrizione: sabato 15 ottobre 2011, 22:25

Re: [Progetto] C Library for parsing command line arguments

Messaggio da melfnt »

Dato che devo scrivere un programma ex novo lo testo un po', se trovo errori te lo dico.

Grazie per ora.
melfnt
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1312
Iscrizione: sabato 15 ottobre 2011, 22:25

Re: [Progetto] C Library for parsing command line arguments

Messaggio da melfnt »

Una piccola sottigliezza:

Imposto zero o più parametri posizionali INTERI:

Codice: Seleziona tutto

myopt_SetPositionalArgsParams(parser, "POS_ARGS", 0, OR_MORE, "int");
lancio:

Codice: Seleziona tutto

./effitest 3ciao 4come 1 

List of positional argument:
int    : 3
int    : 4
int    : 1
Le stringhe che cominciano con un numero lui le interpreta come numeri.
Per esempio "3ciao" lo legge 3, senza restituire errore.
Avatar utente
Vincenzo1968
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 450
Iscrizione: lunedì 14 gennaio 2013, 14:21
Desktop: Unity
Distribuzione: Ubuntu 18.04.3 LTS x86_64
Località: Villabate(PA)
Contatti:

Re: [Progetto] C Library for parsing command line arguments

Messaggio da Vincenzo1968 »

melfnt [url=http://forum.ubuntu-it.org/viewtopic.php?p=4447182#p4447182][img]http://forum.ubuntu-it.org/images/icons/icona-cita.gif[/img][/url] ha scritto:Una piccola sottigliezza:

Imposto zero o più parametri posizionali INTERI:

Codice: Seleziona tutto

myopt_SetPositionalArgsParams(parser, "POS_ARGS", 0, OR_MORE, "int");
lancio:

Codice: Seleziona tutto

./effitest 3ciao 4come 1 

List of positional argument:
int    : 3
int    : 4
int    : 1
Le stringhe che cominciano con un numero lui le interpreta come numeri.
Per esempio "3ciao" lo legge 3, senza restituire errore.
Ciao, scusa per il ritardo nella risposta.

Si, è un bug, grazie per la segnalazione.
Vedrò di correggerlo al più presto.

:ciao:
È ormai difficile incontrare un cretino che non sia intelligente e un intelligente che non sia un cretino. [...] Oh i bei cretini di una volta! Genuini, integrali. Come il pane di casa. Come l'olio e il vino dei contadini. (da "Nero su nero" di Leonardo Sciascia)
Avatar utente
Vincenzo1968
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 450
Iscrizione: lunedì 14 gennaio 2013, 14:21
Desktop: Unity
Distribuzione: Ubuntu 18.04.3 LTS x86_64
Località: Villabate(PA)
Contatti:

Re: [Progetto] C Library for parsing command line arguments

Messaggio da Vincenzo1968 »

Ho eliminato il bug:

Codice: Seleziona tutto

[vincenzo]$ gcc -Wall -pedantic -O3 -std=c99 prova.c -oprova -lmyoptParser
[vincenzo]$ ls
prova  prova.c  sample1.c  sample1.cpp  sample2.c  sample2.cpp
[vincenzo]$ ./prova 3ciao 4come 1
Usage:
./prova POS_ARGS(zero or more)(int)

Error: positional argument 1 wrong type. Must be int; found string: '3ciao'
Error: positional argument 2 wrong type. Must be int; found string: '4come'

[vincenzo]$ ./prova 3 4 1

List of positional argument:
int    : 3
int    : 4
int    : 1
prova.c:

Codice: Seleziona tutto

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>

#include "myoptParser.h"

int main(int argc, char* argv[])
{
	myopt_Parser_t parser;
	int x;
	int32_t idOption;
	bool bParse;
		
	parser = myopt_InitParser();
	if ( !parser )
		return -1;
	
	myopt_SetPositionalArgsParams(parser, "POS_ARGS", 0, OR_MORE, "int");	
		
	bParse = myopt_ParseArray(parser, argc, argv);
	
	if ( parser->countInternalErrors > 0 )
	{
		printf("Internal errors:\n");
		printf("%s\n", parser->strInternalErrors);
		return -1;
	}		
	
	/* idOption = myopt_LookupShort(parser, 'h'); */
	idOption = myopt_LookupLong(parser, "help");
	if ( idOption >= 0 && parser->arrayOptArgs[idOption].countOccurrences > 0 )
	{
		printf("%s\n", parser->strUsage);
		myopt_FreeParser(parser);
		return 0;
	}	
	
	if ( !bParse )
	{
		printf("%s\n", parser->strUsage);
		printf("%s\n", parser->strErrors);
		myopt_FreeParser(parser);
		return -1;		
	}
		
	if ( parser->countPosArgs )
		printf("\nList of positional argument:\n");
	for ( x = 0; x < parser->countPosArgs; x++ )
	{
		switch (parser->arrayPosArgs[x].Type )
		{
			case T_STRING:			
				printf("string : %s", parser->arrayPosArgs[x].strValue);
				break;
			case T_INT:
				printf("int    : %lli", (long long int)parser->arrayPosArgs[x].intValue);
				break;
			case T_FLOAT:
				printf("float  : %g", parser->arrayPosArgs[x].floatValue);
				break;
		}
		printf("\n");
	}
		
	myopt_FreeParser(parser);
	
	return 0;
}
È ormai difficile incontrare un cretino che non sia intelligente e un intelligente che non sia un cretino. [...] Oh i bei cretini di una volta! Genuini, integrali. Come il pane di casa. Come l'olio e il vino dei contadini. (da "Nero su nero" di Leonardo Sciascia)
melfnt
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1312
Iscrizione: sabato 15 ottobre 2011, 22:25

Re: [Progetto] C Library for parsing command line arguments

Messaggio da melfnt »

Ok, grazie.

atoi?
;)
Avatar utente
vaeVictis
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 4703
Iscrizione: venerdì 27 luglio 2012, 17:58
Desktop: Gnome
Distribuzione: Ubuntu 20.04 64bit

Re: [Progetto] C Library for parsing command line arguments

Messaggio da vaeVictis »

:ciao:
Mi unisco alla discussione per essere aggiornato.
Grazie del MP, Vincenzo!

p.s.: forse il titolo sarebbe migliore in italiano :)
Pirates arrrrrrrrrrr awesome!!!
«I fear not the man who has practiced 10000 kicks once,
but I fear the man who has practiced one kick 10000 times.»
Avatar utente
Vincenzo1968
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 450
Iscrizione: lunedì 14 gennaio 2013, 14:21
Desktop: Unity
Distribuzione: Ubuntu 18.04.3 LTS x86_64
Località: Villabate(PA)
Contatti:

Re: [Progetto] C Library for parsing command line arguments

Messaggio da Vincenzo1968 »

vaeVictis [url=http://forum.ubuntu-it.org/viewtopic.php?p=4449472#p4449472][img]http://forum.ubuntu-it.org/images/icons/icona-cita.gif[/img][/url] ha scritto::ciao:
Mi unisco alla discussione per essere aggiornato.
Grazie del MP, Vincenzo!

p.s.: forse il titolo sarebbe migliore in italiano :)
Ho provato a mettere questo titolo:

"[Progetto] Libreria C per il parsing degli argomenti da linea di comando"

ma lo tronca:

"[Progetto] Libreria C per il parsing degli argomenti da line"
È ormai difficile incontrare un cretino che non sia intelligente e un intelligente che non sia un cretino. [...] Oh i bei cretini di una volta! Genuini, integrali. Come il pane di casa. Come l'olio e il vino dei contadini. (da "Nero su nero" di Leonardo Sciascia)
Avatar utente
Vincenzo1968
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 450
Iscrizione: lunedì 14 gennaio 2013, 14:21
Desktop: Unity
Distribuzione: Ubuntu 18.04.3 LTS x86_64
Località: Villabate(PA)
Contatti:

Re: [Progetto] C Library for parsing command line arguments

Messaggio da Vincenzo1968 »

Stavo pensando di estendere la libreria in modo da dare all'utente un maggiore controllo sui valori degli argomenti delle opzioni.

Per esempio, un'opzione, --choises, che accetti un argomento di tipo intero il cui valore debba essere uno tra 3, 5 e 8, potrebbe essere espressa così:

Codice: Seleziona tutto

strcpy(strValue, "int(value in [3,5,8])");
myopt_AddOption(parser, idGroup, 'c', "choices", strDescr, true, MOB_OVERRIDE, 1, 1, strValue);
Esempio 2: opzione con argomento di tipo intero il cui valore debba essere compreso tra -100 e 100:

Codice: Seleziona tutto

strcpy(strValue, "int(value between -100 and 100)");
myopt_AddOption(parser, idGroup, 'c', "choices", strDescr, true, MOB_OVERRIDE, 1, 1, strValue);
Esempio 3: opzione con argomento di tipo stringa il cui valore debba essere uno tra "foo", "bar" e "ciao":

Codice: Seleziona tutto

strcpy(strValue, "string(value in [foo, bar, ciao])");
myopt_AddOption(parser, idGroup, 'c', "choices", strDescr, true, MOB_OVERRIDE, 1, 1, strValue);
È ormai difficile incontrare un cretino che non sia intelligente e un intelligente che non sia un cretino. [...] Oh i bei cretini di una volta! Genuini, integrali. Come il pane di casa. Come l'olio e il vino dei contadini. (da "Nero su nero" di Leonardo Sciascia)
Avatar utente
vaeVictis
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 4703
Iscrizione: venerdì 27 luglio 2012, 17:58
Desktop: Gnome
Distribuzione: Ubuntu 20.04 64bit

Re: [Progetto] C Library for parsing command line arguments

Messaggio da vaeVictis »

Tu non sai quanto mi piacerebbe riscrivere il programma in C++ :)
Per il titolo, ora ci penso meglio ;)
Pirates arrrrrrrrrrr awesome!!!
«I fear not the man who has practiced 10000 kicks once,
but I fear the man who has practiced one kick 10000 times.»
Avatar utente
Vincenzo1968
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 450
Iscrizione: lunedì 14 gennaio 2013, 14:21
Desktop: Unity
Distribuzione: Ubuntu 18.04.3 LTS x86_64
Località: Villabate(PA)
Contatti:

Re: [Progetto] C Library for parsing command line arguments

Messaggio da Vincenzo1968 »

vaeVictis [url=http://forum.ubuntu-it.org/viewtopic.php?p=4449768#p4449768][img]http://forum.ubuntu-it.org/images/icons/icona-cita.gif[/img][/url] ha scritto:Tu non sai quanto mi piacerebbe riscrivere il programma in C++ :)
Per il titolo, ora ci penso meglio ;)
Ottimo! Si potrebbe fornire un'interfaccia C++ un po' come avviene con la libreria GMP che ti consente di specificare l'opzione --enable-cxx.
Se, specificata, l'opzione consente di creare la libreria libgmpxx.a(per il C++) e la libreria libgmp.a(per il C).

Esempio versione C:

Codice: Seleziona tutto

#include <stdio.h>
#include <stdlib.h>
#include <gmp.h>

int main(void)
{
	mpz_t x;
	mpz_t y;
	mpz_t result;
	
	mpz_init(x);
	mpz_init(y);
	mpz_init(result);
	
	mpz_set_str(x, "7612058254738945", 10);
	mpz_set_str(y, "9263591128439081", 10);
	
	mpz_mul(result, x, y);
	
	gmp_printf("\n    %Zd\n*\n    %Zd\n--------------------\n%Zd\n\n", x, y, result);
	
	/* free used memory */
	mpz_clear(x);
	mpz_clear(y);
	mpz_clear(result);
	
	return EXIT_SUCCESS;
}
Esempio versione C++:

Codice: Seleziona tutto

#include <iostream>
#include <gmpxx.h>
 
int main()
{
	mpz_class x("7612058254738945");
	mpz_class y("9263591128439081");
	
	std::cout << "\n    " << x << "\n*\n    " << y;
	std::cout << "\n--------------------\n" << x * y << "\n\n";
	
	return 0;
}
;)
È ormai difficile incontrare un cretino che non sia intelligente e un intelligente che non sia un cretino. [...] Oh i bei cretini di una volta! Genuini, integrali. Come il pane di casa. Come l'olio e il vino dei contadini. (da "Nero su nero" di Leonardo Sciascia)
Avatar utente
vaeVictis
Imperturbabile Insigne
Imperturbabile Insigne
Messaggi: 4703
Iscrizione: venerdì 27 luglio 2012, 17:58
Desktop: Gnome
Distribuzione: Ubuntu 20.04 64bit

Re: [Progetto] C Library for parsing command line arguments

Messaggio da vaeVictis »

Diciamo che stai "qualche" passo avanti a me :)
Pirates arrrrrrrrrrr awesome!!!
«I fear not the man who has practiced 10000 kicks once,
but I fear the man who has practiced one kick 10000 times.»
Avatar utente
Vincenzo1968
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 450
Iscrizione: lunedì 14 gennaio 2013, 14:21
Desktop: Unity
Distribuzione: Ubuntu 18.04.3 LTS x86_64
Località: Villabate(PA)
Contatti:

Re: [Progetto] C Library for parsing command line arguments

Messaggio da Vincenzo1968 »

Può darsi, ma col C, non col C++ che conosco poco e niente.
Sarebbe davvero utile realizzare un'interfaccia C++ per la libreria. Come puoi notare con l'esempio sopra su GMP, il codice risulterebbe più compatto e leggibile.
Eventualmente puoi fare come hanno fatto con GMP. La libreria C++, libgmpxx.a, è un wrapper attorno alla libreria C, libgmp.a.
Infatti, per compilare l'esempio C++, devi utilizzarle entrambe -lgmpxx -lgmp.
In questo modo non devi reimplementare da zero la libreria: puoi creare l'interfaccia C++ e richiamare, all'interno di questa, le funzioni della libreria C.
Io una mano te la darei volentieri ma, come ti dicevo, C++ lo conosco poco e niente.
È ormai difficile incontrare un cretino che non sia intelligente e un intelligente che non sia un cretino. [...] Oh i bei cretini di una volta! Genuini, integrali. Come il pane di casa. Come l'olio e il vino dei contadini. (da "Nero su nero" di Leonardo Sciascia)
melfnt
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1312
Iscrizione: sabato 15 ottobre 2011, 22:25

Re: [Progetto] C Library for parsing command line arguments

Messaggio da melfnt »

Stavo pensando di estendere la libreria in modo da dare all'utente un maggiore controllo sui valori degli argomenti delle opzioni.
Ma come la mettiamo se i parametri da specificare sono più di uno?
Io metterei un numero davanti a "int", "string" eccetera.

E già che ci sei, metti anche i valori di default:

Codice: Seleziona tutto

strcpy(strValue, "4 int(value in [3,5,8])");
strcpy (strDefault, "1,2,3,4")
myopt_AddOption(parser, idGroup, 'c', "choices", strDescr, true, MOB_OVERRIDE, 1, 1, strValue,strDefault);
Ottimo! Si potrebbe fornire un'interfaccia C++ un po' come avviene con la libreria GMP che ti consente di specificare l'opzione --enable-cxx.
Se, specificata, l'opzione consente di creare la libreria libgmpxx.a(per il C++) e la libreria libgmp.a(per il C).
Erano bei tempi quando anch'io ho programmato una libreria per memorizzare interi di lunghezza arbritaria...
Avatar utente
Vincenzo1968
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 450
Iscrizione: lunedì 14 gennaio 2013, 14:21
Desktop: Unity
Distribuzione: Ubuntu 18.04.3 LTS x86_64
Località: Villabate(PA)
Contatti:

Re: [Progetto] C Library for parsing command line arguments

Messaggio da Vincenzo1968 »

melfnt [url=http://forum.ubuntu-it.org/viewtopic.php?p=4450175#p4450175][img]http://forum.ubuntu-it.org/images/icons/icona-cita.gif[/img][/url] ha scritto:
Stavo pensando di estendere la libreria in modo da dare all'utente un maggiore controllo sui valori degli argomenti delle opzioni.
Ma come la mettiamo se i parametri da specificare sono più di uno?
Io metterei un numero davanti a "int", "string" eccetera.

E già che ci sei, metti anche i valori di default:

Codice: Seleziona tutto

strcpy(strValue, "4 int(value in [3,5,8])");
strcpy (strDefault, "1,2,3,4")
myopt_AddOption(parser, idGroup, 'c', "choices", strDescr, true, MOB_OVERRIDE, 1, 1, strValue,strDefault);
Nel caso di un'opzione che accetta più di un argomento, pensavo di utilizzare il ";" come separatore.
Per esempio, se l'opzione accetta tre argomenti(int, float e string) si potrebbe fare così:

Codice: Seleziona tutto

strcpy(strValue, "int(value in [3,5,8]); float(value between 1.5 and 8.21); string(value in[foo, bar, ciao])");
myopt_AddOption(parser, idGroup, 'c', "choices", strDescr, true, MOB_OVERRIDE, 3, 3, strValue);
Ottimo! Si potrebbe fornire un'interfaccia C++ un po' come avviene con la libreria GMP che ti consente di specificare l'opzione --enable-cxx.
Se, specificata, l'opzione consente di creare la libreria libgmpxx.a(per il C++) e la libreria libgmp.a(per il C).
Erano bei tempi quando anch'io ho programmato una libreria per memorizzare interi di lunghezza arbritaria...
Interessante! Anche in vista del fatto che stavo pensando di estendere la libreria con la gestione dei numeri a precisione arbitraria.
Scarico la tua libreria e faccio qualche prova.

;)
È ormai difficile incontrare un cretino che non sia intelligente e un intelligente che non sia un cretino. [...] Oh i bei cretini di una volta! Genuini, integrali. Come il pane di casa. Come l'olio e il vino dei contadini. (da "Nero su nero" di Leonardo Sciascia)
melfnt
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1312
Iscrizione: sabato 15 ottobre 2011, 22:25

Re: [Progetto] C Library for parsing command line arguments

Messaggio da melfnt »

Scusa una cosa, vincenzo:

effitest.c

Codice: Seleziona tutto

idGroup = myopt_AddGroup(parser, "Formattazione output", true, false);
sprintf(strDescr, "Specify the formatting of the output");
myopt_AddOption(parser, idGroup, 'o', "output-mode", strDescr, false, MOB_OVERRIDE, 1, 1, "string");
E

Codice: Seleziona tutto

mario@ubuntu:~/Scrivania/Programmi c++/effitest$ ./effitest -o n -o h ciao
---
Il programma va avanti e termina correttamente
---
O è un bug, oppure non ho capito io:
idGroup = myopt_AddGroup(parser, "Formattazione output", true, false);
Le opzioni di questo gruppo non dovrebbero escludersi mutualmente?

Ovvero: se specifico più di una volta -o, il parser non dovrebbe restituire errore?

;)
Ultima modifica di melfnt il martedì 28 giugno 2022, 18:53, modificato 1 volta in totale.
Avatar utente
Vincenzo1968
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 450
Iscrizione: lunedì 14 gennaio 2013, 14:21
Desktop: Unity
Distribuzione: Ubuntu 18.04.3 LTS x86_64
Località: Villabate(PA)
Contatti:

Re: [Progetto] C Library for parsing command line arguments

Messaggio da Vincenzo1968 »

Se vuoi che il programma restituisca un errore nel caso di più occorrenze di un'opzione devi specificare MOB_ERROR al posto di MOB_OVERRIDE.
con MOB_OVERRIDE viene letto l'argomento dell'ultima occorrenza(nel tuo esempio h).

Per quanto riguarda Il parametro "bMutuallyExclusive" nella funzione "myopt_AddGroup":
https://github.com/Vincenzo1968/myoptPa ... _si_usa.md
Il parametro "bMutuallyExclusive" è un valore booleano; bisogna specificare "true" se si vuole che le opzioni del gruppo siano mutualmente esclusive. Se questo parametro è impostato a "true" e l'utente specifica più di un'opzione del gruppo, il parser restituisce un errore.
In pratica se nel gruppo hai più di un'opzione, passando true, puoi utilizzarne soltanto una alla volta. Ma questa opzione puoi utilizzarla più volte se passi MOB_OVERRIDE o MOB_APPEND alla funzione "myopt_AddOption".
Con MOB_APPEND invece di prendere soltanto l'ultima occorrenza le prende tutte. Nel tuo esempio verrebbe restituita la lista (n, h) per l'opzione -o.
È ormai difficile incontrare un cretino che non sia intelligente e un intelligente che non sia un cretino. [...] Oh i bei cretini di una volta! Genuini, integrali. Come il pane di casa. Come l'olio e il vino dei contadini. (da "Nero su nero" di Leonardo Sciascia)
melfnt
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1312
Iscrizione: sabato 15 ottobre 2011, 22:25

Re: [Progetto] C Library for parsing command line arguments

Messaggio da melfnt »

Sì, sì, scusa, me ne sono accorto dopo.

Credevo che l'impostazione di mutually_esclusive valesse anche per più occorrenze dello stesso parametro.
melfnt
Entusiasta Emergente
Entusiasta Emergente
Messaggi: 1312
Iscrizione: sabato 15 ottobre 2011, 22:25

Re: [Progetto] C Library for parsing command line arguments

Messaggio da melfnt »

Stavolta l'errore è "serio".

Anche qui non so se è un problema mio, o se è normale che si comporti così.

effitest.c

Codice: Seleziona tutto

idGroup = myopt_AddGroup(parser, "Aiuto", false, false);
strcpy(strDescr, "Print this message and exit");
myopt_AddOption(parser, idGroup, 'h', "help", strDescr, false, MOB_OVERRIDE, 0, 0, "");	
strcpy(strDescr, "Show version number and exit");
myopt_AddOption(parser, idGroup, 'v', "version", strDescr, false, MOB_OVERRIDE,	0, 0, "");

idGroup = myopt_AddGroup(parser, "Limiti", false, false);
sprintf(strDescr, "Specify the number of tests (default %d)",_NUMERO_PROVE);
myopt_AddOption(parser, idGroup, 'N', "tests-number", strDescr, false, MOB_OVERRIDE, 1, 1, "int");
sprintf(strDescr, "Specify how many slower results ignore (default %d)",_ELIMINA_LENTI);	
myopt_AddOption(parser, idGroup, 'i', "ignore-slow", strDescr, false, MOB_OVERRIDE, 1, 1, "int");
sprintf(strDescr, "Specify how many faster results ignore (default %d)", _ELIMINA_VELOCI );	
myopt_AddOption(parser, idGroup, 'I', "ignore-fast", strDescr, false, MOB_OVERRIDE, 1, 1, "int");
	
idGroup = myopt_AddGroup(parser, "Formattazione output", true, false);
sprintf(strDescr, "Specify the formatting of the output");
myopt_AddOption(parser, idGroup, 'o', "output-mode", strDescr, false, MOB_ERROR, 1, 1, "string");

idGroup = myopt_AddGroup(parser, "Ordinamento", true, false);
sprintf(strDescr, "Specify how to sort the output");
myopt_AddOption(parser, idGroup, 's', "sort-mode", strDescr, false, MOB_ERROR, 1, 1, "string");
sprintf(strDescr, "Don't sort the output");
myopt_AddOption(parser, idGroup, 'n', "do-not-sort", strDescr, false, MOB_ERROR, 0, 0, "");

idGroup = myopt_AddGroup(parser, "Verbosità", true, false);
sprintf(strDescr, "Specify the level of verbosity");
myopt_AddOption(parser, idGroup, 'l', "debug-level", strDescr, false, MOB_ERROR, 1, 1, "int");
sprintf(strDescr, "Do verbose output");
myopt_AddOption(parser, idGroup, 'V', "verbose", strDescr, false, MOB_ERROR, 0, 0, "");
sprintf(strDescr, "Enter debug mode");
myopt_AddOption(parser, idGroup, 'd', "debug", strDescr, false, MOB_ERROR, 0, 0, "");
sprintf(strDescr, "Don't produce any output");
myopt_AddOption(parser, idGroup, 'q', "quiet", strDescr, false, MOB_ERROR, 0, 0, "");

myopt_SetPositionalArgsParams(parser, "POS_ARGS", 1, OR_MORE, "string");
In pratica, ho impostato queste opzioni:

Codice: Seleziona tutto

h	help
v	version
N	tests-number
i	ignore-slow
I	ignore-fast
o	output-mode
s	sort-mode
n	do-not-sort
l	debug-level
V	verbose
d	debug
q	quiet
l'output:

Codice: Seleziona tutto

effitest: ERROR: Parsing internal errors: Invalid call myopt_AddOption(-d, --debug): the option is already present in the symbol table
Penso che --debug vada in conflitto con --debug-level.
Forse perché --debug è prefisso di --debug-level, e myopt pensa che siano la stessa opzione.

Posso risolvere cambiando una delle due, ma mi piacerebbe sapere se è una cosa normale che due parametri non possano essere uno prefisso dell'altro.
Sinceramente non ci ho fatto caso nei programmi visti finora.

Grazie
;)

EDIT:
se può aiutare, questo non da errore:

Codice: Seleziona tutto

strcpy(strDescr, "Opzione ciao");
myopt_AddOption(parser, idGroup, 'c', "ciao", strDescr, false, MOB_ERROR, 0, 0, "");	

strcpy(strDescr, "Opzione ciao-mamma, più lunga di ciao");
myopt_AddOption(parser, idGroup, 'm', "ciao-mamma", strDescr, false, MOB_ERROR, 0, 0, "");
Mentre specificare prima ciao-mamma sì:

Codice: Seleziona tutto

strcpy(strDescr, "Opzione ciao mamma");
myopt_AddOption(parser, idGroup, 'c', "ciao-mamma", strDescr, false, MOB_ERROR, 0, 0, "");	

strcpy(strDescr, "Opzione ciao, prefisso di ciao-mamma");
myopt_AddOption(parser, idGroup, 'm', "ciao-mamma", strDescr, false, MOB_ERROR, 0, 0, "");

Codice: Seleziona tutto

Internal errors:
Invalid call myopt_AddOption(-m, --ciao): the option is already present in the symbol table
Avatar utente
Vincenzo1968
Scoppiettante Seguace
Scoppiettante Seguace
Messaggi: 450
Iscrizione: lunedì 14 gennaio 2013, 14:21
Desktop: Unity
Distribuzione: Ubuntu 18.04.3 LTS x86_64
Località: Villabate(PA)
Contatti:

Re: [Progetto] C Library for parsing command line arguments

Messaggio da Vincenzo1968 »

Si, era un bug.

Scarica i nuovi sorgenti e fammi sapere.
È ormai difficile incontrare un cretino che non sia intelligente e un intelligente che non sia un cretino. [...] Oh i bei cretini di una volta! Genuini, integrali. Come il pane di casa. Come l'olio e il vino dei contadini. (da "Nero su nero" di Leonardo Sciascia)
Scrivi risposta

Ritorna a “Progetti della Comunità”

Chi c’è in linea

Visualizzano questa sezione: 0 utenti iscritti e 20 ospiti