OSDN Git Service

Add thread search from all boards.
authorAkira <akohta001@gmail.com>
Sat, 16 Nov 2013 15:47:14 +0000 (00:47 +0900)
committerAkira <akohta001@gmail.com>
Sat, 16 Nov 2013 15:47:14 +0000 (00:47 +0900)
31 files changed:
Makefile
Makefile.in
README
config.h
config.h.in
configure
configure.ac
help.txt
src/_2ch/_2ch.c
src/_2ch/model_2ch.c
src/_2ch/model_func.c
src/_2ch/parse_string.c
src/_2ch/search_2ch.c [new file with mode: 0644]
src/inc/_2ch/_2ch.h
src/inc/_2ch/model_2ch.h
src/inc/_2ch/search_2ch.h [new file with mode: 0644]
src/inc/config.h
src/inc/env.h
src/inc/net/nt_http.h
src/inc/ui/disp.h
src/inc/ui/disp_string.h
src/inc/utils/text.h
src/main.c
src/net/nt_http.c
src/ui/disp_board_menu.c
src/ui/disp_reslist.c
src/ui/disp_search_thread.c [new file with mode: 0644]
src/ui/disp_string.c
src/ui/disp_threadlist.c
src/utils/nt_conv_char.c
src/utils/text.c

index 3dc08a2..2e190c8 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -37,12 +37,14 @@ OBJS = ${OBJ_DIR}/main.o ${OBJ_DIR}/utils/nt_std_t.o \
     ${OBJ_DIR}/_2ch/_2ch.o \
     ${OBJ_DIR}/_2ch/model_2ch.o \
     ${OBJ_DIR}/_2ch/model_func.o \
+    ${OBJ_DIR}/_2ch/search_2ch.o \
     ${OBJ_DIR}/_2ch/parse_2ch.o \
     ${OBJ_DIR}/_2ch/parse_string.o \
     ${OBJ_DIR}/_2ch/maru_2ch.o \
     ${OBJ_DIR}/ui/disp_board_menu.o \
     ${OBJ_DIR}/ui/disp_threadlist.o \
     ${OBJ_DIR}/ui/disp_reslist.o \
+    ${OBJ_DIR}/ui/disp_search_thread.o \
     ${OBJ_DIR}/ui/disp_win.o \
     ${OBJ_DIR}/ui/disp_editor.o \
     ${OBJ_DIR}/ui/disp_html_result.o \
@@ -56,6 +58,7 @@ INC_FILES = ${INC_DIR}/config.h \
        ${INC_DIR}/_2ch/model_2ch.h \
        ${INC_DIR}/_2ch/maru_2ch.h \
        ${INC_DIR}/_2ch/parse_2ch.h \
+       ${INC_DIR}/_2ch/search_2ch.h \
        ${INC_DIR}/ui/disp.h \
        ${INC_DIR}/ui/disp_win.h \
        ${INC_DIR}/ui/disp_string.h \
@@ -214,6 +217,10 @@ $(OBJ_DIR)/_2ch/parse_2ch.o : ${SRC_DIR}/_2ch/parse_2ch.c ${INC_FILES}
        @ ${SHELL} prepare_proj.sh
        ${CC} ${CFLAGS} ${INCLUDES} -c -o $@ $< 
 
+$(OBJ_DIR)/_2ch/search_2ch.o : ${SRC_DIR}/_2ch/search_2ch.c ${INC_FILES}
+       @ ${SHELL} prepare_proj.sh
+       ${CC} ${CFLAGS} ${INCLUDES} -c -o $@ $< 
+
 $(OBJ_DIR)/_2ch/parse_string.o : ${SRC_DIR}/_2ch/parse_string.c ${INC_FILES}
        @ ${SHELL} prepare_proj.sh
        ${CC} ${CFLAGS} ${INCLUDES} -c -o $@ $< 
@@ -234,6 +241,10 @@ $(OBJ_DIR)/ui/disp_reslist.o : ${SRC_DIR}/ui/disp_reslist.c ${INC_FILES}
        @ ${SHELL} prepare_proj.sh
        ${CC} ${CFLAGS} ${INCLUDES} -c -o $@ $< 
 
+$(OBJ_DIR)/ui/disp_search_thread.o : ${SRC_DIR}/ui/disp_search_thread.c ${INC_FILES}
+       @ ${SHELL} prepare_proj.sh
+       ${CC} ${CFLAGS} ${INCLUDES} -c -o $@ $< 
+
 $(OBJ_DIR)/ui/disp_string.o : ${SRC_DIR}/ui/disp_string.c ${INC_FILES}
        @ ${SHELL} prepare_proj.sh
        ${CC} ${CFLAGS} ${INCLUDES} -c -o $@ $< 
index 25fb461..c101fbd 100644 (file)
@@ -37,12 +37,14 @@ OBJS = ${OBJ_DIR}/main.o ${OBJ_DIR}/utils/nt_std_t.o \
     ${OBJ_DIR}/_2ch/_2ch.o \
     ${OBJ_DIR}/_2ch/model_2ch.o \
     ${OBJ_DIR}/_2ch/model_func.o \
+    ${OBJ_DIR}/_2ch/search_2ch.o \
     ${OBJ_DIR}/_2ch/parse_2ch.o \
     ${OBJ_DIR}/_2ch/parse_string.o \
     ${OBJ_DIR}/_2ch/maru_2ch.o \
     ${OBJ_DIR}/ui/disp_board_menu.o \
     ${OBJ_DIR}/ui/disp_threadlist.o \
     ${OBJ_DIR}/ui/disp_reslist.o \
+    ${OBJ_DIR}/ui/disp_search_thread.o \
     ${OBJ_DIR}/ui/disp_win.o \
     ${OBJ_DIR}/ui/disp_editor.o \
     ${OBJ_DIR}/ui/disp_html_result.o \
@@ -56,6 +58,7 @@ INC_FILES = ${INC_DIR}/config.h \
        ${INC_DIR}/_2ch/model_2ch.h \
        ${INC_DIR}/_2ch/maru_2ch.h \
        ${INC_DIR}/_2ch/parse_2ch.h \
+       ${INC_DIR}/_2ch/search_2ch.h \
        ${INC_DIR}/ui/disp.h \
        ${INC_DIR}/ui/disp_win.h \
        ${INC_DIR}/ui/disp_string.h \
@@ -214,6 +217,10 @@ $(OBJ_DIR)/_2ch/parse_2ch.o : ${SRC_DIR}/_2ch/parse_2ch.c ${INC_FILES}
        @ ${SHELL} prepare_proj.sh
        ${CC} ${CFLAGS} ${INCLUDES} -c -o $@ $< 
 
+$(OBJ_DIR)/_2ch/search_2ch.o : ${SRC_DIR}/_2ch/search_2ch.c ${INC_FILES}
+       @ ${SHELL} prepare_proj.sh
+       ${CC} ${CFLAGS} ${INCLUDES} -c -o $@ $< 
+
 $(OBJ_DIR)/_2ch/parse_string.o : ${SRC_DIR}/_2ch/parse_string.c ${INC_FILES}
        @ ${SHELL} prepare_proj.sh
        ${CC} ${CFLAGS} ${INCLUDES} -c -o $@ $< 
@@ -234,6 +241,10 @@ $(OBJ_DIR)/ui/disp_reslist.o : ${SRC_DIR}/ui/disp_reslist.c ${INC_FILES}
        @ ${SHELL} prepare_proj.sh
        ${CC} ${CFLAGS} ${INCLUDES} -c -o $@ $< 
 
+$(OBJ_DIR)/ui/disp_search_thread.o : ${SRC_DIR}/ui/disp_search_thread.c ${INC_FILES}
+       @ ${SHELL} prepare_proj.sh
+       ${CC} ${CFLAGS} ${INCLUDES} -c -o $@ $< 
+
 $(OBJ_DIR)/ui/disp_string.o : ${SRC_DIR}/ui/disp_string.c ${INC_FILES}
        @ ${SHELL} prepare_proj.sh
        ${CC} ${CFLAGS} ${INCLUDES} -c -o $@ $< 
diff --git a/README b/README
index 7c40777..1e7fccf 100644 (file)
--- a/README
+++ b/README
@@ -1,5 +1,5 @@
 
-    ntch  version 1.0.1.6
+    ntch  version 1.0.1.7
 
     This file is part of ntch.
 
@@ -22,13 +22,13 @@ Linux用 2ch専用ブラウザー
 
 ntch のインストール方法
 
-ダウンロードファイルを使用する場合、適当なディレクトリにntch-1.0.1.5.tgzファイルを解凍します
+ダウンロードファイルを使用する場合、適当なディレクトリにntch-1.0.1.7.tgzファイルを解凍します
 
-tar zxvf ntch-1.0.1.6.tgz
+tar zxvf ntch-1.0.1.7.tgz
 
 作成されたディレクトリに移動します
 
-cd ntch-1.0.1.6
+cd ntch-1.0.1.7
 
 以下のコマンドを実行して、実行ファイルを作成します
 
index 42a742d..a77ab8a 100644 (file)
--- a/config.h
+++ b/config.h
@@ -7,6 +7,9 @@
 /* Define to 1 if you have the <fcntl.h> header file. */
 #define HAVE_FCNTL_H 1
 
+/* Define to 1 if you have the <gdbm-ndbm.h> header file. */
+/* #undef HAVE_GDBM_NDBM_H */
+
 /* Define to 1 if you have the `gethostbyname' function. */
 #define HAVE_GETHOSTBYNAME 1
 
@@ -16,6 +19,9 @@
 /* Define to 1 if you have the `crypto' library (-lcrypto). */
 #define HAVE_LIBCRYPTO 1
 
+/* Define to 1 if you have the `dl' library (-ldl). */
+#define HAVE_LIBDL 1
+
 /* Define to 1 if you have the `gdbm' library (-lgdbm). */
 /* #undef HAVE_LIBGDBM */
 
 /* Define to 1 if you have the `ncursesw' library (-lncursesw). */
 #define HAVE_LIBNCURSESW 1
 
+/* Define to 1 if you have the `pthread' library (-lpthread). */
+#define HAVE_LIBPTHREAD 1
+
+/* Define to 1 if you have the `sqlite3' library (-lsqlite3). */
+#define HAVE_LIBSQLITE3 1
+
 /* Define to 1 if you have the `ssl' library (-lssl). */
 #define HAVE_LIBSSL 1
 
+/* Define to 1 if you have the `z' library (-lz). */
+#define HAVE_LIBZ 1
+
+/* Define to 1 if you have the <limits.h> header file. */
+#define HAVE_LIMITS_H 1
+
 /* Define to 1 if you have the <locale.h> header file. */
 #define HAVE_LOCALE_H 1
 
 /* Define to 1 if you have the `mkdir' function. */
 #define HAVE_MKDIR 1
 
+/* Define to 1 if you have the <ndbm.h> header file. */
+#define HAVE_NDBM_H 1
+
 /* Define to 1 if you have the <netdb.h> header file. */
 #define HAVE_NETDB_H 1
 
+/* Define to 1 if you have the <netinet/in.h> header file. */
+#define HAVE_NETINET_IN_H 1
+
+/* Define to 1 if you have the `regcomp' function. */
+#define HAVE_REGCOMP 1
+
 /* Define to 1 if you have the `setlocale' function. */
 #define HAVE_SETLOCALE 1
 
 /* Define to 1 if you have the `strrchr' function. */
 #define HAVE_STRRCHR 1
 
