First revision

This commit is contained in:
Laurent Vivier 2007-05-05 22:05:43 +00:00
parent 49480d82b3
commit a2cfb4a4a7
2 changed files with 340 additions and 0 deletions

306
tools/emile_config.c Normal file
View 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
View 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);