vxBoot/src/cli/parser.c

141 lines
3.1 KiB
C
Raw Normal View History

#include "vxBoot/cli.h"
#include <stdlib.h>
#include <string.h>
/* define external symbols */
extern int cli_parser_strtotab(int *argc, char ***argv, char const *str);
extern void cli_parser_strtotab_quit(int *argc, char ***argv);
/* parser_get_word(): Get the word at the current cursor location. */
static int parser_get_word(char ***tab, size_t *tab_pos,
char const *str, int *counter)
{
int i;
/* skip until separator */
i = -1;
while (str[++i] != '\0'
&& str[i] != '\n'
&& str[i] != ' '
&& str[i] != '\t');
/* dump the word of needed */
if (*tab != NULL) {
(*tab)[*tab_pos] = (char*)calloc(1, i + 1);
if ((*tab)[*tab_pos] == NULL)
return (-1);
memset((*tab)[*tab_pos], 0, i + 1);
strncpy((*tab)[(*tab_pos)++], str, i);
}
/* update the internal counter */
(*counter)++;
return (i);
}
/* parser_get_inibitor()
This function will get the content of an inhibitor (and check if the
inhibitor characteres are alone or not). */
static int parser_get_inibitor(char ***tab, size_t *tab_pos,
char const *str, int *counter)
{
int i;
/* get the inibitor end */
i = 0;
while (str[++i] != '\0' && str[i] != '\"');
if (str[i] != '\"')
return (0);
/* dump the word if needed */
if (*tab != NULL) {
(*tab)[*tab_pos] = (char*)calloc(1, i + 1);
if ((*tab)[*tab_pos] == NULL)
return (-1);
memset((*tab)[*tab_pos], 0, i + 1);
strncpy((*tab)[(*tab_pos)++], str + 1, i - 1);
}
/* update the internal counter */
(*counter)++;
return (i + 1);
}
/* parser_setup_arg()
This function removes useless spaces, tabs and handle '\"' inhibitor.
Return the number of word(s) stored in "str". */
static int parser_entry(char ***tab, char const *str)
{
size_t tab_pos;
int counter;
int sz;
str--;
sz = 0;
counter = 0;
tab_pos = 0;
while (*(++str) != '\0' && *str != '\n' && sz >= 0) {
if (*str == '\"') {
sz = parser_get_inibitor(tab, &tab_pos, str, &counter);
if (sz > 0) {
str = &str[sz];
continue;
}
}
if (*str != ' ' && *str != '\t') {
sz = parser_get_word(tab, &tab_pos, str, &counter) - 1;
if (sz > 0)
str = &str[sz];
}
}
return (counter);
}
/* cli_parser_strtotab()
Generate word table and indicated the number of word find in the string. */
int cli_parser_strtotab(int *argc, char ***argv, char const *str)
{
if (argc == NULL || argv == NULL || str == NULL)
return (-1);
/* Get the number of word. */
*argv = NULL;
*argc = parser_entry(argv, str);
if (*argc <= 0)
return (-2);
*argv = (char **)calloc(1, sizeof(char *) * (*argc + 1));
if (*argv == NULL)
return (-3);
/* Dump all word. */
if (parser_entry(argv, str) != *argc) {
cli_parser_strtotab_quit(argc, argv);
return (-4);
}
(*argv)[*argc] = NULL;
return (0);
}
/* cli_parser_strtotab_quit()
Free all allocated memory generated by "strtotab()" */
void cli_parser_strtotab_quit(int *argc, char ***argv)
{
if (argc == NULL || argv == NULL)
return;
if (*argv == NULL) {
*argc = 0;
return;
}
while (--(*argc) >= 0) {
if ((*argv)[*argc] != NULL)
free((*argv)[*argc]);
}
free(*argv);
*argv = NULL;
*argc = 0;
}