Kouhei Sutou
null+****@clear*****
Sat Nov 14 23:29:41 JST 2015
Kouhei Sutou 2015-11-14 23:29:41 +0900 (Sat, 14 Nov 2015) New Revision: c1fe48e130b8c64b293b694502767cab9fdb6e48 https://github.com/groonga/groonga/commit/c1fe48e130b8c64b293b694502767cab9fdb6e48 Message: Add grn_file_reader It's for hiding FILE and fgets() into libgroonga. Added files: lib/file_reader.c Copied files: include/groonga/file_reader.h (from include/groonga.h) Modified files: include/groonga.h include/groonga/Makefile.am lib/sources.am lib/str.c plugins/query_expanders/tsv.c src/groonga.c src/groonga_benchmark.c Modified: include/groonga.h (+1 -0) =================================================================== --- include/groonga.h 2015-11-14 22:03:39 +0900 (e155127) +++ include/groonga.h 2015-11-14 23:29:41 +0900 (a9cceb10) @@ -31,5 +31,6 @@ #include "groonga/thread.h" #include "groonga/windows.h" #include "groonga/windows_event_logger.h" +#include "groonga/file_reader.h" #endif /* GROONGA_H */ Modified: include/groonga/Makefile.am (+1 -0) =================================================================== --- include/groonga/Makefile.am 2015-11-14 22:03:39 +0900 (4694306) +++ include/groonga/Makefile.am 2015-11-14 23:29:41 +0900 (5220853) @@ -3,6 +3,7 @@ groonga_include_HEADERS = \ command.h \ conf.h \ expr.h \ + file_reader.h \ geo.h \ groonga.h \ ii.h \ Copied: include/groonga/file_reader.h (+24 -19) 54% =================================================================== --- include/groonga.h 2015-11-14 22:03:39 +0900 (e155127) +++ include/groonga/file_reader.h 2015-11-14 23:29:41 +0900 (8cf178b) @@ -1,5 +1,5 @@ /* - Copyright(C) 2014-2015 Brazil + Copyright(C) 2015 Brazil This library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public @@ -15,21 +15,26 @@ License along with this library; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef GROONGA_H -#define GROONGA_H - -#include "groonga/portability.h" -#include "groonga/groonga.h" -#include "groonga/conf.h" -#include "groonga/obj.h" -#include "groonga/ii.h" -#include "groonga/geo.h" -#include "groonga/expr.h" -#include "groonga/output.h" -#include "groonga/util.h" -#include "groonga/request_canceler.h" -#include "groonga/thread.h" -#include "groonga/windows.h" -#include "groonga/windows_event_logger.h" - -#endif /* GROONGA_H */ + +#ifndef GROONGA_FILE_READER_H +#define GROONGA_FILE_READER_H + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct _grn_file_reader grn_file_reader; + +GRN_API grn_file_reader *grn_file_reader_open(grn_ctx *ctx, const char *path); +GRN_API void grn_file_reader_close(grn_ctx *ctx, + grn_file_reader *reader); + +GRN_API grn_rc grn_file_reader_read_line(grn_ctx *ctx, + grn_file_reader *reader, + grn_obj *buffer); + +#ifdef __cplusplus +} +#endif + +#endif /* GROONGA_FILE_READER_H */ Added: lib/file_reader.c (+108 -0) 100644 =================================================================== --- /dev/null +++ lib/file_reader.c 2015-11-14 23:29:41 +0900 (10927cb) @@ -0,0 +1,108 @@ +/* -*- c-basic-offset: 2 -*- */ +/* + Copyright(C) 2015 Brazil + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License version 2.1 as published by the Free Software Foundation. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +#include "grn_ctx.h" +#include "grn_str.h" + +#include <stdio.h> +#include <string.h> + +typedef struct _grn_file_reader { + FILE *file; + grn_bool file_need_close; +} grn_file_reader; + +grn_file_reader * +grn_file_reader_open(grn_ctx *ctx, const char *path) +{ + grn_file_reader *reader; + FILE *file; + grn_bool file_need_close; + + GRN_API_ENTER; + + if (!path) { + ERR(GRN_INVALID_ARGUMENT, "[file-reader][open] path must not NULL"); + GRN_API_RETURN(NULL); + } + + if (strcmp(path, "-") == 0) { + file = stdin; + file_need_close = GRN_FALSE; + } else { + file = fopen(path, "r"); + if (!file) { + SERR("fopen"); + GRN_LOG(ctx, GRN_LOG_ERROR, + "[file-reader][open] failed to open path: <%s>", + path); + GRN_API_RETURN(NULL); + } + file_need_close = GRN_TRUE; + } + + reader = GRN_MALLOC(sizeof(grn_file_reader)); + reader->file = file; + reader->file_need_close = file_need_close; + + GRN_API_RETURN(reader); +} + +void +grn_file_reader_close(grn_ctx *ctx, grn_file_reader *reader) +{ + if (!reader) { + return; + } + + if (reader->file_need_close) { + if (fclose(reader->file) != 0) { + GRN_LOG(ctx, GRN_LOG_ERROR, + "[file-reader][close] failed to close: <%s>", + grn_strerror(errno)); + } + } + + GRN_FREE(reader); +} + +grn_rc +grn_file_reader_read_line(grn_ctx *ctx, + grn_file_reader *reader, + grn_obj *buffer) +{ + grn_rc rc = GRN_END_OF_DATA; + + for (;;) { + size_t len; + +#define BUFFER_SIZE 4096 + grn_bulk_reserve(ctx, buffer, BUFFER_SIZE); + if (!fgets(GRN_BULK_CURR(buffer), BUFFER_SIZE, reader->file)) { + break; + } +#undef BUFFER_SIZE + + if (!(len = strlen(GRN_BULK_CURR(buffer)))) { break; } + GRN_BULK_INCR_LEN(buffer, len); + rc = GRN_SUCCESS; + if (GRN_BULK_CURR(buffer)[-1] == '\n') { break; } + } + + return rc; +} Modified: lib/sources.am (+2 -1) =================================================================== --- lib/sources.am 2015-11-14 22:03:39 +0900 (a1c670c) +++ lib/sources.am 2015-11-14 23:29:41 +0900 (617210c) @@ -79,4 +79,5 @@ libgroonga_la_SOURCES = \ util.c \ grn_util.h \ windows.c \ - windows_event_logger.c + windows_event_logger.c \ + file_reader.c Modified: lib/str.c (+0 -17) =================================================================== --- lib/str.c 2015-11-14 22:03:39 +0900 (1bbe43a) +++ lib/str.c 2015-11-14 23:29:41 +0900 (2f784b4) @@ -16,7 +16,6 @@ */ #include "grn.h" #include <limits.h> -#include <stdio.h> #include <stdarg.h> #include <string.h> #include "grn_db.h" @@ -3223,22 +3222,6 @@ grn_str_url_path_normalize(grn_ctx *ctx, const char *path, size_t path_len, *b = '\0'; } -grn_rc -grn_text_fgets(grn_ctx *ctx, grn_obj *buf, FILE *fp) -{ - size_t len; - grn_rc rc = GRN_END_OF_DATA; - for (;;) { - grn_bulk_reserve(ctx, buf, BUFSIZ); - if (!fgets(GRN_BULK_CURR(buf), BUFSIZ, fp)) { break; } - if (!(len = strlen(GRN_BULK_CURR(buf)))) { break; } - GRN_BULK_INCR_LEN(buf, len); - rc = GRN_SUCCESS; - if (GRN_BULK_CURR(buf)[-1] == '\n') { break; } - } - return rc; -} - grn_bool grn_bulk_is_zero(grn_ctx *ctx, grn_obj *obj) { Modified: plugins/query_expanders/tsv.c (+9 -10) =================================================================== --- plugins/query_expanders/tsv.c 2015-11-14 22:03:39 +0900 (0f1914c) +++ plugins/query_expanders/tsv.c 2015-11-14 23:29:41 +0900 (5562b6a) @@ -19,14 +19,13 @@ # define GRN_PLUGIN_FUNCTION_TAG query_expanders_tsv #endif -/* groonga's internal headers */ -/* for grn_text_fgets(): We don't want to require stdio.h for groonga.h. - What should we do? Should we split header file such as groonga/stdio.h? */ -#include <grn_str.h> +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif /* HAVE_CONFIG_H */ #include <groonga/plugin.h> -#include <stdio.h> +#include <stdlib.h> #include <string.h> #ifdef WIN32 @@ -194,7 +193,7 @@ load_synonyms(grn_ctx *ctx) { static char path_env[GRN_ENV_BUFFER_SIZE]; const char *path; - FILE *file; + grn_file_reader *file_reader; int number_of_lines; grn_encoding encoding; grn_obj line, key, value; @@ -207,8 +206,8 @@ load_synonyms(grn_ctx *ctx) } else { path = get_system_synonyms_file(); } - file = grn_fopen(path, "r"); - if (!file) { + file_reader = grn_file_reader_open(ctx, path); + if (!file_reader) { GRN_LOG(ctx, GRN_LOG_WARNING, "[plugin][query-expander][tsv] " "synonyms file doesn't exist: <%s>", @@ -221,7 +220,7 @@ load_synonyms(grn_ctx *ctx) GRN_TEXT_INIT(&value, 0); grn_bulk_reserve(ctx, &value, MAX_SYNONYM_BYTES); number_of_lines = 0; - while (grn_text_fgets(ctx, &line, file) == GRN_SUCCESS) { + while (grn_file_reader_read_line(ctx, file_reader, &line) == GRN_SUCCESS) { const char *line_value = GRN_TEXT_VALUE(&line); size_t line_length = GRN_TEXT_LEN(&line); @@ -245,7 +244,7 @@ load_synonyms(grn_ctx *ctx) GRN_OBJ_FIN(ctx, &key); GRN_OBJ_FIN(ctx, &value); - fclose(file); + grn_file_reader_close(ctx, file_reader); } static grn_obj * Modified: src/groonga.c (+53 -38) =================================================================== --- src/groonga.c 2015-11-14 22:03:39 +0900 (4d0153a) +++ src/groonga.c 2015-11-14 23:29:41 +0900 (31919e4) @@ -96,6 +96,7 @@ static int (*do_client)(int argc, char **argv); static int (*do_server)(char *path); static const char *pid_file_path = NULL; static const char *input_path = NULL; +static grn_file_reader *input_reader = NULL; static FILE *output = NULL; static int ready_notify_pipe[2]; @@ -221,10 +222,10 @@ read_next_line(grn_ctx *ctx, grn_obj *buf) #else fprintf(stderr, "> "); fflush(stderr); - rc = grn_text_fgets(ctx, buf, stdin); + rc = grn_file_reader_read_line(ctx, input_reader, buf); #endif } else { - rc = grn_text_fgets(ctx, buf, stdin); + rc = grn_file_reader_read_line(ctx, input_reader, buf); if (rc != GRN_END_OF_DATA) { number_of_lines++; } @@ -3033,42 +3034,6 @@ main(int argc, char **argv) grn_thread_set_get_limit_func(groonga_get_thread_limit, NULL); grn_thread_set_set_limit_func(groonga_set_thread_limit, NULL); - if (input_path) { - if (!freopen(input_path, "r", stdin)) { - fprintf(stderr, "can't open input file: %s (%s)\n", - input_path, strerror(errno)); - return EXIT_FAILURE; - } - batchmode = GRN_TRUE; - } else { - if (input_fd_arg) { - const char * const end = input_fd_arg + strlen(input_fd_arg); - const char *rest = NULL; - const int input_fd = grn_atoi(input_fd_arg, end, &rest); - if (rest != end || input_fd == 0) { - fprintf(stderr, "invalid input FD: <%s>\n", input_fd_arg); - return EXIT_FAILURE; - } - if (dup2(input_fd, STDIN_FILENO) == -1) { - fprintf(stderr, "can't open input FD: %d (%s)\n", - input_fd, strerror(errno)); - return EXIT_FAILURE; - } - batchmode = GRN_TRUE; - } else { - if (argc - i > 1) { - batchmode = GRN_TRUE; - } else { - batchmode = !isatty(0); - } - } - } - - if ((flags & (FLAG_MODE_ALONE | FLAG_MODE_CLIENT)) && - !batchmode) { - need_line_editor = GRN_TRUE; - } - if (output_fd_arg) { const char * const end = output_fd_arg + strlen(output_fd_arg); const char *rest = NULL; @@ -3204,6 +3169,53 @@ main(int argc, char **argv) COND_INIT(q_cond); CRITICAL_SECTION_INIT(cache_lock); + if (input_path) { + input_reader = grn_file_reader_open(&grn_gctx, input_path); + if (!input_reader) { + fprintf(stderr, "can't open input file: %s (%s)\n", + input_path, strerror(errno)); + return EXIT_FAILURE; + } + batchmode = GRN_TRUE; + } else { + if (input_fd_arg) { + const char * const end = input_fd_arg + strlen(input_fd_arg); + const char *rest = NULL; + const int input_fd = grn_atoi(input_fd_arg, end, &rest); + if (rest != end || input_fd == 0) { + fprintf(stderr, "invalid input FD: <%s>\n", input_fd_arg); + return EXIT_FAILURE; + } + if (dup2(input_fd, STDIN_FILENO) == -1) { + fprintf(stderr, "can't open input FD: %d (%s)\n", + input_fd, strerror(errno)); + return EXIT_FAILURE; + } + input_reader = grn_file_reader_open(&grn_gctx, "-"); + if (!input_reader) { + fprintf(stderr, "%s", grn_gctx.errbuf); + return EXIT_FAILURE; + } + batchmode = GRN_TRUE; + } else { + input_reader = grn_file_reader_open(&grn_gctx, "-"); + if (!input_reader) { + fprintf(stderr, "%s", grn_gctx.errbuf); + return EXIT_FAILURE; + } + if (argc - i > 1) { + batchmode = GRN_TRUE; + } else { + batchmode = !isatty(0); + } + } + } + + if ((flags & (FLAG_MODE_ALONE | FLAG_MODE_CLIENT)) && + !batchmode) { + need_line_editor = GRN_TRUE; + } + newdb = (flags & FLAG_NEW_DB); is_daemon_mode = (flags & FLAG_MODE_DAEMON); if (flags & FLAG_MODE_CLIENT) { @@ -3218,6 +3230,9 @@ main(int argc, char **argv) COND_FIN(q_cond); MUTEX_FIN(q_mutex); + if (input_reader) { + grn_file_reader_close(&grn_gctx, input_reader); + } #ifdef GRN_WITH_LIBEDIT if (need_line_editor) { line_editor_fin(); Modified: src/groonga_benchmark.c (+28 -32) =================================================================== --- src/groonga_benchmark.c 2015-11-14 22:03:39 +0900 (2ebca38) +++ src/groonga_benchmark.c 2015-11-14 23:29:41 +0900 (3960e47) @@ -146,7 +146,7 @@ struct job { long long int max; long long int min; FILE *outputlog; - FILE *inputlog; + grn_file_reader *inputlog; char logfile[BUF_LEN]; }; @@ -802,12 +802,12 @@ do_load_command(grn_ctx *ctx, char *command, int type, int task_id, } if (test_p(grntest_task[task_id].jobtype)) { grn_obj log; - FILE *input; + grn_file_reader *input; FILE *output; GRN_TEXT_INIT(&log, 0); input = grntest_job[grntest_task[task_id].job_id].inputlog; output = grntest_job[grntest_task[task_id].job_id].outputlog; - if (grn_text_fgets(ctx, &log, input) != GRN_SUCCESS) { + if (grn_file_reader_read_line(ctx, input, &log) != GRN_SUCCESS) { GRN_LOG(ctx, GRN_ERROR, "Cannot get input-log"); error_exit_in_thread(55); } @@ -888,12 +888,12 @@ do_command(grn_ctx *ctx, char *command, int type, int task_id) } if (test_p(grntest_task[task_id].jobtype)) { grn_obj log; - FILE *input; + grn_file_reader *input; FILE *output; GRN_TEXT_INIT(&log, 0); input = grntest_job[grntest_task[task_id].job_id].inputlog; output = grntest_job[grntest_task[task_id].job_id].outputlog; - if (grn_text_fgets(ctx, &log, input) != GRN_SUCCESS) { + if (grn_file_reader_read_line(ctx, input, &log) != GRN_SUCCESS) { GRN_LOG(ctx, GRN_ERROR, "Cannot get input-log"); error_exit_in_thread(55); } @@ -971,10 +971,10 @@ worker_sub(grn_ctx *ctx, grn_obj *log, int task_id) for (i = 0; i < task->ntimes; i++) { if (task->file != NULL) { - FILE *fp; + grn_file_reader *reader; grn_obj line; - fp = fopen(task->file, "r"); - if (!fp) { + reader = grn_file_reader_open(ctx, task->file); + if (!reader) { fprintf(stderr, "Cannot open %s\n",grntest_task[task_id].file); error_exit_in_thread(1); } @@ -982,7 +982,7 @@ worker_sub(grn_ctx *ctx, grn_obj *log, int task_id) load_count = 0; load_start = 0LL; GRN_TEXT_INIT(&line, 0); - while (grn_text_fgets(ctx, &line, fp) == GRN_SUCCESS) { + while (grn_file_reader_read_line(ctx, reader, &line) == GRN_SUCCESS) { if (GRN_TEXT_VALUE(&line)[GRN_TEXT_LEN(&line) - 1] == '\n') { grn_bulk_truncate(ctx, &line, GRN_TEXT_LEN(&line) - 1); } @@ -1022,7 +1022,7 @@ worker_sub(grn_ctx *ctx, grn_obj *log, int task_id) } } GRN_OBJ_FIN(ctx, &line); - fclose(fp); + grn_file_reader_close(ctx, reader); } else { int i, n_commands; grn_obj *commands; @@ -1602,7 +1602,7 @@ start_server(const char *dbpath, int r) } static int -parse_line(char *buf, int start, int end, int num) +parse_line(grn_ctx *ctx, char *buf, int start, int end, int num) { int i, j, error_flag = 0, out_or_test = 0; char tmpbuf[BUF_LEN]; @@ -1758,7 +1758,7 @@ parse_line(char *buf, int start, int end, int num) } } else { char outlog[BUF_LEN]; - grntest_job[num].inputlog = fopen(tmpbuf, "rb"); + grntest_job[num].inputlog = grn_file_reader_open(ctx, tmpbuf); if (grntest_job[num].inputlog == NULL) { fprintf(stderr, "Cannot open %s\n", tmpbuf); return 14; @@ -1840,7 +1840,7 @@ get_jobs(grn_ctx *ctx, char *buf, int line) while (i < len) { if (buf[i] == ';') { end = i; - ret = parse_line(buf, start, end, jnum); + ret = parse_line(ctx, buf, start, end, jnum); if (ret) { if (ret > 1) { fprintf(stderr, "Syntax error:line=%d:ret=%d:%s\n", line, ret, buf); @@ -1854,7 +1854,7 @@ get_jobs(grn_ctx *ctx, char *buf, int line) i++; } end = len; - ret = parse_line(buf, start, end, jnum); + ret = parse_line(ctx, buf, start, end, jnum); if (ret) { if (ret > 1) { fprintf(stderr, "Syntax error:line=%d:ret=%d:%s\n", line, ret, buf); @@ -1871,7 +1871,6 @@ make_task_table(grn_ctx *ctx, int jobnum) { int i, j; int tid = 0; - FILE *fp; grn_obj *commands = NULL; for (i = 0; i < jobnum; i++) { @@ -1886,6 +1885,7 @@ make_task_table(grn_ctx *ctx, int jobnum) } for (j = 0; j < grntest_job[i].concurrency; j++) { if (j == 0) { + grn_file_reader *reader; grn_obj line; GRN_TEXT_INIT(&line, 0); commands = grn_obj_open(ctx, GRN_PVECTOR, 0, GRN_VOID); @@ -1893,13 +1893,13 @@ make_task_table(grn_ctx *ctx, int jobnum) fprintf(stderr, "Cannot alloc commands\n"); error_exit(ctx, 1); } - fp = fopen(grntest_job[i].commandfile, "r"); - if (!fp) { + reader = grn_file_reader_open(ctx, grntest_job[i].commandfile); + if (!reader) { fprintf(stderr, "Cannot alloc commandfile:%s\n", grntest_job[i].commandfile); error_exit(ctx, 1); } - while (grn_text_fgets(ctx, &line, fp) == GRN_SUCCESS) { + while (grn_file_reader_read_line(ctx, reader, &line) == GRN_SUCCESS) { grn_obj *command; if (GRN_TEXT_VALUE(&line)[GRN_TEXT_LEN(&line) - 1] == '\n') { grn_bulk_truncate(ctx, &line, GRN_TEXT_LEN(&line) - 1); @@ -1924,6 +1924,7 @@ make_task_table(grn_ctx *ctx, int jobnum) GRN_PTR_PUT(ctx, commands, command); GRN_BULK_REWIND(&line); } + grn_file_reader_close(ctx, reader); GRN_OBJ_FIN(ctx, &line); } grntest_task[tid].file = NULL; @@ -2063,12 +2064,7 @@ printf("%d:type =%d:file=%s:con=%d:ntimes=%d\n", i, grntest_job[i].jobtype, } } if (grntest_job[i].inputlog) { - int ret; - ret = fclose(grntest_job[i].inputlog); - if (ret) { - fprintf(stderr, "Cannot close %s\n", grntest_job[i].logfile); - exit(1); - } + grn_file_reader_close(ctx, grntest_job[i].inputlog); } } return qnum; @@ -2081,17 +2077,17 @@ do_script(grn_ctx *ctx, const char *script_file_path) int n_lines = 0; int n_jobs; int n_queries, total_n_queries = 0; - FILE *script_file; + grn_file_reader *script_file; grn_obj line; - script_file = fopen(script_file_path, "r"); + script_file = grn_file_reader_open(ctx, script_file_path); if (script_file == NULL) { fprintf(stderr, "Cannot open script file: <%s>\n", script_file_path); error_exit(ctx, 1); } GRN_TEXT_INIT(&line, 0); - while (grn_text_fgets(ctx, &line, script_file) == GRN_SUCCESS) { + while (grn_file_reader_read_line(ctx, script_file, &line) == GRN_SUCCESS) { if (grntest_sigint) { break; } @@ -2126,7 +2122,7 @@ do_script(grn_ctx *ctx, const char *script_file_path) } grn_obj_unlink(ctx, &line); - fclose(script_file); + grn_file_reader_close(ctx, script_file); return total_n_queries; } @@ -2861,20 +2857,20 @@ get_token(char *line, char *token, int maxlen, char **next) static grn_bool check_script(grn_ctx *ctx, const char *script_file_path) { - FILE *script_file; + grn_file_reader *script_file; grn_obj line; char token[BUF_LEN]; char prev[BUF_LEN]; char *next = NULL; - script_file = fopen(script_file_path, "r"); + script_file = grn_file_reader_open(ctx, script_file_path); if (!script_file) { fprintf(stderr, "Cannot open script file: <%s>\n", script_file_path); return GRN_FALSE; } GRN_TEXT_INIT(&line, 0); - while (grn_text_fgets(ctx, &line, script_file) == GRN_SUCCESS) { + while (grn_file_reader_read_line(ctx, script_file, &line) == GRN_SUCCESS) { GRN_TEXT_VALUE(&line)[GRN_TEXT_LEN(&line) - 1] = '\0'; get_token(GRN_TEXT_VALUE(&line), token, BUF_LEN, &next); grn_strcpy(prev, BUF_LEN, token); @@ -2893,7 +2889,7 @@ check_script(grn_ctx *ctx, const char *script_file_path) } grn_obj_unlink(ctx, &line); - fclose(script_file); + grn_file_reader_close(ctx, script_file); return GRN_TRUE; } -------------- next part -------------- HTML����������������������������... Download