int main(int argc, char** argv) { if (argc < 2) { return print_usage(argv[0], true); } FILE* in_fd = NULL; SerdSyntax input_syntax = SERD_TURTLE; SerdSyntax output_syntax = SERD_NTRIPLES; bool from_file = true; const uint8_t* in_name = NULL; int a = 1; for (; a < argc && argv[a][0] == '-'; ++a) { if (argv[a][1] == '\0') { in_name = (const uint8_t*)"(stdin)"; in_fd = stdin; break; } else if (argv[a][1] == 'h') { return print_usage(argv[0], false); } else if (argv[a][1] == 'v') { return print_version(); } else if (argv[a][1] == 's') { in_name = (const uint8_t*)"(string)"; from_file = false; ++a; break; } else if (argv[a][1] == 'i') { if (++a == argc) { fprintf(stderr, "Missing value for -i\n"); return 1; } if (!set_syntax(&input_syntax, argv[a])) { return 1; } } else if (argv[a][1] == 'o') { if (++a == argc) { fprintf(stderr, "Missing value for -o\n"); return 1; } if (!set_syntax(&output_syntax, argv[a])) { return 1; } } else { fprintf(stderr, "Unknown option `%s'\n", argv[a]); return print_usage(argv[0], true); } } if (a == argc) { fprintf(stderr, "Missing input\n"); return 1; } const uint8_t* input = (const uint8_t*)argv[a++]; uint8_t* in_path = NULL; if (from_file) { in_name = in_name ? in_name : input; if (!in_fd) { in_path = absolute_path(serd_uri_to_path(in_name)); if (!in_path || !(in_fd = fopen((const char*)in_path, "rb"))) { return 1; } } } SerdURI base_uri = SERD_URI_NULL; SerdNode base_uri_node = SERD_NODE_NULL; if (a < argc) { // Base URI given on command line base_uri_node = serd_node_new_uri_from_string( (const uint8_t*)argv[a], NULL, &base_uri); } else if (from_file) { // Use input file URI base_uri_node = serd_node_new_file_uri(in_path, NULL, &base_uri, false); } if (!base_uri_node.buf) { fprintf(stderr, "Missing base URI\n"); return 1; } SordWorld* world = sord_world_new(); SordModel* sord = sord_new(world, SORD_SPO|SORD_OPS, false); SerdEnv* env = serd_env_new(&base_uri_node); SerdReader* reader = sord_new_reader(sord, env, input_syntax, NULL); const SerdStatus status = (from_file) ? serd_reader_read_file_handle(reader, in_fd, in_name) : serd_reader_read_string(reader, input); serd_reader_free(reader); fprintf(stderr, "Loaded %lu statements\n", (unsigned long)sord_num_quads(sord)); SerdEnv* write_env = serd_env_new(&base_uri_node); int output_style = SERD_STYLE_RESOLVED; if (output_syntax == SERD_NTRIPLES) { output_style |= SERD_STYLE_ASCII; } else { output_style |= SERD_STYLE_CURIED | SERD_STYLE_ABBREVIATED; } SerdWriter* writer = serd_writer_new( output_syntax, (SerdStyle)output_style, write_env, &base_uri, serd_file_sink, stdout); // Write @prefix directives serd_env_foreach(env, (SerdPrefixSink)serd_writer_set_prefix, writer); // Write statements sord_write(sord, writer, NULL); serd_writer_finish(writer); serd_writer_free(writer); serd_env_free(env); serd_env_free(write_env); serd_node_free(&base_uri_node); sord_free(sord); sord_world_free(world); return (status > SERD_FAILURE) ? 1 : 0; }
static error_t parse_arg( int key, char * arg, struct argp_state *state ) { struct opdis_options * opts = state->input; switch ( key ) { case 'c': if (! add_job( opts->jobs, job_cflow, arg ) ) { argp_error( state, "Invalid argument for -c" ); } break; case 'l': if (! add_job( opts->jobs, job_linear, arg ) ) { argp_error( state, "Invalid argument for -l" ); } break; case 'a': if (! set_arch( opts, arg ) ) { argp_error( state, "Invalid argument for -s" ); } break; case 's': if (! set_syntax( opts, arg ) ) { argp_error( state, "Invalid argument for -s" ); } break; case 'f': if (! set_format( opts, arg ) ) { argp_error( state, "Invalid argument for -f" ); } break; case 'o': if (! set_output_file( opts, arg ) ) { argp_error( state, "Invalid argument for -o" ); } break; case 'b': if (! tgt_list_add( opts->targets, tgt_bytes, arg ) ) { argp_error( state, "Invalid argument for -b" ); } break; case 'm': if (! add_map( opts->map, arg ) ) { argp_error( state, "Invalid argument for -m" ); } break; case 'O': opts->disasm_opts = arg; break; case 'B': if (! set_bfd_target( opts, arg ) ) { argp_error( state, "Invalid argument for -B" ); } break; case 'E': add_bfd_job( opts, job_bfd_entry, NULL ); break; case 'N': if (! add_bfd_job( opts, job_bfd_symbol, arg ) ) { argp_error( state, "Invalid argument for -N" ); } break; case 'S': if (! add_bfd_job( opts, job_bfd_section, arg ) ) { argp_error( state, "Invalid argument for -N" ); } break; case 'q': opts->quiet = 1; break; case 1: opts->list_arch = 1; break; case 2: opts->list_disasm_opt = 1; break; case 3: opts->list_syntax = 1; break; case 4: opts->list_format = 1; break; case 5: opts->dry_run = 1; break; case ARGP_KEY_ARG: tgt_list_add( opts->targets, tgt_file, arg ); break; default: return ARGP_ERR_UNKNOWN; } return 0; }
const unsigned char* do_action( const unsigned char* action, CIStream* args, COStream out) { const unsigned char* as; unsigned char ac; int argn = 0; as = action; if ( as != NULL ) for ( ; ; ) { ac = *as++; switch (ac) { case PT_END: return as-1; case PT_SEPARATOR: return as; case PT_PUT_ARG: { CIStream arg = args[ (*as++) - 1 ]; cis_rewind(arg); cos_copy_input_stream(out,arg); break; } case PT_ONE_OPT: cos_putch(out,arg_char); break; case PT_DOMAIN: { CIStream inbuf; Pattern save_rule = current_rule; #if MAX_DOMAINS < 256 int domain = *as++ - 1; #else /* Get domain index as 14 bit little endian number */ int domain = ((unsigned char)*as++)&0x7f; domain = ((((unsigned char)*as++)&0x7f)<<7) | domain; #endif if ( as[0] == PT_VAR1 || ( as[0] == PT_OP && ( as[1] == OP_VAR || as[1] == OP_VAR_DFLT ) ) ) { /* for safety, copy the variable's value in case it is changed during translation. */ COStream outbuf; outbuf = make_buffer_output_stream(); as = do_action( as, args, outbuf ); inbuf = convert_output_to_input( outbuf ); } else /* optimized operand access */ inbuf = function_operand( &as, args ); #ifdef TRACE if ( trace_switch ) { int n; fprintf( stderr, "%12ld,%2d ", cis_line(input_stream), cis_column(input_stream)); for ( n = trace_indent ; n > 0 ; n-- ) fputc(' ',stderr); if ( cis_is_file(inbuf) ) { const char* inpath = cis_pathname(inbuf); if ( inpath == NULL ) inpath = "-"; fprintf( stderr, "@%s{@read{%s}}\n", domains[domain]->name, inpath); } else fprintf( stderr, "@%s{%.60s}\n", domains[domain]->name, cis_whole_string(inbuf)); ++trace_indent; } #endif if ( !translate( inbuf, domains[domain], out, NULL ) && cis_is_file(inbuf) && exit_status < EXS_FAIL ) exit_status = EXS_FAIL; #ifdef TRACE if ( trace_switch ) { --trace_indent; } #endif current_rule = save_rule; cis_close(inbuf); break; } case PT_VAR1: { char vname[2]; vname[0] = *as++; vname[1] = '\0'; put_var(out, vname, FALSE); break; } case PT_LINE: cos_freshline(out); break; case PT_MATCHED_TEXT: do_action( current_rule->pattern, args, out ); break; case PT_SPECIAL_ARG: #if MAX_DOMAINS >= 256 /* advance one more since 2 bytes for domain index */ case PT_RECUR: #endif as++; case PT_REGEXP: #if MAX_DOMAINS < 256 case PT_RECUR: #endif as++; case PT_MATCH_ANY: case PT_MATCH_ONE: { /* these will be encountered only when replaying the template as $0 */ CIStream arg = args[ argn++ ]; cis_rewind(arg); cos_copy_input_stream(out,arg); break; } case PT_AUX: as++; break; case PT_OP: { CIStream inbuf = NULL; enum Operators ac; ac = (enum Operators)*as++; switch(ac) { case OP_UNDEFINE: case OP_DEFINE: { inbuf = function_operand( &as, args ); read_patterns(inbuf, "", ac==OP_UNDEFINE); break; } case OP_SUBST: { int d; CIStream arg; Pattern save_rule = current_rule; arg = function_operand( &as, args ); d = read_patterns(arg," temp ",FALSE); inbuf = function_operand( &as, args ); translate ( inbuf, domains[d], out, NULL ); current_rule = save_rule; delete_domain(d); cis_close(arg); break; } case OP_VAR: { inbuf = function_operand( &as, args ); put_var(out, cis_whole_string(inbuf), FALSE ); break; } case OP_VAR_DFLT: { inbuf = function_operand( &as, args ); /* variable name */ if ( put_var(out, cis_whole_string(inbuf), TRUE ) ) as = skip_action(as); /* skip default value */ else as = do_action( as, args, out ); /* output default */ break; } case OP_SET: { CIStream name; name = function_operand( &as, args ); inbuf = function_operand( &as, args ); set_var( cis_whole_string(name), cis_whole_string(inbuf), cis_length(inbuf) ); cis_close(name); break; } case OP_BIND: { CIStream name; name = function_operand( &as, args ); inbuf = function_operand( &as, args ); bind_var( cis_whole_string(name), cis_whole_string(inbuf), cis_length(inbuf) ); cis_close(name); break; } case OP_UNBIND: { CIStream name; name = function_operand( &as, args ); unbind_var( cis_whole_string(name) ); cis_close(name); break; } case OP_APPEND: { CIStream name; name = function_operand( &as, args ); inbuf = function_operand( &as, args ); append_var( cis_whole_string(name), cis_whole_string(inbuf), cis_length(inbuf) ); cis_close(name); break; } case OP_INCR: case OP_DECR: { CIStream name; name = function_operand( &as, args ); incr_var( cis_whole_string(name), ac==OP_DECR? -1 : 1 ); cis_close(name); break; } case OP_GETENV: case OP_GETENV_DEFAULT: { CIStream dbuf = NULL; char* value; inbuf = function_operand( &as, args ); if ( ac == OP_GETENV_DEFAULT ) dbuf = function_operand( &as, args ); value = getenv(cis_whole_string(inbuf)); if ( value == NULL ) cos_copy_input_stream(out, dbuf); else cos_puts(out, value); cis_close(dbuf); break; } case OP_ERR: { static COStream err_stream = NULL; if ( err_stream == NULL ) err_stream = make_file_output_stream(stderr,"stderr"); as = do_action( as, args, err_stream ); break; } case OP_OUT: { as = do_action( as, args, output_stream ); break; } case OP_PATH: case OP_FILE: { const char* path = cis_pathname(input_stream); if ( path != NULL ) { if ( ac == OP_FILE ) path = pathname_name_and_type(path); cos_puts(out, path); } break; } case OP_OUTFILE: { const char* opath; opath = cos_pathname(out); if ( opath == NULL ) opath = cos_pathname(output_stream); cos_puts(out, opath); break; } case OP_LINE: { put_number(out, cis_line(input_stream)); break; } case OP_COL: { put_number(out, cis_column(input_stream)); break; } case OP_OUTCOL: { put_number(out, cos_column(output_stream)); break; } case OP_HELP: usage(); break; case OP_VERSION: cos_puts(out, Version); break; case OP_DATE: case OP_TIME: { time_t now; struct tm* ts; char tbuf [12]; now = time(NULL); ts = localtime(&now); if ( ac == OP_TIME ) sprintf(tbuf, "%02d:%02d:%02d", ts->tm_hour, ts->tm_min, ts->tm_sec); else sprintf(tbuf, "%02d/%02d/%d", ts->tm_mon + 1, ts->tm_mday, 1900 + ts->tm_year); cos_puts(out, tbuf); break; } case OP_DATIME: { time_t now; now = time(NULL); put_datime( out, &now ); break; } case OP_MODTIME: { time_t mtime; mtime = cis_mod_time(input_stream); if ( mtime != 0 ) put_datime( out, &mtime ); break; } case OP_PROBE: { inbuf = function_operand( &as, args ); cos_putch(out, probe_pathname(cis_whole_string(inbuf))); break; } case OP_READ: { const char* pathname; CIStream in; inbuf = function_operand( &as, args ); pathname = cis_whole_string(inbuf); close_output(pathname); in = open_input_file(pathname,binary); cos_copy_input_stream(out, in); cis_close(in); break; } case OP_WRITE: { COStream oldout; const char* pathname; oldout = output_stream; inbuf = function_operand( &as, args ); pathname = cis_whole_string(inbuf); output_stream = find_output_file(pathname,TRUE); as = do_action( as, args, output_stream ); output_stream = oldout; break; } case OP_CLOSE: { inbuf = function_operand( &as, args ); close_output(cis_whole_string(inbuf)); break; } case OP_COMBINEPATH: case OP_MERGEPATH: { CIStream dir; CIStream name; CIStream typ; dir = function_operand( &as, args ); name = function_operand( &as, args ); typ = function_operand( &as, args ); merge_pathnames( out, ac==OP_COMBINEPATH, cis_whole_string(dir), cis_whole_string(name), cis_whole_string(typ) ); cis_close(dir); cis_close(name); cis_close(typ); break; } case OP_RELPATH: { CIStream dir; dir = function_operand( &as, args ); inbuf = function_operand( &as, args ); cos_puts( out, relative_pathname(cis_whole_string(dir), cis_whole_string(inbuf)) ); cis_close(dir); break; } case OP_EXP_WILD: { inbuf = function_operand( &as, args ); expand_wildcard ( cis_whole_string(inbuf), out ); break; } case OP_ADD: case OP_SUB: case OP_MUL: case OP_DIV: case OP_MOD: case OP_AND: case OP_OR: { long x,y,z; x = numeric_operand( &as, args ); y = numeric_operand( &as, args ); switch(ac) { case OP_ADD: z = x + y; break; case OP_SUB: z = x - y; break; case OP_MUL: z = x * y; break; case OP_DIV: z = x / y; break; case OP_MOD: z = x % y; break; case OP_AND: z = x & y; break; case OP_OR: z = x | y; break; default: /* can't happen; just to avoid compiler warning */ assert(FALSE); z = 0; break; } put_number(out,z); break; } case OP_NOT: put_number(out, ~ numeric_operand( &as, args ) ); break; case OP_RADIX: { int from, to; unsigned long value; char* string; char* end; const char* fmt; char buf[24]; /* enough for 64 bits in octal */ from = (int)numeric_operand( &as, args ); to = (int)numeric_operand( &as, args ); inbuf = function_operand( &as, args ); string = cis_whole_string(inbuf); value = strtoul( string, &end, from ); if ( *end != '\0' ) input_error ( input_stream, EXS_NUM, "Invalid argument for radix %d conversion: \"%.99s\"\n", from, string); if ( to == 8 ) fmt = "%lo"; else if ( to == 16 ) fmt = "%lX"; else { if ( to != 10 ) input_error ( input_stream, EXS_NUM, "Unsupported radix: %d\n", to); while ( isspace(string[0]) ) string++; fmt = (string[0]=='-') ? "%ld" : "%lu"; } sprintf(buf, fmt, value); cos_puts(out, buf); break; } case OP_STR_CMP: case OP_STRI_CMP: { /* string comparison */ CIStream x = function_operand( &as, args ); CIStream y = function_operand( &as, args ); const char* xs = cis_whole_string(x); const char* ys = cis_whole_string(y); int cmp; cmp = ac == OP_STRI_CMP ? stricmp(xs, ys) : strcmp(xs, ys); cis_close(x); cis_close(y); as = do_cmp( cmp, as, args, out); break; } case OP_NUM_CMP: { /* numeric comparison */ long x = numeric_operand( &as, args ); long y = numeric_operand( &as, args ); int cmp; if ( x < y ) cmp = -1; else if ( x == y ) cmp = 0; else cmp = 1; as = do_cmp( cmp, as, args, out); break; } case OP_LENGTH: { inbuf = function_operand( &as, args ); put_number(out, cis_length(inbuf)); break; } case OP_TAB: { int col; col = (int)numeric_operand( &as, args ); cos_spaces(out, col - (int)cos_column(out)); break; } case OP_WRAP: { unsigned length; unsigned col; inbuf = function_operand( &as, args ); length = cis_length(inbuf); col = cos_column(out); if ( ( ((int)(col + length)) > wrap_column && col > wrap_indent_length ) || ( col <= 1 && length > 0 ) ) { cos_freshline(out); cos_puts(out, wrap_indent); skip_whitespace(inbuf); } cos_copy_input_stream(out, inbuf); break; } case OP_SET_WRAP: { wrap_column = (int)numeric_operand( &as, args ); inbuf = function_operand( &as, args ); if ( wrap_indent != NULL ) free(wrap_indent); wrap_indent_length = cis_length(inbuf); wrap_indent = str_dup_len( cis_whole_string(inbuf), wrap_indent_length ); break; } case OP_RIGHT: case OP_LEFT: case OP_CENTER: { /* justify value in fixed-length field */ int field_length, string_length, left_pad, right_pad; field_length = (int)numeric_operand( &as, args ); inbuf = function_operand( &as, args ); string_length = cis_length(inbuf); left_pad = field_length - string_length; right_pad = 0; if ( left_pad < 0 ) left_pad = 0; if ( ac == OP_LEFT ) { right_pad = left_pad; left_pad = 0; } else if ( ac == OP_CENTER ) { left_pad = left_pad / 2; right_pad = field_length - string_length - left_pad; } cos_spaces(out, left_pad); cos_copy_input_stream(out, inbuf); cos_spaces(out, right_pad); break; } case OP_FILL_RIGHT: case OP_FILL_LEFT: case OP_FILL_CENTER: { /* justify value in fixed-length field */ int field_length, string_length, left_pad, right_pad; CIStream background; int i; background = function_operand( &as, args ); field_length = cis_length(background); inbuf = function_operand( &as, args ); string_length = cis_length(inbuf); left_pad = field_length - string_length; right_pad = 0; if ( left_pad < 0 ) left_pad = 0; if ( ac == OP_FILL_LEFT ) { right_pad = left_pad; left_pad = 0; } else if ( ac == OP_FILL_CENTER ) { left_pad = left_pad / 2; right_pad = field_length - string_length - left_pad; } else assert( ac == OP_FILL_RIGHT ); for ( i = left_pad ; i > 0 ; i-- ) cos_putch(out, cis_getch(background)); cos_copy_input_stream(out, inbuf); if ( right_pad > 0 ) { for ( i = string_length ; i > 0 ; i-- ) (void)cis_getch(background); cos_copy_input_stream(out, background); } cis_close(background); break; } case OP_SUBSTRING: { int skip_length, result_length, string_length; skip_length = (int)numeric_operand( &as, args ); result_length = (int)numeric_operand( &as, args ); inbuf = function_operand( &as, args ); string_length = cis_length(inbuf); if ( skip_length <= string_length ) { if ( skip_length < 0 ) skip_length = 0; if ( (skip_length + result_length) > string_length ) result_length = string_length - skip_length; cos_put_len(out, cis_whole_string(inbuf) + skip_length, result_length); } break; } case OP_DOWNCASE: case OP_UPCASE: { int cc; inbuf = function_operand( &as, args ); while ( (cc = cis_getch(inbuf)) != EOF ) cos_putch(out, ac==OP_DOWNCASE ? tolower(cc) : toupper(cc) ); break; } case OP_CHARINT: inbuf = function_operand( &as, args ); put_number(out, cis_getch(inbuf)); break; case OP_INTCHAR: cos_putch(out, (char)numeric_operand( &as, args )); break; case OP_REVERSE: { int len; const char* start; const char* ip; inbuf = function_operand( &as, args ); len = cis_length(inbuf); start = cis_whole_string(inbuf); for ( ip = start+len-1 ; ip >= start ; ip-- ) cos_putch(out, *ip); break; } case OP_SHELL: { const char* command; inbuf = function_operand( &as, args ); command = cis_whole_string(inbuf); fflush(stdout); if ( system( command ) < 0 ) { input_error ( input_stream, EXS_SHELL, "Failed shell command \"%.20s...\":\n", command ); perror("system"); } break; } case OP_EXIT: translation_status = Translate_Exited; break; case OP_FAIL: translation_status = Translate_Failed; break; case OP_END_OR_FAIL: /* ideally this should be testing whether the input stream has been advanced, but that is not so easy. */ translation_status = ( cis_out_length(out) == 0 )? Translate_Failed : Translate_Exited; break; case OP_EXIT_STATUS: exit_status = (Exit_States)(int)numeric_operand( &as, args ); break; case OP_ABORT: exit((int)(exit_status > EXS_FAIL ? exit_status : EXS_FAIL )); break; case OP_GET_SWITCH: case OP_SET_SWITCH: { const char* name; int* valpt; inbuf = function_operand( &as, args ); name = cis_whole_string(inbuf); valpt = find_switch(name); if ( valpt == NULL ) { input_error(input_stream, EXS_UNDEF, "Undefined switch name \"%.99s\"\n", name ); if ( ac == OP_SET_SWITCH ) (void)numeric_operand( &as, args ); } else { if ( ac == OP_SET_SWITCH ) *valpt = (int)numeric_operand( &as, args ); else put_number( out, *valpt ); } break; } case OP_SET_PARM: { const char* name; CIStream val; inbuf = function_operand( &as, args ); name = cis_whole_string(inbuf); val = function_operand( &as, args ); if ( !set_parm( name, cis_whole_string(val) ) ) input_error(input_stream, EXS_UNDEF, "Undefined parameter name \"%.99s\"\n", name ); cis_close(val); break; } case OP_SYNTAX: { const char* type; const char* charset; CIStream val; inbuf = function_operand( &as, args ); val = function_operand( &as, args ); charset = cis_whole_string(val); for ( type = cis_whole_string(inbuf) ; *type != '\0' ; type++ ) { const char* chars; char c[2]; if ( type[1] == '\0' ) chars = charset; else { c[0] = *charset++; c[1] = '\0'; chars = c; } if ( !set_syntax(type[0], chars) ) input_error(input_stream, EXS_UNDEF, "Undefined syntax type \"%.99s\"\n", type ); } cis_close(val); break; } case OP_DEFAULT_SYNTAX: initialize_syntax(); break; #ifndef MSDOS case OP_LOCALE: { const char* lname; inbuf = function_operand( &as, args ); lname = cis_whole_string(inbuf); if ( setlocale(LC_ALL, lname) == NULL ) input_error(input_stream, EXS_UNDEF, "Undefined locale \"%.99s\"\n", lname ); break; } #endif case OP_REPEAT: { long n = numeric_operand( &as, args ); if ( n <= 0 ) as = skip_action(as); else { const unsigned char* start = as; for ( ; n > 0 ; n-- ) as = do_action( start, args, out ); } break; } case OP_QUOTE: { inbuf = function_operand( &as, args ); quoted_copy( inbuf, out ); break; } default: fprintf(stderr, "Undefined op in action: %d\n", (int)ac); break; } /* end switch on ops */ cis_close(inbuf); break; } /* end PT_OP */ case PT_WORD_DELIM: case PT_ID_DELIM: /* Ignore if in expansion of "$0" */ if ( current_rule == NULL || action != current_rule->pattern ) { /* output a space if needed as a delimiter */ int prevch = cos_prevch(out); if ( prevch != EOF ) if ( ac == PT_ID_DELIM ? isident(prevch) : isalnum(prevch) ) cos_putch(out,' '); } break; #if 0 /* not needed now */ case PT_ARG_DELIM: if ( cos_prevch(out) != Arg_Delim ) cos_putch(out,Arg_Delim); break; #endif case PT_SPACE: { /* output a space if the last character is not white space */ int prevch = cos_prevch(out); if ( !isspace(prevch) ) cos_putch(out,' '); break; } case PT_SKIP_WHITE_SPACE: break; case PT_QUOTE: /* use next character literally */ ac = *as++; /* and fall-through */ default: cos_putch(out, ac); } /* end switch ac */ } /* end for */ /* can't ever get here, but return to avoid Gnu compiler warning. */ return as; }
int main(int argc, char** argv) { if (argc < 2) { return print_usage(argv[0], true); } FILE* in_fd = NULL; SerdSyntax input_syntax = SERD_TURTLE; SerdSyntax output_syntax = SERD_NTRIPLES; bool from_file = true; bool bulk_read = true; bool bulk_write = false; bool full_uris = false; bool lax = false; bool quiet = false; const uint8_t* in_name = NULL; const uint8_t* add_prefix = NULL; const uint8_t* chop_prefix = NULL; const uint8_t* root_uri = NULL; int a = 1; for (; a < argc && argv[a][0] == '-'; ++a) { if (argv[a][1] == '\0') { in_name = (const uint8_t*)"(stdin)"; in_fd = stdin; break; } else if (argv[a][1] == 'b') { bulk_write = true; } else if (argv[a][1] == 'e') { bulk_read = false; } else if (argv[a][1] == 'f') { full_uris = true; } else if (argv[a][1] == 'h') { return print_usage(argv[0], false); } else if (argv[a][1] == 'l') { lax = true; } else if (argv[a][1] == 'q') { quiet = true; } else if (argv[a][1] == 'v') { return print_version(); } else if (argv[a][1] == 's') { in_name = (const uint8_t*)"(string)"; from_file = false; ++a; break; } else if (argv[a][1] == 'i') { if (++a == argc) { return missing_arg(argv[0], 'i'); } else if (!set_syntax(&input_syntax, argv[a])) { return print_usage(argv[0], true); } } else if (argv[a][1] == 'o') { if (++a == argc) { return missing_arg(argv[0], 'o'); } else if (!set_syntax(&output_syntax, argv[a])) { return print_usage(argv[0], true); } } else if (argv[a][1] == 'p') { if (++a == argc) { return missing_arg(argv[0], 'p'); } add_prefix = (const uint8_t*)argv[a]; } else if (argv[a][1] == 'c') { if (++a == argc) { return missing_arg(argv[0], 'c'); } chop_prefix = (const uint8_t*)argv[a]; } else if (argv[a][1] == 'r') { if (++a == argc) { return missing_arg(argv[0], 'r'); } root_uri = (const uint8_t*)argv[a]; } else { SERDI_ERRORF("invalid option -- '%s'\n", argv[a] + 1); return print_usage(argv[0], true); } } if (a == argc) { SERDI_ERROR("missing input\n"); return 1; } const uint8_t* input = (const uint8_t*)argv[a++]; if (from_file) { in_name = in_name ? in_name : input; if (!in_fd) { input = serd_uri_to_path(in_name); if (!input || !(in_fd = serd_fopen((const char*)input, "r"))) { return 1; } } } SerdURI base_uri = SERD_URI_NULL; SerdNode base = SERD_NODE_NULL; if (a < argc) { // Base URI given on command line base = serd_node_new_uri_from_string( (const uint8_t*)argv[a], NULL, &base_uri); } else if (from_file && in_fd != stdin) { // Use input file URI base = serd_node_new_file_uri(input, NULL, &base_uri, false); } FILE* out_fd = stdout; SerdEnv* env = serd_env_new(&base); int output_style = 0; if (output_syntax == SERD_NTRIPLES) { output_style |= SERD_STYLE_ASCII; } else { output_style |= SERD_STYLE_ABBREVIATED; if (!full_uris) { output_style |= SERD_STYLE_CURIED; } } if (input_syntax != SERD_NTRIPLES || (output_style & SERD_STYLE_CURIED)) { // Base URI may change and/or we're abbreviating URIs, so must resolve output_style |= SERD_STYLE_RESOLVED; // Base may chan } if (bulk_write) { output_style |= SERD_STYLE_BULK; } SerdWriter* writer = serd_writer_new( output_syntax, (SerdStyle)output_style, env, &base_uri, serd_file_sink, out_fd); SerdReader* reader = serd_reader_new( input_syntax, writer, NULL, (SerdBaseSink)serd_writer_set_base_uri, (SerdPrefixSink)serd_writer_set_prefix, (SerdStatementSink)serd_writer_write_statement, (SerdEndSink)serd_writer_end_anon); serd_reader_set_strict(reader, !lax); if (quiet) { serd_reader_set_error_sink(reader, quiet_error_sink, NULL); serd_writer_set_error_sink(writer, quiet_error_sink, NULL); } SerdNode root = serd_node_from_string(SERD_URI, root_uri); serd_writer_set_root_uri(writer, &root); serd_writer_chop_blank_prefix(writer, chop_prefix); serd_reader_add_blank_prefix(reader, add_prefix); SerdStatus status = SERD_SUCCESS; if (!from_file) { status = serd_reader_read_string(reader, input); } else if (bulk_read) { status = serd_reader_read_file_handle(reader, in_fd, in_name); } else { status = serd_reader_start_stream(reader, in_fd, in_name, false); while (!status) { status = serd_reader_read_chunk(reader); } serd_reader_end_stream(reader); } serd_reader_free(reader); if (from_file) { fclose(in_fd); } serd_writer_finish(writer); serd_writer_free(writer); serd_env_free(env); serd_node_free(&base); return (status > SERD_FAILURE) ? 1 : 0; }
int main(int argc, char** argv) { if (argc < 2) { return print_usage(argv[0], true); } FILE* in_fd = NULL; SerdSyntax input_syntax = SERD_TURTLE; SerdSyntax output_syntax = SERD_NTRIPLES; bool from_file = true; bool bulk_write = false; bool full_uris = false; const uint8_t* in_name = NULL; const uint8_t* add_prefix = NULL; const uint8_t* chop_prefix = NULL; const uint8_t* root_uri = NULL; int a = 1; for (; a < argc && argv[a][0] == '-'; ++a) { if (argv[a][1] == '\0') { in_name = (const uint8_t*)"(stdin)"; in_fd = stdin; break; } else if (argv[a][1] == 'b') { bulk_write = true; } else if (argv[a][1] == 'f') { full_uris = true; } else if (argv[a][1] == 'h') { return print_usage(argv[0], false); } else if (argv[a][1] == 'v') { return print_version(); } else if (argv[a][1] == 's') { in_name = (const uint8_t*)"(string)"; from_file = false; ++a; break; } else if (argv[a][1] == 'i') { if (++a == argc || !set_syntax(&input_syntax, argv[a])) { return bad_arg(argv[0], 'i'); } } else if (argv[a][1] == 'o') { if (++a == argc || !set_syntax(&output_syntax, argv[a])) { return bad_arg(argv[0], 'o'); } } else if (argv[a][1] == 'p') { if (++a == argc) { return bad_arg(argv[0], 'p'); } add_prefix = (const uint8_t*)argv[a]; } else if (argv[a][1] == 'c') { if (++a == argc) { return bad_arg(argv[0], 'c'); } chop_prefix = (const uint8_t*)argv[a]; } else if (argv[a][1] == 'r') { if (++a == argc) { return bad_arg(argv[0], 'r'); } root_uri = (const uint8_t*)argv[a]; } else { fprintf(stderr, "%s: Unknown option `%s'\n", argv[0], argv[a]); return print_usage(argv[0], true); } } if (a == argc) { fprintf(stderr, "%s: Missing input\n", argv[0]); return 1; } const uint8_t* input = (const uint8_t*)argv[a++]; if (from_file) { in_name = in_name ? in_name : input; if (!in_fd) { input = serd_uri_to_path(in_name); if (!input || !(in_fd = serd_fopen((const char*)input, "r"))) { return 1; } } } SerdURI base_uri = SERD_URI_NULL; SerdNode base = SERD_NODE_NULL; if (a < argc) { // Base URI given on command line base = serd_node_new_uri_from_string( (const uint8_t*)argv[a], NULL, &base_uri); } else if (from_file && in_fd != stdin) { // Use input file URI base = serd_node_new_file_uri(input, NULL, &base_uri, false); } FILE* out_fd = stdout; SerdEnv* env = serd_env_new(&base); int output_style = 0; if (output_syntax == SERD_NTRIPLES) { output_style |= SERD_STYLE_ASCII; } else { output_style |= SERD_STYLE_ABBREVIATED; if (!full_uris) { output_style |= SERD_STYLE_CURIED; } } if (input_syntax != SERD_NTRIPLES // Base URI may change (@base) || (output_syntax == SERD_TURTLE)) { output_style |= SERD_STYLE_RESOLVED; } if (bulk_write) { output_style |= SERD_STYLE_BULK; } SerdWriter* writer = serd_writer_new( output_syntax, (SerdStyle)output_style, env, &base_uri, serd_file_sink, out_fd); SerdReader* reader = serd_reader_new( input_syntax, writer, NULL, (SerdBaseSink)serd_writer_set_base_uri, (SerdPrefixSink)serd_writer_set_prefix, (SerdStatementSink)serd_writer_write_statement, (SerdEndSink)serd_writer_end_anon); SerdNode root = serd_node_from_string(SERD_URI, root_uri); serd_writer_set_root_uri(writer, &root); serd_writer_chop_blank_prefix(writer, chop_prefix); serd_reader_add_blank_prefix(reader, add_prefix); const SerdStatus status = (from_file) ? serd_reader_read_file_handle(reader, in_fd, in_name) : serd_reader_read_string(reader, input); serd_reader_free(reader); if (from_file) { fclose(in_fd); } serd_writer_finish(writer); serd_writer_free(writer); serd_env_free(env); serd_node_free(&base); return (status > SERD_FAILURE) ? 1 : 0; }