Astrophysics/yaml.c
2023-08-04 10:39:16 +02:00

249 lines
5.3 KiB
C

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "constantes.h"
#include "yaml.h"
void parseYamlFileVariables(const struct yamlFile *yamlFile, char *entry, char dst[2][BUF_SIZE]){
int line, res;
char buf[2][BUF_SIZE];
char buf_var[2][BUF_SIZE];
char section[20];
/* Get entry and variable name */
res = explodeEntry(entry, buf, ':');
if (res != YAML_SUCCESS) {
printf("Failed to parse YAML's file\n");
exit(1);
}
/* Seek section in yaml */
res = addDoublePoint(buf[0], section);
line = getPositionSection(yamlFile, section);
if (line == -1){
printf("Failed to find section %s in YAML's file\n", buf[0]);
exit(1);
}
/* Get variables */
res = getVariables(yamlFile, buf[1], buf_var, line);
if (res == VARIABLE_YAML_NOT_FOUND){
printf("Variable %s not found in YAML's file\n", buf[1]);
exit(1);
}
strcpy(dst[0], buf_var[0]);
strcpy(dst[1], buf_var[1]);
}
void parseYamlFileChar(const struct yamlFile *yamlFile, char *entry, char *dst) {
char buf_var[2][BUF_SIZE];
/* Get variables */
parseYamlFileVariables(yamlFile, entry, buf_var);
strcpy(dst, buf_var[1]);
}
double parseYamlFileDouble(const struct yamlFile *yamlFile, char *entry) {
char buf[2][BUF_SIZE];
char buf_var[2][BUF_SIZE];
int res;
/* Get variables */
parseYamlFileVariables(yamlFile, entry, buf_var);
/* Get if pow */
res = explodeEntry(buf_var[1], buf, 'e');
if (res == YAML_SUCCESS){
double d1, d2;
d1 = atof(buf[0]);
d2 = atof(buf[1]);
return d1 * pow(10, d2);
}
return atof(buf_var[1]);
}
int parseYamlFileInt(const struct yamlFile *yamlFile, char *entry){
char buf[2][BUF_SIZE];
char buf_var[2][BUF_SIZE];
int res;
/* Get variables */
parseYamlFileVariables(yamlFile, entry, buf_var);
/* Get if pow */
res = explodeEntry(buf_var[1], buf, 'e');
if (res == YAML_SUCCESS){
double d1, d2;
d1 = atof(buf[0]);
d2 = atof(buf[1]);
return d1 * pow(10, d2);
}
return atoi(buf_var[1]);
}
/*
* This function read the YAML's file and stock all data in structure
*/
struct yamlFile *bufferingFiles(FILE *f, struct yamlFile *yamlFile){
char c;
char buf_tmp[BUF_SIZE];
int i=0, lines=0;
/* We count the number of lines */
fseek(f, 0, SEEK_SET);
do{
c = fgetc(f);
if(c == '\n')
lines++;
}while (c != EOF);
yamlFile->len = lines;
/* We allocate our buffer */
if((yamlFile->buf = malloc(lines * sizeof(char*))) == NULL){
printf("Failed to malloc\n");
fclose(f);
exit(1);
}
for(i = 0; i < lines; i++)
if((yamlFile->buf[i] = malloc(BUF_SIZE)) == NULL){
printf("Failed to malloc\n");
fclose(f);
exit(1);
}
fseek(f, 0, SEEK_SET);
lines = 0;
do{
c = fgetc(f);
buf_tmp[i++] = c;
if(c == '\n'){
buf_tmp[--i] = '\0';
memcpy(yamlFile->buf[lines++], buf_tmp, i);
memset(buf_tmp, 0, BUF_SIZE);
i = 0;
}
}while (c != EOF);
return yamlFile;
}
int addDoublePoint(char *src, char *dst){
int i = 0;
while (src[i] != '\0'){
dst[i] = src[i];
i++;
}
dst[i++] = ':';
dst[i++] = '\0';
return i;
}
int readYaml(FILE *f, char *section){
char buf[BUF_SIZE];
char c;
int i = 0;
int line = 0;
int seek = PARSE_YAML_FAILED;
/* Seek the section, example gravity: in file */
do {
c = fgetc(f);
buf[i++] = c;
if(c == '\n') {
buf[--i] = '\0'; /* Remove the '\n' */
seek = findEntry(buf, section);
if (seek == YAML_SUCCESS) break;
/* Get cursor position in file */
memset(buf, 0, BUF_SIZE);
i = 0;
}
line++;
}while(c != EOF);
if (seek == PARSE_YAML_FAILED) return seek;
return line;
}
int findEntry(char *buf, char *entry) {
int seek = PARSE_YAML_FAILED;
if (strcmp(buf, entry) == 0) {
seek = YAML_SUCCESS;
}
return seek;
}
int getVariables(const struct yamlFile *yamlFile, char *variable, char buf_var[2][BUF_SIZE], int posEntry) {
char buf[BUF_SIZE];
char buf2[2][BUF_SIZE];
memset(buf2[0], 0, BUF_SIZE);
memset(buf2[1], 0, BUF_SIZE);
char c;
int i = 0, j, pos=0, lines=0;
int res = PARSE_YAML_FAILED;
for(lines = posEntry; lines < yamlFile->len; lines++){
do {
c = yamlFile->buf[lines][pos++];
if (c != ' ')
buf[i++] = c;
} while(c != '\0');
/* Seek our variable */
if(strlen(buf) > 0){
res = explodeEntry(buf, buf_var, ':');
if(res == YAML_SUCCESS) {
char t[BUF_SIZE];
if (buf_var[0][0] == '-'){
int x = 0;
for(j = 1; j < strlen(buf_var[0]); j++)
t[x++] = buf_var[0][j];
}
else
strcpy(t, buf_var[0]);
if(strcmp(t, variable) == 0){
res = YAML_SUCCESS;
break;
}
else res = VARIABLE_YAML_NOT_FOUND;
memset(t, 0, BUF_SIZE);
}
}
memset(buf, 0, BUF_SIZE);
i = 0;
pos = 0;
}
return res;
}
int explodeEntry(char *entry, char var[2][BUF_SIZE], char delimiter) {
char c;
int i = 0, j = 0, pos = 0;
/* Get position of delimiter */
do {
c = entry[i];
if (c == delimiter) pos = i;
i++;
}while(c != '\0');
if (pos == 0)
return YAML_DELIMITER_NOT_FOUND;
for(i = 0; i < pos; i++) {
var[0][i] = entry[i];
}
var[0][i++] = '\0';
for(i = pos + 1, j=0; i < strlen(entry); i++, j++) {
var[1][j] = entry[i];
}
var[1][j++] = '\0';
return YAML_SUCCESS;
}
/*
* This function get the position (int) for the section
*/
int getPositionSection(const struct yamlFile *yamlFile, char *section){
int i = 0, pos = -1;
for(i = 0; i < yamlFile->len; i++){
if(strcmp(yamlFile->buf[i], section) == 0)
pos = i;
}
return pos;
}