+/* Define to 1 if you have the `strstr' function. */
+#define HAVE_STRSTR 1
+
 /* Define to 1 if you have the `strtol' function. */
 #define HAVE_STRTOL 1
 
 /* Define to 1 if you have the <wchar.h> header file. */
 #define HAVE_WCHAR_H 1
 
+/* Define to 1 if the system has the type `_Bool'. */
+#define HAVE__BOOL 1
+
 /* Define to the address where bug reports for this package should be sent. */
 #define PACKAGE_BUGREPORT "akohta001@gmail.com"
 
 #define PACKAGE_NAME "ntch"
 
 /* Define to the full name and version of this package. */
-#define PACKAGE_STRING "ntch 1.0.1.6"
+#define PACKAGE_STRING "ntch 1.0.1.7"
 
 /* Define to the one symbol short name of this package. */
 #define PACKAGE_TARNAME "ntch"
 #define PACKAGE_URL "https://sourceforge.jp/projects/ntch/"
 
 /* Define to the version of this package. */
-#define PACKAGE_VERSION "1.0.1.6"
+#define PACKAGE_VERSION "1.0.1.7"
 
 /* Define to 1 if you have the ANSI C header files. */
 #define STDC_HEADERS 1
 
+/* Define to `int' if <sys/types.h> doesn't define. */
+/* #undef gid_t */
+
 /* Define to rpl_malloc if the replacement function should be used. */
 /* #undef malloc */
 
 
 /* Define to `unsigned int' if <sys/types.h> does not define. */
 /* #undef size_t */
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+/* #undef uid_t */
index 5fd7ef6..97784e4 100644 (file)
@@ -6,6 +6,9 @@
 /* Define to 1 if you have the <fcntl.h> header file. */
 #undef HAVE_FCNTL_H
 
+/* Define to 1 if you have the <gdbm-ndbm.h> header file. */
+#undef HAVE_GDBM_NDBM_H
+
 /* Define to 1 if you have the `gethostbyname' function. */
 #undef HAVE_GETHOSTBYNAME
 
@@ -15,6 +18,9 @@
 /* Define to 1 if you have the `crypto' library (-lcrypto). */
 #undef HAVE_LIBCRYPTO
 
+/* Define to 1 if you have the `dl' library (-ldl). */
+#undef HAVE_LIBDL
+
 /* Define to 1 if you have the `gdbm' library (-lgdbm). */
 #undef HAVE_LIBGDBM
 
 /* Define to 1 if you have the `ncursesw' library (-lncursesw). */
 #undef HAVE_LIBNCURSESW
 
+/* Define to 1 if you have the `pthread' library (-lpthread). */
+#undef HAVE_LIBPTHREAD
+
+/* Define to 1 if you have the `sqlite3' library (-lsqlite3). */
+#undef HAVE_LIBSQLITE3
+
 /* Define to 1 if you have the `ssl' library (-lssl). */
 #undef HAVE_LIBSSL
 
+/* Define to 1 if you have the `z' library (-lz). */
+#undef HAVE_LIBZ
+
+/* Define to 1 if you have the <limits.h> header file. */
+#undef HAVE_LIMITS_H
+
 /* Define to 1 if you have the <locale.h> header file. */
 #undef HAVE_LOCALE_H
 
 /* Define to 1 if you have the `mkdir' function. */
 #undef HAVE_MKDIR
 
+/* Define to 1 if you have the <ndbm.h> header file. */
+#undef HAVE_NDBM_H
+
 /* Define to 1 if you have the <netdb.h> header file. */
 #undef HAVE_NETDB_H
 
+/* Define to 1 if you have the <netinet/in.h> header file. */
+#undef HAVE_NETINET_IN_H
+
+/* Define to 1 if you have the `regcomp' function. */
+#undef HAVE_REGCOMP
+
 /* Define to 1 if you have the `setlocale' function. */
 #undef HAVE_SETLOCALE
 
 /* Define to 1 if you have the `strrchr' function. */
 #undef HAVE_STRRCHR
 
+/* Define to 1 if you have the `strstr' function. */
+#undef HAVE_STRSTR
+
 /* Define to 1 if you have the `strtol' function. */
 #undef HAVE_STRTOL
 
 /* Define to 1 if you have the <wchar.h> header file. */
 #undef HAVE_WCHAR_H
 
+/* Define to 1 if the system has the type `_Bool'. */
+#undef HAVE__BOOL
+
 /* Define to the address where bug reports for this package should be sent. */
 #undef PACKAGE_BUGREPORT
 
 /* Define to 1 if you have the ANSI C header files. */
 #undef STDC_HEADERS
 
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef gid_t
+
 /* Define to rpl_malloc if the replacement function should be used. */
 #undef malloc
 
 
 /* Define to `unsigned int' if <sys/types.h> does not define. */
 #undef size_t
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+#undef uid_t
index ba5bc57..14a8454 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for ntch 1.0.1.6.
+# Generated by GNU Autoconf 2.69 for ntch 1.0.1.7.
 #
 # Report bugs to <akohta001@gmail.com>.
 #
@@ -580,8 +580,8 @@ MAKEFLAGS=
 # Identity of this package.
 PACKAGE_NAME='ntch'
 PACKAGE_TARNAME='ntch'
-PACKAGE_VERSION='1.0.1.6'
-PACKAGE_STRING='ntch 1.0.1.6'
+PACKAGE_VERSION='1.0.1.7'
+PACKAGE_STRING='ntch 1.0.1.7'
 PACKAGE_BUGREPORT='akohta001@gmail.com'
 PACKAGE_URL='https://sourceforge.jp/projects/ntch/'
 
@@ -1230,7 +1230,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures ntch 1.0.1.6 to adapt to many kinds of systems.
+\`configure' configures ntch 1.0.1.7 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1291,7 +1291,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of ntch 1.0.1.6:";;
+     short | recursive ) echo "Configuration of ntch 1.0.1.7:";;
    esac
   cat <<\_ACEOF
 
@@ -1372,7 +1372,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-ntch configure 1.0.1.6
+ntch configure 1.0.1.7
 generated by GNU Autoconf 2.69
 
 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1795,7 +1795,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by ntch $as_me 1.0.1.6, which was
+It was created by ntch $as_me 1.0.1.7, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   $ $0 $@
@@ -3911,7 +3911,7 @@ fi
 done
 
 
-for ac_header in arpa/inet.h fcntl.h limits.h locale.h memory.h netdb.h netinet/in.h stdlib.h string.h sys/socket.h unistd.h wchar.h
+for ac_header in arpa/inet.h fcntl.h limits.h locale.h memory.h netdb.h netinet/in.h stdlib.h string.h sys/socket.h unistd.h wchar.h ndbm.h gdbm-ndbm.h
 do :
   as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh`
 ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
@@ -4752,7 +4752,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by ntch $as_me 1.0.1.6, which was
+This file was extended by ntch $as_me 1.0.1.7, which was
 generated by GNU Autoconf 2.69.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -4819,7 +4819,7 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
-ntch config.status 1.0.1.6
+ntch config.status 1.0.1.7
 configured by $0, generated by GNU Autoconf 2.69,
   with options \\"\$ac_cs_config\\"
 
index 9269635..626f2da 100644 (file)
@@ -2,7 +2,7 @@
 # Process this file with autoconf to produce a configure script.
 
 AC_PREREQ([2.69])
