|
Packit Service |
569379 |
#include <stdio.h>
|
|
Packit Service |
569379 |
#include <unistd.h>
|
|
Packit Service |
569379 |
#include <errno.h>
|
|
Packit Service |
569379 |
#include <stdlib.h>
|
|
Packit Service |
569379 |
#include <string.h>
|
|
Packit Service |
569379 |
|
|
Packit Service |
569379 |
#include <yaml.h>
|
|
Packit Service |
569379 |
|
|
Packit Service |
569379 |
#include "yaml-path.h"
|
|
Packit Service |
569379 |
|
|
Packit Service |
569379 |
|
|
Packit Service |
569379 |
int parse_and_emit (yaml_parser_t *parser, yaml_emitter_t *emitter, yaml_path_t *path, yaml_path_filter_mode_t mode, int use_flow_style)
|
|
Packit Service |
569379 |
{
|
|
Packit Service |
569379 |
yaml_event_t event;
|
|
Packit Service |
569379 |
yaml_event_type_t prev_event_type, event_type;
|
|
Packit Service |
569379 |
|
|
Packit Service |
569379 |
do {
|
|
Packit Service |
569379 |
|
|
Packit Service |
569379 |
if (!yaml_parser_parse(parser, &event)) {
|
|
Packit Service |
569379 |
switch (parser->error) {
|
|
Packit Service |
569379 |
case YAML_MEMORY_ERROR:
|
|
Packit Service |
569379 |
fprintf(stderr, "Memory error: Not enough memory for parsing\n");
|
|
Packit Service |
569379 |
break;
|
|
Packit Service |
569379 |
case YAML_READER_ERROR:
|
|
Packit Service |
569379 |
if (parser->problem_value != -1) {
|
|
Packit Service |
569379 |
fprintf(stderr, "Reader error: %s: #%X at %ld\n", parser->problem, parser->problem_value, (long)parser->problem_offset);
|
|
Packit Service |
569379 |
} else {
|
|
Packit Service |
569379 |
fprintf(stderr, "Reader error: %s at %ld\n", parser->problem, (long)parser->problem_offset);
|
|
Packit Service |
569379 |
}
|
|
Packit Service |
569379 |
break;
|
|
Packit Service |
569379 |
case YAML_SCANNER_ERROR:
|
|
Packit Service |
569379 |
if (parser->context) {
|
|
Packit Service |
569379 |
fprintf(stderr, "Scanner error: %s at line %d, column %d\n%s at line %d, column %d\n", parser->context,
|
|
Packit Service |
569379 |
(int)parser->context_mark.line+1,(int)parser->context_mark.column+1, parser->problem,
|
|
Packit Service |
569379 |
(int)parser->problem_mark.line+1, (int)parser->problem_mark.column+1);
|
|
Packit Service |
569379 |
} else {
|
|
Packit Service |
569379 |
fprintf(stderr, "Scanner error: %s at line %d, column %d\n", parser->problem, (int)parser->problem_mark.line+1, (int)parser->problem_mark.column+1);
|
|
Packit Service |
569379 |
}
|
|
Packit Service |
569379 |
break;
|
|
Packit Service |
569379 |
case YAML_PARSER_ERROR:
|
|
Packit Service |
569379 |
if (parser->context) {
|
|
Packit Service |
569379 |
fprintf(stderr, "Parser error: %s at line %d, column %d\n%s at line %d, column %d\n", parser->context,
|
|
Packit Service |
569379 |
(int)parser->context_mark.line+1, (int)parser->context_mark.column+1, parser->problem,
|
|
Packit Service |
569379 |
(int)parser->problem_mark.line+1, (int)parser->problem_mark.column+1);
|
|
Packit Service |
569379 |
} else {
|
|
Packit Service |
569379 |
fprintf(stderr, "Parser error: %s at line %d, column %d\n", parser->problem, (int)parser->problem_mark.line+1, (int)parser->problem_mark.column+1);
|
|
Packit Service |
569379 |
}
|
|
Packit Service |
569379 |
break;
|
|
Packit Service |
569379 |
default:
|
|
Packit Service |
569379 |
fprintf(stderr, "Internal error\n");
|
|
Packit Service |
569379 |
break;
|
|
Packit Service |
569379 |
}
|
|
Packit Service |
569379 |
return 1;
|
|
Packit Service |
569379 |
} else {
|
|
Packit Service |
569379 |
event_type = event.type;
|
|
Packit Service |
569379 |
if (!yaml_path_filter_event(path, parser, &event, mode)) {
|
|
Packit Service |
569379 |
yaml_event_delete(&event);
|
|
Packit Service |
569379 |
} else {
|
|
Packit Service |
569379 |
if (use_flow_style) {
|
|
Packit Service |
569379 |
switch (event.type) {
|
|
Packit Service |
569379 |
case YAML_SEQUENCE_START_EVENT:
|
|
Packit Service |
569379 |
event.data.sequence_start.style = YAML_FLOW_SEQUENCE_STYLE;
|
|
Packit Service |
569379 |
break;
|
|
Packit Service |
569379 |
case YAML_MAPPING_START_EVENT:
|
|
Packit Service |
569379 |
event.data.mapping_start.style = YAML_FLOW_MAPPING_STYLE;
|
|
Packit Service |
569379 |
break;
|
|
Packit Service |
569379 |
default:
|
|
Packit Service |
569379 |
break;
|
|
Packit Service |
569379 |
}
|
|
Packit Service |
569379 |
}
|
|
Packit Service |
569379 |
if (prev_event_type == YAML_DOCUMENT_START_EVENT && event_type == YAML_DOCUMENT_END_EVENT) {
|
|
Packit Service |
569379 |
yaml_event_t null_event= {0};
|
|
Packit Service |
569379 |
yaml_scalar_event_initialize(&null_event, NULL, (yaml_char_t *)"!!null", (yaml_char_t *)"null", 4, 1, 0, YAML_ANY_SCALAR_STYLE);
|
|
Packit Service |
569379 |
yaml_emitter_emit(emitter, &null_event);
|
|
Packit Service |
569379 |
}
|
|
Packit Service |
569379 |
prev_event_type = event_type;
|
|
Packit Service |
569379 |
if (!yaml_emitter_emit(emitter, &event)) {
|
|
Packit Service |
569379 |
switch (emitter->error)
|
|
Packit Service |
569379 |
{
|
|
Packit Service |
569379 |
case YAML_MEMORY_ERROR:
|
|
Packit Service |
569379 |
fprintf(stderr, "Memory error: Not enough memory for emitting\n");
|
|
Packit Service |
569379 |
break;
|
|
Packit Service |
569379 |
case YAML_WRITER_ERROR:
|
|
Packit Service |
569379 |
fprintf(stderr, "Writer error: %s\n", emitter->problem);
|
|
Packit Service |
569379 |
break;
|
|
Packit Service |
569379 |
case YAML_EMITTER_ERROR:
|
|
Packit Service |
569379 |
fprintf(stderr, "Emitter error: %s\n", emitter->problem);
|
|
Packit Service |
569379 |
break;
|
|
Packit Service |
569379 |
default:
|
|
Packit Service |
569379 |
fprintf(stderr, "Internal error\n");
|
|
Packit Service |
569379 |
break;
|
|
Packit Service |
569379 |
}
|
|
Packit Service |
569379 |
return 2;
|
|
Packit Service |
569379 |
}
|
|
Packit Service |
569379 |
}
|
|
Packit Service |
569379 |
}
|
|
Packit Service |
569379 |
} while (event_type != YAML_STREAM_END_EVENT);
|
|
Packit Service |
569379 |
|
|
Packit Service |
569379 |
return 0;
|
|
Packit Service |
569379 |
}
|
|
Packit Service |
569379 |
|
|
Packit Service |
569379 |
|
|
Packit Service |
569379 |
void help (void)
|
|
Packit Service |
569379 |
{
|
|
Packit Service |
569379 |
printf("yamlp - filtering utility for YAML documents\n");
|
|
Packit Service |
569379 |
printf("\n");
|
|
Packit Service |
569379 |
printf("Usage: yamlp [-F] [-S] [-W <width>] [-f <file>] <path>\n");
|
|
Packit Service |
569379 |
printf(" yamlp -h\n");
|
|
Packit Service |
569379 |
printf("\n");
|
|
Packit Service |
569379 |
printf("The tool will take the input YAML document from <stdin> or a <file> (-f option),\n");
|
|
Packit Service |
569379 |
printf("and it will then return the portion of the document marked with the given <path>.\n");
|
|
Packit Service |
569379 |
printf("\n");
|
|
Packit Service |
569379 |
printf("Options:\n");
|
|
Packit Service |
569379 |
printf(" -f a filename to get the YAML document from,\n");
|
|
Packit Service |
569379 |
printf(" <stdin> will be used if omitted;\n");
|
|
Packit Service |
569379 |
printf("\n");
|
|
Packit Service |
569379 |
printf(" -F forced 'flow' style for the output YAML document;\n");
|
|
Packit Service |
569379 |
printf("\n");
|
|
Packit Service |
569379 |
printf(" -h help;\n");
|
|
Packit Service |
569379 |
printf("\n");
|
|
Packit Service |
569379 |
printf(" -S 'shallow' filter mode;\n");
|
|
Packit Service |
569379 |
printf("\n");
|
|
Packit Service |
569379 |
printf(" -W line wrap width, no wrapping if omitted.\n");
|
|
Packit Service |
569379 |
printf("\n");
|
|
Packit Service |
569379 |
}
|
|
Packit Service |
569379 |
|
|
Packit Service |
569379 |
int main(int argc, char *argv[])
|
|
Packit Service |
569379 |
{
|
|
Packit Service |
569379 |
int flow = 0;
|
|
Packit Service |
569379 |
char *file_name = NULL;
|
|
Packit Service |
569379 |
char *path_string = NULL;
|
|
Packit Service |
569379 |
int wrap = -1;
|
|
Packit Service |
569379 |
yaml_path_filter_mode_t mode = YAML_PATH_FILTER_RETURN_ALL;
|
|
Packit Service |
569379 |
|
|
Packit Service |
569379 |
int opt;
|
|
Packit Service |
569379 |
while ((opt = getopt(argc, argv, ":f:W:vhSF")) != -1) {
|
|
Packit Service |
569379 |
switch (opt) {
|
|
Packit Service |
569379 |
case 'h':
|
|
Packit Service |
569379 |
help();
|
|
Packit Service |
569379 |
return 0;
|
|
Packit Service |
569379 |
break;
|
|
Packit Service |
569379 |
case 'F':
|
|
Packit Service |
569379 |
flow = 1;
|
|
Packit Service |
569379 |
break;
|
|
Packit Service |
569379 |
case 'S':
|
|
Packit Service |
569379 |
mode = YAML_PATH_FILTER_RETURN_SHALLOW;
|
|
Packit Service |
569379 |
break;
|
|
Packit Service |
569379 |
case 'W':
|
|
Packit Service |
569379 |
wrap = strtol(optarg, NULL, 10);
|
|
Packit Service |
569379 |
if (!wrap) {
|
|
Packit Service |
569379 |
fprintf(stderr, "Invalid value for wrap width '%s'\n", optarg);
|
|
Packit Service |
569379 |
return 1;
|
|
Packit Service |
569379 |
}
|
|
Packit Service |
569379 |
break;
|
|
Packit Service |
569379 |
case 'f':
|
|
Packit Service |
569379 |
file_name = optarg;
|
|
Packit Service |
569379 |
break;
|
|
Packit Service |
569379 |
case ':':
|
|
Packit Service |
569379 |
fprintf(stderr, "Option needs a value\n");
|
|
Packit Service |
569379 |
return 1;
|
|
Packit Service |
569379 |
break;
|
|
Packit Service |
569379 |
case '?':
|
|
Packit Service |
569379 |
fprintf(stderr, "Unknown option '%c'\n", optopt);
|
|
Packit Service |
569379 |
return 1;
|
|
Packit Service |
569379 |
break;
|
|
Packit Service |
569379 |
}
|
|
Packit Service |
569379 |
}
|
|
Packit Service |
569379 |
|
|
Packit Service |
569379 |
for (; optind < argc; optind++) {
|
|
Packit Service |
569379 |
path_string = argv[optind];
|
|
Packit Service |
569379 |
}
|
|
Packit Service |
569379 |
|
|
Packit Service |
569379 |
FILE *file = NULL;
|
|
Packit Service |
569379 |
if (file_name != NULL) {
|
|
Packit Service |
569379 |
file = fopen(file_name, "r");
|
|
Packit Service |
569379 |
if (file == NULL) {
|
|
Packit Service |
569379 |
fprintf(stderr, "Unable to open file '%s' (%s)\n", file_name, strerror(errno));
|
|
Packit Service |
569379 |
return 2;
|
|
Packit Service |
569379 |
}
|
|
Packit Service |
569379 |
}
|
|
Packit Service |
569379 |
|
|
Packit Service |
569379 |
if (path_string == NULL || path_string[0] == 0) {
|
|
Packit Service |
569379 |
fprintf(stderr, "Empty path\n");
|
|
Packit Service |
569379 |
return 3;
|
|
Packit Service |
569379 |
}
|
|
Packit Service |
569379 |
|
|
Packit Service |
569379 |
yaml_path_t *path = yaml_path_create();
|
|
Packit Service |
569379 |
if (yaml_path_parse(path, path_string)) {
|
|
Packit Service |
569379 |
fprintf(stderr, "Invalid path '%s' (%s)\n", path_string, yaml_path_error_get(path)->message);
|
|
Packit Service |
569379 |
return 3;
|
|
Packit Service |
569379 |
};
|
|
Packit Service |
569379 |
|
|
Packit Service |
569379 |
yaml_parser_t parser;
|
|
Packit Service |
569379 |
yaml_emitter_t emitter;
|
|
Packit Service |
569379 |
|
|
Packit Service |
569379 |
yaml_parser_initialize(&parser);
|
|
Packit Service |
569379 |
yaml_parser_set_input_file(&parser, file != NULL ? file : stdin);
|
|
Packit Service |
569379 |
|
|
Packit Service |
569379 |
yaml_emitter_initialize(&emitter);
|
|
Packit Service |
569379 |
yaml_emitter_set_output_file(&emitter, stdout);
|
|
Packit Service |
569379 |
yaml_emitter_set_width(&emitter, wrap);
|
|
Packit Service |
569379 |
|
|
Packit Service |
569379 |
if (parse_and_emit(&parser, &emitter, path, mode, flow)) {
|
|
Packit Service |
569379 |
return 4;
|
|
Packit Service |
569379 |
}
|
|
Packit Service |
569379 |
|
|
Packit Service |
569379 |
yaml_parser_delete(&parser);
|
|
Packit Service |
569379 |
yaml_emitter_delete(&emitter);
|
|
Packit Service |
569379 |
|
|
Packit Service |
569379 |
yaml_path_destroy(path);
|
|
Packit Service |
569379 |
fclose(file);
|
|
Packit Service |
569379 |
|
|
Packit Service |
569379 |
return 0;
|
|
Packit Service |
569379 |
}
|