Пример #1
0
int check_utf8_sequences (void) {
  yaml_parser_t parser;
  int failed = 0;
  int k;
  printf ("checking utf-8 sequences...\n");

  for (k = 0; utf8_sequences[k].test; k++) {
    char* title = utf8_sequences[k].title;
    int check = utf8_sequences[k].result;
    int result;
    char* start = utf8_sequences[k].test;
    char* end = start;
    printf ("\t%s:\n", title);

    while (1) {
      while (*end != '|' && *end != '!') {
        end++;
        }

      yaml_parser_initialize (&parser);
      yaml_parser_set_input_string (&parser, (unsigned char*) start, end - start);
      result = yaml_parser_update_buffer (&parser, end - start);

      if (result != check) {
        printf ("\t\t- ");
        failed ++;
        }

      else {
        printf ("\t\t+ ");
        }

      if (!parser.error) {
        printf ("(no error)\n");
        }

      else if (parser.error == YAML_READER_ERROR) {
        if (parser.problem_value != -1) {
          printf ("(reader error: %s: #%X at %d)\n",
                  parser.problem, parser.problem_value, parser.problem_offset);
          }

        else {
          printf ("(reader error: %s at %d)\n",
                  parser.problem, parser.problem_offset);
          }
        }

      if (*end == '!') {
        break;
        }

      start = ++end;
      yaml_parser_delete (&parser);
      };

    printf ("\n");
    }

  printf ("checking utf-8 sequences: %d fail(s)\n", failed);
  return failed;
  }
Пример #2
0
int
main(int argc, char *argv[])
{
    int number;
    int canonical = 0;
    int unicode = 0;

    number = 1;
    while (number < argc) {
        if (strcmp(argv[number], "-c") == 0) {
            canonical = 1;
        }
        else if (strcmp(argv[number], "-u") == 0) {
            unicode = 1;
        }
        else if (argv[number][0] == '-') {
            printf("Unknown option: '%s'\n", argv[number]);
            return 0;
        }
        if (argv[number][0] == '-') {
            if (number < argc-1) {
                memmove(argv+number, argv+number+1, (argc-number-1)*sizeof(char *));
            }
            argc --;
        }
        else {
            number ++;
        }
    }

    if (argc < 2) {
        printf("Usage: %s [-c] [-u] file1.yaml ...\n", argv[0]);
        return 0;
    }

    for (number = 1; number < argc; number ++)
    {
        FILE *file;
        yaml_parser_t parser;
        yaml_emitter_t emitter;

        yaml_document_t document;
        unsigned char buffer[BUFFER_SIZE+1];
        size_t written = 0;
        yaml_document_t documents[MAX_DOCUMENTS];
        size_t document_number = 0;
        int done = 0;
        int count = 0;
        int error = 0;
        int k;
        memset(buffer, 0, BUFFER_SIZE+1);
        memset(documents, 0, MAX_DOCUMENTS*sizeof(yaml_document_t));

        printf("[%d] Loading, dumping, and loading again '%s': ", number, argv[number]);
        fflush(stdout);

        file = fopen(argv[number], "rb");
        assert(file);

        assert(yaml_parser_initialize(&parser));
        yaml_parser_set_input_file(&parser, file);
        assert(yaml_emitter_initialize(&emitter));
        if (canonical) {
            yaml_emitter_set_canonical(&emitter, 1);
        }
        if (unicode) {
            yaml_emitter_set_unicode(&emitter, 1);
        }
        yaml_emitter_set_output_string(&emitter, buffer, BUFFER_SIZE, &written);
        yaml_emitter_open(&emitter);

        while (!done)
        {
            if (!yaml_parser_load(&parser, &document)) {
                error = 1;
                break;
            }

            done = (!yaml_document_get_root_node(&document));
            if (!done) {
                assert(document_number < MAX_DOCUMENTS);
                assert(copy_document(&(documents[document_number++]), &document));
                assert(yaml_emitter_dump(&emitter, &document) || 
                        (yaml_emitter_flush(&emitter) && print_output(argv[number], buffer, written, count)));
                count ++;
            }
            else {
                yaml_document_delete(&document);
            }
        }

        yaml_parser_delete(&parser);
        assert(!fclose(file));
        yaml_emitter_close(&emitter);
        yaml_emitter_delete(&emitter);

        if (!error)
        {
            count = done = 0;
            assert(yaml_parser_initialize(&parser));
            yaml_parser_set_input_string(&parser, buffer, written);

            while (!done)
            {
                assert(yaml_parser_load(&parser, &document) || print_output(argv[number], buffer, written, count));
                done = (!yaml_document_get_root_node(&document));
                if (!done) {
                    assert(compare_documents(documents+count, &document) || print_output(argv[number], buffer, written, count));
                    count ++;
                }
                yaml_document_delete(&document);
            }
            yaml_parser_delete(&parser);
        }

        for (k = 0; k < document_number; k ++) {
            yaml_document_delete(documents+k);
        }

        printf("PASSED (length: %zd)\n", written);
        print_output(argv[number], buffer, written, -1);
    }

    return 0;
}
Пример #3
0
/*
 * call-seq:
 *    parser.parse(yaml)
 *
 * Parse the YAML document contained in +yaml+.  Events will be called on
 * the handler set on the parser instance.
 *
 * See Psych::Parser and Psych::Parser#handler
 */
