Commit MetaInfo

Revisiond3c3c80eb6a40e6c8b2cda442784d00b82e218fd (tree)
Zeit2014-01-19 22:59:36
AutorAkira <akohta001@gmai...>
CommiterAkira

Log Message

v1.0.2.6
Support: ng word

Ändern Zusammenfassung

Diff

--- a/Makefile
+++ b/Makefile
@@ -4,7 +4,6 @@
44 # You may need to install then.
55
66 #Option for development
7-#CFLAGS = -g -Wall -DDEBUG ${DEFS} ${CDEF} -DNT_CLOUD
87 CFLAGS = -g -Wall -DDEBUG ${DEFS} ${CDEF} -DNT_CLOUD -DNT_NET_IPV6
98 #Option for release
109 #CFLAGS = -Wall ${DEFS} ${CDEF} -DNT_CLOUD -DNT_NET_IPV6
@@ -43,6 +42,7 @@ OBJS = ${OBJ_DIR}/main.o ${OBJ_DIR}/utils/nt_std_t.o \
4342 ${OBJ_DIR}/_2ch/parse_string.o \
4443 ${OBJ_DIR}/_2ch/maru_2ch.o \
4544 ${OBJ_DIR}/usr/favorite_t.o \
45+ ${OBJ_DIR}/usr/ng_word_t.o \
4646 ${OBJ_DIR}/usr/usr_db_t.o \
4747 ${OBJ_DIR}/ui/disp_board_menu.o \
4848 ${OBJ_DIR}/ui/disp_threadlist.o \
@@ -66,6 +66,8 @@ INC_FILES = ${INC_DIR}/config.h \
6666 ${INC_DIR}/_2ch/parse_2ch.h \
6767 ${INC_DIR}/_2ch/search_2ch.h \
6868 ${INC_DIR}/usr/favorite_t.h \
69+ ${INC_DIR}/usr/ng_word_t.h \
70+ ${INC_DIR}/usr/usr_db_t.h \
6971 ${INC_DIR}/ui/disp.h \
7072 ${INC_DIR}/ui/disp_win.h \
7173 ${INC_DIR}/ui/disp_string.h \
@@ -79,7 +81,6 @@ INC_FILES = ${INC_DIR}/config.h \
7981 ${INC_DIR}/utils/zip.h \
8082 ${INC_DIR}/utils/db.h \
8183 ${INC_DIR}/utils/text.h \
82- ${INC_DIR}/usr/usr_db_t.h \
8384 ${INC_DIR}/utils/nt_conv_char.h \
8485 ${INC_DIR}/utils/nt_mutex.h \
8586 ${INC_DIR}/utils/nt_pthread.h \
@@ -203,6 +204,10 @@ $(OBJ_DIR)/usr/favorite_t.o : ${SRC_DIR}/usr/favorite_t.c ${INC_FILES}
203204 @ ${SHELL} prepare_proj.sh
204205 ${CC} ${CFLAGS} ${INCLUDES} -c -o $@ $<
205206
207+$(OBJ_DIR)/usr/ng_word_t.o : ${SRC_DIR}/usr/ng_word_t.c ${INC_FILES}
208+ @ ${SHELL} prepare_proj.sh
209+ ${CC} ${CFLAGS} ${INCLUDES} -c -o $@ $<
210+
206211 $(OBJ_DIR)/utils/base64.o : ${SRC_DIR}/utils/base64.c ${INC_FILES}
207212 @ ${SHELL} prepare_proj.sh
208213 ${CC} ${CFLAGS} ${INCLUDES} -c -o $@ $<
--- a/Makefile.in
+++ b/Makefile.in
@@ -4,7 +4,6 @@
44 # You may need to install then.
55
66 #Option for development
7-#CFLAGS = -g -Wall -DDEBUG ${DEFS} ${CDEF} -DNT_CLOUD
87 #CFLAGS = -g -Wall -DDEBUG ${DEFS} ${CDEF} -DNT_CLOUD -DNT_NET_IPV6
98 #Option for release
109 CFLAGS = -Wall ${DEFS} ${CDEF} -DNT_CLOUD -DNT_NET_IPV6
@@ -43,6 +42,7 @@ OBJS = ${OBJ_DIR}/main.o ${OBJ_DIR}/utils/nt_std_t.o \
4342 ${OBJ_DIR}/_2ch/parse_string.o \
4443 ${OBJ_DIR}/_2ch/maru_2ch.o \
4544 ${OBJ_DIR}/usr/favorite_t.o \
45+ ${OBJ_DIR}/usr/ng_word_t.o \
4646 ${OBJ_DIR}/usr/usr_db_t.o \
4747 ${OBJ_DIR}/ui/disp_board_menu.o \
4848 ${OBJ_DIR}/ui/disp_threadlist.o \
@@ -66,6 +66,8 @@ INC_FILES = ${INC_DIR}/config.h \
6666 ${INC_DIR}/_2ch/parse_2ch.h \
6767 ${INC_DIR}/_2ch/search_2ch.h \
6868 ${INC_DIR}/usr/favorite_t.h \
69+ ${INC_DIR}/usr/ng_word_t.h \
70+ ${INC_DIR}/usr/usr_db_t.h \
6971 ${INC_DIR}/ui/disp.h \
7072 ${INC_DIR}/ui/disp_win.h \
7173 ${INC_DIR}/ui/disp_string.h \
@@ -79,7 +81,6 @@ INC_FILES = ${INC_DIR}/config.h \
7981 ${INC_DIR}/utils/zip.h \
8082 ${INC_DIR}/utils/db.h \
8183 ${INC_DIR}/utils/text.h \
82- ${INC_DIR}/usr/usr_db_t.h \
8384 ${INC_DIR}/utils/nt_conv_char.h \
8485 ${INC_DIR}/utils/nt_mutex.h \
8586 ${INC_DIR}/utils/nt_pthread.h \
@@ -203,6 +204,10 @@ $(OBJ_DIR)/usr/favorite_t.o : ${SRC_DIR}/usr/favorite_t.c ${INC_FILES}
203204 @ ${SHELL} prepare_proj.sh
204205 ${CC} ${CFLAGS} ${INCLUDES} -c -o $@ $<
205206
207+$(OBJ_DIR)/usr/ng_word_t.o : ${SRC_DIR}/usr/ng_word_t.c ${INC_FILES}
208+ @ ${SHELL} prepare_proj.sh
209+ ${CC} ${CFLAGS} ${INCLUDES} -c -o $@ $<
210+
206211 $(OBJ_DIR)/utils/base64.o : ${SRC_DIR}/utils/base64.c ${INC_FILES}
207212 @ ${SHELL} prepare_proj.sh
208213 ${CC} ${CFLAGS} ${INCLUDES} -c -o $@ $<
--- a/README
+++ b/README
@@ -1,5 +1,5 @@
11
2- ntch version 1.0.2.5
2+ ntch version 1.0.2.6
33
44 This file is part of ntch.
55
@@ -27,13 +27,13 @@ Linux用 2ch専用ブラウザー
2727
2828 ntch のインストール方法
2929
30-ダウンロードファイルを使用する場合、適当なディレクトリにntch-1.0.2.1.tgzファイルを解凍します
30+ダウンロードファイルを使用する場合、適当なディレクトリにntch-1.0.2.6.tgzファイルを解凍します
3131
32-tar zxvf ntch-1.0.2.1.tgz
32+tar zxvf ntch-1.0.2.6.tgz
3333
3434 作成されたディレクトリに移動します
3535
36-cd ntch-1.0.2.1
36+cd ntch-1.0.2.6
3737
3838 以下のコマンドを実行して、実行ファイルを作成します
3939
@@ -61,5 +61,5 @@ sudo make install
6161
6262 ntchは以下のライブラリィに依存しています。openssl, gdbm, ncurses, sqlite
6363 これらのライブラリのデベロップ版がビルドには必要です。
64-また、Fedora18で動作確認していますので、その他のディストリビューション等では、
64+また、Fedora19で動作確認していますので、その他のディストリビューション等では、
6565 作成されたMakefileやソースファイルを編集する必要があるかもしれません。
--- a/config.h
+++ b/config.h
@@ -141,7 +141,7 @@
141141 #define PACKAGE_NAME "ntch"
142142
143143 /* Define to the full name and version of this package. */
144-#define PACKAGE_STRING "ntch 1.0.2.5"
144+#define PACKAGE_STRING "ntch 1.0.2.6"
145145
146146 /* Define to the one symbol short name of this package. */
147147 #define PACKAGE_TARNAME "ntch"
@@ -150,7 +150,7 @@
150150 #define PACKAGE_URL "https://sourceforge.jp/projects/ntch/"
151151
152152 /* Define to the version of this package. */
153-#define PACKAGE_VERSION "1.0.2.5"
153+#define PACKAGE_VERSION "1.0.2.6"
154154
155155 /* Define to 1 if you have the ANSI C header files. */
156156 #define STDC_HEADERS 1
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
11 #! /bin/sh
22 # Guess values for system-dependent variables and create Makefiles.
3-# Generated by GNU Autoconf 2.69 for ntch 1.0.2.5.
3+# Generated by GNU Autoconf 2.69 for ntch 1.0.2.6.
44 #
55 # Report bugs to <akohta001@gmail.com>.
66 #
@@ -580,8 +580,8 @@ MAKEFLAGS=
580580 # Identity of this package.
581581 PACKAGE_NAME='ntch'
582582 PACKAGE_TARNAME='ntch'
583-PACKAGE_VERSION='1.0.2.5'
584-PACKAGE_STRING='ntch 1.0.2.5'
583+PACKAGE_VERSION='1.0.2.6'
584+PACKAGE_STRING='ntch 1.0.2.6'
585585 PACKAGE_BUGREPORT='akohta001@gmail.com'
586586 PACKAGE_URL='https://sourceforge.jp/projects/ntch/'
587587
@@ -1230,7 +1230,7 @@ if test "$ac_init_help" = "long"; then
12301230 # Omit some internal or obsolete options to make the list less imposing.
12311231 # This message is too long to be a string in the A/UX 3.1 sh.
12321232 cat <<_ACEOF
1233-\`configure' configures ntch 1.0.2.5 to adapt to many kinds of systems.
1233+\`configure' configures ntch 1.0.2.6 to adapt to many kinds of systems.
12341234
12351235 Usage: $0 [OPTION]... [VAR=VALUE]...
12361236
@@ -1291,7 +1291,7 @@ fi
12911291
12921292 if test -n "$ac_init_help"; then
12931293 case $ac_init_help in
1294- short | recursive ) echo "Configuration of ntch 1.0.2.5:";;
1294+ short | recursive ) echo "Configuration of ntch 1.0.2.6:";;
12951295 esac
12961296 cat <<\_ACEOF
12971297
@@ -1372,7 +1372,7 @@ fi
13721372 test -n "$ac_init_help" && exit $ac_status
13731373 if $ac_init_version; then
13741374 cat <<\_ACEOF
1375-ntch configure 1.0.2.5
1375+ntch configure 1.0.2.6
13761376 generated by GNU Autoconf 2.69
13771377
13781378 Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1795,7 +1795,7 @@ cat >config.log <<_ACEOF
17951795 This file contains any messages produced by compilers while
17961796 running configure, to aid debugging if configure makes a mistake.
17971797
1798-It was created by ntch $as_me 1.0.2.5, which was
1798+It was created by ntch $as_me 1.0.2.6, which was
17991799 generated by GNU Autoconf 2.69. Invocation command line was
18001800
18011801 $ $0 $@
@@ -4797,7 +4797,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
47974797 # report actual input values of CONFIG_FILES etc. instead of their
47984798 # values after options handling.
47994799 ac_log="
4800-This file was extended by ntch $as_me 1.0.2.5, which was
4800+This file was extended by ntch $as_me 1.0.2.6, which was
48014801 generated by GNU Autoconf 2.69. Invocation command line was
48024802
48034803 CONFIG_FILES = $CONFIG_FILES
@@ -4864,7 +4864,7 @@ _ACEOF
48644864 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
48654865 ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
48664866 ac_cs_version="\\
4867-ntch config.status 1.0.2.5
4867+ntch config.status 1.0.2.6
48684868 configured by $0, generated by GNU Autoconf 2.69,
48694869 with options \\"\$ac_cs_config\\"
48704870
--- a/configure.ac
+++ b/configure.ac
@@ -2,7 +2,7 @@
22 # Process this file with autoconf to produce a configure script.
33
44 AC_PREREQ([2.69])
5-AC_INIT([ntch], [1.0.2.5], [akohta001@gmail.com],[ntch],[https://sourceforge.jp/projects/ntch/])
5+AC_INIT([ntch], [1.0.2.6], [akohta001@gmail.com],[ntch],[https://sourceforge.jp/projects/ntch/])
66 AC_CONFIG_SRCDIR([src/main.c])
77 AC_CONFIG_HEADERS([config.h])
88
--- a/help.txt
+++ b/help.txt
@@ -1,5 +1,5 @@
11
2- ntch version 1.0.2.5
2+ ntch version 1.0.2.6
33
44 This file is part of ntch.
55
@@ -139,6 +139,32 @@ Linux用 2ch専用ブラウザー
139139 :a :autoscroll 自動スクロール
140140 j,k,f,bキー以外の入力で自動スクロール解除
141141 k,bキーで反転スクロール
142+ :ngwd [NG指定文字列] , :ngnm [NG指定文字列] , :ngid [NG指定文字列]
143+ ngwd レス本文に対するNG指定 
144+ 文字列には後述する方法で正規表現を指定出来ます。
145+ 文字列を省略すると、現在設定されている全ての
146+ NGWORDをエディターで表示しますので、これを直接
147+ 編集できます。
148+ ngnm, ngid それぞれレスの名前欄、IDに対するNGの指定です。
149+ 指定方法はngwdと同様です
150+ NG文字列に正規表現を指定する方法
151+ 指定したい正規表現をスラッシュ'/'で囲んで指定します。
152+ 例
153+ :ngwd /(L|l)inux/ 左はLinuxとlinuxにマッチします。
154+ :ngwd /ですか\\? $/ 行末が「ですか?」で終わる文字列に
155+ にマッチします。
156+ ?マークをエスケープすることと、
157+ 2chのレスの行末には空白が1文字
158+ 付加されるていることに注意して下さい
159+ :ngwd /windows/i スラッシュの後ろに'i'を指定すると
160+ 大文字小文字を無視します
161+ 左の例ではWindows, windows, WiNdOwS
162+ などにマッチします
163+ 先頭が'/'で始まる文字列を正規表現を使わないでNG指定する方法
164+ 先頭のスラッシュ'/'を円マーク'\\'でエスケープして下さい
165+ 例
166+ :ngwd \\/[a-z]/ 左は正規表現を使わずに文字列として
167+ /[a-z]/ にマッチします。
142168
143169 お気に入り一覧
144170 d 選択項目をお気に入りから削除
@@ -236,7 +262,7 @@ nce-pass preference.phpで登録したユーザーパスワード
236262 クラウド設定有効時には起動時にクラウドのデータを読み込みます。
237263 現在のお気に入りの内容でクラウドのデータを明示的に更新したい場合は、
238264 お気に入り一覧で、以下のコマンドを入力します
239-:upload 現在のお気に入りを全てアップロード
265+:upload 現在のお気に入り、NGワードの設定を全てアップロード
240266 :upload board 現在の板のお気に入りをアップロード
241267 :upload thread 現在のスレッドのお気に入りをアップロード
242-
268+:upload ng 現在のNGワードの設定をアップロード
--- a/src/cloud/nt_cloud.c
+++ b/src/cloud/nt_cloud.c
@@ -30,6 +30,7 @@
3030 #include "utils/nt_std_t.h"
3131 #include "utils/text.h"
3232 #include "utils/file.h"
33+#include "utils/nt_pthread.h"
3334 #include "utils/base64.h"
3435 #include "utils/crypt.h"
3536 #include "utils/nt_conv_char.h"
@@ -42,6 +43,10 @@ static BOOL nt_cloud_edit_lines_file(nt_cloud_handle handle,
4243 static BOOL nt_cloud_upload_file_local(nt_cloud_handle handle,
4344 const char *file_name, nt_link_tp lines, int depth);
4445 static nt_cloud_handle g_cloud_handle = NULL;
46+static nt_pthread_result_t upload_file_pthread_func(void *param);
47+static BOOL nt_cloud_edit_lines_file_async(nt_cloud_handle handle,
48+ const char *file_name, nt_link_tp lines, const char *php_file);
49+static nt_pthread_result_t edit_lines_file_pthread_func(void *param);
4550
4651 nt_cloud_handle nt_cloud_get_handle(){
4752 if(!g_cloud_handle)
@@ -215,6 +220,102 @@ BOOL nt_cloud_delete_lines_from_file(nt_cloud_handle handle,
215220 {
216221 return nt_cloud_edit_lines_file(handle, file_name, lines, NT_CLOUD_DELETE_LINES_FILE_PHP, 0);
217222 }
223+BOOL nt_cloud_insert_lines_into_file_async(nt_cloud_handle handle,
224+ const char *file_name, nt_link_tp lines)
225+{
226+ return nt_cloud_edit_lines_file_async(
227+ handle, file_name, lines, NT_CLOUD_INSERT_LINES_FILE_PHP);
228+}
229+BOOL nt_cloud_delete_lines_from_file_async(nt_cloud_handle handle,
230+ const char *file_name, nt_link_tp lines)
231+{
232+ return nt_cloud_edit_lines_file_async(
233+ handle, file_name, lines, NT_CLOUD_DELETE_LINES_FILE_PHP);
234+}
235+
236+
237+static BOOL nt_cloud_edit_lines_file_async(nt_cloud_handle handle,
238+ const char *file_name, nt_link_tp lines, const char *php_file)
239+{
240+ nt_link_tp param;
241+ nt_pthread_handle h_pthread;
242+ char *cptr;
243+
244+ cptr = nt_str_clone(file_name);
245+ if(!cptr){
246+ return FALSE;
247+ }
248+
249+ param = nt_link_add_data(NULL, handle);
250+ if(!param){
251+ free(cptr);
252+ return FALSE;
253+ }
254+ if(NULL == nt_link_add_data(param, cptr)){
255+ nt_all_link_free(param, NULL);
256+ free(cptr);
257+ return FALSE;
258+ }
259+ if(NULL == nt_link_add_data(param, php_file)){
260+ nt_all_link_free(param, NULL);
261+ free(cptr);
262+ return FALSE;
263+ }
264+ if(NULL == nt_link_add_data(param, lines)){
265+ nt_all_link_free(param, NULL);
266+ free(cptr);
267+ return FALSE;
268+ }
269+ nt_cloud_add_ref(handle);
270+
271+ h_pthread = nt_pthread_alloc(
272+ edit_lines_file_pthread_func, param, NULL);
273+ if(!h_pthread){
274+ nt_cloud_release_ref(handle);
275+ nt_all_link_free(param, NULL);
276+ free(cptr);
277+ return FALSE;
278+ }
279+
280+ if(!nt_pthread_put_que(h_pthread)){
281+ nt_pthread_release_ref(h_pthread);
282+ nt_cloud_release_ref(handle);
283+ nt_all_link_free(param, NULL);
284+ free(cptr);
285+ return FALSE;
286+ }
287+ nt_pthread_release_ref(h_pthread);
288+ return TRUE;
289+}
290+
291+static nt_pthread_result_t edit_lines_file_pthread_func(void *param)
292+{
293+ nt_pthread_result_t result;
294+ nt_link_tp linkp, lines;
295+ char *file_name, *php_file_name;
296+ nt_cloud_handle h_cloud;
297+
298+
299+ result.code = 0;
300+ result.data = NULL;
301+
302+ linkp = (nt_link_tp)param;
303+ if(4 != nt_link_num(linkp)){
304+ nt_all_link_free(linkp, NULL);
305+ return result;
306+ }
307+ h_cloud = linkp->data;
308+ file_name = linkp->next->data;
309+ php_file_name = linkp->next->next->data;
310+ lines = linkp->next->next->next->data;
311+ (void)nt_cloud_edit_lines_file(h_cloud,
312+ file_name, lines, php_file_name, 0);
313+ nt_cloud_release_ref(h_cloud);
314+ nt_all_link_free(lines, free);
315+ nt_all_link_free(linkp, NULL);
316+ free(file_name);
317+ return result;
318+}
218319
219320 static BOOL nt_cloud_edit_lines_file(nt_cloud_handle handle,
220321 const char *file_name, nt_link_tp lines, const char *php_file, int depth)
@@ -430,6 +531,84 @@ BOOL nt_cloud_upload_file(nt_cloud_handle handle,
430531 file_name, lines, 0);
431532 }
432533
534+BOOL nt_cloud_upload_file_async(nt_cloud_handle handle,
535+ const char *file_name, nt_link_tp lines)
536+{
537+ nt_link_tp param;
538+ nt_pthread_handle h_pthread;
539+ char *cptr;
540+
541+ cptr = nt_str_clone(file_name);
542+ if(!cptr){
543+ return FALSE;
544+ }
545+
546+ param = nt_link_add_data(NULL, handle);
547+ if(param){
548+ free(cptr);
549+ return FALSE;
550+ }
551+ if(NULL == nt_link_add_data(param, cptr)){
552+ nt_all_link_free(param, NULL);
553+ free(cptr);
554+ return FALSE;
555+ }
556+ if(NULL == nt_link_add_data(param, lines)){
557+ nt_all_link_free(param, NULL);
558+ free(cptr);
559+ return FALSE;
560+ }
561+ nt_cloud_add_ref(handle);
562+
563+ h_pthread = nt_pthread_alloc(
564+ upload_file_pthread_func, param, NULL);
565+ if(!h_pthread){
566+ nt_cloud_release_ref(handle);
567+ nt_all_link_free(param, NULL);
568+ free(cptr);
569+ return FALSE;
570+ }
571+
572+ if(!nt_pthread_put_que(h_pthread)){
573+ nt_pthread_release_ref(h_pthread);
574+ nt_cloud_release_ref(handle);
575+ nt_all_link_free(param, NULL);
576+ free(cptr);
577+ return FALSE;
578+ }
579+ nt_pthread_release_ref(h_pthread);
580+ return TRUE;
581+}
582+
583+static nt_pthread_result_t upload_file_pthread_func(void *param)
584+{
585+ nt_pthread_result_t result;
586+ nt_link_tp linkp, lines;
587+ char *file_name;
588+ nt_cloud_handle h_cloud;
589+
590+
591+ result.code = 0;
592+ result.data = NULL;
593+
594+ linkp = (nt_link_tp)param;
595+ if(3 != nt_link_num(linkp)){
596+ nt_all_link_free(linkp, NULL);
597+ return result;
598+ }
599+ h_cloud = linkp->data;
600+ file_name = linkp->next->data;
601+ lines = linkp->next->next->data;
602+ (void)nt_cloud_upload_file_local(h_cloud,
603+ file_name, lines, 0);
604+ nt_cloud_release_ref(h_cloud);
605+ nt_all_link_free(lines, free);
606+ nt_all_link_free(linkp, NULL);
607+ free(file_name);
608+ return result;
609+}
610+
611+
433612 static BOOL nt_cloud_upload_file_local(nt_cloud_handle handle,
434613 const char *file_name, nt_link_tp lines, int depth)
435614 {
--- a/src/env.c
+++ b/src/env.c
@@ -40,6 +40,9 @@ char USR_LOG_DB_PATH[1024];
4040 char USR_FAVORITE_BOARD_FILE_PATH[1024];
4141 char USR_FAVORITE_GRP_FILE_PATH[1024];
4242 char USR_FAVORITE_THREAD_FILE_PATH[1024];
43+char USR_NG_WORD_FILE_PATH[1024];
44+char USR_NG_NAME_FILE_PATH[1024];
45+char USR_NG_ID_FILE_PATH[1024];
4346 char EDITOR_CMD[1024];
4447 int FORCE_REFRESH = 0;
4548 int THREAD_SORT_TYPE = NT_THREAD_SORT_BY_READ;
@@ -130,6 +133,9 @@ int set_option(int argc, char* argv[])
130133 sprintf(USR_FAVORITE_BOARD_FILE_PATH, "%s/fb.txt", USR_PATH);
131134 sprintf(USR_FAVORITE_GRP_FILE_PATH, "%s/ftab.txt", USR_PATH);
132135 sprintf(USR_FAVORITE_THREAD_FILE_PATH, "%s/ft.txt", USR_PATH);
136+ sprintf(USR_NG_WORD_FILE_PATH, "%s/ngwd.txt", USR_PATH);
137+ sprintf(USR_NG_NAME_FILE_PATH, "%s/ngnm.txt", USR_PATH);
138+ sprintf(USR_NG_ID_FILE_PATH, "%s/ngid.txt", USR_PATH);
133139
134140 sprintf(buf, "%s/.ntchrc", pw->pw_dir);
135141 if(!read_resource(buf)){
--- a/src/inc/cloud/nt_cloud.h
+++ b/src/inc/cloud/nt_cloud.h
@@ -41,6 +41,10 @@ extern BOOL nt_cloud_insert_lines_into_file(nt_cloud_handle handle,
4141 const char *file_name, nt_link_tp lines);
4242 extern BOOL nt_cloud_delete_lines_from_file(nt_cloud_handle handle,
4343 const char *file_name, nt_link_tp lines);
44+extern BOOL nt_cloud_insert_lines_into_file_async(nt_cloud_handle handle,
45+ const char *file_name, nt_link_tp lines);
46+extern BOOL nt_cloud_delete_lines_from_file_async(nt_cloud_handle handle,
47+ const char *file_name, nt_link_tp lines);
4448
4549 extern void nt_cloud_update_read_count_async(nt_cloud_handle handle,
4650 const wchar_t *board_name, const wchar_t *dat_name,
--- a/src/inc/config.h
+++ b/src/inc/config.h
@@ -141,7 +141,7 @@
141141 #define PACKAGE_NAME "ntch"
142142
143143 /* Define to the full name and version of this package. */
144-#define PACKAGE_STRING "ntch 1.0.2.5"
144+#define PACKAGE_STRING "ntch 1.0.2.6"
145145
146146 /* Define to the one symbol short name of this package. */
147147 #define PACKAGE_TARNAME "ntch"
@@ -150,7 +150,7 @@
150150 #define PACKAGE_URL "https://sourceforge.jp/projects/ntch/"
151151
152152 /* Define to the version of this package. */
153-#define PACKAGE_VERSION "1.0.2.5"
153+#define PACKAGE_VERSION "1.0.2.6"
154154
155155 /* Define to 1 if you have the ANSI C header files. */
156156 #define STDC_HEADERS 1
--- a/src/inc/env.h
+++ b/src/inc/env.h
@@ -27,6 +27,10 @@ extern char USR_LOG_DB_PATH[];
2727 extern char USR_FAVORITE_BOARD_FILE_PATH[];
2828 extern char USR_FAVORITE_GRP_FILE_PATH[];
2929 extern char USR_FAVORITE_THREAD_FILE_PATH[];
30+extern char USR_NG_WORD_FILE_PATH[];
31+extern char USR_NG_NAME_FILE_PATH[];
32+extern char USR_NG_ID_FILE_PATH[];
33+
3034 extern char *RFC2898_SALT;
3135 extern int RFC2898_ITERATION;
3236 extern char *AES256_PASS;
@@ -80,9 +84,11 @@ extern char *MARU_PW;
8084 #define NT_KEY_COMMAND1 ':'
8185 #define NT_KEY_COMMAND2 '/'
8286 #define NT_KEY_COMMAND3 '?'
87+#define NT_KEY_CMD_BASE (65536)
8388 #define NT_KEY_CMD_BOARD_UPDATE (65536 + 1)
8489 #define NT_KEY_CMD_AUTO_SCROLL (65536 + 2)
8590 #define NT_KEY_CMD_FAVORITE_UPDATE (65536 + 3)
91+#define NT_KEY_CMD_NGWORD_UPDATE (65536 + 4)
8692
8793 #define NT_COMMAND1_WRITE_MSG_1 "write"
8894 #define NT_COMMAND1_WRITE_MSG_2 "w"
@@ -115,8 +121,15 @@ extern char *MARU_PW;
115121 #define NT_COMMAND1_UPLOAD_BOARD2 "b"
116122 #define NT_COMMAND1_UPLOAD_THREAD1 "thread"
117123 #define NT_COMMAND1_UPLOAD_THREAD2 "t"
124+#define NT_COMMAND1_UPLOAD_NG_FILE1 "ng"
125+#define NT_COMMAND1_UPLOAD_NG_FILE2 "n"
118126 #define NT_COMMAND1_LIMIT_1 "limit"
119127 #define NT_COMMAND1_LIMIT_2 "l"
128+#define NT_COMMAND1_NG_WORD_1 "ngword"
129+#define NT_COMMAND1_NG_WORD_2 "ngwd"
130+#define NT_COMMAND1_NG_NAME_1 "ngname"
131+#define NT_COMMAND1_NG_NAME_2 "ngnm"
132+#define NT_COMMAND1_NG_ID_1 "ngid"
120133
121134 extern int set_option(int argc, char* argv[]);
122135
--- a/src/inc/nt_string.h
+++ b/src/inc/nt_string.h
@@ -29,6 +29,7 @@
2929 #define NT_INFO_DEL_FAVORITE_SUCCEEDED (L"お気に入りから削除しました")
3030
3131 #define NT_INFO_UPLOAD_FAVORITE_SUCCEEDED (L"クラウドのお気に入りを更新しました")
32+#define NT_INFO_UPLOAD_NG_FILES_SUCCEEDED (L"クラウドのNGファイルを更新しました")
3233
3334 #define NT_TEXT_UNTRACKED_LOG_NAME (L"[DAT落] ")
3435
--- a/src/inc/ui/disp.h
+++ b/src/inc/ui/disp.h
@@ -29,6 +29,7 @@
2929 #include "_2ch/search_2ch.h"
3030 #include "usr/favorite_t.h"
3131 #include "usr/usr_db_t.h"
32+#include "usr/ng_word_t.h"
3233
3334 #define DISP_STATE_MASK 0xff
3435 #define DISP_CMD_MASK 0xff00
@@ -61,13 +62,19 @@
6162 #define DISP_CMD_UPLOAD_THREADS (11*256)
6263 #define DISP_CMD_REFRESH (12*256)
6364 #define DISP_CMD_REENTER (13*256)
65+#define DISP_CMD_EDIT_NGWORD (14*256)
66+#define DISP_CMD_EDIT_NGNAME (15*256)
67+#define DISP_CMD_EDIT_NGID (16*256)
68+#define DISP_CMD_UPLOAD_NG_FILES (17*256)
69+
6470
6571 extern int disp_board_menu(nt_window_tp wp,
6672 nt_2ch_model_handle h_model, nt_2ch_selected_item_handle h_select);
6773 extern int disp_threadlist(nt_window_tp wp, int state,
6874 nt_2ch_selected_item_handle h_select, nt_usr_db_handle usr_db_handle);
6975 extern int disp_reslist(nt_window_tp wp, int state,
70- nt_2ch_selected_item_handle h_select, nt_usr_db_handle usr_db_handle);
76+ nt_2ch_selected_item_handle h_select, nt_usr_db_handle usr_db_handle,
77+ nt_ng_word_handle h_ng_word, nt_cloud_handle h_cloud);
7178 extern int disp_thread_search(nt_window_tp wp,
7279 int prev_state, nt_link_tp thread_list,
7380 nt_searched_thread_handle *h_sel_threadp);
@@ -88,6 +95,8 @@ extern void free_search_thread_ctx(void *ptr);
8895 extern void free_favorite_ctx(void *ptr);
8996 extern void free_history_ctx(void *ptr);
9097 extern BOOL disp_editor(nt_write_data_handle h_write_data);
98+extern BOOL disp_editor2(const char *file_name);
99+extern nt_link_tp disp_editor3(nt_link_tp text_list);
91100 extern int disp_html_result(nt_write_data_handle h_write_data);
92101
93102 #endif /* _DISP_H_ */
--- /dev/null
+++ b/src/inc/usr/ng_word_t.h
@@ -0,0 +1,100 @@
1+/* Copyright 2014 Akira Ohta (akohta001@gmail.com)
2+ This file is part of ntch.
3+
4+ The ntch is free software: you can redistribute it and/or modify
5+ it under the terms of the GNU General Public License as published by
6+ the Free Software Foundation, either version 3 of the License, or
7+ (at your option) any later version.
8+
9+ The ntch is distributed in the hope that it will be useful,
10+ but WITHOUT ANY WARRANTY; without even the implied warranty of
11+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+ GNU General Public License for more details.
13+
14+ You should have received a copy of the GNU General Public License
15+ along with ntch. If not, see <http://www.gnu.org/licenses/>.
16+
17+*/
18+#ifndef _NG_WORD_T_H_
19+#define _NG_WORD_T_H_
20+
21+#include "utils/nt_std_t.h"
22+#include "utils/nt_mutex.h"
23+#ifdef NT_CLOUD
24+#include "cloud/nt_cloud.h"
25+#endif
26+
27+#define NG_ITEM_NONE 0
28+#define NG_ITEM_MSG 1
29+#define NG_ITEM_NAME 2
30+#define NG_ITEM_ID 4
31+#define NG_ITEM_ALL 7
32+
33+
34+typedef struct tag_nt_ng_word_handle{
35+ int chk_sum;
36+} nt_ng_word_handle_t, *nt_ng_word_handle;
37+
38+extern int nt_ng_word_add_ref(nt_ng_word_handle handle);
39+extern int nt_ng_word_release_ref(nt_ng_word_handle handle);
40+
41+extern nt_mutex_handle nt_ng_get_mutex(nt_ng_word_handle handle);
42+extern nt_mutex_handle nt_ng_word_get_mutex(nt_ng_word_handle handle);
43+extern nt_mutex_handle nt_ng_name_get_mutex(nt_ng_word_handle handle);
44+extern nt_mutex_handle nt_ng_id_get_mutex(nt_ng_word_handle handle);
45+
46+extern nt_ng_word_handle nt_ng_word_load(
47+#ifdef NT_CLOUD
48+ nt_cloud_handle h_cloud,
49+#endif
50+ const char *ng_word_file_name,
51+ const char *ng_name_file_name,
52+ const char *ng_id_file_name
53+ );
54+extern BOOL nt_ng_word_save(nt_ng_word_handle handle,
55+ const char *ng_word_file_name,
56+ const char *ng_name_file_name,
57+ const char *ng_id_file_name
58+ );
59+
60+#ifdef NT_CLOUD
61+extern BOOL nt_ng_word_upload_cloud(
62+ nt_cloud_handle h_cloud, nt_ng_word_handle h_ng_word);
63+extern BOOL nt_ng_word_add_ng_word(nt_cloud_handle h_cloud,
64+ nt_ng_word_handle handle, const char *ng_word);
65+extern BOOL nt_ng_word_add_ng_name(nt_cloud_handle h_cloud,
66+ nt_ng_word_handle handle, const char *ng_name);
67+extern BOOL nt_ng_word_add_ng_id(nt_cloud_handle h_cloud,
68+ nt_ng_word_handle handle, const char *ng_id);
69+extern BOOL nt_ng_word_set_words(
70+ nt_ng_word_handle handle, nt_link_tp text_list,
71+ nt_cloud_handle h_cloud);
72+extern BOOL nt_ng_word_set_names(
73+ nt_ng_word_handle handle, nt_link_tp text_list,
74+ nt_cloud_handle h_cloud);
75+extern BOOL nt_ng_word_set_ids(
76+ nt_ng_word_handle handle, nt_link_tp text_list,
77+ nt_cloud_handle h_cloud);
78+
79+#else
80+extern BOOL nt_ng_word_add_ng_word(
81+ nt_ng_word_handle handle, const char *ng_word);
82+extern BOOL nt_ng_word_add_ng_name(
83+ nt_ng_word_handle handle, const char *ng_name);
84+extern BOOL nt_ng_word_add_ng_id(
85+ nt_ng_word_handle handle, const char *ng_id);
86+extern BOOL nt_ng_word_set_words(nt_ng_word_handle handle, nt_link_tp text_list);
87+extern BOOL nt_ng_word_set_names(nt_ng_word_handle handle, nt_link_tp text_list);
88+extern BOOL nt_ng_word_set_ids(nt_ng_word_handle handle, nt_link_tp text_list);
89+
90+#endif
91+extern int ng_word_match(nt_ng_word_handle handle,
92+ int item_type, const wchar_t *source,
93+ wchar_t *match, size_t match_buf_len);
94+extern nt_link_tp nt_ng_word_get_words(nt_ng_word_handle handle);
95+extern nt_link_tp nt_ng_word_get_names(nt_ng_word_handle handle);
96+extern nt_link_tp nt_ng_word_get_ids(nt_ng_word_handle handle);
97+
98+
99+#endif /* _NG_WORD_T_H_ */
100+
--- a/src/inc/utils/nt_std_t.h
+++ b/src/inc/utils/nt_std_t.h
@@ -28,6 +28,7 @@ typedef int BOOL;
2828 typedef void (*nt_memfree_fn)(void* ptr);
2929 typedef int (*nt_compare_fn)(void *lhs, void *rhs);
3030 typedef int (*nt_compare_n_fn)(int a, int b);
31+typedef void* (*nt_memcopy_fn)(void* ptr);
3132
3233 typedef struct tag_nt_link_t *nt_link_tp;
3334 typedef struct tag_nt_link_t{
@@ -120,7 +121,10 @@ extern nt_link_tp nt_link_next(nt_link_tp link);
120121 extern int nt_link_num(nt_link_tp linkp);
121122 extern void* nt_link_get_by_index(nt_link_tp linkp, int index);
122123 extern void nt_all_link_free(nt_link_tp ptr, nt_memfree_fn free_func);
123-extern nt_link_tp nt_link_copy(nt_link_tp src_linkp);
124+extern nt_link_tp nt_link_copy(nt_link_tp src_linkp, nt_memcopy_fn copy_func);
125+
126+extern void* nt_link_strcpy_fnc(void *ptr);
127+extern void* nt_link_wcscpy_fnc(void *ptr);
124128 extern int nt_link_wcscmp_fnc(void *lhs, void *rhs);
125129
126130 typedef struct tag_nt_key_value_t *nt_key_value_tp;
--- a/src/main.c
+++ b/src/main.c
@@ -47,24 +47,19 @@
4747 #include "ui/disp.h"
4848 #include "ui/disp_win.h"
4949 #include "ui/disp_string.h"
50-#ifdef NT_CLOUD
5150 #include "cloud/nt_cloud.h"
52-#endif
51+#include "usr/ng_word_t.h"
52+
5353 #define S_SIZE (1024)
5454
5555 extern int server_main();
5656
5757 static int draw_title(WINDOW *wp, const wchar_t *title, attr_t attr);
58-#ifdef NT_CLOUD
5958 static BOOL DoLoop(WINDOW *scrp, nt_usr_db_handle db_handle,
6059 nt_cloud_handle h_cloud,
6160 nt_favorite_handle h_favorite,
62- nt_favorite_grp_handle h_favorite_grp);
63-#else
64-static BOOL DoLoop(WINDOW *scrp, nt_usr_db_handle db_handle,
65- nt_favorite_handle h_favorite,
66- nt_favorite_grp_handle h_favorite_grp);
67-#endif
61+ nt_favorite_grp_handle h_favorite_grp,
62+ nt_ng_word_handle h_ng_word);
6863 static void print_error(WINDOW *wp, const wchar_t *msg);
6964
7065 static void _2ch_selected_item_free(void *ptr)
@@ -83,10 +78,9 @@ int main(int argc, char *argv[])
8378 nt_favorite_grp_handle h_favorite_grp;
8479 nt_link_tp text_linkp, text2_linkp;
8580 const char *err_msg;
86-#ifdef NT_CLOUD
81+ nt_ng_word_handle h_ng_word;
8782 nt_cloud_handle h_cloud;
8883 h_cloud = NULL;
89-#endif
9084 err_msg = NULL;
9185
9286 setlocale(LC_ALL, "ja_JP.UTF-8");
@@ -129,7 +123,6 @@ int main(int argc, char *argv[])
129123 goto ERROR_TRAP;
130124 }
131125
132-#ifdef NT_CLOUD
133126 if(nt_crypt_lib_init(RFC2898_SALT, RFC2898_ITERATION,
134127 AES256_PASS, &err_msg)){
135128 if(NCE_AUTH_URL && NCE_ID && NCE_PASS){
@@ -141,7 +134,6 @@ int main(int argc, char *argv[])
141134 sleep(1);
142135 }
143136 }
144-#endif
145137
146138 if(!nt_2ch_model_init()){
147139 fputs("Failed to read board menu data.\n", stderr);
@@ -167,11 +159,9 @@ int main(int argc, char *argv[])
167159 }
168160
169161 text_linkp = NULL;
170-#ifdef NT_CLOUD
171162 if(h_cloud){
172163 text_linkp = nt_cloud_download_file(h_cloud, "fb.txt");
173164 }
174-#endif
175165 if(!text_linkp)
176166 text_linkp = nt_read_text_file(USR_FAVORITE_BOARD_FILE_PATH);
177167 if(text_linkp){
@@ -179,13 +169,11 @@ int main(int argc, char *argv[])
179169 nt_all_link_free(text_linkp, free);
180170 }
181171 text_linkp = NULL;
182-#ifdef NT_CLOUD
183172 if(h_cloud){
184173 text_linkp = nt_cloud_download_file(h_cloud, "ft.txt");
185174 nt_cloud_query_favorite_attributes_async(h_cloud, usr_db_handle);
186175 //nt_cloud_query_attributes(h_cloud, usr_db_handle, 0);
187176 }
188-#endif
189177 if(!text_linkp)
190178 text_linkp = nt_read_text_file(USR_FAVORITE_THREAD_FILE_PATH);
191179 if(text_linkp){
@@ -193,19 +181,28 @@ int main(int argc, char *argv[])
193181 nt_all_link_free(text_linkp, free);
194182 }
195183
184+ h_ng_word = nt_ng_word_load(h_cloud,
185+ USR_NG_WORD_FILE_PATH,
186+ USR_NG_NAME_FILE_PATH,
187+ USR_NG_ID_FILE_PATH);
188+
196189 cbreak();
197190 noecho();
198191
199-#ifdef NT_CLOUD
200- if(DoLoop(scrp, usr_db_handle, h_cloud, h_favorite, h_favorite_grp))
201-#else
202- if(DoLoop(scrp, usr_db_handle, h_favorite, h_favorite_grp))
203-#endif
192+ if(DoLoop(scrp, usr_db_handle, h_cloud, h_favorite, h_favorite_grp, h_ng_word))
204193 result = 0;
205194
206195 echo();
207196 nocbreak();
208197
198+ if(h_ng_word){
199+ nt_ng_word_save(h_ng_word,
200+ USR_NG_WORD_FILE_PATH,
201+ USR_NG_NAME_FILE_PATH,
202+ USR_NG_ID_FILE_PATH);
203+ nt_ng_word_release_ref(h_ng_word);
204+ }
205+
209206 text_linkp = nt_favorite_retrieve_boards(h_favorite);
210207 if(text_linkp){
211208 nt_write_text_file(USR_FAVORITE_BOARD_FILE_PATH, text_linkp);
@@ -244,11 +241,9 @@ ERROR_TRAP:
244241
245242 nt_timer_lib_finish();
246243
247-#ifdef NT_CLOUD
248244 nt_crypt_lib_finish();
249245 if(h_cloud)
250246 nt_cloud_release_ref(h_cloud);
251-#endif
252247 nt_env_free();
253248 return (result);
254249 }
@@ -267,16 +262,11 @@ static int auto_update_timer_func(int id)
267262 return TIMER_ID_AUTO_UPDATE_NONE;
268263 }
269264
270-#ifdef NT_CLOUD
271265 static BOOL DoLoop(WINDOW *scrp, nt_usr_db_handle db_handle,
272266 nt_cloud_handle h_cloud,
273267 nt_favorite_handle h_favorite,
274- nt_favorite_grp_handle h_favorite_grp)
275-#else
276-static BOOL DoLoop(WINDOW *scrp, nt_usr_db_handle db_handle,
277- nt_favorite_handle h_favorite,
278- nt_favorite_grp_handle h_favorite_grp)
279-#endif
268+ nt_favorite_grp_handle h_favorite_grp,
269+ nt_ng_word_handle h_ng_word)
280270 {
281271 int ch, state, num;
282272 int disp_state, nresult;
@@ -369,14 +359,12 @@ static BOOL DoLoop(WINDOW *scrp, nt_usr_db_handle db_handle,
369359 h_favorite_board = nt_favorite_board_alloc(
370360 h_favorite, board_name);
371361 if(h_favorite_board){
372-#ifdef NT_CLOUD
373362 linkp = nt_link_add_data(NULL, (void*)board_name);
374363 if(linkp){
375364 if(h_cloud)
376365 nt_cloud_insert_lines_into_file(h_cloud, "fb.txt", linkp);
377366 free(linkp);
378367 }
379-#endif
380368 nt_favorite_board_release_ref(h_favorite_board);
381369 //favorite_dump(h_favorite);
382370 }
@@ -423,14 +411,12 @@ static BOOL DoLoop(WINDOW *scrp, nt_usr_db_handle db_handle,
423411 nt_2ch_selected_item_get_board_name(h_sel_items),
424412 nt_2ch_selected_item_get_thread_title(h_sel_items));
425413 if(h_favorite_thread){
426-#ifdef NT_CLOUD
427414 linkp = NULL;
428415 if(nt_favorite_retrieve_thread(h_favorite_thread, &linkp)){
429416 if(h_cloud)
430417 nt_cloud_insert_lines_into_file(h_cloud, "ft.txt", linkp);
431418 nt_all_link_free(linkp, free);
432419 }
433-#endif
434420 nt_favorite_thread_release_ref(h_favorite_thread);
435421 //favorite_dump(h_favorite);
436422 status_msg = NT_INFO_ADD_FAVORITE_SUCCEEDED;
@@ -507,7 +493,7 @@ static BOOL DoLoop(WINDOW *scrp, nt_usr_db_handle db_handle,
507493 LINES - num, COLS, num, 0))
508494 goto END_WHILE;
509495 rwinp->key = ch;
510- state = disp_reslist(rwinp, state, h_sel_items, db_handle);
496+ state = disp_reslist(rwinp, state, h_sel_items, db_handle, h_ng_word, h_cloud);
511497 auto_scrolling = FALSE;
512498 if(DISP_CMD(state)){
513499 if(DISP_CMD(state) == DISP_CMD_AUTO_SCROLL){
@@ -516,6 +502,7 @@ static BOOL DoLoop(WINDOW *scrp, nt_usr_db_handle db_handle,
516502 h_timer_auto_scroll, NT_AUTO_SCROLL_INTERVAL);
517503 }
518504 auto_scrolling = TRUE;
505+ state = DISP_STATE_RESLIST;
519506 }else if(DISP_CMD(state) == DISP_CMD_REFRESH){
520507 state = DISP_STATE_RESLIST;
521508 ch = NT_KEY_NONE;
@@ -531,8 +518,50 @@ static BOOL DoLoop(WINDOW *scrp, nt_usr_db_handle db_handle,
531518 status_msg = NT_INFO_REFRESH_THREAD_SUCCESS;
532519 wclear(scrp);
533520 continue;
521+ }else if(DISP_CMD(state) == DISP_CMD_REENTER){
522+ DISP_CLR_CMD(state);
523+ ch = NT_KEY_NONE;
524+ continue;
525+ }else if(DISP_CMD(state) == DISP_CMD_EDIT_NGWORD){
526+ ch = NT_KEY_NONE;
527+ if(!h_ng_word)
528+ break;
529+ linkp = nt_ng_word_get_words(h_ng_word);
530+ linkp = disp_editor3(linkp);
531+ if(linkp && nt_ng_word_set_words(h_ng_word, linkp, h_cloud)){
532+ ch = NT_KEY_CMD_NGWORD_UPDATE;
533+ }
534+ DISP_CLR_CMD(state);
535+ keypad(stdscr, true);
536+ wclear(scrp);
537+ continue;
538+ }else if(DISP_CMD(state) == DISP_CMD_EDIT_NGNAME){
539+ ch = NT_KEY_NONE;
540+ if(!h_ng_word)
541+ break;
542+ linkp = nt_ng_word_get_names(h_ng_word);
543+ linkp = disp_editor3(linkp);
544+ if(linkp && nt_ng_word_set_names(h_ng_word, linkp, h_cloud)){
545+ ch = NT_KEY_CMD_NGWORD_UPDATE;
546+ }
547+ DISP_CLR_CMD(state);
548+ keypad(stdscr, true);
549+ wclear(scrp);
550+ continue;
551+ }else if(DISP_CMD(state) == DISP_CMD_EDIT_NGID){
552+ ch = NT_KEY_NONE;
553+ if(!h_ng_word)
554+ break;
555+ linkp = nt_ng_word_get_ids(h_ng_word);
556+ linkp = disp_editor3(linkp);
557+ if(linkp && nt_ng_word_set_ids(h_ng_word, linkp, h_cloud)){
558+ ch = NT_KEY_CMD_NGWORD_UPDATE;
559+ }
560+ DISP_CLR_CMD(state);
561+ keypad(stdscr, true);
562+ wclear(scrp);
563+ continue;
534564 }
535- DISP_CLR_CMD(state);
536565 }
537566 if(!auto_scrolling){
538567 nt_timer_set_interval(h_timer_auto_scroll, -1);
@@ -723,7 +752,6 @@ static BOOL DoLoop(WINDOW *scrp, nt_usr_db_handle db_handle,
723752 if(DISP_CMD(state) == DISP_CMD_DEL_FAVORITE_BOARD){
724753 if(nt_favorite_board_remove(handle)){
725754 h_favorite_board = (nt_favorite_board_handle)handle;
726-#ifdef NT_CLOUD
727755 if(h_cloud){
728756 linkp = nt_link_add_data(NULL,
729757 (void*)nt_favorite_board_get_name(h_favorite_board));
@@ -732,7 +760,6 @@ static BOOL DoLoop(WINDOW *scrp, nt_usr_db_handle db_handle,
732760 free(linkp);
733761 }
734762 }
735-#endif
736763 nt_favorite_board_release_ref(h_favorite_board);
737764 status_msg = NT_INFO_DEL_FAVORITE_SUCCEEDED;
738765 }else{
@@ -741,7 +768,6 @@ static BOOL DoLoop(WINDOW *scrp, nt_usr_db_handle db_handle,
741768 }else if(DISP_CMD(state) == DISP_CMD_DEL_FAVORITE_THREAD){
742769 if(nt_favorite_thread_remove(handle)){
743770 h_favorite_thread = (nt_favorite_thread_handle)handle;
744-#ifdef NT_CLOUD
745771 if(h_cloud){
746772 linkp = NULL;
747773 if(nt_favorite_retrieve_thread(h_favorite_thread, &linkp)){
@@ -749,7 +775,6 @@ static BOOL DoLoop(WINDOW *scrp, nt_usr_db_handle db_handle,
749775 nt_all_link_free(linkp, free);
750776 }
751777 }
752-#endif
753778 nt_favorite_thread_release_ref(h_favorite_thread);
754779 status_msg = NT_INFO_DEL_FAVORITE_SUCCEEDED;
755780 }else{
@@ -786,7 +811,6 @@ static BOOL DoLoop(WINDOW *scrp, nt_usr_db_handle db_handle,
786811 status_msg = NT_INFO_REFRESH_FAVORITE_SUCCESS;
787812 wclear(scrp);
788813 continue;
789-#ifdef NT_CLOUD
790814 }else if(h_cloud){
791815 if(DISP_CMD(state) == DISP_CMD_UPLOAD_ALL ||
792816 DISP_CMD(state) == DISP_CMD_UPLOAD_BOARDS){
@@ -813,8 +837,13 @@ static BOOL DoLoop(WINDOW *scrp, nt_usr_db_handle db_handle,
813837 }
814838 }
815839 }
840+ if(DISP_CMD(state) == DISP_CMD_UPLOAD_ALL ||
841+ DISP_CMD(state) == DISP_CMD_UPLOAD_NG_FILES){
842+ if(nt_ng_word_upload_cloud(h_cloud, h_ng_word)){
843+ status_msg = NT_INFO_UPLOAD_FAVORITE_SUCCEEDED;
844+ }
845+ }
816846 disp_state = state = DISP_STATE_FAVORITE;
817-#endif
818847 }else{
819848 disp_state = state = DISP_STATE_FAVORITE;
820849 }
--- a/src/ui/disp_editor.c
+++ b/src/ui/disp_editor.c
@@ -29,12 +29,81 @@
2929 #include "_2ch/_2ch.h"
3030 #include "utils/nt_std_t.h"
3131 #include "utils/text.h"
32+#include "utils/file.h"
3233 #include "ui/disp.h"
3334
3435
3536 static BOOL read_editor(FILE *fp, nt_write_data_handle h_write_data,
3637 char *buf_reuse, size_t buf_len);
3738
39+BOOL disp_editor2(const char *file_name)
40+{
41+ char buf[1024*2];
42+ int ret;
43+
44+ sprintf(buf, "%s %s", EDITOR_CMD, file_name);
45+ ret = system(buf);
46+ if (WIFSIGNALED(ret) &&
47+ (WTERMSIG(ret) == SIGINT ||
48+ WTERMSIG(ret) == SIGQUIT))
49+ return FALSE;
50+ return TRUE;
51+}
52+
53+BOOL nt_link_cmp(nt_link_tp l, nt_link_tp r, nt_compare_fn cmp_func)
54+{
55+ nt_link_tp lp, rp;
56+ lp = l;
57+ rp = r;
58+ do{
59+ if(0 != cmp_func(lp->data, rp->data))
60+ return FALSE;
61+ lp = lp->next;
62+ rp = rp->next;
63+ }while(l != lp || r != rp);
64+ return (l == lp && r == rp);
65+}
66+
67+nt_link_tp disp_editor3(nt_link_tp text_list)
68+{
69+ FILE *tmp_fp;
70+ pid_t pid;
71+ char fname[512];
72+ char buf[128];
73+ int ret;
74+ nt_link_tp out_linkp;
75+ pid = getpid();
76+
77+ sprintf(fname, "%s/txt%d.tmp", LOG_PATH, pid);
78+ if(!text_list){
79+ tmp_fp = fopen(fname, "w");
80+ if(!tmp_fp)
81+ return FALSE;
82+ fclose(tmp_fp);
83+ }else{
84+ if(!nt_write_text_file(fname, text_list))
85+ return NULL;
86+ }
87+
88+ sprintf(buf, "%s %s", EDITOR_CMD, fname);
89+ ret = system(buf);
90+ if (WIFSIGNALED(ret) &&
91+ (WTERMSIG(ret) == SIGINT ||
92+ WTERMSIG(ret) == SIGQUIT))
93+ return NULL;
94+
95+ out_linkp = nt_read_text_file(fname);
96+ if(!out_linkp)
97+ return NULL;
98+
99+ if(nt_link_cmp(out_linkp, text_list, nt_link_wcscmp_fnc)){
100+ nt_all_link_free(out_linkp, free);
101+ return NULL;
102+ }
103+ return out_linkp;
104+}
105+
106+
38107 BOOL disp_editor(nt_write_data_handle h_write_data)
39108 {
40109 FILE *tmp_fp;
--- a/src/ui/disp_favorite.c
+++ b/src/ui/disp_favorite.c
@@ -37,6 +37,7 @@
3737 #define NT_CMD_UPLOAD_BOARDS 2
3838 #define NT_CMD_UPLOAD_THREADS 3
3939 #define NT_CMD_DISP_HISTORY 4
40+#define NT_CMD_UPLOAD_NG_FILES 5
4041
4142 typedef struct tag_favorite_ctx_t *favorite_ctx_tp;
4243 typedef struct tag_favorite_ctx_t {
@@ -121,6 +122,8 @@ int disp_favorite(nt_window_tp wp,
121122 return DISP_CMD_UPLOAD_BOARDS;
122123 case NT_CMD_UPLOAD_THREADS:
123124 return DISP_CMD_UPLOAD_THREADS;
125+ case NT_CMD_UPLOAD_NG_FILES:
126+ return DISP_CMD_UPLOAD_NG_FILES;
124127 case NT_CMD_DISP_HISTORY:
125128 return DISP_STATE_HISTORY;
126129 }
@@ -491,6 +494,9 @@ static int parse_cmd1(const char *param)
491494 }else if(0 == strncmp(start, NT_COMMAND1_UPLOAD_THREAD1,len) ||
492495 0 == strncmp(start, NT_COMMAND1_UPLOAD_THREAD2,len)){
493496 return NT_CMD_UPLOAD_THREADS;
497+ }else if(0 == strncmp(start, NT_COMMAND1_UPLOAD_NG_FILE1,len) ||
498+ 0 == strncmp(start, NT_COMMAND1_UPLOAD_NG_FILE2,len)){
499+ return NT_CMD_UPLOAD_NG_FILES;
494500 }
495501
496502 return NT_CMD_ERR;
--- a/src/ui/disp_history.c
+++ b/src/ui/disp_history.c
@@ -179,8 +179,10 @@ static BOOL set_model_data(nt_2ch_model_handle h_model,
179179 if(!nt_mutex_unlock(h_mutex)){
180180 assert(0);
181181 }
182- if(h_map)
182+ if(h_map){
183183 *update_board_list = nt_map_get_values(h_map);
184+ nt_map_free(h_map, NULL);
185+ }
184186 return TRUE;
185187 }
186188
--- a/src/ui/disp_reslist.c
+++ b/src/ui/disp_reslist.c
@@ -43,6 +43,12 @@
4343 #define NT_CMD_FAVORITE 6
4444 #define NT_CMD_HISTORY 7
4545 #define NT_CMD_AUTO_SCROLL 8
46+#define NT_CMD_ADD_NGWORD 9
47+#define NT_CMD_ADD_NGNAME 10
48+#define NT_CMD_ADD_NGID 11
49+#define NT_CMD_EDT_NGWORD 12
50+#define NT_CMD_EDT_NGNAME 13
51+#define NT_CMD_EDT_NGID 14
4652
4753 #define AUTO_SCROLL_NONE 0
4854 #define AUTO_SCROLL_UP -1
@@ -91,18 +97,21 @@ static BOOL reslist_clone(nt_thread_handle h_thread, ctx_reslist_tp ctxp);
9197 static void int_ptr_free(void *ptr);
9298 static int parse_cmd1(const char *param, const char **end);
9399 static BOOL search_line_asc(regex_t *regexp, nt_link_tp reslistp,
94- int *sel_res_no, int *sel_res_line, int column);
100+ int *sel_res_no, int *sel_res_line, int column,
101+ nt_ng_word_handle h_ngword);
95102 static BOOL search_line_desc(regex_t *regexp, ctx_reslist_tp ctxp,
96103 nt_link_tp reslistp,
97- int *sel_res_no, int *sel_res_line, int column);
104+ int *sel_res_no, int *sel_res_line, int column,
105+ nt_ng_word_handle h_ngword);
98106 static int parse_res_msg(nt_link_tp disp_res_list,
99- res_data_tp res_datap, size_t colmns);
107+ res_data_tp res_datap, size_t colmns, nt_ng_word_handle h_ngword);
100108 static void res_msg_free(void *ptr);
101109 static nt_link_tp get_cited_num_list(nt_link_tp res_listp, int seq_no);
102110 static BOOL reslist_copy(ctx_reslist_tp ctxp, ctx_reslist_tp copy_ctxp,
103111 nt_link_tp num_listp);
104112 static ctx_reslist_tp init_sub_context(ctx_reslist_tp ctxp, nt_link_tp num_listp);
105113 static void free_reslist_sub_ctx(void *ptr);
114+static void free_disp_lines_ctx(void *ptr);
106115 static nt_link_tp parse_tree_list(ctx_reslist_tp ctxp, const char *param);
107116 static nt_link_tp parse_id_list(ctx_reslist_tp ctxp, const char *param);
108117 static void search_up_tree(int seq_no, nt_link_tp disp_list, nt_link_tp *num_linkp);
@@ -112,7 +121,7 @@ static BOOL set_res_header(ctx_reslist_tp ctxp, res_data_tp res_datap,
112121 wchar_t *buf, size_t buf_len);
113122
114123 int disp_reslist(nt_window_tp wp, int prev_state, nt_2ch_selected_item_handle h_select,
115- nt_usr_db_handle usr_db_handle)
124+ nt_usr_db_handle usr_db_handle, nt_ng_word_handle h_ng_word, nt_cloud_handle h_cloud)
116125 {
117126 ctx_reslist_tp ctxp, child_ctxp;
118127 res_data_tp res_datap;
@@ -154,7 +163,8 @@ int disp_reslist(nt_window_tp wp, int prev_state, nt_2ch_selected_item_handle h_
154163 }
155164 }
156165
157- if(prev_state != DISP_STATE_RESLIST)
166+ if(prev_state != DISP_STATE_RESLIST &&
167+ prev_state < NT_KEY_CMD_BASE)
158168 ctxp->prev_state = prev_state;
159169
160170 ch = wp->key;
@@ -168,7 +178,7 @@ int disp_reslist(nt_window_tp wp, int prev_state, nt_2ch_selected_item_handle h_
168178 while(clistp != ctxp->res_disp_list){
169179 res_datap = (res_data_tp)clistp->data;
170180 if(!res_datap->msg_line_linkp){
171- parse_res_msg(ctxp->res_disp_list, res_datap, wp->cols-5);
181+ parse_res_msg(ctxp->res_disp_list, res_datap, wp->cols-5, h_ng_word);
172182 }
173183
174184 if(res_datap->msg_header_line_num <= 0){
@@ -344,14 +354,14 @@ int disp_reslist(nt_window_tp wp, int prev_state, nt_2ch_selected_item_handle h_
344354 if(search_asc){
345355 if(search_line_asc(&(ctxp->regex),ctxp->res_disp_list,
346356 &ctxp->sel_res_no, &ctxp->sel_res_line,
347- wp->cols - 5)){
357+ wp->cols - 5, h_ng_word)){
348358 adjust = TRUE;
349359 }
350360 }else{
351361 if(search_line_desc(&(ctxp->regex),ctxp,
352362 ctxp->res_disp_list,
353363 &ctxp->sel_res_no, &ctxp->sel_res_line,
354- wp->cols - 5)){
364+ wp->cols - 5, h_ng_word)){
355365 adjust = TRUE;
356366 }
357367 }
@@ -366,7 +376,7 @@ int disp_reslist(nt_window_tp wp, int prev_state, nt_2ch_selected_item_handle h_
366376 res_datap = (res_data_tp)clistp->data;
367377 //resp = (nt_res_tp)clistp->data;
368378 if(!res_datap->msg_line_linkp){
369- parse_res_msg(ctxp->res_disp_list, res_datap, wp->cols-5);
379+ parse_res_msg(ctxp->res_disp_list, res_datap, wp->cols-5, h_ng_word);
370380 }
371381 if(res_datap->msg_header_line_num <= 0){
372382 if(!set_res_header((ctx_reslist_tp)wp->data,
@@ -447,6 +457,27 @@ int disp_reslist(nt_window_tp wp, int prev_state, nt_2ch_selected_item_handle h_
447457 }
448458 ctxp->cur_res_offset = 0;
449459 break;
460+ case NT_CMD_ADD_NGWORD:
461+ nt_ng_word_add_ng_word(h_cloud, h_ng_word, endp);
462+ free_disp_lines_ctx(wp->data);
463+ return DISP_CMD_REENTER | DISP_STATE_RESLIST;
464+ case NT_CMD_ADD_NGNAME:
465+ nt_ng_word_add_ng_name(h_cloud, h_ng_word, endp);
466+ free_disp_lines_ctx(wp->data);
467+ return DISP_CMD_REENTER | DISP_STATE_RESLIST;
468+ case NT_CMD_ADD_NGID:
469+ nt_ng_word_add_ng_id(h_cloud, h_ng_word, endp);
470+ free_disp_lines_ctx(wp->data);
471+ return DISP_CMD_REENTER | DISP_STATE_RESLIST;
472+ case NT_CMD_EDT_NGWORD:
473+ free_disp_lines_ctx(wp->data);
474+ return DISP_CMD_EDIT_NGWORD | DISP_STATE_RESLIST;
475+ case NT_CMD_EDT_NGNAME:
476+ free_disp_lines_ctx(wp->data);
477+ return DISP_CMD_EDIT_NGNAME | DISP_STATE_RESLIST;
478+ case NT_CMD_EDT_NGID:
479+ free_disp_lines_ctx(wp->data);
480+ return DISP_CMD_EDIT_NGID | DISP_STATE_RESLIST;
450481 default:
451482 if(cmd == NT_CMD_TREE){
452483 linkp = parse_tree_list((ctx_reslist_tp)wp->data, endp);
@@ -516,7 +547,7 @@ int disp_reslist(nt_window_tp wp, int prev_state, nt_2ch_selected_item_handle h_
516547 break;
517548 res_datap = (res_data_tp)clistp->data;
518549 if(!res_datap->msg_line_linkp){
519- parse_res_msg(ctxp->res_disp_list, res_datap, wp->cols-5);
550+ parse_res_msg(ctxp->res_disp_list, res_datap, wp->cols-5, h_ng_word);
520551 }
521552 if(res_datap->msg_header_line_num <= 0){
522553 if(!set_res_header((ctx_reslist_tp)wp->data,
@@ -557,7 +588,7 @@ int disp_reslist(nt_window_tp wp, int prev_state, nt_2ch_selected_item_handle h_
557588 break;
558589 res_datap = (res_data_tp)clistp->data;
559590 if(!res_datap->msg_line_linkp){
560- parse_res_msg(ctxp->res_disp_list, res_datap, wp->cols-5);
591+ parse_res_msg(ctxp->res_disp_list, res_datap, wp->cols-5, h_ng_word);
561592 }
562593 if(res_datap->msg_header_line_num <= 0){
563594 if(!set_res_header((ctx_reslist_tp)wp->data,
@@ -608,7 +639,7 @@ int disp_reslist(nt_window_tp wp, int prev_state, nt_2ch_selected_item_handle h_
608639 for( ; i > 0; i--){
609640 res_datap = (res_data_tp)clistp->data;
610641 if(!res_datap->msg_line_linkp){
611- parse_res_msg(ctxp->res_disp_list, res_datap, wp->cols-5);
642+ parse_res_msg(ctxp->res_disp_list, res_datap, wp->cols-5, h_ng_word);
612643 }
613644 if(res_datap->msg_header_line_num <= 0){
614645 if(!set_res_header((ctx_reslist_tp)wp->data,
@@ -665,7 +696,7 @@ int disp_reslist(nt_window_tp wp, int prev_state, nt_2ch_selected_item_handle h_
665696 for( ; i < ctxp->res_num; i++){
666697 res_datap = (res_data_tp)clistp->data;
667698 if(!res_datap->msg_line_linkp){
668- parse_res_msg(ctxp->res_disp_list, res_datap, wp->cols-5);
699+ parse_res_msg(ctxp->res_disp_list, res_datap, wp->cols-5, h_ng_word);
669700 }
670701 if(res_datap->msg_header_line_num <= 0){
671702 if(!set_res_header((ctx_reslist_tp)wp->data,
@@ -768,7 +799,7 @@ int disp_reslist(nt_window_tp wp, int prev_state, nt_2ch_selected_item_handle h_
768799 if(rows == wp->lines)
769800 break;
770801 if(!res_datap->msg_line_linkp){
771- parse_res_msg(ctxp->res_disp_list, res_datap, wp->cols-5);
802+ parse_res_msg(ctxp->res_disp_list, res_datap, wp->cols-5, h_ng_word);
772803 }
773804 if(0 == res_datap->msg_line_num)
774805 continue;
@@ -935,6 +966,35 @@ static int parse_cmd1(const char *param, const char **end)
935966 0 == strncmp(NT_COMMAND1_AUTOSCROLL_2,param,
936967 strlen(NT_COMMAND1_AUTOSCROLL_2))){
937968 return NT_CMD_AUTO_SCROLL;
969+ }else if(0 == strncmp(NT_COMMAND1_NG_WORD_1,param,len) ||
970+ 0 == strncmp(NT_COMMAND1_NG_WORD_2,param, len)){
971+ if(!nt_strtok(*end, ' ', &start, end))
972+ return NT_CMD_EDT_NGWORD;
973+
974+ len = *end - start;
975+ if(len <= 0)
976+ return NT_CMD_EDT_NGWORD;
977+ *end = start;
978+ return NT_CMD_ADD_NGWORD;
979+ }else if(0 == strncmp(NT_COMMAND1_NG_NAME_1,param,len) ||
980+ 0 == strncmp(NT_COMMAND1_NG_NAME_2,param, len)){
981+ if(!nt_strtok(*end, ' ', &start, end))
982+ return NT_CMD_EDT_NGNAME;
983+
984+ len = *end - start;
985+ if(len <= 0)
986+ return NT_CMD_EDT_NGNAME;
987+ *end = start;
988+ return NT_CMD_ADD_NGNAME;
989+ }else if(0 == strncmp(NT_COMMAND1_NG_ID_1,param,len)){
990+ if(!nt_strtok(*end, ' ', &start, end))
991+ return NT_CMD_EDT_NGID;
992+
993+ len = *end - start;
994+ if(len <= 0)
995+ return NT_CMD_EDT_NGID;
996+ *end = start;
997+ return NT_CMD_ADD_NGID;
938998 }
939999 return NT_CMD_NONE;
9401000 }
@@ -1035,6 +1095,20 @@ static ctx_reslist_tp init_sub_context(ctx_reslist_tp ctxp, nt_link_tp num_listp
10351095 return child_ctxp;
10361096 }
10371097
1098+static const wchar_t *get_id(const wchar_t *source)
1099+{
1100+ const wchar_t *cptr;
1101+ if(!source)
1102+ return NULL;
1103+ cptr = wcsstr(source, L"ID:");
1104+ if(!cptr)
1105+ return NULL;
1106+ cptr += 3;
1107+ if(cptr[0] == L'\0' || cptr[0] == L'?')
1108+ return NULL;
1109+ return cptr;
1110+}
1111+
10381112 static BOOL reslist_clone(nt_thread_handle h_thread, ctx_reslist_tp ctxp)
10391113 {
10401114 nt_enum_handle h_enum_res;
@@ -1131,6 +1205,36 @@ void free_reslist_ctx(void *ptr)
11311205 }
11321206 free(ptr);
11331207 }
1208+
1209+static void free_disp_lines_ctx(void *ptr)
1210+{
1211+ ctx_reslist_tp ctxp;
1212+ nt_stack_tp stackp;
1213+ nt_link_tp linkp;
1214+ res_data_tp res_datap;
1215+ if(!ptr)
1216+ return;
1217+ ctxp = (ctx_reslist_tp)ptr;
1218+ if(ctxp->res_disp_list){
1219+ linkp = ctxp->res_disp_list;
1220+ do{
1221+ res_datap = (res_data_tp)linkp->data;
1222+ if(res_datap->msg_line_linkp){
1223+ free(res_datap->msg_line_linkp->data);
1224+ nt_all_link_free(res_datap->msg_line_linkp, NULL);
1225+ res_datap->msg_line_linkp = NULL;
1226+ }
1227+ res_datap->msg_line_num = 0;
1228+ linkp = linkp->next;
1229+ }while(linkp != ctxp->res_disp_list);
1230+ }
1231+ stackp = ctxp->child_ctx_stackp;
1232+ if(stackp){
1233+ nt_stack_free(stackp, free_reslist_sub_ctx);
1234+ ctxp->child_ctx_stackp = NULL;
1235+ }
1236+}
1237+
11341238 static void free_reslist_sub_ctx(void *ptr)
11351239 {
11361240 ctx_reslist_tp ctxp;
@@ -1223,11 +1327,14 @@ static nt_link_tp get_cited_num_list(nt_link_tp res_listp, int seq_no)
12231327 }
12241328
12251329 static int parse_res_msg(nt_link_tp disp_res_list,
1226- res_data_tp res_datap, size_t colmns)
1330+ res_data_tp res_datap, size_t colmns,
1331+ nt_ng_word_handle h_ngword)
12271332 {
1228- int i, len, start, lines;
1333+ int i, len, start, lines, nwrite;
12291334 wchar_t ch;
12301335 wchar_t *buf, *cptr, *srcp, *wrk_buf;
1336+ const wchar_t *name, *id, *misc;
1337+ wchar_t match[256];
12311338 int offset;
12321339 nt_link_tp linkp;
12331340 int consume_colmns;
@@ -1240,8 +1347,47 @@ static int parse_res_msg(nt_link_tp disp_res_list,
12401347
12411348 //res_msg_free(res_datap);
12421349 res_datap->msg_line_num = 0;
1243-
1244- len = wcslen(res_datap->res_msg);
1350+
1351+ name = nt_res_get_name(res_datap->h_res);
1352+ misc = nt_res_get_misc(res_datap->h_res);
1353+ if(misc)
1354+ id = get_id(misc);
1355+ else
1356+ id = NULL;
1357+ cptr = NULL;
1358+ if(name && NG_ITEM_NAME ==
1359+ ng_word_match(h_ngword, NG_ITEM_NAME, name,
1360+ match, sizeof(match)/sizeof(wchar_t))){
1361+ cptr = L"NGNAME:";
1362+ }else if(id && NG_ITEM_ID ==
1363+ ng_word_match(h_ngword, NG_ITEM_ID, id,
1364+ match, sizeof(match)/sizeof(wchar_t))){
1365+ cptr = L"NGID:";
1366+ }else if(NG_ITEM_MSG == ng_word_match(h_ngword, NG_ITEM_MSG,
1367+ res_datap->res_msg,
1368+ match, sizeof(match)/sizeof(wchar_t))){
1369+ cptr = L"NGWORD:";
1370+ }
1371+ if(cptr){
1372+ len = wcslen(cptr) + wcslen(match) + 1;
1373+ buf = malloc(len*sizeof(wchar_t));
1374+ if(!buf)
1375+ return 0;
1376+ swprintf(buf, len, L"%ls%ls", cptr, match);
1377+ nwrite = nt_get_wc_count_within_colmns(buf, colmns);
1378+ if(nwrite <= 0){
1379+ free(buf);
1380+ return 0;
1381+ }
1382+ buf[nwrite] = L'\0';
1383+ res_datap->msg_line_num = 1;
1384+ res_datap->msg_line_linkp = nt_link_add_data(NULL, buf);
1385+ return 1;
1386+ }
1387+
1388+ srcp = res_datap->res_msg;
1389+
1390+ len = wcslen(srcp);
12451391 if(len == 0)
12461392 return 0;
12471393 buf_size = len + delta;
@@ -1253,7 +1399,6 @@ static int parse_res_msg(nt_link_tp disp_res_list,
12531399 return 0;
12541400 buf_idx = 0;
12551401
1256- srcp = res_datap->res_msg;
12571402
12581403 lines = 0;
12591404 start = 0;
@@ -1340,7 +1485,7 @@ END_FOR:
13401485 }
13411486
13421487 static BOOL search_line_asc(regex_t *regexp, nt_link_tp reslistp,
1343- int *sel_res_no, int *sel_res_line, int column)
1488+ int *sel_res_no, int *sel_res_line, int column, nt_ng_word_handle h_ngword)
13441489 {
13451490 nt_link_tp clistp, listp;
13461491 //nt_res_tp resp;
@@ -1370,7 +1515,7 @@ static BOOL search_line_asc(regex_t *regexp, nt_link_tp reslistp,
13701515 res_datap = (res_data_tp)clistp->data;
13711516 //resp = res_datap->resp;
13721517 if(!res_datap->msg_line_linkp)
1373- parse_res_msg(reslistp, res_datap, column);
1518+ parse_res_msg(reslistp, res_datap, column, h_ngword);
13741519 listp = res_datap->msg_line_linkp;
13751520 line = 0;
13761521 do{
@@ -1402,7 +1547,7 @@ static BOOL search_line_asc(regex_t *regexp, nt_link_tp reslistp,
14021547
14031548 res_datap = (res_data_tp)clistp->data;
14041549 if(!res_datap->msg_line_linkp)
1405- parse_res_msg(reslistp, res_datap, column);
1550+ parse_res_msg(reslistp, res_datap, column, h_ngword);
14061551 listp = res_datap->msg_line_linkp;
14071552 line = 0;
14081553 do{
@@ -1429,7 +1574,8 @@ static BOOL search_line_asc(regex_t *regexp, nt_link_tp reslistp,
14291574
14301575 static BOOL search_line_desc(regex_t *regexp, ctx_reslist_tp ctxp,
14311576 nt_link_tp reslistp,
1432- int *sel_res_no, int *sel_res_line, int column)
1577+ int *sel_res_no, int *sel_res_line, int column,
1578+ nt_ng_word_handle h_ngword)
14331579 {
14341580 nt_link_tp clistp, listp;
14351581 //nt_res_tp resp;
@@ -1461,7 +1607,7 @@ static BOOL search_line_desc(regex_t *regexp, ctx_reslist_tp ctxp,
14611607 res_datap = (res_data_tp)clistp->data;
14621608 //resp = res_datap->resp;
14631609 if(!res_datap->msg_line_linkp)
1464- parse_res_msg(reslistp, res_datap, column);
1610+ parse_res_msg(reslistp, res_datap, column, h_ngword);
14651611 listp = res_datap->msg_line_linkp->prev;
14661612 line = res_datap->msg_line_num - 1;
14671613 do{
@@ -1494,7 +1640,7 @@ static BOOL search_line_desc(regex_t *regexp, ctx_reslist_tp ctxp,
14941640 res_datap = (res_data_tp)clistp->data;
14951641 //resp = (nt_res_tp)clistp->data;
14961642 if(!res_datap->msg_line_linkp)
1497- parse_res_msg(reslistp, res_datap, column);
1643+ parse_res_msg(reslistp, res_datap, column, h_ngword);
14981644 listp = res_datap->msg_line_linkp->prev;
14991645 line = res_datap->msg_line_num - 1;
15001646 do{
--- a/src/usr/favorite_t.c
+++ b/src/usr/favorite_t.c
@@ -1345,7 +1345,7 @@ nt_link_tp nt_favorite_get_update_board_list(
13451345 nt_board_handle h_board;
13461346 nt_mutex_handle h_mutex;
13471347 nt_link_tp res_linkp, tmp_linkp, board_name_linkp;
1348- const wchar_t *board_name, *cptr;
1348+ const wchar_t *board_name;
13491349
13501350 h_mutex = nt_favorite_get_mutex(h_favorite);
13511351 if(!h_mutex){
@@ -1372,10 +1372,10 @@ nt_link_tp nt_favorite_get_update_board_list(
13721372 if(!board_name)
13731373 continue;
13741374 if(board_name_linkp){
1375- cptr = (const wchar_t*)nt_link_find(
1376- board_name_linkp, (void*)board_name, nt_link_wcscmp_fnc);
1377- if(cptr)
1375+ if(nt_link_find(board_name_linkp,
1376+ (void*)board_name, nt_link_wcscmp_fnc)){
13781377 continue;
1378+ }
13791379 }
13801380 //fwprintf(stderr, L"%ls\n", board_name);
13811381 h_board = nt_get_board_by_name(h_model, board_name, &h_category);
--- /dev/null
+++ b/src/usr/ng_word_t.c
@@ -0,0 +1,791 @@
1+/* Copyright 2014 Akira Ohta (akohta001@gmail.com)
2+ This file is part of ntch.
3+
4+ The ntch is free software: you can redistribute it and/or modify
5+ it under the terms of the GNU General Public License as published by
6+ the Free Software Foundation, either version 3 of the License, or
7+ (at your option) any later version.
8+
9+ The ntch is distributed in the hope that it will be useful,
10+ but WITHOUT ANY WARRANTY; without even the implied warranty of
11+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+ GNU General Public License for more details.
13+
14+ You should have received a copy of the GNU General Public License
15+ along with ntch. If not, see <http://www.gnu.org/licenses/>.
16+
17+*/
18+#include <stdio.h>
19+#include <stdlib.h>
20+#include <string.h>
21+#include <unistd.h>
22+#include <wchar.h>
23+#include <assert.h>
24+#include <iconv.h>
25+#include <sys/types.h>
26+#include <regex.h>
27+
28+
29+#include "usr/ng_word_t.h"
30+#include "usr/usr_db_t.h"
31+#include "utils/text.h"
32+#include "utils/file.h"
33+#include "utils/nt_conv_char.h"
34+
35+#define NT_NG_WORD_CHK_SUM (1678428)
36+
37+#define NT_NG_ROOT_MUTEX_KEY (L"ng")
38+#define NT_NG_WORD_MUTEX_KEY (L"ng_word")
39+#define NT_NG_NAME_MUTEX_KEY (L"ng_name")
40+#define NT_NG_ID_MUTEX_KEY (L"ng_id")
41+
42+
43+typedef struct tag_nt_ng_word_t *nt_ng_word_tp;
44+typedef struct tag_nt_ng_word_t {
45+ nt_ng_word_handle_t handle;
46+ int ref_count;
47+ wchar_t *key;
48+ nt_link_tp ng_words;
49+ nt_link_tp ng_names;
50+ nt_link_tp ng_ids;
51+ nt_link_tp ng_word_patterns;
52+ nt_link_tp ng_name_patterns;
53+ nt_link_tp ng_id_patterns;
54+ nt_link_tp ng_word_reg_patterns;
55+ nt_link_tp ng_name_reg_patterns;
56+ nt_link_tp ng_id_reg_patterns;
57+} nt_ng_word_t;
58+
59+static nt_mutex_handle local_ng_word_get_mutex(
60+ const wchar_t *key, nt_ng_word_handle handle);
61+static nt_ng_word_handle nt_ng_word_alloc();
62+static BOOL ng_word_add(
63+ nt_cloud_handle h_cloud, const char *cloud_file_name,
64+ nt_ng_word_handle handle,
65+ const char *ng_word,
66+ nt_link_tp *org_linkpp,
67+ nt_link_tp *text_linkpp,
68+ nt_link_tp *regx_linkpp);
69+static wchar_t *parse_plain_text(const wchar_t *source);
70+static regex_t *get_regx_pattern(const char *source);
71+static BOOL word_match_local(nt_ng_word_tp ng_wordp,
72+ const wchar_t *source,
73+ nt_link_tp patterns,
74+ nt_link_tp reg_patterns,
75+ wchar_t *match_buf, size_t match_buf_len);
76+
77+
78+static wchar_t *parse_plain_text(const wchar_t *source){
79+ if(!source || source[0] == L'\0')
80+ return NULL;
81+
82+ if(source[0] == L'\\' &&
83+ source[0] == L'/'){
84+ return nt_w_str_clone(source+1);
85+ }else{
86+ return nt_w_str_clone(source);
87+ }
88+}
89+
90+static regex_t *get_regx_pattern(const char *source)
91+{
92+ int len, cflags;
93+ char *cptr;
94+ char buf[256];
95+ regex_t *regp;
96+
97+ if(!source || '\0' == source[0])
98+ return NULL;
99+
100+ if('/' != source[0])
101+ return NULL;
102+
103+ cptr = strrchr (source, '/');
104+ if(!cptr || cptr == source)
105+ return NULL;
106+ cflags = REG_NEWLINE | REG_EXTENDED;
107+ if(cptr[1] == 'i')
108+ cflags |= REG_ICASE;
109+
110+ len = cptr - source - 1;
111+ if(len >= sizeof(buf)-1)
112+ return NULL;
113+ strncpy(buf, source+1, len);
114+ buf[len] = '\0';
115+
116+ regp = malloc(sizeof(regex_t));
117+ if(!regp){
118+ return NULL;
119+ }
120+ if(0 != regcomp(regp, buf, cflags)){
121+ free(regp);
122+ return NULL;
123+ }
124+ return regp;
125+}
126+
127+nt_link_tp nt_ng_word_get_words(nt_ng_word_handle handle)
128+{
129+ nt_ng_word_tp ng_wordp;
130+ assert(handle);
131+ assert(handle->chk_sum == NT_NG_WORD_CHK_SUM);
132+ ng_wordp = (nt_ng_word_tp)handle;
133+ assert(ng_wordp->ref_count > 0);
134+ return ng_wordp->ng_words;
135+}
136+
137+nt_link_tp nt_ng_word_get_names(nt_ng_word_handle handle)
138+{
139+ nt_ng_word_tp ng_wordp;
140+ assert(handle);
141+ assert(handle->chk_sum == NT_NG_WORD_CHK_SUM);
142+ ng_wordp = (nt_ng_word_tp)handle;
143+ assert(ng_wordp->ref_count > 0);
144+ return ng_wordp->ng_names;
145+}
146+
147+nt_link_tp nt_ng_word_get_ids(nt_ng_word_handle handle)
148+{
149+ nt_ng_word_tp ng_wordp;
150+ assert(handle);
151+ assert(handle->chk_sum == NT_NG_WORD_CHK_SUM);
152+ ng_wordp = (nt_ng_word_tp)handle;
153+ assert(ng_wordp->ref_count > 0);
154+ return ng_wordp->ng_ids;
155+}
156+
157+static void reg_free(void *ptr){
158+ regex_t *regp;
159+ regp = (regex_t*)ptr;
160+ regfree(regp);
161+ free(regp);
162+}
163+
164+BOOL nt_ng_word_set_words(nt_ng_word_handle handle,
165+ nt_link_tp text_list, nt_cloud_handle h_cloud)
166+{
167+ nt_ng_word_tp ng_wordp;
168+ nt_link_tp linkp;
169+ wchar_t *cptr;
170+ char buf[256];
171+
172+ assert(handle);
173+ assert(handle->chk_sum == NT_NG_WORD_CHK_SUM);
174+ ng_wordp = (nt_ng_word_tp)handle;
175+ assert(ng_wordp->ref_count > 0);
176+ if(ng_wordp->ng_words)
177+ nt_all_link_free(ng_wordp->ng_words, free);
178+ if(ng_wordp->ng_word_patterns)
179+ nt_all_link_free(ng_wordp->ng_word_patterns, free);
180+ if(ng_wordp->ng_word_reg_patterns)
181+ nt_all_link_free(ng_wordp->ng_word_reg_patterns, reg_free);
182+ ng_wordp->ng_words = NULL;
183+ ng_wordp->ng_word_patterns = NULL;
184+ ng_wordp->ng_word_reg_patterns = NULL;
185+ if(text_list){
186+ linkp = text_list;
187+ do{
188+ cptr = (wchar_t*)linkp->data;
189+ if((size_t)-1 != wcstombs(buf, cptr, sizeof(buf))){
190+ nt_ng_word_add_ng_word(NULL, &ng_wordp->handle, buf);
191+ }
192+ linkp = linkp->next;
193+ }while(linkp != text_list);
194+ nt_all_link_free(text_list, free);
195+ if(h_cloud)
196+ nt_cloud_upload_file(h_cloud,
197+ "ngwd.txt", ng_wordp->ng_words);
198+ }
199+ return TRUE;
200+}
201+
202+BOOL nt_ng_word_set_names(nt_ng_word_handle handle,
203+ nt_link_tp text_list, nt_cloud_handle h_cloud)
204+{
205+ nt_ng_word_tp ng_wordp;
206+ nt_link_tp linkp;
207+ wchar_t *cptr;
208+ char buf[256];
209+
210+ assert(handle);
211+ assert(handle->chk_sum == NT_NG_WORD_CHK_SUM);
212+ ng_wordp = (nt_ng_word_tp)handle;
213+ assert(ng_wordp->ref_count > 0);
214+ if(ng_wordp->ng_names)
215+ nt_all_link_free(ng_wordp->ng_names, free);
216+ if(ng_wordp->ng_name_patterns)
217+ nt_all_link_free(ng_wordp->ng_name_patterns, free);
218+ if(ng_wordp->ng_name_reg_patterns)
219+ nt_all_link_free(ng_wordp->ng_name_reg_patterns, reg_free);
220+ ng_wordp->ng_names = NULL;
221+ ng_wordp->ng_name_patterns = NULL;
222+ ng_wordp->ng_name_reg_patterns = NULL;
223+ if(text_list){
224+ linkp = text_list;
225+ do{
226+ cptr = (wchar_t*)linkp->data;
227+ if((size_t)-1 != wcstombs(buf, cptr, sizeof(buf))){
228+ nt_ng_word_add_ng_name(NULL, &ng_wordp->handle, buf);
229+ }
230+ linkp = linkp->next;
231+ }while(linkp != text_list);
232+ nt_all_link_free(text_list, free);
233+ if(h_cloud)
234+ nt_cloud_upload_file(h_cloud,
235+ "ngnm.txt", ng_wordp->ng_names);
236+ }
237+ return TRUE;
238+}
239+
240+BOOL nt_ng_word_set_ids(nt_ng_word_handle handle,
241+ nt_link_tp text_list, nt_cloud_handle h_cloud)
242+{
243+ nt_ng_word_tp ng_wordp;
244+ nt_link_tp linkp;
245+ wchar_t *cptr;
246+ char buf[256];
247+
248+ assert(handle);
249+ assert(handle->chk_sum == NT_NG_WORD_CHK_SUM);
250+ ng_wordp = (nt_ng_word_tp)handle;
251+ assert(ng_wordp->ref_count > 0);
252+ if(ng_wordp->ng_ids)
253+ nt_all_link_free(ng_wordp->ng_ids, free);
254+ if(ng_wordp->ng_id_patterns)
255+ nt_all_link_free(ng_wordp->ng_id_patterns, free);
256+ if(ng_wordp->ng_id_reg_patterns)
257+ nt_all_link_free(ng_wordp->ng_id_reg_patterns, reg_free);
258+ ng_wordp->ng_ids = NULL;
259+ ng_wordp->ng_id_patterns = NULL;
260+ ng_wordp->ng_id_reg_patterns = NULL;
261+ if(text_list){
262+ linkp = text_list;
263+ do{
264+ cptr = (wchar_t*)linkp->data;
265+ if((size_t)-1 != wcstombs(buf, cptr, sizeof(buf))){
266+ nt_ng_word_add_ng_id(NULL, &ng_wordp->handle, buf);
267+ }
268+ linkp = linkp->next;
269+ }while(linkp != text_list);
270+ nt_all_link_free(text_list, free);
271+ if(h_cloud)
272+ nt_cloud_upload_file(h_cloud,
273+ "ngid.txt", ng_wordp->ng_ids);
274+ }
275+ return TRUE;
276+}
277+
278+nt_ng_word_handle nt_ng_word_load(
279+ nt_cloud_handle h_cloud,
280+ const char *ng_word_file_name,
281+ const char *ng_name_file_name,
282+ const char *ng_id_file_name
283+ )
284+{
285+ nt_ng_word_tp ng_wordp;
286+ nt_link_tp text_linkp, linkp;
287+ wchar_t *cptr;
288+ char buf[256];
289+
290+ ng_wordp = (nt_ng_word_tp)nt_ng_word_alloc();
291+ if(!ng_wordp)
292+ return NULL;
293+ text_linkp = NULL;
294+ if(h_cloud)
295+ text_linkp = nt_cloud_download_file(h_cloud, "ngwd.txt");
296+ if(!text_linkp)
297+ text_linkp = nt_read_text_file(ng_word_file_name);
298+ if(text_linkp){
299+ linkp = text_linkp;
300+ do{
301+ cptr = (wchar_t*)linkp->data;
302+ if((size_t)-1 != wcstombs(buf, cptr, sizeof(buf))){
303+ nt_ng_word_add_ng_word(NULL, &ng_wordp->handle, buf);
304+ }
305+ linkp = linkp->next;
306+ }while(linkp != text_linkp);
307+ nt_all_link_free(text_linkp, free);
308+ }
309+ text_linkp = NULL;
310+ if(h_cloud)
311+ text_linkp = nt_cloud_download_file(h_cloud, "ngnm.txt");
312+ if(!text_linkp)
313+ text_linkp = nt_read_text_file(ng_name_file_name);
314+ if(text_linkp){
315+ linkp = text_linkp;
316+ do{
317+ cptr = (wchar_t*)linkp->data;
318+ if((size_t)-1 != wcstombs(buf, cptr, sizeof(buf))){
319+ nt_ng_word_add_ng_name(NULL, &ng_wordp->handle, buf);
320+ }
321+ linkp = linkp->next;
322+ }while(linkp != text_linkp);
323+ nt_all_link_free(text_linkp, free);
324+ }
325+ text_linkp = NULL;
326+ if(h_cloud)
327+ text_linkp = nt_cloud_download_file(h_cloud, "ngid.txt");
328+ if(!text_linkp)
329+ text_linkp = nt_read_text_file(ng_id_file_name);
330+ if(text_linkp){
331+ linkp = text_linkp;
332+ do{
333+ cptr = (wchar_t*)linkp->data;
334+ if((size_t)-1 != wcstombs(buf, cptr, sizeof(buf))){
335+ nt_ng_word_add_ng_id(NULL, &ng_wordp->handle, buf);
336+ }
337+ linkp = linkp->next;
338+ }while(linkp != text_linkp);
339+ nt_all_link_free(text_linkp, free);
340+ }
341+
342+ return &ng_wordp->handle;
343+}
344+
345+BOOL nt_ng_word_save(nt_ng_word_handle handle,
346+ const char *ng_word_file_name,
347+ const char *ng_name_file_name,
348+ const char *ng_id_file_name
349+ )
350+{
351+ nt_ng_word_tp ng_wordp;
352+ nt_mutex_handle h_mutex;
353+
354+ assert(handle);
355+ assert(handle->chk_sum == NT_NG_WORD_CHK_SUM);
356+ ng_wordp = (nt_ng_word_tp)handle;
357+ assert(ng_wordp->ref_count > 0);
358+
359+ h_mutex = nt_ng_get_mutex(handle);
360+ if(h_mutex)
361+ nt_mutex_lock(h_mutex);
362+
363+ if(ng_wordp->ng_words)
364+ nt_write_text_file(ng_word_file_name, ng_wordp->ng_words);
365+ if(ng_wordp->ng_names)
366+ nt_write_text_file(ng_name_file_name, ng_wordp->ng_names);
367+ if(ng_wordp->ng_ids)
368+ nt_write_text_file(ng_id_file_name, ng_wordp->ng_ids);
369+
370+ if(h_mutex)
371+ nt_mutex_unlock(h_mutex);
372+ return TRUE;
373+}
374+
375+BOOL nt_ng_word_add_ng_word(
376+ nt_cloud_handle h_cloud,
377+ nt_ng_word_handle handle, const char *ng_word)
378+{
379+ nt_ng_word_tp ng_wordp;
380+ nt_mutex_handle h_mutex;
381+ BOOL bret;
382+ assert(handle);
383+ assert(handle->chk_sum == NT_NG_WORD_CHK_SUM);
384+ ng_wordp = (nt_ng_word_tp)handle;
385+ assert(ng_wordp->ref_count > 0);
386+ h_mutex = nt_ng_word_get_mutex(handle);
387+ if(h_mutex)
388+ nt_mutex_lock(h_mutex);
389+ bret = ng_word_add(
390+ h_cloud, "ngwd.txt",
391+ handle, ng_word,
392+ &ng_wordp->ng_words,
393+ &ng_wordp->ng_word_patterns,
394+ &ng_wordp->ng_word_reg_patterns);
395+ if(h_mutex)
396+ nt_mutex_unlock(h_mutex);
397+ return bret;
398+}
399+
400+BOOL nt_ng_word_add_ng_name(
401+ nt_cloud_handle h_cloud,
402+ nt_ng_word_handle handle, const char *ng_name)
403+{
404+ nt_ng_word_tp ng_wordp;
405+ nt_mutex_handle h_mutex;
406+ BOOL bret;
407+ assert(handle);
408+ assert(handle->chk_sum == NT_NG_WORD_CHK_SUM);
409+ ng_wordp = (nt_ng_word_tp)handle;
410+ assert(ng_wordp->ref_count > 0);
411+ h_mutex = nt_ng_name_get_mutex(handle);
412+ if(h_mutex)
413+ nt_mutex_lock(h_mutex);
414+ bret = ng_word_add(
415+ h_cloud, "ngnm.txt",
416+ handle, ng_name,
417+ &ng_wordp->ng_names,
418+ &ng_wordp->ng_name_patterns,
419+ &ng_wordp->ng_name_reg_patterns);
420+ if(h_mutex)
421+ nt_mutex_unlock(h_mutex);
422+ return bret;
423+}
424+
425+BOOL nt_ng_word_add_ng_id(
426+ nt_cloud_handle h_cloud,
427+ nt_ng_word_handle handle, const char *ng_id)
428+{
429+ nt_ng_word_tp ng_wordp;
430+ nt_mutex_handle h_mutex;
431+ BOOL bret;
432+ assert(handle);
433+ assert(handle->chk_sum == NT_NG_WORD_CHK_SUM);
434+ ng_wordp = (nt_ng_word_tp)handle;
435+ assert(ng_wordp->ref_count > 0);
436+ h_mutex = nt_ng_id_get_mutex(handle);
437+ if(h_mutex)
438+ nt_mutex_lock(h_mutex);
439+ bret = ng_word_add(
440+ h_cloud, "ngid.txt",
441+ handle, ng_id,
442+ &ng_wordp->ng_ids,
443+ &ng_wordp->ng_id_patterns,
444+ &ng_wordp->ng_id_reg_patterns);
445+ if(h_mutex)
446+ nt_mutex_unlock(h_mutex);
447+ return bret;
448+}
449+
450+static BOOL ng_word_add(
451+ nt_cloud_handle h_cloud, const char *cloud_file_name,
452+ nt_ng_word_handle handle,
453+ const char *ng_word,
454+ nt_link_tp *org_linkpp,
455+ nt_link_tp *text_linkpp,
456+ nt_link_tp *regx_linkpp)
457+{
458+ int len;
459+ wchar_t wbuf[1024];
460+ wchar_t *cptr;
461+ nt_link_tp linkp;
462+ regex_t *regp;
463+
464+ if(!ng_word || (0 == (len = strlen(ng_word))))
465+ return FALSE;
466+
467+ if(-1 == mbstowcs(wbuf, ng_word, sizeof(wbuf)))
468+ return FALSE;
469+
470+ if(*org_linkpp){
471+ cptr = (wchar_t*)nt_link_find(
472+ *org_linkpp, (void*)wbuf, nt_link_wcscmp_fnc);
473+ if(cptr)
474+ return TRUE;
475+ }
476+
477+ if(NULL == (cptr = nt_w_str_clone(wbuf)))
478+ return FALSE;
479+ linkp = nt_link_add_data(*org_linkpp, cptr);
480+ if(!linkp){
481+ free(cptr);
482+ return FALSE;
483+ }
484+ if(!(*org_linkpp))
485+ *org_linkpp = linkp;
486+
487+ if(h_cloud){
488+ cptr = nt_w_str_clone(wbuf);
489+ if(cptr){
490+ linkp = nt_link_add_data(NULL, (void*)cptr);
491+ if(linkp){
492+ nt_cloud_insert_lines_into_file_async(h_cloud, cloud_file_name, linkp);
493+ }
494+ }
495+ }
496+
497+ if(NULL != (regp = get_regx_pattern(ng_word))){
498+ linkp = nt_link_add_data(*regx_linkpp, regp);
499+ if(!linkp){
500+ regfree(regp);
501+ free(regp);
502+ return FALSE;
503+ }
504+ if(!(*regx_linkpp))
505+ *regx_linkpp = linkp;
506+ return TRUE;
507+ }
508+ if(NULL != (cptr = parse_plain_text(wbuf))){
509+ linkp = nt_link_add_data(*text_linkpp, cptr);
510+ if(!linkp){
511+ free(cptr);
512+ return FALSE;
513+ }
514+ if(!(*text_linkpp))
515+ *text_linkpp = linkp;
516+ return TRUE;
517+ }
518+
519+ return FALSE;
520+}
521+
522+int ng_word_match(nt_ng_word_handle handle,
523+ int item_type, const wchar_t *source,
524+ wchar_t *match_buf, size_t match_buf_len)
525+{
526+ nt_ng_word_tp ng_wordp;
527+
528+ //assert(match);
529+ assert(handle);
530+ assert(handle->chk_sum == NT_NG_WORD_CHK_SUM);
531+ ng_wordp = (nt_ng_word_tp)handle;
532+ assert(ng_wordp->ref_count > 0);
533+ if(item_type & NG_ITEM_MSG){
534+ if(word_match_local(ng_wordp, source,
535+ ng_wordp->ng_word_patterns,
536+ ng_wordp->ng_word_reg_patterns,
537+ match_buf, match_buf_len)){
538+ return NG_ITEM_MSG;
539+ }
540+ }else if(item_type & NG_ITEM_NAME){
541+ if(word_match_local(ng_wordp, source,
542+ ng_wordp->ng_name_patterns,
543+ ng_wordp->ng_name_reg_patterns,
544+ match_buf, match_buf_len)){
545+ return NG_ITEM_NAME;
546+ }
547+ }else if(item_type & NG_ITEM_ID){
548+ if(word_match_local(ng_wordp, source,
549+ ng_wordp->ng_id_patterns,
550+ ng_wordp->ng_id_reg_patterns,
551+ match_buf, match_buf_len)){
552+ return NG_ITEM_ID;
553+ }
554+ }
555+ return NG_ITEM_NONE;
556+}
557+
558+static BOOL word_match_local(nt_ng_word_tp ng_wordp,
559+ const wchar_t *source,
560+ nt_link_tp patterns,
561+ nt_link_tp reg_patterns,
562+ wchar_t *match_buf, size_t match_buf_len)
563+{
564+ nt_link_tp linkp;
565+ wchar_t *cptr1, *cptr2;
566+ regex_t *regp;
567+ regmatch_t match[2];
568+ char *ptr;
569+ int len;
570+
571+ if(patterns){
572+ linkp = patterns;
573+ do{
574+ cptr1 = (wchar_t*)linkp->data;
575+ if(NULL != (cptr2 = wcsstr(source, cptr1))){
576+ if(match_buf_len > wcslen(cptr1))
577+ wcscpy(match_buf, cptr1);
578+ else
579+ match_buf[0] = L'\0';
580+ return TRUE;
581+ }
582+ linkp = linkp->next;
583+ }while(linkp != patterns);
584+ }
585+ if(reg_patterns){
586+ len = wcslen(source);
587+ if(len == 0)
588+ goto EXIT_NG_ITEM_MSG;
589+ ptr = malloc((len+1)*3);/*max utf-8 char size*/
590+ if(!ptr)
591+ goto EXIT_NG_ITEM_MSG;
592+ if((size_t)-1 == wcstombs(ptr, source, (len+1)*3)){
593+ free(ptr);
594+ goto EXIT_NG_ITEM_MSG;
595+ }
596+ linkp = reg_patterns;
597+ do{
598+ regp = (regex_t*)linkp->data;
599+ if(0 == regexec(regp, ptr,
600+ sizeof(match)/sizeof(regmatch_t),
601+ match, 0)){
602+ if(match[0].rm_so > -1){
603+ len = match[0].rm_eo - match[0].rm_so;
604+ if(match_buf_len > len){
605+ ptr[match[0].rm_eo] = '\0';
606+ if((size_t)-1 == mbstowcs(
607+ match_buf,
608+ ptr + match[0].rm_so,
609+ match_buf_len)){
610+ match_buf[0] = L'\0';
611+ }
612+ }else{
613+ match_buf[0] = L'\0';
614+ }
615+ }else{
616+ match_buf[0] = L'\0';
617+ }
618+ free(ptr);
619+ return TRUE;
620+ }
621+ linkp = linkp->next;
622+ }while(linkp != reg_patterns);
623+ free(ptr);
624+ }
625+EXIT_NG_ITEM_MSG:
626+ return FALSE;
627+}
628+
629+
630+static nt_ng_word_handle nt_ng_word_alloc()
631+{
632+ nt_ng_word_tp ng_wordp =
633+ malloc(sizeof(nt_ng_word_t));
634+ if(!ng_wordp)
635+ return NULL;
636+
637+ ng_wordp->handle.chk_sum = NT_NG_WORD_CHK_SUM;
638+ ng_wordp->ng_words = NULL;
639+ ng_wordp->ng_names = NULL;
640+ ng_wordp->ng_word_patterns = NULL;
641+ ng_wordp->ng_name_patterns = NULL;
642+ ng_wordp->ng_id_patterns = NULL;
643+ ng_wordp->ng_word_reg_patterns = NULL;
644+ ng_wordp->ng_name_reg_patterns = NULL;
645+ ng_wordp->ng_id_reg_patterns = NULL;
646+
647+ ng_wordp->ng_ids = NULL;
648+ ng_wordp->ref_count = 1;
649+ ng_wordp->key = NT_NG_ROOT_MUTEX_KEY;
650+ return (nt_ng_word_handle)&ng_wordp->handle;
651+}
652+
653+
654+nt_mutex_handle nt_ng_get_mutex(nt_ng_word_handle handle)
655+{
656+ nt_mutex_handle h_mutex;
657+ nt_ng_word_tp ng_wordp;
658+
659+ assert(handle);
660+ assert(handle->chk_sum == NT_NG_WORD_CHK_SUM);
661+ ng_wordp = (nt_ng_word_tp)handle;
662+ assert(ng_wordp->ref_count > 0);
663+
664+ nt_ng_word_add_ref(handle);
665+
666+ h_mutex = nt_mutex_get_one_time_handle(ng_wordp->key);
667+
668+ nt_ng_word_release_ref(handle);
669+ if(!h_mutex){
670+ return NULL;
671+ }
672+ return h_mutex;
673+}
674+
675+static nt_mutex_handle local_ng_word_get_mutex(
676+ const wchar_t *key, nt_ng_word_handle handle)
677+{
678+ nt_mutex_handle h_mutex;
679+ nt_ng_word_tp ng_wordp;
680+
681+ assert(handle);
682+ assert(handle->chk_sum == NT_NG_WORD_CHK_SUM);
683+ ng_wordp = (nt_ng_word_tp)handle;
684+ assert(ng_wordp->ref_count > 0);
685+
686+ nt_ng_word_add_ref(handle);
687+
688+ h_mutex = nt_mutex_get_one_time_handle(ng_wordp->key);
689+
690+ nt_ng_word_release_ref(handle);
691+ if(!h_mutex){
692+ return NULL;
693+ }
694+ if(!nt_mutex_add_moniker(h_mutex, key)){
695+ return NULL;
696+ }
697+ return h_mutex;
698+}
699+
700+nt_mutex_handle nt_ng_word_get_mutex(nt_ng_word_handle handle)
701+{
702+ return local_ng_word_get_mutex(NT_NG_WORD_MUTEX_KEY, handle);
703+}
704+nt_mutex_handle nt_ng_name_get_mutex(nt_ng_word_handle handle)
705+{
706+ return local_ng_word_get_mutex(NT_NG_NAME_MUTEX_KEY, handle);
707+}
708+nt_mutex_handle nt_ng_id_get_mutex(nt_ng_word_handle handle)
709+{
710+ return local_ng_word_get_mutex(NT_NG_ID_MUTEX_KEY, handle);
711+}
712+
713+
714+int nt_ng_word_add_ref(nt_ng_word_handle handle)
715+{
716+ nt_ng_word_tp ng_wordp;
717+ assert(handle);
718+ assert(handle->chk_sum == NT_NG_WORD_CHK_SUM);
719+ ng_wordp = (nt_ng_word_tp)handle;
720+ assert(ng_wordp->ref_count > 0);
721+ return ++ng_wordp->ref_count;
722+}
723+
724+
725+int nt_ng_word_release_ref(nt_ng_word_handle handle)
726+{
727+ nt_ng_word_tp ng_wordp;
728+ assert(handle);
729+ assert(handle->chk_sum == NT_NG_WORD_CHK_SUM);
730+ ng_wordp = (nt_ng_word_tp)handle;
731+ assert(ng_wordp->ref_count > 0);
732+ ng_wordp->ref_count--;
733+ if(0 != ng_wordp->ref_count)
734+ return ng_wordp->ref_count;
735+
736+
737+ if(ng_wordp->ng_words)
738+ nt_all_link_free(ng_wordp->ng_words, free);
739+ if(ng_wordp->ng_word_patterns)
740+ nt_all_link_free(ng_wordp->ng_word_patterns, free);
741+ if(ng_wordp->ng_word_reg_patterns)
742+ nt_all_link_free(ng_wordp->ng_word_reg_patterns, reg_free);
743+ if(ng_wordp->ng_names)
744+ nt_all_link_free(ng_wordp->ng_names, free);
745+ if(ng_wordp->ng_name_patterns)
746+ nt_all_link_free(ng_wordp->ng_name_patterns, free);
747+ if(ng_wordp->ng_name_reg_patterns)
748+ nt_all_link_free(ng_wordp->ng_name_reg_patterns, reg_free);
749+ if(ng_wordp->ng_ids)
750+ nt_all_link_free(ng_wordp->ng_ids, free);
751+ if(ng_wordp->ng_id_patterns)
752+ nt_all_link_free(ng_wordp->ng_id_patterns, free);
753+ if(ng_wordp->ng_id_reg_patterns)
754+ nt_all_link_free(ng_wordp->ng_id_reg_patterns, reg_free);
755+ free(ng_wordp);
756+ return 0;
757+}
758+
759+BOOL nt_ng_word_upload_cloud(nt_cloud_handle h_cloud, nt_ng_word_handle h_ng_word)
760+{
761+ nt_ng_word_tp ng_wordp;
762+ nt_link_tp empty_linkp;
763+ assert(h_ng_word);
764+ assert(h_ng_word->chk_sum == NT_NG_WORD_CHK_SUM);
765+ ng_wordp = (nt_ng_word_tp)h_ng_word;
766+ assert(ng_wordp->ref_count > 0);
767+
768+ empty_linkp = nt_link_add_data(NULL, L"");
769+
770+ if(ng_wordp->ng_words){
771+ nt_cloud_upload_file(h_cloud, "ngwd.txt", ng_wordp->ng_words);
772+ }else if(empty_linkp){
773+ nt_cloud_upload_file(h_cloud, "ngwd.txt", empty_linkp);
774+ }
775+
776+ if(ng_wordp->ng_names){
777+ nt_cloud_upload_file(h_cloud, "ngnm.txt", ng_wordp->ng_names);
778+ }else if(empty_linkp){
779+ nt_cloud_upload_file(h_cloud, "ngnm.txt", empty_linkp);
780+ }
781+ if(ng_wordp->ng_ids){
782+ nt_cloud_upload_file(h_cloud, "ngid.txt", ng_wordp->ng_ids);
783+ }else if(empty_linkp){
784+ nt_cloud_upload_file(h_cloud, "ngid.txt", empty_linkp);
785+ }
786+
787+ if(empty_linkp)
788+ nt_all_link_free(empty_linkp, NULL);
789+ return TRUE;
790+}
791+
--- a/src/utils/nt_std_t.c
+++ b/src/utils/nt_std_t.c
@@ -500,15 +500,25 @@ nt_link_tp nt_link_next(nt_link_tp link)
500500 return link->next;
501501 }
502502
503-nt_link_tp nt_link_copy(nt_link_tp src_linkp)
503+nt_link_tp nt_link_copy(nt_link_tp src_linkp, nt_memcopy_fn copy_func)
504504 {
505505 nt_link_tp srcp, resultp, workp;
506+ void *ptr;
507+
506508 assert(src_linkp);
507509
508510 srcp = src_linkp;
509511 resultp = NULL;
510512 do{
511- workp = nt_link_add_data(resultp, srcp->data);
513+ if(!copy_func){
514+ workp = nt_link_add_data(resultp, srcp->data);
515+ }else{
516+ ptr = (copy_func)(srcp->data);
517+ if(ptr)
518+ workp = nt_link_add_data(resultp, ptr);
519+ else
520+ workp = NULL;
521+ }
512522 if(!workp){
513523 if(resultp)
514524 nt_all_link_free(resultp, NULL);
@@ -521,6 +531,31 @@ nt_link_tp nt_link_copy(nt_link_tp src_linkp)
521531 return resultp;
522532 }
523533
534+void* nt_link_strcpy_fnc(void *ptr)
535+{
536+ char *cptr, *p;
537+ int len;
538+ cptr = (char*)ptr;
539+ len = strlen(cptr);
540+ p = malloc(len+1);
541+ if(!p)
542+ return NULL;
543+ strcpy(p, cptr);
544+ return p;
545+}
546+void* nt_link_wcscpy_fnc(void *ptr)
547+{
548+ wchar_t *cptr, *p;
549+ int len;
550+ cptr = (wchar_t*)ptr;
551+ len = wcslen(cptr);
552+ p = malloc((len+1)*sizeof(wchar_t));
553+ if(!p)
554+ return NULL;
555+ wcscpy(p, cptr);
556+ return p;
557+}
558+
524559 int nt_link_wcscmp_fnc(void *lhs, void *rhs)
525560 {
526561 return wcscmp((const wchar_t *)lhs, (const wchar_t *)rhs);
Show on old repository browser