Skip to content
GitLab
Explorer
Connexion
Navigation principale
Rechercher ou aller à…
Projet
lektor
Gestion
Activité
Membres
Labels
Programmation
Tickets
Tableaux des tickets
Jalons
Code
Requêtes de fusion
Dépôt
Branches
Validations
Étiquettes
Graphe du dépôt
Comparer les révisions
Compilation
Pipelines
Jobs
Planifications de pipeline
Artéfacts
Aide
Aide
Support
Documentation de GitLab
Comparer les forfaits GitLab
Forum de la communauté GitLab
Contribuer à GitLab
Donner votre avis
Raccourcis clavier
?
Extraits de code
Groupes
Projets
Afficher davantage de fils d'Ariane
Kubat
lektor
Validations
44ea9ada
Vérifiée
Valider
44ea9ada
rédigé
Il y a 4 ans
par
Kubat
Parcourir les fichiers
Options
Téléchargements
Correctifs
Plain Diff
CMD: Basic trie to store commands, only support insert for now
parent
90cbacec
Aucune branche associée trouvée
Aucune étiquette associée trouvée
1 requête de fusion
!162
Add a trie structure to get all the commands + various fixes
Modifications
1
Afficher les modifications d'espaces
En ligne
Côte à côte
Affichage de
1 fichier modifié
src/net/listen.c
+126
-0
126 ajouts, 0 suppression
src/net/listen.c
avec
126 ajouts
et
0 suppression
src/net/listen.c
+
126
−
0
Voir le fichier @
44ea9ada
...
@@ -18,6 +18,132 @@
...
@@ -18,6 +18,132 @@
#include
<sys/un.h>
#include
<sys/un.h>
#include
<sys/socket.h>
#include
<sys/socket.h>
/* Server commands, stored in a trie for a bit more efficient lookups.
* Commands have ascii names, but use the size of a char to not bother with
* bounds. If the `type` is not LKT_COMMAND_NULL, then the node is a terminal
* node, otherwise you need to reinterpret the `cmd_ptr` to the right function
* pointer type. */
#define CHARS_MAX (sizeof(char) * 256)
typedef
enum
{
/* Not a terminal node, so no commands */
LKT_COMMAND_NULL
,
/* Some common types of commands */
LKT_COMMAND_SIMPLE
,
/* srv, c, args */
LKT_COMMAND_INTEGER
,
/* srv, c, args, int */
/* Some specialized types... */
}
LKT_COMMAND_TYPE
;
struct
cmd_trie_node
{
LKT_COMMAND_TYPE
type
;
/* The type of the command, to reinterpret the function pointer */
void
(
*
cmd_ptr
)(
void
);
/* The function pointer of the command */
struct
cmd_trie_node
*
children
[
CHARS_MAX
];
/* Childrens, a byte is 256 possible values */
};
PRIVATE_FUNCTION
struct
cmd_trie_node
*
cmd_trie_new
(
void
)
{
struct
cmd_trie_node
*
ret
=
safe_malloc
(
sizeof
(
struct
cmd_trie_node
));
for
(
size_t
i
=
0
;
i
<
CHARS_MAX
;
++
i
)
{
ret
->
children
[
i
]
=
NULL
;
}
/* cmd_ptr == NULL && type == NULL => invalid node, for empty tries. */
ret
->
cmd_ptr
=
NULL
;
ret
->
type
=
LKT_COMMAND_NULL
;
return
ret
;
}
PRIVATE_FUNCTION
void
cmd_trie_insert
(
struct
cmd_trie_node
*
root
,
const
char
*
signed_cmd_name
,
void
(
*
cmd_ptr
)(
void
),
LKT_COMMAND_TYPE
cmd_type
)
{
FAIL_UNLESS
(
root
,
"Passing an empty trie root"
);
unsigned
const
char
*
cmd_name
=
(
unsigned
const
char
*
)
signed_cmd_name
;
size_t
cmd_name_index
=
0
;
size_t
current_char
=
cmd_name
[
cmd_name_index
];
while
(
current_char
)
{
/* Create the node if it doesn't exist */
if
(
root
->
children
[
current_char
]
==
NULL
)
{
root
->
children
[
current_char
]
=
cmd_trie_new
();
}
/* curr = curr->next */
cmd_name_index
+=
1
;
root
=
root
->
children
[
current_char
];
current_char
=
cmd_name
[
cmd_name_index
];
}
/* Insert the new command */
if
(
root
->
type
==
LKT_COMMAND_NULL
)
{
root
->
type
=
cmd_type
;
root
->
cmd_ptr
=
cmd_ptr
;
}
/* The command was already inserted */
else
{
LOG_FATAL
(
"The command '%s' was already present in the cmd_trie"
,
signed_cmd_name
);
}
}
PRIVATE_FUNCTION
void
___cmd_trie_print
(
struct
cmd_trie_node
*
root
,
char
*
old_prefix
,
const
size_t
length
)
{
char
prefix
[
length
+
2
];
/* Old + new_char + \0 */
memcpy
(
prefix
,
old_prefix
,
sizeof
(
char
)
*
length
);
prefix
[
length
+
1
]
=
'\0'
;
switch
(
root
->
type
)
{
/* Not a terminal node */
case
LKT_COMMAND_NULL
:
break
;
/* A terminal node */
case
LKT_COMMAND_SIMPLE
:
case
LKT_COMMAND_INTEGER
:
LKT_OUTPUT
(
"CMD_TRIE"
,
"Got function in trie: %s (type: %d)"
,
prefix
,
root
->
type
);
break
;
}
for
(
size_t
i
=
0
;
i
<
CHARS_MAX
;
++
i
)
{
/* Rec-call with new children */
if
(
root
->
children
[
i
]
!=
NULL
)
{
prefix
[
length
]
=
i
;
___cmd_trie_print
(
root
->
children
[
i
],
prefix
,
length
+
1
);
}
}
}
PRIVATE_FUNCTION
void
cmd_trie_print
(
struct
cmd_trie_node
*
root
)
{
FAIL_UNLESS
(
root
,
"Passing an empty trie root"
);
___cmd_trie_print
(
root
,
NULL
,
0
);
}
struct
cmd_trie_node
*
cmd_trie_root
=
NULL
;
CONSTRUCTOR_FUNCTION
___cmd_trie_init
(
void
)
{
cmd_trie_root
=
cmd_trie_new
();
cmd_trie_insert
(
cmd_trie_root
,
"next"
,
FUNCTION_POINTER
(
command_next
),
LKT_COMMAND_SIMPLE
);
cmd_trie_print
(
cmd_trie_root
);
}
DESTRUCTOR_FUNCTION
___cmd_trie_deinit
(
void
)
{
}
/* Client structure */
typedef
enum
{
typedef
enum
{
LKT_COMMAND_LIST_OFF
,
LKT_COMMAND_LIST_OFF
,
LKT_COMMAND_LIST_ON
,
LKT_COMMAND_LIST_ON
,
...
...
Ce diff est replié.
Cliquez pour l'agrandir.
Aperçu
0%
Chargement en cours
Veuillez réessayer
ou
joindre un nouveau fichier
.
Annuler
You are about to add
0
people
to the discussion. Proceed with caution.
Terminez d'abord l'édition de ce message.
Enregistrer le commentaire
Annuler
Veuillez vous
inscrire
ou vous
se connecter
pour commenter