Skip to content
Fetching contributors…
Cannot retrieve contributors at this time
281 lines (231 sloc) 5.29 KB
#ifdef UWSGI_YAML
#include "uwsgi.h"
extern struct uwsgi_server uwsgi;
#ifndef UWSGI_LIBYAML
/*
yaml file must be read ALL into memory.
This memory must not be freed for all the server lifecycle
*/
void yaml_rstrip(char *line) {
off_t i;
for(i = strlen(line)-1;i>=0; i--) {
if (line[i] == ' ' || line[i] == '\t') {
line[i] = 0;
continue;
}
break;
}
}
char *yaml_lstrip(char *line) {
off_t i;
char *ptr = line;
for(i=0;i< (int) strlen(line);i++) {
if (line[i] == ' ' || line[i] == '\t' || line[i] == '\r') {
ptr++;
continue;
}
break;
}
return ptr;
}
int yaml_get_depth(char *line) {
off_t i;
int depth = 0;
for(i=0;i< (int) strlen(line);i++) {
if (line[i] == ' ') {
depth++;
continue;
}
else if (line[i] == '\t' || line[i] == '\r') {
depth+=8;
continue;
}
break;
}
return depth;
}
char *yaml_get_line(char *yaml, off_t size) {
off_t i;
char *ptr = yaml;
int comment = 0;
for(i=0;i<size;i++) {
ptr++;
if (yaml[i] == '#') {
yaml[i] = 0;
comment = 1;
}
else if (yaml[i] == '\n') {
yaml[i] = 0;
return ptr;
}
else if (comment) {
yaml[i] = 0;
}
}
// check if it is a stupid file without \n at the end
if (ptr > yaml) {
return ptr;
}
return NULL;
}
#else
#include <yaml.h>
#endif
void uwsgi_yaml_config(char *file, char *magic_table[]) {
int len = 0;
char *yaml;
int in_uwsgi_section = 0;
char *key = NULL;
char *val = NULL;
char *section_asked = "uwsgi";
char *colon;
if (uwsgi_check_scheme(file)) {
colon = uwsgi_get_last_char(file, '/');
colon = uwsgi_get_last_char(colon, ':');
}
else {
colon = uwsgi_get_last_char(file, ':');
}
if (colon) {
colon[0] = 0;
if (colon[1] != 0) {
section_asked = colon+1;
}
}
uwsgi_log("[uWSGI] getting YAML configuration from %s\n", file);
yaml = uwsgi_open_and_read(file, &len, 1, magic_table);
#ifdef UWSGI_LIBYAML
yaml_parser_t parser;
yaml_token_t token;
int status = 0;
int parsing = 1;
if(!yaml_parser_initialize(&parser)) {
uwsgi_log("unable to initialize YAML parser (libyaml)\n");
exit(1);
}
yaml_parser_set_input_string(&parser, (const unsigned char *)yaml, (size_t) len-1);
while(parsing) {
if (!yaml_parser_scan(&parser, &token)) {
uwsgi_log("error parsing YAML file: %s (%c)\n", parser.problem, yaml[parser.problem_offset]);
exit(1);
}
switch(token.type) {
case YAML_STREAM_END_TOKEN:
parsing = 0;
break;
case YAML_KEY_TOKEN:
status = 1;
break;
case YAML_VALUE_TOKEN:
status = 2;
break;
case YAML_FLOW_SEQUENCE_START_TOKEN:
case YAML_BLOCK_SEQUENCE_START_TOKEN:
status = 3;
break;
case YAML_BLOCK_MAPPING_START_TOKEN:
if (!in_uwsgi_section) {
if (key) {
if (!strcmp(section_asked, key)) {
in_uwsgi_section = 1;
}
}
}
break;
case YAML_BLOCK_END_TOKEN:
if (in_uwsgi_section) {
parsing = 0;
break;
}
break;
case YAML_SCALAR_TOKEN:
case YAML_FLOW_ENTRY_TOKEN:
case YAML_BLOCK_ENTRY_TOKEN:
if (status == 1) {
key = (char *) token.data.scalar.value;
}
else if (status == 2) {
val = (char *) token.data.scalar.value;
if (key && val && in_uwsgi_section) {
add_exported_option(key, val, 0);
}
status = 0;
}
else if (status == 3) {
val = (char *) token.data.scalar.value;
if (key && val && in_uwsgi_section) {
add_exported_option(key, val, 0);
}
}
else {
uwsgi_log("unsupported YAML token in %s block\n", section_asked);
parsing = 0;
break;
}
break;
default:
status = 0;
}
}
#else
int depth;
int current_depth = 0;
int lines = 1;
char *yaml_line;
char *section = "";
while(len) {
yaml_line = yaml_get_line(yaml, len);
if (yaml_line == NULL) {
break;
}
lines++;
// skip empty line
if (yaml[0] == 0) goto next;
depth = yaml_get_depth(yaml);
if (depth <= current_depth) {
current_depth = depth;
// end the parsing cycle
if (in_uwsgi_section) return;
}
else if (depth > current_depth && !in_uwsgi_section) {
goto next;
}
key = yaml_lstrip(yaml);
// skip empty line
if (key[0] == 0) goto next;
// skip list and {} defined dict
if (key[0] == '-' || key[0] == '[' || key[0] == '{') {
if (in_uwsgi_section) return;
goto next;
}
if (!in_uwsgi_section) {
section = strchr(key,':');
if (!section) goto next;
section[0] = 0;
if (!strcmp(key, section_asked)) {
in_uwsgi_section = 1;
}
}
else {
// get dict value
val = strstr(key, ": ");
if (!val) {
val = strstr(key, ":\t");
}
if (!val) return;
// get the right key
val[0] = 0;
// yeah overengeneering....
yaml_rstrip(key);
val = yaml_lstrip(val+2);
yaml_rstrip(val);
//uwsgi_log("YAML: %s = %s\n", key, val);
add_exported_option((char *)key, val, 0);
}
next:
len -= (yaml_line - yaml);
yaml += (yaml_line - yaml);
}
#endif
}
#endif
Jump to Line
Something went wrong with that request. Please try again.