mirror of
https://github.com/vivier/EMILE.git
synced 2024-12-22 10:29:31 +00:00
First revision
This commit is contained in:
parent
49480d82b3
commit
a2cfb4a4a7
306
tools/emile_config.c
Normal file
306
tools/emile_config.c
Normal file
@ -0,0 +1,306 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* (c) 2007 Laurent Vivier <Laurent@lvivier.info>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#include "emile_config.h"
|
||||||
|
|
||||||
|
static int read_char(FILE* fd)
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
|
||||||
|
c = getc(fd);
|
||||||
|
|
||||||
|
if (c == '#')
|
||||||
|
while ( (c = getc(fd)) != '\n');
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void skip_blank(FILE* fd)
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
|
||||||
|
do {
|
||||||
|
c = read_char(fd);
|
||||||
|
} while ( (c == ' ') || (c == '\t') );
|
||||||
|
|
||||||
|
ungetc(c, fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void skip_blank_line(FILE* fd)
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
|
||||||
|
do {
|
||||||
|
skip_blank(fd);
|
||||||
|
c = read_char(fd);
|
||||||
|
} while (c == '\n');
|
||||||
|
|
||||||
|
ungetc(c, fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int read_word(FILE* fd, char* word)
|
||||||
|
{
|
||||||
|
int index = 0;
|
||||||
|
int c;
|
||||||
|
|
||||||
|
skip_blank(fd);
|
||||||
|
|
||||||
|
c = read_char(fd);
|
||||||
|
if (c == -1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
if (c == '\n')
|
||||||
|
{
|
||||||
|
word[index++] = c;
|
||||||
|
word[index] = 0;
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
while ( (c != ' ') && (c != '\t') && (c != '\n') && (c != -1) )
|
||||||
|
{
|
||||||
|
word[index++] = c;
|
||||||
|
c = read_char(fd);
|
||||||
|
}
|
||||||
|
ungetc(c, fd);
|
||||||
|
word[index] = 0;
|
||||||
|
return index;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int read_line(FILE* fd, char *name, char *value)
|
||||||
|
{
|
||||||
|
int c;
|
||||||
|
int index = 0;
|
||||||
|
|
||||||
|
skip_blank_line(fd);
|
||||||
|
|
||||||
|
if (read_word(fd, name) == -1)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
skip_blank(fd);
|
||||||
|
|
||||||
|
c = read_char(fd);
|
||||||
|
while ( (c != '\n') && (c != -1) )
|
||||||
|
{
|
||||||
|
value[index++] = c;
|
||||||
|
c = read_char(fd);
|
||||||
|
}
|
||||||
|
while ( (value[index-1] == ' ') || (value[index-1] == '\t') )
|
||||||
|
index--;
|
||||||
|
value[index] = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char* set_tag(char* string, int tag, char* value)
|
||||||
|
{
|
||||||
|
int len;
|
||||||
|
|
||||||
|
len = strlen(value);
|
||||||
|
*string++ = tag;
|
||||||
|
*string++ = len + 2;
|
||||||
|
strcpy(string, value);
|
||||||
|
string += len;
|
||||||
|
*string++ = 0;
|
||||||
|
|
||||||
|
*string = CONFIG_END; /* mark end of string */
|
||||||
|
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
|
||||||
|
static char* get_tag(char* string, int tag)
|
||||||
|
{
|
||||||
|
while (*string != tag)
|
||||||
|
{
|
||||||
|
if (*string == CONFIG_END)
|
||||||
|
return NULL;
|
||||||
|
string++;
|
||||||
|
string += *string;
|
||||||
|
}
|
||||||
|
|
||||||
|
return string + 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int read_header(FILE* fd, char* header, int size)
|
||||||
|
{
|
||||||
|
int offset = 0;
|
||||||
|
char name[256];
|
||||||
|
char value[1024];
|
||||||
|
int len;
|
||||||
|
|
||||||
|
rewind(fd);
|
||||||
|
|
||||||
|
while (read_line(fd, name, value) != -1)
|
||||||
|
{
|
||||||
|
if (strcmp("partition", name) == 0)
|
||||||
|
{
|
||||||
|
header = set_tag(header, CONFIG_PARTITION, value);
|
||||||
|
}
|
||||||
|
else if (strcmp("first_level", name) == 0)
|
||||||
|
{
|
||||||
|
header = set_tag(header, CONFIG_FIRST_LEVEL, value);
|
||||||
|
}
|
||||||
|
else if (strcmp("second_level", name) == 0)
|
||||||
|
{
|
||||||
|
header = set_tag(header, CONFIG_SECOND_LEVEL, value);
|
||||||
|
}
|
||||||
|
else if (strcmp("timeout", name) == 0)
|
||||||
|
{
|
||||||
|
header = set_tag(header, CONFIG_TIMEOUT, value);
|
||||||
|
}
|
||||||
|
else if (strcmp("default", name) == 0)
|
||||||
|
{
|
||||||
|
header = set_tag(header, CONFIG_DEFAULT, value);
|
||||||
|
}
|
||||||
|
else if (strcmp("title", name) == 0)
|
||||||
|
{
|
||||||
|
fseek(fd, offset, SEEK_SET);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf(stderr, "ERROR: syntax error on word %s\n", name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
offset = ftell(fd);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
emile_config* emile_config_open(char* name)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
FILE* fd;
|
||||||
|
emile_config* config;
|
||||||
|
|
||||||
|
fd = fopen(name, "r");
|
||||||
|
if (fd == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
config = (emile_config*)malloc(sizeof(emile_config));
|
||||||
|
if (config == NULL)
|
||||||
|
goto close_file;
|
||||||
|
|
||||||
|
memset(config, 0, sizeof(emile_config));
|
||||||
|
|
||||||
|
config->fd = fd;
|
||||||
|
config->header_size = 1024;
|
||||||
|
config->header = (char*)malloc(config->header_size);
|
||||||
|
if (config->header == NULL)
|
||||||
|
goto free_config;
|
||||||
|
config->current_size = 1024;
|
||||||
|
config->current = (char*)malloc(config->current_size);
|
||||||
|
if (config->current == NULL)
|
||||||
|
goto free_header;
|
||||||
|
|
||||||
|
ret = read_header(config->fd, config->header, config->header_size);
|
||||||
|
if (ret == -1)
|
||||||
|
goto free_current;
|
||||||
|
|
||||||
|
return config;
|
||||||
|
free_current:
|
||||||
|
free(config->current);
|
||||||
|
free_header:
|
||||||
|
free(config->header);
|
||||||
|
free_config:
|
||||||
|
free(config);
|
||||||
|
close_file:
|
||||||
|
fclose(fd);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void emile_config_close(emile_config* config)
|
||||||
|
{
|
||||||
|
free(config->current);
|
||||||
|
free(config->header);
|
||||||
|
fclose(config->fd);
|
||||||
|
free(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int read_description(FILE* fd, char* desc, int size)
|
||||||
|
{
|
||||||
|
int offset = 0;
|
||||||
|
char name[256];
|
||||||
|
char value[1024];
|
||||||
|
int len;
|
||||||
|
int found = 0;
|
||||||
|
|
||||||
|
while (read_line(fd, name, value) != -1)
|
||||||
|
{
|
||||||
|
if (strcmp("title", name) == 0)
|
||||||
|
{
|
||||||
|
if (found)
|
||||||
|
{
|
||||||
|
fseek(fd, offset, SEEK_SET);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
found = 1;
|
||||||
|
desc = set_tag(desc, CONFIG_TITLE, value);
|
||||||
|
}
|
||||||
|
else if (strcmp("kernel", name) == 0)
|
||||||
|
{
|
||||||
|
desc = set_tag(desc, CONFIG_KERNEL, value);
|
||||||
|
}
|
||||||
|
else if (strcmp("args", name) == 0)
|
||||||
|
{
|
||||||
|
desc = set_tag(desc, CONFIG_ARGS, value);
|
||||||
|
}
|
||||||
|
else if (strcmp("initrd", name) == 0)
|
||||||
|
{
|
||||||
|
desc = set_tag(desc, CONFIG_INITRD, value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
fprintf(stderr, "ERROR: syntax error on word %s\n", name);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
offset = ftell(fd);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int emile_config_read_next(emile_config* config)
|
||||||
|
{
|
||||||
|
return read_description(config->fd, config->current, config->current_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
int emile_config_read_first_entry(emile_config* config)
|
||||||
|
{
|
||||||
|
int offset = 0;
|
||||||
|
char name[256];
|
||||||
|
char value[1024];
|
||||||
|
|
||||||
|
rewind(config->fd);
|
||||||
|
while (read_line(config->fd, name, value) != -1)
|
||||||
|
{
|
||||||
|
if (strcmp("title", name) == 0)
|
||||||
|
{
|
||||||
|
fseek(config->fd, offset, SEEK_SET);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
offset = ftell(config->fd);
|
||||||
|
}
|
||||||
|
return read_description(config->fd, config->current, config->current_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
char* emile_config_get(emile_config* config, int tag)
|
||||||
|
{
|
||||||
|
switch(tag)
|
||||||
|
{
|
||||||
|
case CONFIG_PARTITION:
|
||||||
|
case CONFIG_FIRST_LEVEL:
|
||||||
|
case CONFIG_SECOND_LEVEL:
|
||||||
|
case CONFIG_TIMEOUT:
|
||||||
|
case CONFIG_DEFAULT:
|
||||||
|
return get_tag(config->header, tag);
|
||||||
|
case CONFIG_TITLE:
|
||||||
|
case CONFIG_KERNEL:
|
||||||
|
case CONFIG_ARGS:
|
||||||
|
case CONFIG_INITRD:
|
||||||
|
return get_tag(config->current, tag);
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
34
tools/emile_config.h
Normal file
34
tools/emile_config.h
Normal file
@ -0,0 +1,34 @@
|
|||||||
|
/*
|
||||||
|
*
|
||||||
|
* (c) 2007 Laurent Vivier <Laurent@lvivier.info>
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
typedef struct emile_config {
|
||||||
|
FILE* fd;
|
||||||
|
char* header;
|
||||||
|
int header_size;
|
||||||
|
char* current;
|
||||||
|
int current_size;
|
||||||
|
} emile_config;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
CONFIG_END,
|
||||||
|
CONFIG_PARTITION,
|
||||||
|
CONFIG_FIRST_LEVEL,
|
||||||
|
CONFIG_SECOND_LEVEL,
|
||||||
|
CONFIG_TIMEOUT,
|
||||||
|
CONFIG_DEFAULT,
|
||||||
|
CONFIG_TITLE,
|
||||||
|
CONFIG_KERNEL,
|
||||||
|
CONFIG_ARGS,
|
||||||
|
CONFIG_INITRD,
|
||||||
|
};
|
||||||
|
|
||||||
|
extern emile_config* emile_config_open(char* name);
|
||||||
|
extern void emile_config_close(emile_config* config);
|
||||||
|
|
||||||
|
extern int emile_config_read_first_entry(emile_config* config);
|
||||||
|
extern int emile_config_read_next(emile_config* config);
|
||||||
|
|
||||||
|
extern char* emile_config_get(emile_config* config, int tag);
|
Loading…
Reference in New Issue
Block a user