Changeset: 700ef34601e0 for MonetDB URL: https://dev.monetdb.org/hg/MonetDB?cmd=changeset;node=700ef34601e0 Modified Files: clients/Tests/exports.stable.out gdk/gdk_logger.c monetdb5/mal/mal_profiler.c monetdb5/modules/mal/remote.c monetdb5/modules/mal/tablet.c monetdb5/modules/mal/tokenizer.c sql/backends/monet5/sql.c sql/backends/monet5/sql_result.c sql/backends/monet5/sql_scenario.c sql/backends/monet5/wlr.c sql/server/rel_updates.c sql/server/sql_scan.c sql/storage/bat/bat_logger.c sql/storage/store.c sql/test/sys-schema/Tests/systemfunctions.stable.out sql/test/sys-schema/Tests/systemfunctions.stable.out.int128 Branch: unlock Log Message:
Merge with default branch. diffs (truncated from 23400 to 300 lines): diff --git a/clients/Tests/exports.stable.out b/clients/Tests/exports.stable.out --- a/clients/Tests/exports.stable.out +++ b/clients/Tests/exports.stable.out @@ -1877,25 +1877,29 @@ char *buffer_get_buf(buffer *b); void buffer_init(buffer *restrict b, char *restrict buf, size_t size); stream *buffer_rastream(buffer *restrict b, const char *restrict name); stream *buffer_wastream(buffer *restrict b, const char *restrict name); +stream *bz2_stream(stream *inner, int preset); stream *callback_stream(void *restrict priv, ssize_t (*read)(void *restrict priv, void *restrict buf, size_t elmsize, size_t cnt), ssize_t (*write)(void *restrict priv, const void *restrict buf, size_t elmsize, size_t cnt), void (*close)(void *priv), void (*destroy)(void *priv), const char *restrict name); void close_stream(stream *s); -stream *file_rastream(FILE *restrict fp, const char *restrict name); -stream *file_rstream(FILE *restrict fp, const char *restrict name); -stream *file_wastream(FILE *restrict fp, const char *restrict name); -stream *file_wstream(FILE *restrict fp, const char *restrict name); +stream *compressed_stream(stream *inner, int preset); +stream *create_text_stream(stream *s); +stream *file_rstream(FILE *restrict fp, bool binary, const char *restrict name); +stream *file_wstream(FILE *restrict fp, bool binary, const char *restrict name); FILE *getFile(stream *s); int getFileNo(stream *s); size_t getFileSize(stream *s); +stream *gz_stream(stream *inner, int preset); stream *iconv_rstream(stream *restrict ss, const char *restrict charset, const char *restrict name); stream *iconv_wstream(stream *restrict ss, const char *restrict charset, const char *restrict name); bool isa_block_stream(const stream *s); +stream *lz4_stream(stream *inner, int preset); void mnstr_clearerr(stream *s); void mnstr_close(stream *s); void mnstr_destroy(stream *s); -int mnstr_errnr(const stream *s); +mnstr_error_kind mnstr_errnr(const stream *s); char *mnstr_error(const stream *s); +const char *mnstr_error_kind_name(mnstr_error_kind k); int mnstr_fgetpos(stream *restrict s, fpos_t *restrict p); -int mnstr_flush(stream *s); +int mnstr_flush(stream *s, mnstr_flush_level flush_level); int mnstr_fsetpos(stream *restrict s, fpos_t *restrict p); int mnstr_fsync(stream *s); buffer *mnstr_get_buffer(stream *s); @@ -1904,6 +1908,7 @@ int mnstr_init(int embedded); int mnstr_isalive(const stream *s); bool mnstr_isbinary(const stream *s); char *mnstr_name(const stream *s); +const char *mnstr_peek_error(const stream *s); int mnstr_printf(stream *restrict s, _In_z_ _Printf_format_string_ const char *restrict format, ...) __attribute__((__format__(__printf__, 2, 3))); ssize_t mnstr_read(stream *restrict s, void *restrict buf, size_t elmsize, size_t cnt); int mnstr_readBte(stream *restrict s, int8_t *restrict val); @@ -1944,8 +1949,12 @@ stream *open_wastream(const char *filena stream *open_wstream(const char *filename); stream *socket_rstream(SOCKET socket, const char *name); stream *socket_wstream(SOCKET socket, const char *name); +stream *stderr_wastream(void); +stream *stdin_rastream(void); +stream *stdout_wastream(void); stream *stream_blackhole_create(void); stream *stream_fwf_create(stream *restrict s, size_t num_fields, size_t *restrict widths, char filler); +stream *xz_stream(stream *inner, int preset); # 21:41:06 > diff --git a/clients/examples/C/CMakeLists.txt b/clients/examples/C/CMakeLists.txt --- a/clients/examples/C/CMakeLists.txt +++ b/clients/examples/C/CMakeLists.txt @@ -37,12 +37,21 @@ if(TESTING) target_link_libraries(smack01 PRIVATE mapi) + add_executable(streamcat + streamcat.c) + + target_link_libraries(streamcat + PRIVATE + monetdb_config_header + stream) + install(TARGETS sample0 sample1 sample4 smack00 smack01 + streamcat RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} diff --git a/clients/examples/C/streamcat.c b/clients/examples/C/streamcat.c new file mode 100644 --- /dev/null +++ b/clients/examples/C/streamcat.c @@ -0,0 +1,565 @@ +#include "monetdb_config.h" +#include "stream.h" + +#include <errno.h> +#include <fcntl.h> +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#if defined(_MSC_VER) && _MSC_VER >= 1400 +#define fdopen _fdopen +#endif + + +const char *USAGE = + "Usage:\n" + " streamcat read [-o FILE] FILE R_OPENER [R_WRAPPER..]\n" + " streamcat write [-i FILE] FILE W_OPENER [W_WRAPPER..]\n" + " streamcat bstream -i (FILE | -)\n" + " streamcat bstream -o (FILE | -) [-a ADDITIONAL_TEXT] FILE...\n" + "Options:\n" + " -o FILE use FILE instead of stdout\n" + " -i FILE use FILE instead of stdin\n" + "With R_OPENER:\n" + " - rstream stream = open_rstream(filename)\n" + " - rastream stream = open_rastream(filename)\n" + " - urlstream stream = open_urlstream(filename)\n" + "" + "With W_OPENER:\n" + " - wstream stream = open_wstream(filename)\n" + " - wastream stream = open_wastream(filename)\n" + " - blocksize:N Copy in blocks of this size\n" + " - flush:{data,all} Flush after each block\n" + "With R_WRAPPER:\n" + " - iconv:enc stream = iconv_rstream(stream, enc)\n" + " - blocksize:N Copy in blocks of this size\n" + " - compr Autodecompress\n" + "With W_WRAPPER:\n" + " - iconv:enc stream = iconv_wstream(stream, enc)\n" + " - blocksize:N Copy out blocks of this size\n" + ; + + +static int cmd_read(char *argv[]); +static int cmd_write(char *argv[]); +static int cmd_bstream(char *argv[]); + +typedef stream *(*opener_fun)(char *filename); + +static stream *opener_rstream(char *filename); +static stream *opener_rastream(char *filename); +static stream *opener_urlstream(char *url); + +static stream *opener_wstream(char *filename); +static stream *opener_wastream(char *filename); + +static stream *wrapper_read_iconv(stream *s, char *enc); + +static stream *wrapper_write_iconv(stream *s, char *enc); + +static stream *wrapper_autocompression(stream *s, char *level); + +static void copy_stream_to_file(stream *in, FILE *out, size_t bufsize); + +static void copy_file_to_stream(FILE *in, stream *out, size_t bufsize, bool do_flush, mnstr_flush_level flush_level); + +_Noreturn static void croak(int status, const char *msg, ...) + __attribute__((__format__(__printf__, 2, 3))); + +/* Format the message and write it to stderr. Then exit with the given status. + * If status is 1, include USAGE in the message. + */ +static void +croak(int status, const char *msg, ...) +{ + va_list ap; + + va_start(ap, msg); + if (msg != NULL) { + fprintf(stderr, "Error: "); + vfprintf(stderr, msg, ap); + fprintf(stderr, "\n"); + } + va_end(ap); + if (status == 1) + fprintf(stderr, "%s", USAGE); + exit(status); +} + + +int +main(int argc, char *argv[]) +{ + if (mnstr_init(0) < 0) + croak(2, "Could not initialize streams library"); + + if (argc < 2) + croak(1, NULL); + + if (strcmp(argv[1], "read") == 0) + return cmd_read(argv+1); + else if (strcmp(argv[1], "write") == 0) + return cmd_write(argv+1); + else if (strcmp(argv[1], "bstream") == 0) + return cmd_bstream(argv+1); + else + croak(1, "Unknown subcommand '%s'", argv[1]); +} + + +int cmd_read(char *argv[]) +{ + char **arg = &argv[1]; + char *filename = NULL; + char *opener_name = NULL; + opener_fun opener; + size_t bufsize = 1024; + + stream *s = NULL; + FILE *out = NULL; + + if (*arg != NULL && arg[0][0] == '-') { + char *a = *arg++; + if (a[1] == 'o') { + if (*arg == NULL) + croak(1, "-o requires parameter"); + char *name = *arg++; + out = fopen(name, "wb"); + if (out == NULL) + croak(2, "could not open %s", name); + } else { + croak(1, "unknown option '%s'", a); + } + } + + filename = *arg++; + if (filename == NULL) + croak(1, "Missing filename"); + else if (filename[0] == '-') + croak(1, "Unexpected option: %s", filename); + + opener_name = *arg++; + if (opener_name == NULL) + croak(1, "Missing opener"); + else if (opener_name[0] == '-') + croak(1, "Unexpected option: %s", opener_name); + else if (strcmp(opener_name, "rstream") == 0) + opener = opener_rstream; + else if (strcmp(opener_name, "rastream") == 0) + opener = opener_rastream; + else if (strcmp(opener_name, "urlstream") == 0) + opener = opener_urlstream; + else + croak(1, "Unknown opener '%s'", opener_name); + + s = opener(filename); + if (s == NULL || mnstr_errnr(s)) { + char *msg = mnstr_error(s); + croak(2, "Opener %s failed: %s", opener_name, msg ? msg : "<no error message>"); + } + + for (; *arg != NULL; arg++) { + if (arg[0][0] == '-') + croak(1, "Unexpected option: %s", *arg); + + char *wrapper_name = *arg; + char *parms = strchr(wrapper_name, ':'); + stream *(*wrapper)(stream *s, char *parm) = NULL; + + if (parms != NULL) { + *parms = '\0'; + parms += 1; + } + if (strcmp(wrapper_name, "iconv") == 0) { + if (parms == NULL) + croak(1, "iconv wrapper needs a parameter"); + wrapper = wrapper_read_iconv; + } else if (strcmp(wrapper_name, "blocksize") == 0) { + if (parms == NULL) + croak(1, "blocksize needs a parameter"); + char *end; + long size = strtol(parms, &end, 10); + if (*end != '\0' || size <= 0) + croak(1, "invalid blocksize: %ld", size); + bufsize = size; + } else if (strcmp(wrapper_name, "compr") == 0) { + wrapper = wrapper_autocompression; + } else { + croak(1, "Unknown wrapper: %s", wrapper_name); + } + if (wrapper != NULL) + s = wrapper(s, parms); + if (s == NULL) + croak(2, "Wrapper %s did not return a stream", wrapper_name); + } + + if (out == NULL) { + fflush(stdout); + out = stdout; +#ifdef _MSC_VER + _setmode(_fileno(out), O_BINARY); +#endif + } + + copy_stream_to_file(s, out, bufsize); + close_stream(s); + + return 0; +} _______________________________________________ checkin-list mailing list checkin-list@monetdb.org https://www.monetdb.org/mailman/listinfo/checkin-list