-AC_INIT([ntch], [1.0.1.6], [akohta001@gmail.com],[ntch],[https://sourceforge.jp/projects/ntch/])
+AC_INIT([ntch], [1.0.1.7], [akohta001@gmail.com],[ntch],[https://sourceforge.jp/projects/ntch/])
 AC_CONFIG_SRCDIR([src/main.c])
 AC_CONFIG_HEADERS([config.h])
 
@@ -23,7 +23,7 @@ AC_CHECK_LIB([ssl], [SSL_library_init])
 AC_CHECK_LIB([z], [inflate])
 
 # Checks for header files.
-AC_CHECK_HEADERS([arpa/inet.h fcntl.h limits.h locale.h memory.h netdb.h netinet/in.h stdlib.h string.h sys/socket.h unistd.h wchar.h])
+AC_CHECK_HEADERS([arpa/inet.h fcntl.h limits.h locale.h memory.h netdb.h netinet/in.h stdlib.h string.h sys/socket.h unistd.h wchar.h ndbm.h gdbm-ndbm.h])
 
 # Checks for typedefs, structures, and compiler characteristics.
 AC_TYPE_PID_T
index 653cfec..9db8a31 100644 (file)
--- a/help.txt
+++ b/help.txt
@@ -1,5 +1,5 @@
 
-    ntch  version 1.0.1.6
+    ntch  version 1.0.1.7
 
     This file is part of ntch.
 
@@ -46,6 +46,10 @@ Linux用 2ch専用ブラウザー
     f   ページダウン
     b   ページアップ
     z   画面リフレッシュ
+    :search :se [検索文字列] 全板検索
+            指定された文字列をキーにして板全体からスレッドを検索します
+            文字列の指定はオプションで、未指定時には空の全板検索画面に
+            遷移します
 
 板メニュー
     h   左カラムへ移動
@@ -120,4 +124,3 @@ Linux用 2ch専用ブラウザー
                     標準関数の正規表現が使用できます
     :n :new 新規取得スレにジャンプ
 
-
index b8a6ff5..4f0173e 100644 (file)
@@ -72,7 +72,7 @@ BOOL nt_init_board_menu()
        }
 
 
-       if(!nt_http_get(url, outp, NULL, NULL, NULL, FALSE)){
+       if(!nt_http_get(url, outp, NULL, NULL, NULL, FALSE, FALSE)){
                free(outp);
                return FALSE;
        }
@@ -118,7 +118,7 @@ BOOL nt_init_board_menu()
        return TRUE;
 }
 
-BOOL nt_read_thread(nt_2ch_model_tp modelp)
+BOOL nt_read_thread(nt_2ch_selected_item_tp selectp)
 {
        wchar_t url[1024];
        wchar_t referer[1024];
@@ -140,15 +140,15 @@ BOOL nt_read_thread(nt_2ch_model_tp modelp)
        memset(s_dst, '\0', sizeof(s_dst));
 
 
-       if(!modelp->selected_categoryp)
+       if(!selectp->selected_categoryp)
                return FALSE;
-       if(!modelp->selected_boardp)
+       if(!selectp->selected_boardp)
                return FALSE;
-       if(!modelp->selected_threadp)
+       if(!selectp->selected_threadp)
                return FALSE;
 
-       boardp = modelp->selected_boardp;
-       threadp = modelp->selected_threadp;
+       boardp = selectp->selected_boardp;
+       threadp = selectp->selected_threadp;
        file_name = threadp->file_name;
 
        wcscpy(url, boardp->address);
@@ -189,13 +189,13 @@ BOOL nt_read_thread(nt_2ch_model_tp modelp)
                return  FALSE;
        }
 
-       if(!nt_http_get(s_src, outp, s_dst, NULL, NULL, TRUE)){
+       if(!nt_http_get(s_src, outp, s_dst, NULL, NULL, TRUE, FALSE)){
                if(!set_offlaw_address(s_src, sizeof(s_src),
                                server_name, board_name, file_name)){
                        free(outp);
                        return FALSE;
                }
-               if(!nt_http_get(s_src, outp, s_dst, NULL, NULL, FALSE)){
+               if(!nt_http_get(s_src, outp, s_dst, NULL, NULL, FALSE, FALSE)){
                        free(outp);
                        return FALSE;
                }
@@ -314,7 +314,7 @@ wchar_t* nt_read_thread_title(nt_board_tp boardp,
        return title;
 }
 
-BOOL nt_read_board(nt_2ch_model_tp modelp)
+BOOL nt_read_board(nt_2ch_selected_item_tp selectp)
 {
        wchar_t *address;
        char data[256+1];
@@ -331,12 +331,12 @@ BOOL nt_read_board(nt_2ch_model_tp modelp)
        memset(s_src, '\0', S_SIZE);
        memset(s_dst, '\0', S_SIZE*sizeof(wchar_t));
 
-       if(!modelp->selected_categoryp)
+       if(!selectp->selected_categoryp)
                return FALSE;
-       if(!modelp->selected_boardp)
+       if(!selectp->selected_boardp)
                return FALSE;
 
-       boardp = modelp->selected_boardp;
+       boardp = selectp->selected_boardp;
        nt_board_children_free(boardp);
        address = boardp->address;
        assert(address);
@@ -354,7 +354,7 @@ BOOL nt_read_board(nt_2ch_model_tp modelp)
                return  FALSE;
        }
 
-       if(!nt_http_get(data, outp, URL_2CH_BOARDMENU, NULL, NULL, FALSE)){
+       if(!nt_http_get(data, outp, URL_2CH_BOARDMENU, NULL, NULL, FALSE, FALSE)){
                free(outp);
                return FALSE;
        }
@@ -398,7 +398,7 @@ BOOL nt_read_board(nt_2ch_model_tp modelp)
        return TRUE;
 }
 
-BOOL nt_write_msg(nt_2ch_model_tp modelp, nt_write_data_tp writep,
+BOOL nt_write_msg(nt_2ch_selected_item_tp selectp, nt_write_data_tp writep,
                        nt_cookie_tp cookiep, nt_maru_2ch_tp marup)
 {
        wchar_t url[1024];      
@@ -421,17 +421,15 @@ BOOL nt_write_msg(nt_2ch_model_tp modelp, nt_write_data_tp writep,
        memset(s_dst,   '\0',   sizeof(s_dst));
        memset(post_data,       '\0',   sizeof(post_data));
 
-       assert(modelp);
-
-       if(!modelp->selected_categoryp)
+       if(!selectp->selected_categoryp)
                return  FALSE;
-       if(!modelp->selected_boardp)
+       if(!selectp->selected_boardp)
                return  FALSE;
-       if(!modelp->selected_threadp)
+       if(!selectp->selected_threadp)
                return  FALSE;
 
-       boardp = modelp->selected_boardp;
-       threadp = modelp->selected_threadp;
+       boardp = selectp->selected_boardp;
+       threadp = selectp->selected_threadp;
        file_name = threadp->file_name;
 
        if(!nt_parse_server_name_and_board_name(boardp->address,
index 09427f2..83ec583 100644 (file)
 #include "html/html_string.h"
 #include "_2ch/model_2ch.h"
 
-extern void nt_set_selected_board(nt_2ch_model_tp modelp,
+extern void nt_set_selected_board(nt_2ch_selected_item_tp selectp,
          nt_category_tp categoryp, nt_board_tp boardp)
 {
-       assert(modelp);
+       assert(selectp);
        assert(categoryp);
        assert(boardp);
 
-       modelp->selected_categoryp = categoryp;
-       modelp->selected_boardp = boardp;
-       modelp->selected_threadp = NULL;
+       selectp->selected_categoryp = categoryp;
+       selectp->selected_boardp = boardp;
+       selectp->selected_threadp = NULL;
 }
 
-extern void nt_set_selected_thread(nt_2ch_model_tp modelp,
+extern void nt_set_selected_thread(nt_2ch_selected_item_tp selectp,
         nt_thread_tp threadp)
 {
-       assert(modelp);
+       assert(selectp);
        assert(threadp);
 
-       modelp->selected_threadp = threadp;
+       selectp->selected_threadp = threadp;
 }
 
 nt_2ch_model_tp nt_2ch_model_alloc()
index faf6758..30d0055 100644 (file)
 #include "utils/nt_std_t.h"
 #include "_2ch/model_2ch.h"
 
+static BOOL address_match(const wchar_t *address, const wchar_t *param);
 
+nt_board_tp nt_get_board_by_name(
+               nt_2ch_model_tp modelp, const wchar_t *board_name,
+               nt_category_tp *categorypp)
+{
+       nt_link_tp cate_list, board_list;
+       nt_link_tp clinkp, blinkp;
+       nt_category_tp catep;
+       nt_board_tp boardp;
+       
+       assert(modelp);
+       cate_list = modelp->categorylistp;
+       if(!cate_list)
+               return NULL;
+       
+       clinkp = cate_list;
+       do{
+               catep = (nt_category_tp)clinkp->data;
+               board_list = catep->boardlistp;
+               blinkp = board_list;
+               if(blinkp){
+                       do{
+                               boardp = (nt_board_tp)blinkp->data;
+                               if(0 == wcscmp(boardp->name, board_name)){
+                                       *categorypp = catep;
+                                       return boardp;
+                               }
+                               blinkp = blinkp->next;
+                       }while(blinkp != board_list);
+               }
+               clinkp = clinkp->next;
+       }while(clinkp != cate_list);
+       return NULL;
+}
+
+nt_board_tp nt_get_board_by_address_match(
+               nt_2ch_model_tp modelp, const wchar_t *param)
+{
+       nt_link_tp cate_list, board_list;
+       nt_link_tp clinkp, blinkp;
+       nt_category_tp catep;
+       nt_board_tp boardp;
+       
+       assert(modelp);
+       cate_list = modelp->categorylistp;
+       if(!cate_list)
+               return NULL;
+       
+       clinkp = cate_list;
+       do{
+               catep = (nt_category_tp)clinkp->data;
+               board_list = catep->boardlistp;
+               blinkp = board_list;
+               if(blinkp){
+                       do{
+                               boardp = (nt_board_tp)blinkp->data;
+                               if(address_match(boardp->address, param))
+                                       return boardp;
+                               blinkp = blinkp->next;
+                       }while(blinkp != board_list);
+               }
+               clinkp = clinkp->next;
+       }while(clinkp != cate_list);
+       return NULL;
+}
+
+static BOOL address_match(const wchar_t *address, const wchar_t *param)
+{
+       wchar_t *cptr;
+       assert(address);
+       
+       cptr = wcsstr(address, L"http://");
+       if(!cptr)
+               return FALSE;
+       
+       cptr = wcsstr(cptr, L"/");
+       if(!cptr)
+               return FALSE;
+       cptr = wcsstr(cptr, param);
+       return (cptr == NULL) ? FALSE : TRUE;
+}
 nt_thread_tp nt_get_thread_by_seq_no(
                nt_link_tp thread_list, int seq_no)
 {
@@ -59,3 +140,4 @@ nt_thread_tp nt_get_thread_by_dat_name(
 
        return NULL;
 }
+
index 2add940..49e608a 100644 (file)
@@ -84,17 +84,20 @@ wchar_t* nt_w_format_number_list (nt_link_tp num_listp)
                }else if(num == prev_num+1){
                        if(s_num < 0)
                                s_num = prev_num;
-               }else{
+               }else if(prev_num != -1){
                        if(s_num < 0){
                                if(len == 0)
-                                       ret = swprintf(buf, buf_size, L"%d", num);
+                                       ret = swprintf(buf, buf_size, L"%d", prev_num);
                                else
-                                       ret = swprintf(buf+len, buf_size-len, L",%d", num);
+                                       ret = swprintf(buf+len, buf_size-len, L",%d", prev_num);
                        }else{
                                if(len == 0)
-                                       ret = swprintf(buf, buf_size, L"%d-%d", num);
+                                       ret = swprintf(buf, buf_size, 
+                                                               L"%d-%d", s_num, prev_num);
                                else
-                                       ret = swprintf(buf+len, buf_size-len, L",%d-%d", num);
+                                       ret = swprintf(buf+len, buf_size-len, 
+                                                               L",%d-%d", s_num, prev_num);
+                               s_num = -1;
                        }
                        if(ret < 0){
                                free(buf);
@@ -108,9 +111,28 @@ wchar_t* nt_w_format_number_list (nt_link_tp num_listp)
                                buf_size += delta;
                        }
                }
+               prev_num = num;
                linkp = linkp->next;
        }while(linkp != num_listp);
-       
+       if(prev_num != -1){
+               if(s_num < 0){
+                       if(len == 0)
+                               ret = swprintf(buf, buf_size, L"%d", prev_num);
+                       else
+                               ret = swprintf(buf+len, buf_size-len, L",%d", prev_num);
+               }else{
+                       if(len == 0)
+                               ret = swprintf(buf, buf_size, 
+                                                       L"%d-%d", s_num, prev_num);
+                       else
+                               ret = swprintf(buf+len, buf_size-len, 
+                                                       L",%d-%d", s_num, prev_num);
+               }
+               if(ret < 0){
+                       free(buf);
+                       return NULL;
+               }
+       }
        return buf;
 }
 
diff --git a/src/_2ch/search_2ch.c b/src/_2ch/search_2ch.c
new file mode 100644 (file)
index 0000000..045bceb
--- /dev/null
@@ -0,0 +1,260 @@
+/* Copyright 2013 Akira Ohta (akohta001@gmail.com)
+    This file is part of ntch.
+
+    The ntch is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    The ntch 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 General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with ntch.  If not, see <http://www.gnu.org/licenses/>.
+    
+*/
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <string.h>
+#include <wchar.h>
+#include <assert.h>
+#include <iconv.h>
+
+#include "env.h"
+#include "utils/nt_std_t.h"
+#include "utils/text.h"
+#include "utils/nt_conv_char.h"
+#include "_2ch/model_2ch.h"
+#include "_2ch/search_2ch.h"
+#include "net/nt_http.h"
+
+#define NT_SEARCH_URL_REFERER "http://find.2ch.net/"
+#define NT_SEARCH_URL "http://find.2ch.net/?STR=%s&SCEND=A&SORT=MODIFIED&COUNT=50&TYPE=TITLE&BBS=ALL"
+
+static nt_searched_thread_tp parse_searched_thread(
+                       nt_2ch_model_tp modelp, wchar_t *line);
+
+BOOL nt_get_search_text(const char *in_text, char** out_text)
+{
+       const char *start, *end;
+       int len;
+       char *cptr;
+       
+       if(!nt_strtok(in_text, ' ', &start, &end))
+               return FALSE;
+       
+       len = end - start;
+       if(len <= 0)
+               return FALSE;
+       
+       if(0 != strncmp(NT_COMMAND1_SEARCH_1, start, len) &&
+                       0 != strncmp(NT_COMMAND1_SEARCH_2, start, len))
+               return FALSE;
+       if(0 < strlen(end)){
+               cptr = nt_trim(end);
+               if(!cptr)
+                       return FALSE;
+               *out_text = cptr;
+       }else{
+               *out_text = NULL;
+       }
+       return TRUE;
+}
+
+nt_link_tp nt_search_all_board(nt_2ch_model_tp modelp, 
+                       const char *search_text, const wchar_t** error_msg)
+{
+       char *url;
+       
+       FILE *tmp_fp;
+       pid_t pid;
+       char fname[512];
+       nt_link_tp linkp, result_list;
+       char buf[1024];
+       char buf2[512];
+       wchar_t wc[1024];
+       iconv_t icd;
+       nt_searched_thread_tp threadp;
+       //int len, ret;
+       
+       assert(error_msg);
+       
+       result_list = NULL;
+       *error_msg = NULL;
+       
+       if(!search_text || strlen(search_text) == 0){
+               *error_msg = L"検索文字列が指定されていません";
+               return NULL;
+       }
+       
+       icd =   iconv_open("EUC-JP", "UTF-8");
+       if(((iconv_t)-1) == icd){
+               *error_msg = L"文字コードの変換に失敗しました";
+               return NULL;
+       }
+       if(!nt_conv_local2sjis(icd, search_text, buf, sizeof(buf))){
+               *error_msg = L"文字コードの変換に失敗しました";
+               return NULL;
+       }
+       iconv_close(icd);
+       
+       if(!url_encode(buf, buf2, sizeof(buf2))){
+               *error_msg = L"URLエンコードに失敗しました";
+               return NULL;
+       }
+       
+       pid = getpid();
+
+       sprintf(fname, "%s/msg%d.tmp", LOG_PATH, pid);
+       tmp_fp = fopen(fname, "w");
+       if(!tmp_fp){
+               *error_msg = L"テンポラリファイルの作成に失敗しました";
+               return NULL;
+       }
+       fclose(tmp_fp);
+       
+       url = malloc(strlen(NT_SEARCH_URL) + strlen(buf2) + 1);
+       if(!url){
+               *error_msg = L"メモリーエラー";
+               return NULL;
+       }
+       
+       sprintf(url, NT_SEARCH_URL, buf2);
+       
+       if(!nt_http_get(url, fname, NT_SEARCH_URL_REFERER,
+                       NULL, NULL, FALSE, TRUE)){
+               *error_msg = L"ネットワーク接続に失敗しました";
+               free(url);
+               return NULL;
+       }
+       
+       tmp_fp = fopen(fname, "r");
+       if(!tmp_fp){
+               *error_msg = L"テンポラリファイルの作成に失敗しました";
+               free(url);
+               return NULL;
+       }
+       
+       icd =   iconv_open("wchar_t","EUC-JP");
+       if(((iconv_t)-1) == icd){
+               *error_msg = L"文字コードの変換に失敗しました";
+               goto ERROR_TRAP;
+       }
+       while(fgets(buf, sizeof(buf), tmp_fp)){
+               if(!nt_conv_sjis2wc(icd, buf, wc, 
+                                       sizeof(wc)*sizeof(wchar_t))){
+                       //*error_msg = L"文字コードの変換に失敗しました";
+                       //iconv_close(icd);
+                       //goto ERROR_TRAP;
+               }else{
+                       threadp = parse_searched_thread(modelp, wc);
+                       if(threadp){
+                               linkp = nt_link_add_data(result_list, threadp);
+                               if(!result_list)
+                                       result_list = linkp;
+                       }
+               }
+       }
+       iconv_close(icd);
+ERROR_TRAP:
+       fclose(tmp_fp);
+       unlink(fname);
+       free(url);
+       return result_list;
+}
+
+               
+static nt_searched_thread_tp parse_searched_thread(
+                       nt_2ch_model_tp modelp, wchar_t *line)
+{
+       nt_searched_thread_tp threadp;
+       nt_board_tp boardp;
+       wchar_t *cptr, *cptr2;
+       wchar_t *board_name, *dat, *title;
+       int len1, len2, len3;
+       
+       assert(line);
+       cptr = wcsstr(line, L"<dt><a href=\"");
+       if(!cptr)
+               return NULL;
+       cptr += wcslen(L"<dt><a href=\"");
+       
+       cptr = wcsstr(cptr, L"test/read.cgi/");
+       if(!cptr)
+               return NULL;
+       cptr += wcslen(L"test/read.cgi/");
+       
+       cptr2 = wcsstr(cptr, L"/");
+       if(!cptr2)
+               return NULL;
+       *cptr2 = L'\0';
+       cptr2++;
+       
+       boardp = nt_get_board_by_address_match(modelp, cptr);
+       if(!boardp){
+               return NULL;
+       }
+       board_name = boardp->name;
+       
+       cptr = wcsstr(cptr2, L"/");
+       if(!cptr)
+               return NULL;
+       *cptr = L'\0';
+       cptr++;
+       
+       dat = cptr2;
+       
+       cptr2 = wcsstr(cptr, L">");
+       if(!cptr2)
+               return NULL;
+       cptr2++;
+       
+       cptr = wcsstr(cptr2, L"</a>");
+       if(!cptr)
+               return NULL;
+       *cptr = L'\0';
+       
+       title = cptr2;
+       
+       threadp = malloc(sizeof(nt_searched_thread_t));
+       if(!threadp)
+               return NULL;
+               
+       len1 = wcslen(board_name)+1;
+       len2 = wcslen(dat)+5;
+       len3 = wcslen(title)+1;
+       
+       threadp->board_name = malloc((len1 + len2 + len3)*sizeof(wchar_t));
+       if(!threadp->board_name){
+               free(threadp);
+               return NULL;
+       }
+       wcscpy(threadp->board_name, board_name);
+
+       threadp->dat_name = threadp->board_name + len1;
+       wcscpy(threadp->dat_name, dat);
+       cptr = wcsstr(dat, L".");
+       if(!cptr)
+               wcscat(threadp->dat_name, L".dat");
+
+       threadp->title = threadp->dat_name + len2;
+       wcscpy(threadp->title, title);
+       
+       return threadp;
+}
+
+void free_searched_thread(void *ptr)
+{
+       assert(ptr);
+       nt_searched_thread_tp threadp;
+       threadp = (nt_searched_thread_tp)ptr;
+       free(threadp->board_name);
+       free(threadp);
+}
+
+
+
index 67010b7..6a8de3e 100644 (file)
@@ -22,6 +22,7 @@
 #include "_2ch/model_2ch.h"
 #include "_2ch/maru_2ch.h"
 
+
 extern char *URL_2CH_BOARDMENU;
 
 
@@ -29,9 +30,9 @@ extern nt_2ch_model_tp app_2ch_modelp;
 
 extern BOOL nt_2ch_model_init();
 extern BOOL nt_init_board_menu();
-extern BOOL nt_read_board(nt_2ch_model_tp modelp);
-extern BOOL nt_read_thread(nt_2ch_model_tp modelp);
-extern BOOL nt_write_msg(nt_2ch_model_tp modelp, 
+extern BOOL nt_read_board(nt_2ch_selected_item_tp selectp);
+extern BOOL nt_read_thread(nt_2ch_selected_item_tp selectp);
+extern BOOL nt_write_msg(nt_2ch_selected_item_tp selectp,
                        nt_write_data_tp writep, nt_cookie_tp cookiep, 
                        nt_maru_2ch_tp marup);
 
index f8d78ed..c13f8e6 100644 (file)
@@ -54,12 +54,9 @@ typedef struct tag_nt_res_t{
 
 typedef struct tag_nt_2ch_model_t *nt_2ch_model_tp;
 typedef struct tag_nt_2ch_model_t{
+       
        nt_link_tp categorylistp;
-
-       nt_category_tp selected_categoryp;
-       nt_board_tp selected_boardp;
-       nt_thread_tp selected_threadp;
-
+       
 } nt_2ch_model_t;
 
 typedef struct tag_nt_write_data_t *nt_write_data_tp;
@@ -73,6 +70,15 @@ typedef struct tag_nt_write_data_t
        nt_link_tp cookies;
 } nt_write_data_t;
 
+
+typedef struct tag_nt_2ch_selected_item_t *nt_2ch_selected_item_tp;
+typedef struct tag_nt_2ch_selected_item_t{
+       nt_category_tp selected_categoryp;
+       nt_board_tp selected_boardp;
+       nt_thread_tp selected_threadp;
+}nt_2ch_selected_item_t;
+
+
 extern nt_write_data_tp nt_write_data_alloc();
 extern void nt_write_data_free(nt_write_data_tp ptr);
 
@@ -87,7 +93,10 @@ extern nt_thread_tp nt_thread_alloc(
 extern nt_res_tp nt_res_alloc(nt_thread_tp     threadp, 
                const wchar_t *name, const wchar_t *mail, 
                const wchar_t *misc, const wchar_t *msg);
-
+extern nt_board_tp nt_get_board_by_name(
+               nt_2ch_model_tp modelp, const wchar_t *board_name, nt_category_tp *categorypp);
+extern nt_board_tp nt_get_board_by_address_match(
+               nt_2ch_model_tp modelp, const wchar_t *param);
 extern void nt_2ch_model_free(nt_2ch_model_tp ptr);
 extern void nt_category_free(nt_category_tp ptr);
 extern void nt_board_free(nt_board_tp ptr);
@@ -101,9 +110,10 @@ extern BOOL parse_board_menu(nt_2ch_model_tp modelp,
 extern BOOL parse_board(nt_board_tp boardp, const wchar_t *linep);
 extern BOOL parse_thread(nt_thread_tp boardp, const wchar_t *linep);
 
-extern void nt_set_selected_board(nt_2ch_model_tp modelp,
+extern void nt_set_selected_board(nt_2ch_selected_item_tp selectp,
                nt_category_tp categoryp, nt_board_tp boardp);
-extern void nt_set_selected_thread(nt_2ch_model_tp modelp, nt_thread_tp threadp);
+extern void nt_set_selected_thread(
+               nt_2ch_selected_item_tp selectp, nt_thread_tp threadp);
 
 extern nt_thread_tp nt_get_thread_by_seq_no(
                nt_link_tp thread_list, int seq_no);
diff --git a/src/inc/_2ch/search_2ch.h b/src/inc/_2ch/search_2ch.h
new file mode 100644 (file)
index 0000000..690bbb3
--- /dev/null
@@ -0,0 +1,37 @@
+/* Copyright 2013 Akira Ohta (akohta001@gmail.com)
+    This file is part of ntch.
+
+    The ntch is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    The ntch 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 General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with ntch.  If not, see <http://www.gnu.org/licenses/>.
+    
+*/
+#ifndef _SEARCH_2CH_H_
+#define _SEARCH_2CH_H_
+
+
+typedef struct tag_nt_searched_thread_t *nt_searched_thread_tp;
+typedef struct tag_nt_searched_thread_t{
+       wchar_t *board_name;
+       wchar_t *dat_name;
+       wchar_t *title;
+}nt_searched_thread_t;
+
+extern BOOL nt_get_search_text(const char *in_text, char** out_text);
+extern nt_link_tp nt_search_all_board(nt_2ch_model_tp modelp, 
+                       const char *search_text, const wchar_t **error_msg);
+extern void free_searched_thread(void *ptr);
+
+
+
+
+#endif /* _SEARCH_2CH_H_ */
index 42a742d..a77ab8a 100644 (file)
@@ -7,6 +7,9 @@
 /* Define to 1 if you have the <fcntl.h> header file. */
 #define HAVE_FCNTL_H 1
 
+/* Define to 1 if you have the <gdbm-ndbm.h> header file. */
+/* #undef HAVE_GDBM_NDBM_H */
+
 /* Define to 1 if you have the `gethostbyname' function. */
 #define HAVE_GETHOSTBYNAME 1
 
@@ -16,6 +19,9 @@
 /* Define to 1 if you have the `crypto' library (-lcrypto). */
 #define HAVE_LIBCRYPTO 1
 
+/* Define to 1 if you have the `dl' library (-ldl). */
+#define HAVE_LIBDL 1
+
 /* Define to 1 if you have the `gdbm' library (-lgdbm). */
 /* #undef HAVE_LIBGDBM */
 
 /* Define to 1 if you have the `ncursesw' library (-lncursesw). */
 #define HAVE_LIBNCURSESW 1
 
+/* Define to 1 if you have the `pthread' library (-lpthread). */
+#define HAVE_LIBPTHREAD 1
+
+/* Define to 1 if you have the `sqlite3' library (-lsqlite3). */
+#define HAVE_LIBSQLITE3 1
+
 /* Define to 1 if you have the `ssl' library (-lssl). */
 #define HAVE_LIBSSL 1
 
+/* Define to 1 if you have the `z' library (-lz). */
+#define HAVE_LIBZ 1
+
+/* Define to 1 if you have the <limits.h> header file. */
+#define HAVE_LIMITS_H 1
+
 /* Define to 1 if you have the <locale.h> header file. */
 #define HAVE_LOCALE_H 1
 
 /* Define to 1 if you have the `mkdir' function. */
 #define HAVE_MKDIR 1
 
+/* Define to 1 if you have the <ndbm.h> header file. */
+#define HAVE_NDBM_H 1
+
 /* Define to 1 if you have the <netdb.h> header file. */
 #define HAVE_NETDB_H 1
 
+/* Define to 1 if you have the <netinet/in.h> header file. */
+#define HAVE_NETINET_IN_H 1
+
+/* Define to 1 if you have the `regcomp' function. */
+#define HAVE_REGCOMP 1
+
 /* Define to 1 if you have the `setlocale' function. */
 #define HAVE_SETLOCALE 1
 
 /* Define to 1 if you have the `strrchr' function. */
 #define HAVE_STRRCHR 1
 
+/* Define to 1 if you have the `strstr' function. */
+#define HAVE_STRSTR 1
+
 /* Define to 1 if you have the `strtol' function. */
 #define HAVE_STRTOL 1
 
 /* Define to 1 if you have the <wchar.h> header file. */
 #define HAVE_WCHAR_H 1
 
+/* Define to 1 if the system has the type `_Bool'. */
+#define HAVE__BOOL 1
+
 /* Define to the address where bug reports for this package should be sent. */
 #define PACKAGE_BUGREPORT "akohta001@gmail.com"
 
 #define PACKAGE_NAME "ntch"
 
 /* Define to the full name and version of this package. */
-#define PACKAGE_STRING "ntch 1.0.1.6"
+#define PACKAGE_STRING "ntch 1.0.1.7"
 
 /* Define to the one symbol short name of this package. */
 #define PACKAGE_TARNAME "ntch"
 #define PACKAGE_URL "https://sourceforge.jp/projects/ntch/"
 
 /* Define to the version of this package. */
-#define PACKAGE_VERSION "1.0.1.6"
+#define PACKAGE_VERSION "1.0.1.7"
 
 /* Define to 1 if you have the ANSI C header files. */
 #define STDC_HEADERS 1
 
+/* Define to `int' if <sys/types.h> doesn't define. */
+/* #undef gid_t */
+
 /* Define to rpl_malloc if the replacement function should be used. */
 /* #undef malloc */
 
 
 /* Define to `unsigned int' if <sys/types.h> does not define. */
 /* #undef size_t */
+
+/* Define to `int' if <sys/types.h> doesn't define. */
+/* #undef uid_t */
index a6080ff..b9118c3 100644 (file)
@@ -71,6 +71,8 @@ extern char *MARU_PW;
 #define NT_COMMAND1_TREE_2 "t"
 #define NT_COMMAND1_ID_1 "id"
 #define NT_COMMAND1_ID_2 "i"
+#define NT_COMMAND1_SEARCH_1 "search"
+#define NT_COMMAND1_SEARCH_2 "se"
 
 extern int set_option(int argc, char* argv[]);
 
index fd29907..2a8775c 100644 (file)
@@ -63,7 +63,7 @@ extern BOOL nt_http_post(const char *url,
                nt_link_tp headers, nt_cookie_tp cookiep);
 extern BOOL nt_http_get(const char *url, const char *out_path,
                const char *referer, const char *user_agent, 
-               nt_link_tp headers, BOOL range);
+               nt_link_tp headers, BOOL range, BOOL ignore_cache);
 extern int nt_http_parse_response_header(int readfd,
                nt_http_response_header_tp responsep,
                nt_cookie_tp cookeip, const char *host);
index 7fbd437..eb93c31 100644 (file)
 #ifndef _DISP_H_
 #define _DISP_H_
 #include "ui/disp_win.h"
+#include "_2ch/search_2ch.h"
 
-#define        DISP_STATE_ERROR                (-1)
-#define        DISP_STATE_BOARDMENU    1
-#define        DISP_STATE_THREADTITLE  2
-#define        DISP_STATE_RESLIST              3
-#define        DISP_STATE_EDITOR               4 
-#define        DISP_STATE_HTML_RESULT  5
-#define        DISP_STATE_REFRESH              6
+#define        DISP_STATE_ERROR                        (-1)
+#define        DISP_STATE_BOARDMENU            1
+#define        DISP_STATE_THREADTITLE          2
+#define        DISP_STATE_RESLIST                      3
+#define        DISP_STATE_EDITOR                       4 
+#define        DISP_STATE_HTML_RESULT          5
+#define        DISP_STATE_REFRESH                      6
+#define        DISP_STATE_SEARCH_THREAD        7
 
 
 extern int disp_board_menu(nt_window_tp wp, 
-               nt_2ch_model_tp modelp);
+               nt_2ch_model_tp modelp, nt_2ch_selected_item_tp selectp);
 extern int disp_threadlist(nt_window_tp wp, 
-               nt_2ch_model_tp modelp, void *usr_db_handle);
+               nt_2ch_selected_item_tp selectp, void *usr_db_handle);
 extern int disp_reslist(nt_window_tp wp, 
-               nt_2ch_model_tp modelp, void *usr_db_handle);
+               nt_2ch_selected_item_tp selectp, void *usr_db_handle);
+extern int disp_thread_search(nt_window_tp wp, 
+               int prev_state, nt_link_tp thread_list, 
+               nt_searched_thread_tp *sel_threadpp);
 extern void free_board_menu_ctx(void *ptr);
 extern void init_threadlist_ctx(void *ptr);
 extern void free_threadlist_ctx(void *ptr);
 extern void free_reslist_ctx(void *ptr);
+extern void free_search_thread_ctx(void *ptr);
 extern BOOL disp_editor(nt_write_data_tp writep);
 extern int disp_html_result(nt_write_data_tp writep);
 
index 4a9c068..83a09ff 100644 (file)
 #define _DISP_STRING_H_
 #include <wchar.h>
 
-extern int nt_add_wch(WINDOW *w, wchar_t wc, attr_t attr);
-extern int nt_add_wnch(WINDOW *w, wchar_t wc, 
+extern int nt_add_wch(WINDOW *w, const wchar_t wc, attr_t attr);
+extern int nt_add_wnch(WINDOW *w, const wchar_t wc, 
                                attr_t attr, size_t colmns);
-extern int nt_add_wstr(WINDOW *w, wchar_t *wc, attr_t attr);
-extern int nt_add_wnstr(WINDOW *w, wchar_t *wc, 
+extern int nt_add_wstr(WINDOW *w, const wchar_t *wc, attr_t attr);
+extern int nt_add_wnstr(WINDOW *w, const wchar_t *wc, 
                                attr_t attr, size_t colmns);
 
-extern int nt_get_wc_count_within_colmns(wchar_t *src, size_t colmns);
-extern int nt_get_column_length(const wchar_t *wc);
+extern int nt_get_wc_count_within_colmns(const wchar_t *src, size_t colmns);
+extern int nt_get_column_length(const const wchar_t *wc);
 
 #endif /* _DISP_STRING_H_ */
index 986d26e..3f85c2a 100644 (file)
@@ -28,6 +28,7 @@ extern char *nt_trim2(const char *source, char *buf, size_t buf_len);
 extern wchar_t* nt_w_str_clone(const wchar_t *cptr);
 extern char* nt_str_clone(const char *cptr);
 extern char* nt_substr(const char *cptr, int start, int end);
+extern wchar_t* nt_w_substr(const wchar_t* src, int start, int end);
 extern BOOL nt_strtok(const char *str, char delim, 
                const char** start, const char **end);
 extern wchar_t* nt_w_str_resize(wchar_t *old_src, 
index e6a49b9..fd52cec 100644 (file)
@@ -25,6 +25,7 @@
 #include <locale.h>
 #include <iconv.h>
 #include <netinet/in.h>
+#include <assert.h>
 
 #include "env.h"
 #include "error.h"
@@ -37,6 +38,7 @@
 #include "utils/nt_usr_db.h"
 #include "_2ch/_2ch.h"
 #include "_2ch/maru_2ch.h"
+#include "_2ch/search_2ch.h"
 #include "ui/disp.h"
 #include "ui/disp_win.h"
 #include "ui/disp_string.h"
 
 static int draw_title(WINDOW *wp, wchar_t *title, attr_t attr);
 static BOOL DoLoop(WINDOW *scrp, void *db_handle);
-static void print_error(WINDOW *wp, wchar_t *msg);
+static void print_error(WINDOW *wp, const wchar_t *msg);
+static BOOL set_sel_item(nt_2ch_model_tp modelp,
+                       nt_2ch_selected_item_tp sel_itemp, 
+                       nt_searched_thread_tp sel_threadp, const wchar_t** errorpp);
 
 
 int main(int argc, char *argv[])
@@ -117,14 +122,21 @@ static BOOL DoLoop(WINDOW *scrp, void *db_handle)
        nt_window_tp bwinp = NULL;
        nt_window_tp twinp = NULL;
        nt_window_tp rwinp = NULL;
+       nt_window_tp search_winp = NULL;
        char buf[256];
        wchar_t wch, *title;
-       wchar_t *status_msg = NULL;
+       const wchar_t *status_msg = NULL;
        BOOL result = FALSE;
        nt_write_data_tp writep = NULL;
        nt_maru_2ch_tp marup = NULL;
        nt_cookie_tp cookiep;
-
+       nt_link_tp linkp;
+       char *search;
+       nt_searched_thread_tp sel_threadp;
+       nt_2ch_selected_item_t sel_items;
+       nt_2ch_selected_item_t sel_items_tmp;
+       
+       
        disp_state = DISP_STATE_BOARDMENU; 
        cookiep = nt_load_cookies(USR_COOKIE_PATH);
 
@@ -155,11 +167,11 @@ static BOOL DoLoop(WINDOW *scrp, void *db_handle)
                        draw_title(scrp, L"板一覧", WA_REVERSE);
                        if(!nt_disp_win_move(scrp, bwinp, LINES-1, COLS, 1, 0))
                                goto END_WHILE;
-                       state = disp_board_menu(bwinp, app_2ch_modelp);
+                       state = disp_board_menu(bwinp, app_2ch_modelp, &sel_items);
                        if(DISP_STATE_ERROR == state){
                                goto END_WHILE;
                        }else if(DISP_STATE_THREADTITLE == state){
-                               if(nt_read_board(app_2ch_modelp)){
+                               if(nt_read_board(&sel_items)){
                                        disp_state = state;
                                        if(twinp->data){
                                                free_threadlist_ctx(twinp->data);
@@ -170,26 +182,30 @@ static BOOL DoLoop(WINDOW *scrp, void *db_handle)
                                }else{
                                        print_error(scrp, NT_ERR_MSG_COUDLNOT_READ_BOARD);
                                }
+                       }else if(state == DISP_STATE_SEARCH_THREAD){
+                               state = DISP_STATE_BOARDMENU;
+                               disp_state = DISP_STATE_SEARCH_THREAD;
+                               ch = NT_KEY_NONE;
+                               continue;
                        }
                        break;
                case DISP_STATE_THREADTITLE:
                        werase(twinp->wp);
                        twinp->key = ch;
                        twinp->status_msg = NULL;
-                       title = app_2ch_modelp->selected_boardp->name;
+                       title = sel_items.selected_boardp->name;
                        draw_title(scrp, title, WA_REVERSE);
                        if(!nt_disp_win_move(scrp, twinp, LINES-1, COLS, 1, 0))
                                goto END_WHILE;
-                       state = disp_threadlist(twinp, app_2ch_modelp, db_handle);
+                       state = disp_threadlist(twinp, &sel_items, db_handle);
                        if(DISP_STATE_ERROR == state){
                                goto END_WHILE;
-                       }else {
-                               if(DISP_STATE_BOARDMENU == state){
+                       }else if(DISP_STATE_BOARDMENU == state){
                                        disp_state = state;
                                        ch = NT_KEY_NONE;
                                        continue;
-                               }else if(DISP_STATE_REFRESH == state){
-                                       if(nt_read_board(app_2ch_modelp)){
+                       }else if(DISP_STATE_REFRESH == state){
+                                       if(nt_read_board(&sel_items)){
                                                if(twinp->data){
                                                        free_threadlist_ctx(twinp->data);
                                                        twinp->data = NULL;
@@ -200,8 +216,8 @@ static BOOL DoLoop(WINDOW *scrp, void *db_handle)
                                        }else{
                                                status_msg = NT_ERR_MSG_COUDLNOT_READ_BOARD;
                                        }
-                               }else if(DISP_STATE_RESLIST == state){
-                                       if(!nt_read_thread(app_2ch_modelp)){
+                       }else if(DISP_STATE_RESLIST == state){
+                                       if(!nt_read_thread(&sel_items)){
                                                wclear(scrp);
                                                ch = NT_KEY_NONE;
                                                continue;
@@ -216,25 +232,29 @@ static BOOL DoLoop(WINDOW *scrp, void *db_handle)
                                        disp_state = state;
                                        ch = NT_KEY_NONE;
                                        continue;
-                               }else{
+                       }else if(DISP_STATE_SEARCH_THREAD == state){
+                               state = DISP_STATE_THREADTITLE;
+                               disp_state = DISP_STATE_SEARCH_THREAD;
+                               ch = NT_KEY_NONE;
+                               continue;
+                       }else{
                                        status_msg = twinp->status_msg;
-                               }
                        }
                        break;
                case DISP_STATE_RESLIST:
                        werase(rwinp->wp);
-                       title = app_2ch_modelp->selected_threadp->name;
+                       title = sel_items.selected_threadp->name;
                        num = draw_title(scrp, title, WA_REVERSE);
                        if(!nt_disp_win_move(scrp, rwinp, 
                                                LINES - num, COLS, num, 0))
                                goto END_WHILE;
                        rwinp->key = ch;
-                       state = disp_reslist(rwinp, app_2ch_modelp, db_handle);
+                       state = disp_reslist(rwinp, &sel_items, db_handle);
                        if(DISP_STATE_ERROR == state){
                                goto END_WHILE;
                        }else if(state == DISP_STATE_REFRESH){
                                        ch = NT_KEY_NONE;
-                                       if(!nt_read_thread(app_2ch_modelp)){
+                                       if(!nt_read_thread(&sel_items)){
                                                status_msg = NT_ERR_MSG_REFRESH_THREAD_FAILED;
                                                wclear(scrp);
                                                continue;
@@ -246,6 +266,11 @@ static BOOL DoLoop(WINDOW *scrp, void *db_handle)
                                        status_msg = NT_INFO_REFRESH_THREAD_SUCCESS;
                                        wclear(scrp);
                                        continue;
+                       }else if(state == DISP_STATE_SEARCH_THREAD){
+                               state = DISP_STATE_RESLIST;
+                               disp_state = DISP_STATE_SEARCH_THREAD;
+                               ch = NT_KEY_NONE;
+                               continue;
                        }else if(state != DISP_STATE_RESLIST){
                                disp_state = state;
                                ch = NT_KEY_NONE;
@@ -263,7 +288,7 @@ static BOOL DoLoop(WINDOW *scrp, void *db_handle)
                        if(disp_editor(writep)){
                                if(marup && !marup->sid)
                                        get_session_id(marup);
-                               if(nt_write_msg(app_2ch_modelp
+                               if(nt_write_msg(&sel_items
                                                writep, cookiep, marup)){
                                        disp_state = DISP_STATE_HTML_RESULT;
                                        continue;
@@ -275,17 +300,17 @@ static BOOL DoLoop(WINDOW *scrp, void *db_handle)
                case DISP_STATE_HTML_RESULT:
                        nresult = disp_html_result(writep);
                        if(0 == nresult){
-                               if(!nt_read_thread(app_2ch_modelp))
+                               if(!nt_read_thread(&sel_items))
                                        break;
                                if(rwinp->data){
                                        free_reslist_ctx(rwinp->data);
                                        rwinp->data = NULL;
                                }
                        }else if(1 == nresult){
-                               if(nt_write_msg(app_2ch_modelp
+                               if(nt_write_msg(&sel_items
                                                writep, cookiep, marup)){
                                        if(0 == disp_html_result(writep)){
-                                               if(!nt_read_thread(app_2ch_modelp))
+                                               if(!nt_read_thread(&sel_items))
                                                        break;
                                                if(rwinp->data){
                                                        free_reslist_ctx(rwinp->data);
@@ -299,6 +324,46 @@ static BOOL DoLoop(WINDOW *scrp, void *db_handle)
                        status_msg = writep->status_msg;
                        wclear(scrp);
                        continue;
+               case DISP_STATE_SEARCH_THREAD:
+                       draw_title(scrp, L"全板検索", WA_REVERSE);
+                       if(!search_winp)
+                               search_winp = nt_disp_win_alloc(
+                                               scrp, LINES-1, COLS, 1, 0, buf);
+                       if(!search_winp)
+                               goto END_WHILE;
+                       search_winp->key = ch;
+                       linkp = NULL;
+                       if(nt_get_search_text(buf, &search)){
+                               if(search){
+                                       linkp = nt_search_all_board(
+                                                       app_2ch_modelp, search, &status_msg);
+                                       free(search);
+                                       buf[0] = '\0';
+                               }
+                       }
+                       disp_state = disp_thread_search(search_winp, 
+                                       state, linkp, &sel_threadp);
+                       ch = NT_KEY_NONE;
+                       if(sel_threadp){
+                               if(set_sel_item(app_2ch_modelp,
+                                               &sel_items_tmp, sel_threadp, &status_msg)){
+                                       disp_state = DISP_STATE_RESLIST;
+                                       sel_items = sel_items_tmp;
+                                       if(rwinp->data){
+                                               free_reslist_ctx(rwinp->data);
+                                               rwinp->data = NULL;
+                                       }
+                                       if(twinp->data){
+                                               free_threadlist_ctx(twinp->data);
+                                               twinp->data = NULL;
+                                       }
+                               }
+                               continue;
+                       }
+                       if(disp_state != DISP_STATE_SEARCH_THREAD){
+                               continue;
+                       }
+                       break;
                default:
                        goto END_WHILE;
                }/* end switch*/
@@ -365,12 +430,65 @@ END_WHILE:
        free_board_menu_ctx(bwinp->data);
        free_threadlist_ctx(twinp->data);
        free_reslist_ctx(rwinp->data);
+       if(search_winp){
+               if(search_winp->data)
+                       free_search_thread_ctx(search_winp->data);
+               nt_disp_win_free(search_winp);
+       }
        nt_disp_win_free(bwinp);
        nt_disp_win_free(twinp);
        nt_disp_win_free(rwinp);
        return result;
 }
 
+static BOOL set_sel_item(nt_2ch_model_tp modelp,
+                       nt_2ch_selected_item_tp sel_itemp, 
+                       nt_searched_thread_tp sel_threadp, const wchar_t** errorpp)
+{
+       nt_category_tp categoryp;
+       nt_board_tp boardp;
+       nt_thread_tp threadp;
+       
+       assert(sel_threadp);
+       assert(sel_threadp->board_name);
+       assert(sel_threadp->dat_name);
+       
+       boardp = nt_get_board_by_name(
+                       modelp, sel_threadp->board_name, &categoryp);
+       if(!boardp || !categoryp){
+               *errorpp = L"板情報が見つかりませんでした";
+               return FALSE;
+       }
+               
+       sel_itemp->selected_categoryp = categoryp;
+       sel_itemp->selected_boardp = boardp;
+       sel_itemp->selected_threadp = NULL;
+       
+       if(!boardp->threadlistp){
+               if(!nt_read_board(sel_itemp) 
+                               || !boardp->threadlistp){
+                       *errorpp = L"板が開けませんでした";
+                       return FALSE;
+               }
+       }
+       threadp = nt_get_thread_by_dat_name(
+                       boardp->threadlistp, sel_threadp->dat_name);
+       if(!threadp){
+               *errorpp = L"スレッド情報が見つかりませんでした";
+               return FALSE;
+       }
+       
+       sel_itemp->selected_threadp = threadp;
+       
+       if(!nt_read_thread(sel_itemp)){
+               *errorpp = L"スレッドが開けませんでした";
+               return FALSE;
+       }
+       
+       return TRUE;
+}
+
+
 static int draw_title(WINDOW *wp, wchar_t *title, attr_t attr)
 {
        move(0,0);
@@ -387,7 +505,7 @@ static int draw_title(WINDOW *wp, wchar_t *title, attr_t attr)
 
 
 
-static void print_error(WINDOW *wp, wchar_t *msg)
+static void print_error(WINDOW *wp, const wchar_t *msg)
 {
        move(LINES-1,0);
        nt_add_wstr(wp, msg, 0);
index 383cfa6..e4c1de8 100644 (file)
@@ -225,7 +225,7 @@ ERROR_TRAP:
 
 BOOL nt_http_get(const char *url, const char *out_path,
                const char *referer, const char *user_agent, 
-               nt_link_tp extend_headers, BOOL range)
+               nt_link_tp extend_headers, BOOL range, BOOL ignore_cache)
 {
        nt_socket_tp socketp;
        int fd = -1, sockfd;
@@ -244,8 +244,10 @@ BOOL nt_http_get(const char *url, const char *out_path,
        nt_http_header_tp headerp = nt_http_init_header(url);
        if(headerp == NULL)
                return FALSE;
-       if(!nt_http_init_header2(headerp, out_path))
-               return FALSE;
+       if(!ignore_cache){
+               if(!nt_http_init_header2(headerp, out_path))
+                       return FALSE;
+       }
 
        strcpy(data, "GET ");
        strcat(data, headerp->param);
@@ -366,7 +368,8 @@ BOOL nt_http_get(const char *url, const char *out_path,
                                }
                        }while(nread > 0);
                }
-               nt_http_save_response_header(out_path, responsep);
+               if(!ignore_cache)
+                       nt_http_save_response_header(out_path, responsep);
                result = TRUE;
                break;
        case 206: /* Partial content */
@@ -393,7 +396,8 @@ BOOL nt_http_get(const char *url, const char *out_path,
                                break;
                        }
                }while(nread > 0);
-               nt_http_save_response_header(out_path, responsep);
+               if(!ignore_cache)
+                       nt_http_save_response_header(out_path, responsep);
                result = TRUE;
                break;
        case 304: /* Not Modified */
@@ -414,7 +418,7 @@ ERROR_TRAP:
        nt_http_free_response_header(responsep);
        if(retry && range)
                return nt_http_get(url, out_path, referer, user_agent, 
-                               extend_headers, FALSE);
+                               extend_headers, FALSE, ignore_cache);
 
        return result;
 }
index 594850b..ccbc450 100644 (file)
@@ -17,6 +17,7 @@
 */
 #include <stdlib.h>
 #include <stdio.h>
+#include <string.h>
 #include <assert.h>
 #include <wchar.h>
 #include <ncursesw/ncurses.h>
 #define SET_F(a,b) ((a) |= (b))
 #define UNSET_F(a,b) ((a) &= (~b))
 
+#define NT_CMD_NONE 0
+#define NT_CMD_SEARCH_THREAD 1
+
+
 typedef struct tag_category_data_t *category_data_tp;
 typedef struct tag_category_data_t{
        int flag;
@@ -65,9 +70,11 @@ static BOOL adjust_scroll_pos2(nt_window_tp wp,
                ctx_board_menu_tp ctxp, category_data_tp  datap);
 static int page_up(nt_window_tp wp, ctx_board_menu_tp ctxp);
 static int page_down(nt_window_tp wp, ctx_board_menu_tp ctxp);
+static int parse_cmd1(const char *param);
 
 
-int disp_board_menu(nt_window_tp wp, nt_2ch_model_tp modelp)
+int disp_board_menu(nt_window_tp wp, 
+               nt_2ch_model_tp modelp, nt_2ch_selected_item_tp selectp)
 {
        int cur_line = 0;
        nt_link_tp clistp;
@@ -78,6 +85,7 @@ int disp_board_menu(nt_window_tp wp, nt_2ch_model_tp modelp)
        int i;
        int offset_y, offset_x;
        BOOL selected = FALSE;
+       int cmd;
 
        wchar_t *cname;
        attr_t attr;
@@ -121,6 +129,13 @@ int disp_board_menu(nt_window_tp wp, nt_2ch_model_tp modelp)
        case KEY_RIGHT:
                selected = TRUE;
                break;
+       case NT_KEY_COMMAND1:
+               assert(wp->cmd_param);
+               cmd = parse_cmd1(wp->cmd_param);
+               switch(cmd){
+               case NT_CMD_SEARCH_THREAD:
+                       return DISP_STATE_SEARCH_THREAD;
+               }
        }
 
        clistp = modelp->categorylistp;
@@ -174,7 +189,7 @@ int disp_board_menu(nt_window_tp wp, nt_2ch_model_tp modelp)
                                        selected, &sel_boardp))
                        return FALSE;
                if(selected && sel_boardp){
-                       nt_set_selected_board(modelp, categoryp, sel_boardp);
+                       nt_set_selected_board(selectp, categoryp, sel_boardp);
                        return DISP_STATE_THREADTITLE;
                }
        }
@@ -451,3 +466,17 @@ static int get_menu_disp_row(ctx_board_menu_tp ctxp)
        return num;
 }
 
+static int parse_cmd1(const char *param)
+{
+       assert(param);
+       if(0 == strncmp(NT_COMMAND1_SEARCH_1,param,
+                       strlen(NT_COMMAND1_SEARCH_1)) ||
+               0 == strncmp(NT_COMMAND1_SEARCH_2,param,
+                       strlen(NT_COMMAND1_SEARCH_2))){
+               return NT_CMD_SEARCH_THREAD;
+       }else{
+               return NT_CMD_NONE;
+       }
+}
+
+
index dc59d9e..8ba10ab 100644 (file)
@@ -39,6 +39,7 @@
 #define NT_CMD_JMP_NEW 2
 #define NT_CMD_TREE 3
 #define NT_CMD_ID 4
+#define NT_CMD_SEARCH_THREAD 5
 
 typedef struct tag_ctx_reslist_t *ctx_reslist_tp;
 typedef struct tag_ctx_reslist_t
@@ -73,7 +74,7 @@ typedef struct tag_res_data_t {
        int id_num;
 }res_data_t;
 
-static ctx_reslist_tp init_context(nt_2ch_model_tp modelp, 
+static ctx_reslist_tp init_context(nt_2ch_selected_item_tp selectp, 
                        void *usr_db_handle);
 static BOOL reslist_clone(nt_thread_tp threadp, ctx_reslist_tp ctxp);
 static void int_ptr_free(void *ptr);
@@ -99,7 +100,7 @@ static int get_id_num(ctx_reslist_tp ctxp, const wchar_t *misc);
 static BOOL set_res_header(ctx_reslist_tp ctxp, res_data_tp res_datap,
                                wchar_t *buf, size_t buf_len);
 
-int disp_reslist(nt_window_tp wp, nt_2ch_model_tp modelp,
+int disp_reslist(nt_window_tp wp, nt_2ch_selected_item_tp selectp,
        void *usr_db_handle)
 {
        ctx_reslist_tp ctxp, child_ctxp;
@@ -128,7 +129,7 @@ int disp_reslist(nt_window_tp wp, nt_2ch_model_tp modelp,
 
        ctxp = (ctx_reslist_tp)wp->data;
        if(!ctxp){
-               ctxp = init_context(modelp, usr_db_handle);
+               ctxp = init_context(selectp, usr_db_handle);
                if(!ctxp)
                        return DISP_STATE_ERROR;
                wp->data = ctxp;
@@ -396,6 +397,8 @@ int disp_reslist(nt_window_tp wp, nt_2ch_model_tp modelp,
                assert(wp->cmd_param);
                cmd = parse_cmd1(wp->cmd_param, &state, &endp);
                switch(cmd){
+               case NT_CMD_SEARCH_THREAD:
+                       return DISP_STATE_SEARCH_THREAD;
                case NT_CMD_WRITE:
                        return state;
                case NT_CMD_JMP_NEW:
@@ -874,19 +877,24 @@ static int parse_cmd1(const char *param, int *statep, const char **end)
        }else if(0 == strncmp(NT_COMMAND1_ID_1, start,len) ||
                0 == strncmp(NT_COMMAND1_ID_2, start,len)){
                return NT_CMD_ID;
+       }else if(0 == strncmp(NT_COMMAND1_SEARCH_1,param,
+                       strlen(NT_COMMAND1_SEARCH_1)) ||
+               0 == strncmp(NT_COMMAND1_SEARCH_2,param,
+                       strlen(NT_COMMAND1_SEARCH_2))){
+               return NT_CMD_SEARCH_THREAD;
        }
        return NT_CMD_NONE;
 }
 
-static ctx_reslist_tp init_context(nt_2ch_model_tp modelp,
+static ctx_reslist_tp init_context(nt_2ch_selected_item_tp selectp,
        void *usr_db_handle)
 {
        ctx_reslist_tp ctxp;
        nt_board_tp boardp;
        nt_thread_tp threadp;
 
-       boardp = modelp->selected_boardp;
-       threadp = modelp->selected_threadp;
+       boardp = selectp->selected_boardp;
+       threadp = selectp->selected_threadp;
        assert(boardp && threadp);
 
        ctxp = (ctx_reslist_tp)calloc(1,sizeof(ctx_reslist_t));
@@ -989,6 +997,10 @@ static BOOL reslist_clone(nt_thread_tp threadp, ctx_reslist_tp ctxp)
                                        &datap->cite_num_list);
                                if(!datap->resp->name || !datap->resp->mail ||
                                                !datap->resp->misc || !datap->resp->msg){
+                                       if(datap->resp->name)free(datap->resp->name);
+                                       if(datap->resp->mail)free(datap->resp->mail);
+                                       if(datap->resp->misc)free(datap->resp->misc);
+                                       if(datap->resp->msg)free(datap->resp->msg);
                                        free(datap->resp);
                                        free(datap);
                                }else{
diff --git a/src/ui/disp_search_thread.c b/src/ui/disp_search_thread.c
new file mode 100644 (file)
index 0000000..f0bf1b2
--- /dev/null
@@ -0,0 +1,217 @@
+/* Copyright 2013 Akira Ohta (akohta001@gmail.com)
+    This file is part of ntch.
+
+    The ntch is free software: you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation, either version 3 of the License, or
+    (at your option) any later version.
+
+    The ntch 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 General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with ntch.  If not, see <http://www.gnu.org/licenses/>.
+    
+*/
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <assert.h>
+#include <wchar.h>
+#include <ncursesw/ncurses.h>
+
+#include "env.h"
+#include "utils/nt_std_t.h"
+#include "_2ch/model_2ch.h"
+#include "_2ch/search_2ch.h"
+#include "ui/disp.h"
+#include "ui/disp_string.h"
+
+
+typedef struct tag_thread_search_ctx_t *thread_search_ctx_tp;
+typedef struct tag_thread_search_ctx_t{
+       int prev_state;
+       int cur_cursor;
+       int scroll_y;
+       int item_count;
+       nt_link_tp thread_list;
+}thread_search_ctx_t;
+
+static thread_search_ctx_tp init_context();
+
+int disp_thread_search(nt_window_tp wp, 
+               int prev_state, nt_link_tp thread_list, 
+               nt_searched_thread_tp *sel_threadpp)
+{
+       thread_search_ctx_tp ctxp;
+       nt_searched_thread_tp threadp;
+       nt_link_tp linkp;
+       attr_t attr;
+       int row, num, ch_num;
+       wchar_t wc[128];
+       
+       *sel_threadpp = NULL;
+
+       ctxp = (thread_search_ctx_tp)wp->data;
+       if(!ctxp){
+               ctxp = init_context();
+               if(!ctxp)
+                       return DISP_STATE_ERROR;
+                       
+               wp->data = ctxp;
+       }
+       if(prev_state != DISP_STATE_SEARCH_THREAD)
+               ctxp->prev_state = prev_state;
+       if(thread_list){
+               if(ctxp->thread_list){
+                       nt_all_link_free(
+                               ctxp->thread_list, free_searched_thread);
+               }
+               ctxp->thread_list = thread_list;
+               ctxp->item_count = nt_link_num(ctxp->thread_list);
+       }
+       switch(wp->key){
+       case NT_KEY_CLOSE:
+       case KEY_LEFT:
+               return ctxp->prev_state;
+       case NT_KEY_SELECT:
+       case KEY_RIGHT:
+               if(!ctxp->thread_list)
+                       break;
+               num = 0;
+               linkp = ctxp->thread_list;
+               do{
+                       if(ctxp->cur_cursor == num){
+                               *sel_threadpp = 
+                                       (nt_searched_thread_tp)linkp->data;
+                               return DISP_STATE_SEARCH_THREAD;
+                       }
+                       num++;
+                       linkp = linkp->next;
+               }while(linkp != ctxp->thread_list);
+               break;
+       case NT_KEY_UP:
+       case KEY_UP:
+               if(ctxp->cur_cursor > 0)
+                       ctxp->cur_cursor--;
+               if(ctxp->scroll_y > (ctxp->cur_cursor*2))
+                       ctxp->scroll_y = (ctxp->cur_cursor*2);
+               break;
+       case NT_KEY_DOWN:
+       case KEY_DOWN:
+               if(ctxp->cur_cursor < (ctxp->item_count-1))
+                       ctxp->cur_cursor++;
+               if((ctxp->scroll_y + wp->lines) <= (ctxp->cur_cursor*2)+1){
+                       ctxp->scroll_y = (ctxp->cur_cursor+1) * 2 - wp->lines;
+               }
+               break;
+       case NT_KEY_PAGEUP:
+       case KEY_PPAGE:
+               ctxp->cur_cursor *= 2;
+               ctxp->cur_cursor -= ctxp->scroll_y;
+               ctxp->scroll_y -= wp->lines;
+               if(ctxp->scroll_y < 0)
+                       ctxp->scroll_y = 0;
+               ctxp->cur_cursor += ctxp->scroll_y;
+               ctxp->cur_cursor /= 2;
+               break;
+       case NT_KEY_PAGEDOWN:
+       case KEY_NPAGE:
+               ctxp->cur_cursor *= 2;
+               ctxp->cur_cursor -= ctxp->scroll_y;
+               ctxp->scroll_y += wp->lines;
+               if(ctxp->scroll_y + wp->lines > (ctxp->item_count*2)){
+                       ctxp->scroll_y =
+                               (ctxp->item_count*2) - wp->lines;
+               }
+               ctxp->cur_cursor += ctxp->scroll_y;
+               ctxp->cur_cursor /= 2;
+               break;
+       case NT_KEY_BOTTOM:
+       case KEY_END:
+               ctxp->cur_cursor *= 2;
+               ctxp->cur_cursor -= ctxp->scroll_y;
+               ctxp->scroll_y =
+                               (ctxp->item_count*2) - wp->lines;
+               ctxp->cur_cursor += ctxp->scroll_y;
+               ctxp->cur_cursor /= 2;
+               break;
+       default:
+               //wmove(wp->wp, 1, 1); 
+               //nt_add_wch(wp->wp, (wchar_t)wp->key, 0);
+               break;
+       }
+       
+       if(ctxp->thread_list){
+               row = 0;
+               num = 1;
+               linkp = ctxp->thread_list;
+               do{
+                       if(row >= ctxp->scroll_y + wp->lines)
+                               break;
+                       if(ctxp->cur_cursor+1 == num)
+                               attr = WA_BOLD;
+                       else
+                               attr = 0;
+                       
+                       threadp = (nt_searched_thread_tp)linkp->data;
+                       if(-1 == swprintf(wc, sizeof(wc)-1, 
+                                       L"%4d. %ls [%ls]", num,
+                                       threadp->title, threadp->board_name)){
+                               break;
+                       }
+                       if(row >= ctxp->scroll_y){
+                               wmove(wp->wp, row-ctxp->scroll_y, 0); 
+                               nt_add_wnstr(wp->wp, wc, attr, wp->cols);
+                       }
+                       row++;
+                       if(row >= ctxp->scroll_y + wp->lines)
+                               break;
+                       if(row >= ctxp->scroll_y){
+                               wmove(wp->wp, row-ctxp->scroll_y, 0); 
+                               nt_add_wnch(wp->wp, L' ', attr | WA_UNDERLINE, wp->cols);
+                               ch_num = nt_get_wc_count_within_colmns(wc, wp->cols);
+                               if( wcslen(wc) - ch_num > 0){
+                                       wmove(wp->wp, row-ctxp->scroll_y, 6);
+                                       nt_add_wnstr(wp->wp, wc + ch_num, attr | WA_UNDERLINE, wp->cols - 5);
+                               }
+                       }
+                       row++;
+                       num++;
+                       linkp = linkp->next;
+               }while(linkp != ctxp->thread_list);
+       }
+       return DISP_STATE_SEARCH_THREAD;
+}
+
+static thread_search_ctx_tp init_context()
+{
+       thread_search_ctx_tp ctxp;
+       
+       ctxp = malloc(sizeof(thread_search_ctx_t));
+       if(!ctxp)
+               return NULL;
+       ctxp->prev_state = DISP_STATE_SEARCH_THREAD;
+       ctxp->thread_list = NULL;
+       ctxp->cur_cursor = 0;
+       ctxp->scroll_y = 0;
+       ctxp->item_count = 0;
+       return ctxp;
+}
+
+void free_search_thread_ctx(void *ptr)
+{
+       thread_search_ctx_tp ctxp;
+       
+       assert(ptr);
+       
+       ctxp = (thread_search_ctx_tp)ptr;
+       if(ctxp->thread_list){
+               nt_all_link_free(
+                       ctxp->thread_list, free_searched_thread);
+       }
+       
+       free(ctxp);
+}
index 74b9a4d..5cdb721 100644 (file)
@@ -28,7 +28,7 @@
 
 
 
-int nt_add_wch(WINDOW *w, wchar_t wc, attr_t attr)
+int nt_add_wch(WINDOW *w, const wchar_t wc, attr_t attr)
 {
        cchar_t c;
 
@@ -44,7 +44,7 @@ int nt_add_wch(WINDOW *w, wchar_t wc, attr_t attr)
 }
 
 
-int nt_add_wstr(WINDOW *w, wchar_t *wc, attr_t attr)
+int nt_add_wstr(WINDOW *w, const wchar_t *wc, attr_t attr)
 {
        int ret;
        assert(wc);
@@ -54,7 +54,7 @@ int nt_add_wstr(WINDOW *w, wchar_t *wc, attr_t attr)
        return ret;
 }
 
-int nt_add_wnch(WINDOW *w, wchar_t wc, attr_t attr, size_t colmns)
+int nt_add_wnch(WINDOW *w, const wchar_t wc, attr_t attr, size_t colmns)
 {
        int i, delta;
        cchar_t c;
@@ -78,7 +78,7 @@ int nt_add_wnch(WINDOW *w, wchar_t wc, attr_t attr, size_t colmns)
        return i / delta;
 }
 
-int nt_add_wnstr(WINDOW *w, wchar_t *wc, attr_t attr, size_t colmns)
+int nt_add_wnstr(WINDOW *w, const wchar_t *wc, attr_t attr, size_t colmns)
 {
        int i, col, len;
        cchar_t c;
@@ -128,7 +128,7 @@ int nt_get_column_length(const wchar_t *wc)
 }
 
 
-int nt_get_wc_count_within_colmns(wchar_t *wc, size_t colmns)
+int nt_get_wc_count_within_colmns(const wchar_t *wc, size_t colmns)
 {
        int len;
        int col = 0;
index 9e36806..7fe453b 100644 (file)
@@ -61,6 +61,7 @@ typedef struct tag_ctx_threadlist_t
 #define NT_CMD_SORT_READ 2
 #define NT_CMD_SORT_UNREAD 3
 #define NT_CMD_DEL_THREAD_LOG 4
+#define NT_CMD_SEARCH_THREAD 5
 
 static int parse_cmd1(const char *param);
 static int get_thread_index_by_seqno(nt_link_tp linkp, int seq_no);
@@ -68,7 +69,7 @@ static BOOL search_line_asc(regex_t *regexp,
                                nt_link_tp threadlistp, int *sel_thread_no);
 static BOOL search_line_desc(regex_t *regexp, 
                                nt_link_tp threadlistp, int *sel_thread_no);
-static ctx_threadlist_tp init_context(nt_2ch_model_tp modelp);
+static ctx_threadlist_tp init_context(nt_2ch_selected_item_tp selectp);
 static int merge_untracked_thread_log(nt_board_tp boardp,
                nt_link_tp *disp_thread_listpp, nt_link_tp log_list);
 
@@ -94,8 +95,8 @@ static void sort_thread_title(int sort_type, ctx_threadlist_tp ctxp)
        }
 }
 
-int disp_threadlist(nt_window_tp wp, nt_2ch_model_tp modelp,
-                               void *db_handle)
+int disp_threadlist(nt_window_tp wp, nt_2ch_selected_item_tp selectp,
+                                void *db_handle)
 {
        ctx_threadlist_tp ctxp;
        nt_board_tp boardp;
@@ -115,14 +116,14 @@ int disp_threadlist(nt_window_tp wp, nt_2ch_model_tp modelp,
 
        ctxp = (ctx_threadlist_tp)wp->data;
        if(!ctxp){
-               ctxp = init_context(modelp);
+               ctxp = init_context(selectp);
                if(!ctxp)
                        return DISP_STATE_ERROR;
                wp->data = ctxp;
                sort = TRUE;
        }
 
-       boardp = modelp->selected_boardp;
+       boardp = selectp->selected_boardp;
 
        if(!ctxp->thread_data_list){
                ctxp->thread_data_list =
@@ -242,6 +243,8 @@ int disp_threadlist(nt_window_tp wp, nt_2ch_model_tp modelp,
                                }while(clistp != linkp);
                                nt_all_link_free(linkp, NULL);
                                return DISP_STATE_REFRESH;
+                       case NT_CMD_SEARCH_THREAD:
+                               return DISP_STATE_SEARCH_THREAD;
                        default:
                                break;
                        }
@@ -338,7 +341,7 @@ int disp_threadlist(nt_window_tp wp, nt_2ch_model_tp modelp,
                                ctxp->cursor_pos);
                if(!threadp)
                        break;
-               nt_set_selected_thread(modelp, threadp);
+               nt_set_selected_thread(selectp, threadp);
                return DISP_STATE_RESLIST;
        }
 
@@ -414,7 +417,7 @@ int disp_threadlist(nt_window_tp wp, nt_2ch_model_tp modelp,
        return DISP_STATE_THREADTITLE; 
 }
 
-static ctx_threadlist_tp init_context(nt_2ch_model_tp modelp)
+static ctx_threadlist_tp init_context(nt_2ch_selected_item_tp selectp)
 {
        ctx_threadlist_tp ctxp;
        nt_board_tp boardp;
@@ -423,7 +426,7 @@ static ctx_threadlist_tp init_context(nt_2ch_model_tp modelp)
        if(!ctxp)
                return NULL;
 
-       boardp = modelp->selected_boardp;
+       boardp = selectp->selected_boardp;
        ctxp->thread_num = nt_link_num(boardp->threadlistp);
        ctxp->tracked_thread_num = ctxp->thread_num;
 
@@ -647,7 +650,12 @@ static int parse_cmd1(const char *param)
        const char *start, *end;
 
        assert(param);
-       if(0 == strncmp(NT_COMMAND1_SORT_1, param,
+       if(0 == strncmp(NT_COMMAND1_SEARCH_1,param,
+                       strlen(NT_COMMAND1_SEARCH_1)) ||
+               0 == strncmp(NT_COMMAND1_SEARCH_2,param,
+                       strlen(NT_COMMAND1_SEARCH_2))){
+               return NT_CMD_SEARCH_THREAD;
+       }else if(0 == strncmp(NT_COMMAND1_SORT_1, param,
                        strlen(NT_COMMAND1_SORT_1))){
                offset = strlen(NT_COMMAND1_SORT_1);
        }else if( 0 == strncmp(NT_COMMAND1_SORT_2, param,
index 92af4f5..86a4e00 100644 (file)
@@ -38,7 +38,6 @@ BOOL nt_conv_sjis2wc(iconv_t icd,
        while(0 < n_src){
                sz = iconv(icd, &p_src, &n_src, &p_dst, &n_dst);
                if(sz == -1){
-                       perror("e");
                        return FALSE;
                }
        }
@@ -58,7 +57,6 @@ BOOL nt_conv_wc2sjis(iconv_t icd,
        while(0 < n_src){
                sz = iconv(icd, &p_src, &n_src, &p_dst, &n_dst);
                if(sz == -1){
-                       perror("e");
                        return FALSE;
                }
        }
index ff4ff70..f02147d 100644 (file)
@@ -335,6 +335,29 @@ char* nt_substr(const char* src, int start, int end)
        return cptr;
 }
 
+wchar_t* nt_w_substr(const wchar_t* src, int start, int end)
+{
+       wchar_t *cptr;
+       int len;
+
+       assert(start >= 0);
+       assert(start <= end);
+
+       len = end - start;
+       cptr = malloc((len + 1)*sizeof(wchar_t));
+       if(!cptr)
+               return NULL;
+       
+       if(len == 0){
+               *cptr =  L'\0';
+               return cptr;
+       }
+       
+       wmemcpy(cptr, src+start, len);
+       cptr[len] = L'\0';
+       return cptr;
+}
+
 BOOL nt_strtok(const char *str, char delim,
         const char** start, const char **end)
 {