Barra laterale

programmazione:c:una_libreria_per_leggere_i_file_.desktop

Una libreria per leggere i file .desktop

Autore: Fabio Di Matteo
Ultima revisione: 11/07/2008

I desktop manager come Gnome e Kde utilizzano per i propri collegamenti sul desktop i file .desktop che altro non sono che file di questo tipo:

[Desktop Entry]
Name=Audacious
Comment=Play music
Comment[hu]=Zene lejátszása
Exec=audacious %U
Icon=audacious.png
MimeType=application/x-ogg;audio/mp3;audio/mpeg;audio/mpegurl;audio/prs.sid;audio/x-flac;audio/x-it;audio/x-mod;audio/x-mp3;audio/x-mpeg;audio/x-mpegurl;audio/x-ms-wma;audio/x-musepack;audio/x-s3m;audio/x-scpls;audio/x-stm;audio/x-wav;audio/x-xm;application/ogg;audio/x-vorbis+ogg
Categories=Application;GTK;AudioVideo;Player;
Terminal=false
Type=Application
Encoding=UTF-8

Adesso realizzeremo una libreria C (dinamica e statica) e un eseguibile (utilizzabile in Bash e altri linguaggi interpretati) in grado di leggere e scrivere questi file.
Ricordo che l'utilizzo di questo formato di file non è solo destinato a Gnome e Kde, ma si potrebbe decidere di utilizzare questi file per memorizzare impostazioni di qualsiasi applicativo.

keys.h , il nostro header

#include <stdio.h>
#include <string.h>
#define MAXKEY  50
#define MAXVALUE  350
#define MAXLINE 450
 
int wordcount(char* line);
char* keyread(char *path, char* key);
void keywrite(char *path, char* key, char* value);
int keydel(char *path, char* key);

keys.c , il nostro sorgente

#include <stdio.h>
#include <string.h>
#define MAXKEY  50
#define MAXVALUE  350
#define MAXLINE 450
 
int wordcount(char* line);
char* keyread(char *path, char* key);
void keywrite(char *path, char* key, char* value);
int keydel(char *path, char* key);
 
 
 
 
char* keyread(char *path, char* key){
	FILE *f=fopen(path, "r");
	char valuetmp[MAXVALUE], line[MAXVALUE+MAXKEY], *value, key_now[MAXKEY] ;
	int i;
 
	while (feof(f)==0){
		fgets(line,MAXVALUE+MAXKEY,f);
		if (line[0]!='#'){
			sscanf(line, "%[^'=']=%[^'=\n']",key_now, valuetmp);
			if (strcmp(key_now, key)==0){
				value=malloc(sizeof(valuetmp));
				strcpy(value,valuetmp);
				fclose(f);
				return value;
			}
		}
	}
	fclose(f);
}
 
void keywrite(char *path, char* key, char* value){ 
	FILE *f=fopen(path, "r");
	int i, pos=0, idxline=0 ;
	char valuetmp[MAXVALUE],  *nline[MAXVALUE+MAXKEY], key_now[MAXKEY] ;
 
	//get key's position
	while (feof(f)==0){
	pos++;
		nline[pos-1]=malloc(MAXLINE);
		fgets(nline[pos-1],MAXLINE,f);
		if (nline[pos-1][0]!='#'){
			sscanf(nline[pos-1], "%[^'=']=%[^'=']",key_now, valuetmp);
			if (strcmp(key_now, key)==0 && idxline==0){
				idxline=pos-1;
			}
		}
	}
	fclose(f);
 
	//edit or append key
	nline[idxline]=malloc(MAXLINE+15);
	if (idxline!=0){
		//edit key
		sprintf(nline[idxline] ,"%s=%s\n",key,value);
		FILE *f=fopen(path, "w");
 
		for (i=0;i<=pos-1;i++)	fputs(nline[i],f);
		fclose(f);
 
	}else{
		//append new key
		FILE *f=fopen(path, "a");
		sprintf(nline[pos-1] ,"%s=%s",key,value);;
		fputs(nline[pos-1],f);
		fclose(f);	
	}
 
}
 
 
 
int keydel(char *path, char* key){ 
	FILE *f=fopen(path, "r");
	int i, pos=0, idxline=0 ;
	char valuetmp[MAXVALUE],  *nline[MAXVALUE+MAXKEY], key_now[MAXKEY] ;
 
	//get key's position
	while (feof(f)==0){
	pos++;
		nline[pos-1]=malloc(MAXLINE+15);
 
		fgets(nline[pos-1],MAXLINE,f);
		if (nline[pos-1][0]!='#'){
			sscanf(nline[pos-1], "%[^'=']=%[^'=']\n",key_now, valuetmp);
			if (strcmp(key_now, key)==0 && idxline==0){
				idxline=pos-1;
			}
		}
	}
	fclose(f);
 
	//delete key
	if (idxline!=0){
		FILE *f=fopen(path, "w");
		for (i=0;i<=pos-1;i++){
			if (i!=idxline)fputs(nline[i],f);
		}
		fclose(f);
 
	}else{
		return -1;
	}
}
 
 
 
 
int wordcount(char* line){
	int i,count=0;
	for(i=0; i<strlen(line);i++){
		if (isspace(line[i]) && !isspace(line[i+1]) ) count++;	
	}
	return count;
}

test.c , il nostro eseguibile di test

A partire da test.c verranno generati 2 eseguibili, uno con la libreria compilata in maniera statica dentro di esso e l'altro eseguibile verra linkato dinamicamente alla libreria (il che fa sì che la libreria ne diventi una dipendenza). L'eseguibile generato a partire da test.c ci permetterà di trattare i file .desktop da riga di comando, in questo modo:

Per leggere un valore:

./test-static -r [nome chiave] file.desktop

Per scrivere un valore (se la chiave non esiste la crea infondo al file):

./test-static -w [nome chiave] [valore] file.desktop

Per cancellare un valore:

./test-static -d [nome chiave] file.desktop

Il makefile

Il nostro make file genererà 2 librerie, una statica chiamata libkeys-1.0.0.a , l'altra dinamica chiamata libkeys.so.1.0.0 e poi 2 eseguibili, uno compilato con la libreria statica e l'altro verra linkato dinamicamente alla libreria rispettivamente test-static e test-shared .

p=/usr/local/

all:
	gcc -c keys.c -o libkeys.o
	ar -r libkeys-1.0.0.a libkeys.o
	gcc -fpic -c keys.h keys.c
	gcc -shared -Wl,-soname,libkeys.so.1 -o libkeys.so.1.0.0 keys.o
test:
	gcc test.c libkeys-1.0.0.a -o test-static
	gcc libkeys.so.1.0.0 -o test-shared test.c keys.h
static:
	gcc -c keys.c -o libkeys.o
	ar -r libkeys-1.0.0.a libkeys.o

shared:
	gcc -fpic -c keys.h keys.c
	gcc -shared -Wl,-soname,libkeys.so.1 -o libkeys.so.1.0.0 keys.o

install:
	cp libkeys.so.1.0.0 $p/lib/
	cp libkeys-1.0.0.a $p/lib/
	cp keys.h $p/include/
	ldconfig

uninstall:
	rm $p/lib/libkeys.so.1.0.0
	rm $p/lib/libkeys-1.0.0.a
	rm $p/include/keys.h
	ldconfig



programmazione/c/una_libreria_per_leggere_i_file_.desktop.txt · Ultima modifica: 18/04/2018 - 15:49 (modifica esterna)