My Project
Chargement...
Recherche...
Aucune correspondance
registre.c
Aller à la documentation de ce fichier.
1
8#include <manux/registre.h>
9#include <manux/string.h> // strlen, memcpy, prochainDelimiteur
10#include <manux/printk.h>
11#include <manux/kmalloc.h>
12#include <manux/errno.h> // ENOENT
13#include <manux/debug.h> // assert
14
19typedef struct _parametre {
20 char * nom;
21 int estUnRegistre; // Sous-registre (1) ou non (0)
22 char * valeur;
23 registreMiseAJour miseAJour; // Invoquée par le
24 // registre lors d'une
25 // modification du
26 // paramètre
27 void * prive; // Un pointeur à disposition de l'utilisateur
28 // Ce sera un pointeur vers un registre si
29 // estUnRegistre == 1
31
40
45
54
55static registre * registreSysteme = NULL;
56
57/*----------------------------------------------------------------------------*/
58/* Les paramètres */
59/*----------------------------------------------------------------------------*/
60
64static void parametreMettreAJour(parametre * p)
65{
66 if ((p != NULL) && (p->miseAJour != NULL)) {
67 p->miseAJour(p->prive, p->valeur);
68 }
69}
70
74static void parametreAffecterValeur(parametre * p, char * v)
75{
76 if (p->valeur != NULL) {
77 kfree(p->valeur);
78 }
79
80 if (v != NULL) {
81 p->valeur = kmalloc(strlen(v) +1);
82 memcpy(p->valeur, v, strlen(v) +1);
83 } else {
84 p->valeur = NULL;
85 }
86
87 // On répercute la mise-à-jour
88 parametreMettreAJour(p);
89}
90
94static void parametreAffecterNom(parametre * p, char * n)
95{
96 if (p->nom != NULL) {
97 kfree(p->nom);
98 }
99 p->nom = kmalloc(strlen(n) +1);
100 memcpy(p->nom, n, strlen(n) +1);
101}
102
106static void parametreAffecterMiseAJour(parametre * param,
107 void * prive,
108 registreMiseAJour miseAJour)
109{
110 param->miseAJour = miseAJour;
111 param->prive = prive;
112
113 // On applique car il y a peut-être déjà une valeur
114 parametreMettreAJour(param);
115}
116
120static parametre * parametreCreer(char * nom, char * valeur,
121 void * prive, registreMiseAJour miseAJour)
122{
123 parametre * result = (parametre *) kmalloc(sizeof(parametre));
124
125 if (result != NULL) {
126 memset(result, 0, sizeof(parametre));
127 parametreAffecterNom(result, nom);
128 parametreAffecterValeur(result, valeur);
129 parametreAffecterMiseAJour(result, prive, miseAJour);
130 }
131 return result;
132}
133
134/*----------------------------------------------------------------------------*/
135/* Les listes de paramètres. */
136/*----------------------------------------------------------------------------*/
137
141static listeParametres * listeParametresCreer(void)
142{
144
145 if (result != NULL) {
146 result->premier = NULL;
147 result->dernier = NULL;
148 }
149 return result;
150}
151
157static void listeParametresInserer(listeParametres * lp, parametre * p)
158{
160
161 //printk_debug(DBG_KERNEL_REGISTRE, "Insertion dans 0x%x ...\n", lp);
162 if (cp != NULL) {
163 cp->parametre = p;
164 cp->suivant = lp->premier;
165 cp->precedent = NULL;
166 if (lp->premier != NULL){
167 lp->premier->precedent = cp;
168 }
169 lp->premier = cp;
170 // printk_debug(DBG_KERNEL_REGISTRE, " 0x%x premier = 0x%x\n", lp, cp);
171 if (lp->dernier == NULL) {
172 lp->dernier = cp;
173 }
174 }
175}
176
180static parametre * listeParametresChercher(listeParametres * lp, char * nom)
181{
182 chainonParametre * cp = lp->premier;
183
184 while ((cp != NULL) && (strcmp(nom, cp->parametre->nom))) {
185 cp = cp-> suivant;
186 }
187
188 // On l'a trouvé ?
189 if (cp != NULL) {
190 return cp->parametre;
191 }
192
193 return NULL;
194}
195
196/*----------------------------------------------------------------------------*/
197/* Les registres. */
198/*----------------------------------------------------------------------------*/
199
204{
205 registre * result = (registre *)kmalloc(sizeof(registre));
206
207 if (result != NULL) {
208 result->nom = kmalloc(strlen(nom) +1);
209 memcpy(result->nom, nom, strlen(nom) +1);
210 result->parametres = listeParametresCreer();
211 }
212
213 return result;
214}
215
219static
220registre * registreChercherSousRegistre(registre * b, char * nomSr)
221{
222 registre * result = NULL;
223 chainonParametre * ch;
224
225 if ((b != NULL) && (b->parametres != NULL)) {
226 for (ch = b->parametres->premier ; (ch != NULL) && (result == NULL) ; ch = ch->suivant) {
227 // Si on trouve une sous-base avec le bon nom, on la renvoie
228 if ( (ch->parametre->estUnRegistre)
229 && (strcmp(nomSr, ch->parametre->nom) == 0)){
230 return (registre *) ch->parametre->prive;
231 }
232 }
233 }
234
235 return result;
236}
237
244static
245void registreAjouterParametre(registre * reg, parametre * param)
246{
247 listeParametresInserer(reg->parametres, param);
248}
249
257static
258registre * registreAjouterSousRegistre(registre * reg, char * nomSr)
259{
260 registre * result;
261 parametre * sRParam;
262
263 // Existe-t-il déjà ?
264 result = registreChercherSousRegistre(reg, nomSr);
265
266 // Si non, on le crée
267 if (result == NULL) {
268
269 // Création du (sous) reg
270 result = registreCreer(nomSr);
271
272 // On en fait un paramètre
273 sRParam = parametreCreer(nomSr, NULL, (void *) result, NULL);
274 sRParam->estUnRegistre = 1;
275
276 // On l'insère dans le registre père
277 registreAjouterParametre(reg, sRParam);
278 }
279
280 return result;
281}
282
289#ifndef REGISTRE_NOM_SEPARATEUR
290# define REGISTRE_NOM_SEPARATEUR '.'
291#endif
292#ifndef REGISTRE_AFFECTATION
293# define REGISTRE_AFFECTATION '='
294#endif
295static
296void registreAjouterC(registre * reg, char * chaine)
297{
298 char * debut; // Pointeur sur le début du nom
299 char * fin; // Pointeur sur la fin du nom courant
300 char nom[512]; // Une chaine pour héberger temporairement le nom courant
301 int lgNom; // Longueur du nom courant
302 char * valeur;
303 registre * regSS = reg; // La base du sous-système dans lequel on
304 // va introduire
305 parametre * param; // Le parametre qu'on va créer/modifier
306 char * aff = NULL; // Pour restauter le signe d'affectation
307
308 // On fait pointer valeur sur la représentation ou une chaîne vide
310
311 // On s'assure que le nom (qui précède l'affectation) est terminé
312 // par un 0
313 if (*valeur == REGISTRE_AFFECTATION) {
314 *valeur = 0;
315 aff = valeur; // On note où il était
316 valeur ++;
317 }
318
319 // Nous avons donc maintenant deux chaines de caractères (collées
320 // l'une derrière l'autre) l'une contient un nom, l'autre une
321 // valeur (cette dernière peut être une chaîne vide)
322 debut = chaine;
323
324 // Il faut maintenant construire et/ou renseigner la structure sur
325 // la base du nom
326 while (strlen(debut)) {
328 assert(fin > debut); // Puisque strlen(debut) != 0
329 lgNom = fin - debut;
330 memcpy(nom, debut, lgNom);
331 nom[lgNom] = 0;
332 // Si on a un séparateur, on descend dans l'arborescence, sinon,
333 // on est sur le 0 final
334 if (*fin == REGISTRE_NOM_SEPARATEUR) {
335
336 // On descend dans l'arborescence
337 regSS = registreChercherSousRegistre(reg, nom);
338 if (regSS == NULL) {
339 regSS = registreAjouterSousRegistre(reg, nom);
340 }
341 // Eventuellement en la créant
342 if (regSS != NULL) {
343 reg = regSS; // On travaille maintenant dans le sous reg
344 }
345
346 // On passe au suivant
347 debut = fin + 1;
348 // Si on est à la dernière, on peut placer la donnée
349 } else {
350 param = listeParametresChercher(regSS->parametres, nom);
351 if (param == NULL) {
352 param = parametreCreer(nom, valeur, NULL, NULL);
353 listeParametresInserer(regSS->parametres, param);
354 } else {
355 parametreAffecterValeur(param, valeur);
356 }
357
358 // On en arrive à la fin
359 debut = fin;
360 }
361 }
362 // On restaure le symbole d'affectation
363 if (aff) {
365 }
366}
367
389static
390void registreAffecterParametreT(registre * reg,
391 char * valeur,
392 void * prive,
393 registreMiseAJour miseAJour,
394 va_list argList)
395{
396 char * chaine, * prochaine;
397 registre * regSS = reg; // La base du sous-système
398 parametre * param;
399
400 chaine = va_arg(argList, char *);
401 prochaine = va_arg(argList, char *);
402
403 //printk("Affectation dans %s ...\n", reg->nom);
404 while (chaine != NULL) {
405 // Si on n'est pas à la dernière, on descend dans l'arborescence
406 // en la créant si nécessaire
407 if (prochaine != NULL) {
408 regSS = registreChercherSousRegistre(reg, chaine);
409 if (regSS == NULL) {
410 regSS = registreAjouterSousRegistre(reg, chaine);
411 }
412 if (regSS != NULL) {
413 reg = regSS; // On travaille maintenant dans le sous reg
414 }
415 // Si on est à la dernière, on peut affecter le paramètre
416 } else {
417 // On le récupère s'il existait
418 param = listeParametresChercher(reg->parametres, chaine);
419 // On le crée sinon
420 if (param == NULL) {
421 param = parametreCreer(chaine, valeur, prive, miseAJour);
422 listeParametresInserer(reg->parametres, param);
423 } else {
424 // Si c'est une nouvelle valeur, on appelle la mise-à-jour
425 if (miseAJour == NULL) {
426 parametreAffecterValeur(param, valeur);
427 } else { // Affectation de la mise-à-jour
428 // La valeur fournie avec une fonction de mise-à-jour
429 // est une valeur par défaut, qui n'est utile qu'en
430 // l'absence de valeur déjà renseignée
431 if (param->valeur == NULL) {
432 parametreAffecterValeur(param, valeur);
433 }
434 parametreAffecterMiseAJour(param, prive, miseAJour);
435 }
436 }
437 }
438 // On avance
439 chaine = prochaine;
440 prochaine = va_arg(argList, char *);
441 }
442}
443
450 char * valeur,
451 void * prive,
452 registreMiseAJour miseAJour,
453 ...)
454{
455 va_list argList;
456
457 va_start(argList, miseAJour);
458 registreAffecterParametreT(reg, valeur, prive, miseAJour, argList);
459 va_end(argList);
460}
461
466[[maybe_unused]]
467static
468parametre * registreObtenirParametre(registre * reg, va_list argList)
469{
470 parametre * result = NULL;
471
472 char * chaine, * prochaine;
473 chainonParametre * ch;
474
475 registre * regSS = reg; // Le registre du sous-système
476
477 chaine = va_arg(argList, char *);
478 prochaine = va_arg(argList, char *);
479
480 while (chaine != NULL) {
481 // Si on n'est pas à la dernière, on descend dans l'arborescence
482 if (prochaine != NULL) {
483 regSS = registreChercherSousRegistre(reg, chaine);
484 if (regSS == NULL) {
485 return result;
486 }
487 reg = regSS;
488 // Si on est à la dernière, on peut lire la donnée
489 } else {
490 for (ch = regSS->parametres->premier; ch != NULL; ch = ch->suivant){
491 // Si on la trouve, c'est bon
492 if (strcmp(ch->parametre->nom, chaine) == 0) {
493 return ch->parametre;
494 }
495 }
496 }
497 // On avance
498 chaine = prochaine;
499 prochaine = va_arg(argList, char *);
500 }
501
502 return result;
503}
504
508static
509void registreAfficher(registre * reg, int profondeur)
510{
511 chainonParametre * ch;
512 int p;
513
514 for (p = 0 ; p < profondeur; p++) {printk(" ");}
515 printk("[%s]\n", reg->nom);
516
517 for (ch = reg->parametres->premier; ch != NULL; ch = ch->suivant){
518 for (p = 0 ; p < profondeur; p++) {printk(" ");}
519 printk("%s : ", ch->parametre->nom);
520 if (ch->parametre->estUnRegistre){
521 printk("(reg)\n");
522 registreAfficher((registre *)ch->parametre->prive, profondeur +1);
523 } else {
524 printk("%s\n", ch->parametre->valeur);
525 }
526 }
527}
528
529/*----------------------------------------------------------------------------*/
530/* Le registre système. */
531/*----------------------------------------------------------------------------*/
532
537{
538 registreSysteme = registreCreer("ManuX-Param");
539
540#ifdef MANUX_DEBUG
541 A FAIRE : introduire les masque de debug avec la valeur par défaut
542#endif
543}
544
552void registreSystemeAjouterC(char * chaine)
553{
554 registreAjouterC(registreSysteme, chaine);
555}
556
566 void * prive,
567 registreMiseAJour miseAJour,
568 ...)
569{
570 va_list argList;
571
572 va_start(argList, miseAJour);
573 registreAffecterParametreT(registreSysteme, valeur, prive, miseAJour, argList);
574 va_end(argList);
575}
576
581{
582 registreAfficher(registreSysteme, 0);
583}
Définition de kmalloc.
Définition des fonctions de base d'entrée-sortie du noyau.
void printk(char *format,...)
Fonction principale d'affichage dans le noyau.
Definition printk.c:166
Gestion des registres (outils permettant de stocker des paramètres)
void(* registreMiseAJour)(void *, char *)
La fonction de mise-à-jour d'un registre.
Definition registre.h:89
#define va_arg(ap, type)
Definition stdarg.h:7
#define va_end(ap)
Definition stdarg.h:8
#define va_start(ap, last)
Definition stdarg.h:6
__builtin_va_list va_list
Definition stdarg.h:4
#define NULL
Definition stddef.h:10
int strcmp(const char *s1, const char *s2)
Definition string.c:74
int strlen(const char *s)
Definition string.c:46
void * memset(void *dest, int val, size_t n)
Definition string.c:25
void * memcpy(void *dest, const void *src, size_t n)
Definition string.c:12
char * prochainDelimiteur(char *chaine, char delimiteur)
Recherche d'un délimiteur dans une chaîne.
Definition string.c:104
void * kmalloc(size_t n)
Allocation d'une zone de n octets.
Definition kmalloc-zs.c:139
void kfree(void *p)
Libération d'une zone mémoire allouée.
Definition kmalloc-zs.c:265
uint16_t b
#define assert(cond)
Definition debug.h:126
struct _registre registre
Un registre est simplement une liste (nommée) de paramètres. Les paramètres peuvent être eux-mêmes de...
void registreSystemeAfficher(void)
Affichage du registre système.
Definition registre.c:580
void registreSystemeInitialiser(void)
Création du registre du système.
Definition registre.c:536
#define REGISTRE_NOM_SEPARATEUR
Ajouter dans un registre un paramètre décrit dans une chaîne de caractères.
Definition registre.c:290
struct _parametre parametre
Un paramètre est simplement une valeur sous forme de chaîne de caractères associée à un nom.
void registreSystemeAjouterC(char *chaine)
Ajouter dans un registre système un paramètre décrit dans une chaîne de caractères.
Definition registre.c:552
#define REGISTRE_AFFECTATION
Definition registre.c:293
struct _listeParametres listeParametres
registre * registreCreer(char *nom)
Création d'un registre vide.
Definition registre.c:203
void registreAffecterParametre(registre *reg, char *valeur, void *prive, registreMiseAJour miseAJour,...)
La fonction fournie pour affecter un paramètre dans un registre.
Definition registre.c:449
struct _chainonParametre chainonParametre
On va construire des listes de paramètres.
void registreSystemeAffecterParametre(char *valeur, void *prive, registreMiseAJour miseAJour,...)
Ajouter au registre système un paramètre dont le nom est donné comme une liste de paramètres.
Definition registre.c:565
On va construire des listes de paramètres.
Definition registre.c:35
parametre * parametre
Definition registre.c:36
struct _chainonParametre * suivant
Definition registre.c:37
struct _chainonParametre * precedent
Definition registre.c:38
chainonParametre * dernier
Definition registre.c:43
chainonParametre * premier
Definition registre.c:42
Un paramètre est simplement une valeur sous forme de chaîne de caractères associée à un nom.
Definition registre.c:19
char * valeur
Definition registre.c:22
void * prive
Definition registre.c:27
char * nom
Definition registre.c:20
registreMiseAJour miseAJour
Definition registre.c:23
int estUnRegistre
Definition registre.c:21
Un registre est simplement une liste (nommée) de paramètres. Les paramètres peuvent être eux-mêmes de...
Definition registre.c:50
char * nom
Definition registre.c:51
listeParametres * parametres
Definition registre.c:52