static VALUE parse(VALUE self, VALUE yaml)
{
    yaml_parser_t * parser;
    yaml_event_t event;
    int done = 0;
#ifdef HAVE_RUBY_ENCODING_H
    int encoding = rb_utf8_encindex();
    rb_encoding * internal_enc = rb_default_internal_encoding();
#endif
    VALUE handler = rb_iv_get(self, "@handler");

    Data_Get_Struct(self, yaml_parser_t, parser);

    if(rb_respond_to(yaml, id_read)) {
	yaml_parser_set_input(parser, io_reader, (void *)yaml);
    } else {
	StringValue(yaml);
	yaml_parser_set_input_string(
		parser,
		(const unsigned char *)RSTRING_PTR(yaml),
		(size_t)RSTRING_LEN(yaml)
		);
    }

    while(!done) {
	if(!yaml_parser_parse(parser, &event)) {
	    size_t line   = parser->mark.line;
	    size_t column = parser->mark.column;

	    rb_raise(ePsychSyntaxError, "couldn't parse YAML at line %d column %d",
		    (int)line, (int)column);
	}

	switch(event.type) {
	  case YAML_STREAM_START_EVENT:

	    rb_funcall(handler, id_start_stream, 1,
		       INT2NUM((long)event.data.stream_start.encoding)
		);
	    break;
	  case YAML_DOCUMENT_START_EVENT:
	    {
		/* Get a list of tag directives (if any) */
		VALUE tag_directives = rb_ary_new();
		/* Grab the document version */
		VALUE version = event.data.document_start.version_directive ?
		    rb_ary_new3(
			(long)2,
			INT2NUM((long)event.data.document_start.version_directive->major),
			INT2NUM((long)event.data.document_start.version_directive->minor)
			) : rb_ary_new();

		if(event.data.document_start.tag_directives.start) {
		    yaml_tag_directive_t *start =
			event.data.document_start.tag_directives.start;
		    yaml_tag_directive_t *end =
			event.data.document_start.tag_directives.end;
		    for(; start != end; start++) {
			VALUE handle = Qnil;
			VALUE prefix = Qnil;
			if(start->handle) {
			    handle = rb_str_new2((const char *)start->handle);
#ifdef HAVE_RUBY_ENCODING_H
			    PSYCH_TRANSCODE(handle, encoding, internal_enc);
#endif
			}

			if(start->prefix) {
			    prefix = rb_str_new2((const char *)start->prefix);
#ifdef HAVE_RUBY_ENCODING_H
			    PSYCH_TRANSCODE(prefix, encoding, internal_enc);
#endif
			}

			rb_ary_push(tag_directives, rb_ary_new3((long)2, handle, prefix));
		    }
		}
		rb_funcall(handler, id_start_document, 3,
			   version, tag_directives,
			   event.data.document_start.implicit == 1 ? Qtrue : Qfalse
		    );
	    }
	    break;
	  case YAML_DOCUMENT_END_EVENT:
	    rb_funcall(handler, id_end_document, 1,
		       event.data.document_end.implicit == 1 ? Qtrue : Qfalse
		);
	    break;
	  case YAML_ALIAS_EVENT:
	    {
		VALUE alias = Qnil;
		if(event.data.alias.anchor) {
		    alias = rb_str_new2((const char *)event.data.alias.anchor);
#ifdef HAVE_RUBY_ENCODING_H
		    PSYCH_TRANSCODE(alias, encoding, internal_enc);
#endif
		}

		rb_funcall(handler, id_alias, 1, alias);
	    }
	    break;
	  case YAML_SCALAR_EVENT:
	    {
		VALUE anchor = Qnil;
		VALUE tag = Qnil;
		VALUE plain_implicit, quoted_implicit, style;
		VALUE val = rb_str_new(
		    (const char *)event.data.scalar.value,
		    (long)event.data.scalar.length
		    );

#ifdef HAVE_RUBY_ENCODING_H
		PSYCH_TRANSCODE(val, encoding, internal_enc);
#endif

		if(event.data.scalar.anchor) {
		    anchor = rb_str_new2((const char *)event.data.scalar.anchor);
#ifdef HAVE_RUBY_ENCODING_H
		    PSYCH_TRANSCODE(anchor, encoding, internal_enc);
#endif
		}

		if(event.data.scalar.tag) {
		    tag = rb_str_new2((const char *)event.data.scalar.tag);
#ifdef HAVE_RUBY_ENCODING_H
		    PSYCH_TRANSCODE(tag, encoding, internal_enc);
#endif
		}

		plain_implicit =
		    event.data.scalar.plain_implicit == 0 ? Qfalse : Qtrue;

		quoted_implicit =
		    event.data.scalar.quoted_implicit == 0 ? Qfalse : Qtrue;

		style = INT2NUM((long)event.data.scalar.style);

		rb_funcall(handler, id_scalar, 6,
			   val, anchor, tag, plain_implicit, quoted_implicit, style);
	    }
	    break;
	  case YAML_SEQUENCE_START_EVENT:
	    {
		VALUE anchor = Qnil;
		VALUE tag = Qnil;
		VALUE implicit, style;
		if(event.data.sequence_start.anchor) {
		    anchor = rb_str_new2((const char *)event.data.sequence_start.anchor);
#ifdef HAVE_RUBY_ENCODING_H
		    PSYCH_TRANSCODE(anchor, encoding, internal_enc);
#endif
		}

		tag = Qnil;
		if(event.data.sequence_start.tag) {
		    tag = rb_str_new2((const char *)event.data.sequence_start.tag);
#ifdef HAVE_RUBY_ENCODING_H
		    PSYCH_TRANSCODE(tag, encoding, internal_enc);
#endif
		}

		implicit =
		    event.data.sequence_start.implicit == 0 ? Qfalse : Qtrue;

		style = INT2NUM((long)event.data.sequence_start.style);

		rb_funcall(handler, id_start_sequence, 4,
			   anchor, tag, implicit, style);
	    }
	    break;
	  case YAML_SEQUENCE_END_EVENT:
	    rb_funcall(handler, id_end_sequence, 0);
	    break;
	  case YAML_MAPPING_START_EVENT:
	    {
		VALUE anchor = Qnil;
		VALUE tag = Qnil;
		VALUE implicit, style;
		if(event.data.mapping_start.anchor) {
		    anchor = rb_str_new2((const char *)event.data.mapping_start.anchor);
#ifdef HAVE_RUBY_ENCODING_H
		    PSYCH_TRANSCODE(anchor, encoding, internal_enc);
#endif
		}

		if(event.data.mapping_start.tag) {
		    tag = rb_str_new2((const char *)event.data.mapping_start.tag);
#ifdef HAVE_RUBY_ENCODING_H
		    PSYCH_TRANSCODE(tag, encoding, internal_enc);
#endif
		}

		implicit =
		    event.data.mapping_start.implicit == 0 ? Qfalse : Qtrue;

		style = INT2NUM((long)event.data.mapping_start.style);

		rb_funcall(handler, id_start_mapping, 4,
			   anchor, tag, implicit, style);
	    }
	    break;
	  case YAML_MAPPING_END_EVENT:
	    rb_funcall(handler, id_end_mapping, 0);
	    break;
	  case YAML_NO_EVENT:
	    rb_funcall(handler, id_empty, 0);
	    break;
	  case YAML_STREAM_END_EVENT:
	    rb_funcall(handler, id_end_stream, 0);
	    done = 1;
	    break;
	}
    }

    return self;
}
Пример #4
0
void uwsgi_yaml_config(char *file, char *magic_table[]) {

	size_t 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_initial("[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, (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


}