Newsgroup: it.comp.os.linux.development
Titolo: [C++] Un wrapper per i file di configurazione?

Salve,
sto iniziando adesso a programmare in Linux. Ho iniziato qualche tempo
fa ad usare in Win32 il BCB3.
Ora, visto che su Linux non esiste un registro di configurazione, devo
gestire un file di configurazione in /etc, giusto?
Bene, esiste un wrapper tipo il TIniFile del BCB che permetta di
astrarre le scritture/letture del file?
Grazie.
-- 
Ciao
DGP85
http://daps.cjb.net/

 wrote
| Bene, esiste un wrapper tipo il TIniFile del BCB che permetta di
| astrarre le scritture/letture del file?
Non mi risulta, e infatti mi sto scrivendo un set di classi in c++
all'uopo.

 scritture/letture del file? Grazie.
Pero' non tutti i files di configurazione hanno la stessa sintassi :-((
L'unica soluzione è che tutti i programmatori usino GConf.....
--
PLF

L'unica soluzione è che tutti i programmatori usino GConf.....
A me basta gestire il mio programma... dove trovo GConf, non mi
ricordo di averlo visto su linuxberg...


 dove trovo GConf, non mi ricordo di averlo visto su linuxberg...
Io lo vidi.... Prova su
ftp://ftp.helixcode.com/pub/helix/evolution/distributions/
<tua_distro>/GConf*0.6*.rpm
E' molto bello, per ora gestisce una sorta di registry solo con xml ma in
futuro supportera' numerosi altri sistemi e poi ha 2 librerie una per gtk e
l'altra generica.
--
PLF

 astrarre le scritture/letture del file?
Nulla di standard anche perche' il formato dei file in /etc
(purtroppo) non e' standardizzato.
Se pero' devi sviluppare un'applicazione GNOME GConf e' quello che fa
per te (in pratica e' il registro di windows implementato bene ;-)
Ciao,
-- 
Diego    | Per le repliche elimina dal mio indirizzo le 
Dainese  | `x' e inverti le due parole intorno alla `@'

per te (in pratica e' il registro di windows implementato bene ;-)
Ma se il programma viene installato in una macchina che non ha GConf,
funziona o no?
Sinceramente vorrei riuscire a trovare una libreria per la gestione di
file INI che si adatti sia a DOS (con file INI in c:\windows), e anche
a Linux (solo i miei file CONF in /etc).
Non mi interessa lo standard o no degli altri files, mi basta avere la
possibilità di gestire i file di configurazione dei miei programmi
(solo dei miei) in qualsiasi sistema venga installato il programma.
A proposito, pur non dispiacendomi la separazione dei programmi
Gnome/X11, vorrei sapere se, programmando con Glade, il programma
generato dira solo in Gnome o no?


 (in pratica e' il registro di windows implementato bene ;-)
GConf non è solo per gnome
--
PLF

 Gnome o no?
Glade è solo un gui builder, genera il codice sorgente per un'applicazione gtk
ed eventualmente gnome.....
--
PLF

a Linux (solo i miei file CONF in /etc).
Fattela da te. Per partire:
// EZINI - Eazy INI handling
#ifndef __MSDOS__
#define	stricmp		strcasecmp
#define strnicmp	strncasecmp
#endif
#include <stdio.h>
#include <string.h>
#define	MAXLINEA	256	// Massima lunghezza di una linea
#define MAXSEZ		80	// Massima lunghezza nome sezione
#define MAXKEY		80	// Massima lunghezza nome chiave
enum
{
	INI_IN_RICERCA,
	INI_SEZIONE_OK,
	INI_CHIAVE_OK,
	INI_SALTA,
	INI_TUTTO_OK
};
int SetINIValue(const char *inifile,	// Il file INI da manipolare
		const char *sezione,	// La sezione da consultare
		const char *chiave,     // La chiave da cercare
		char *nuovo_valore)     // Valore da dare alla chiave
// Valori di ritorno:  0 = OK
//   		      -1 = errore sul file
{
	FILE	*fp, *np;
	char 	linea[MAXLINEA];
	char	chiave_sezione[MAXSEZ];
	int	status = 0;
	/* La sezione viene convertita in una chiave */
	/* Per es. PIPPO diventa [PIPPO] seguito da un line-feed */
	snprintf(chiave_sezione, MAXSEZ, "[%s]\n", sezione);
	// Il file inifile viene rinominato in un file temporaneo
	// Sai come godono le altre applicazioni, quando gli levi
	// di sotto il file...
	rename(inifile, "iniwork.tmp");
	if ((np    = fopen (inifile, "w+t")) == NULL)
	{
		rename("iniwork.tmp", inifile);
		return -1;
	}
	fp = fopen("iniwork.tmp", "rt");
	if (fp)
	{
		while (!feof(fp))
		{
			*linea=0;
			switch(status)
			{
				case INI_IN_RICERCA:
					fgets(linea, MAXLINEA, fp);
					if (*linea==0 || *linea==';' ||
*linea=='#')
						break;
					if (!stricmp(linea,
chiave_sezione))
						status = INI_SEZIONE_OK;
					break;
				case INI_SEZIONE_OK:
					sprintf(linea,"%s=%s\n", chiave,
nuovo_valore);
					status = INI_CHIAVE_OK;
					break;
				case INI_CHIAVE_OK:
					fgets(linea, MAXLINEA, fp);
					if (*linea==0 || *linea==';' ||
*linea=='#')
						break;
					if (*linea=='[')
						status = INI_TUTTO_OK;
					if (!strnicmp(linea, chiave,
strlen(chiave)))
					{
	/* Se abbiamo trovato la chiave, dobbiamo
	   scartarla. Per essere sicuri di averla
	   trovata, si deve tener presente che si
	   puo' avere:
	chiave cercata: "Quel ramo"
	linee nel file:
		"Quel = "
		"Quel ramo del lago di Como = "
		"Quel ramo     = "
  	   e che a noi interessa la _terza_ riga.
	   All' interno di questo IF, sappiamo di
	   aver eliminato il falso match (1) e il
	   (2). Ma dobbiamo ancora riconoscere il
	   VERO match (3).
	   Possiamo avere:
		Quel=
		Quel =
		Quel\t=
		Quel\t \t\t=\t\t
	   e TUTTI devono essere riconosciuti.
*/
						char *ptr;
						ptr = linea +
strlen(chiave) -1;
						while (*ptr++)
						{
							if (*ptr == ' ')
continue;
							if (*ptr ==
'\t')
continue;
							if (*ptr == '=')
								status =
INI_SALTA;
							break;
						}
					}
					break;
				case INI_SALTA:
					status = INI_TUTTO_OK;
				case INI_TUTTO_OK:
					fgets(linea, MAXLINEA, fp);
					break;
			}
			if (status != INI_SALTA)
				if (*linea)
					fputs(linea, np);
		}
		fclose(fp);
	}
	remove("iniwork.tmp");
	if(status==INI_IN_RICERCA)	/* Manca TUTTO! */
	{
		fprintf(np, chiave_sezione);
		fprintf(np,"%s=%s\n", chiave, nuovo_valore);
		fprintf(np, "\n");
	}
	fclose(np);
	return 0;
}
char *GetINIValue(const char *inifile,	// Il file INI da manipolare
		const char *sezione,	/* La sezione da consultare
		const char *chiave,     /* La chiave da cercare
		char *valore)     	/* Dove salvarne il valore
/*
	Valore di ritorno: NULL se la chiave non c'e' (perche' file
	errato, sezione mancante, o chiave non trovata).
	Altrimenti, punta alla chiave, priva del \n finale.
	Se 'valore' in ingresso e' NULL ritorna un puntatore a una area
	statica contenente i primi 79 caratteri della chiave.
	ATTENZIONE: prima di passare un valore non nullo, occorre essere
	ben sicuri che il puntatore che si passa punti ad un'area grande
	abbastanza da contenere la chiave.
	TODO: passare a GetINIValue anche la lunghezza del buffer...
*/
{
	FILE	*fp;
	char 	linea[MAXLINEA];
	char	chiave_sezione[MAXSEZ];
	static	char keyvalue [MAXKEY];
	char	*kptr = keyvalue;
	int	status = 0;
	if (valore)
		kptr = valore;
	snprintf(chiave_sezione, MAXSEZ, "[%s]\n", sezione);
	if ((fp = fopen(inifile, "rt")) == NULL)
		return NULL;
	while (!feof(fp))
	{
		*linea=0;
		fgets(linea, MAXLINEA, fp);
		if (*linea==0 || *linea==';' || *linea=='#')
			continue;
		if (strchr(linea,'\r'))
			strcpy(strchr(linea,'\r'),"\n");
		switch(status)
		{
			case INI_IN_RICERCA:
				if (!stricmp(linea, chiave_sezione))
					status = INI_SEZIONE_OK;
				break;
			case INI_SEZIONE_OK:
				if (*linea=='[')
				{
					fclose(fp);
					return NULL;
				}
				if (!strnicmp(linea, chiave,
strlen(chiave)))
				{
					char *ptr;
					ptr = linea + strlen(chiave) -1;
					while (*ptr++)
					{
						if (*ptr == ' ')
							continue;
						if (*ptr == '\t')
							continue;
						if (*ptr == '=')
						{
							while (*ptr++)
							{
								if (*ptr
== ' ')
continue;
								if (*ptr
== '\t')
continue;
								//
Trovata
strncpy(kptr, ptr, 80);
kptr[MAXKEY]=0;
								ptr =
strchr(kptr,'\n');
								if (ptr)
*ptr = 0;
fclose(fp);
								return
kptr;
							}
						}
						break;
					}
				}
		}
	}
	fclose(fp);
	return NULL;
}
/* Prova.
Sintassi: 	INITOOL inifile sez chiave --> mostra valore
		INITOOL inifile sez chiave nuovoval --> imposta valore
*/
int main(int argc, char **argv)
{
	char *ptr;
	switch (argc)
	{
		case 4:	/* GET value */
			ptr = GetINIValue(argv[1], argv[2], argv[3],
NULL);
			if (ptr == NULL)
				printf("File non trovato, sezione non
valida, o chiave mancante\n");
			else
				printf("%s->%s.%s=%s\n",
					argv[1],
					argv[2],
					argv[3],
					ptr);
			break;
		case 5:	/* SET value */
			if (SetINIValue(argv[1], argv[2], argv[3],
argv[4]))
				printf("Impossibile impostare il
valore.\n");
			else
				printf("OK!\n");
			break;
		default:
			fprintf(stderr,
				"Sintassi: 	%s inifile sezione
chiave --> mostra il valore\n"
				"		%s inifile sezione
chiave nuovovalore --> imposta il valore\n"
			, *argv, *argv);
	}
	return 0;
}
Leonardo
".signature": bad command or file name