From: Akira Date: Sun, 19 Jan 2014 13:59:36 +0000 (+0900) Subject: v1.0.2.6 X-Git-Url: http://git.osdn.net/view?p=ntch%2Fdevelop.git;a=commitdiff_plain;h=d3c3c80eb6a40e6c8b2cda442784d00b82e218fd v1.0.2.6 Support: ng word --- diff --git a/Makefile b/Makefile index 09c8fd0..525f56c 100644 --- a/Makefile +++ b/Makefile @@ -4,7 +4,6 @@ # You may need to install then. #Option for development -#CFLAGS = -g -Wall -DDEBUG ${DEFS} ${CDEF} -DNT_CLOUD CFLAGS = -g -Wall -DDEBUG ${DEFS} ${CDEF} -DNT_CLOUD -DNT_NET_IPV6 #Option for release #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 \ ${OBJ_DIR}/_2ch/parse_string.o \ ${OBJ_DIR}/_2ch/maru_2ch.o \ ${OBJ_DIR}/usr/favorite_t.o \ + ${OBJ_DIR}/usr/ng_word_t.o \ ${OBJ_DIR}/usr/usr_db_t.o \ ${OBJ_DIR}/ui/disp_board_menu.o \ ${OBJ_DIR}/ui/disp_threadlist.o \ @@ -66,6 +66,8 @@ INC_FILES = ${INC_DIR}/config.h \ ${INC_DIR}/_2ch/parse_2ch.h \ ${INC_DIR}/_2ch/search_2ch.h \ ${INC_DIR}/usr/favorite_t.h \ + ${INC_DIR}/usr/ng_word_t.h \ + ${INC_DIR}/usr/usr_db_t.h \ ${INC_DIR}/ui/disp.h \ ${INC_DIR}/ui/disp_win.h \ ${INC_DIR}/ui/disp_string.h \ @@ -79,7 +81,6 @@ INC_FILES = ${INC_DIR}/config.h \ ${INC_DIR}/utils/zip.h \ ${INC_DIR}/utils/db.h \ ${INC_DIR}/utils/text.h \ - ${INC_DIR}/usr/usr_db_t.h \ ${INC_DIR}/utils/nt_conv_char.h \ ${INC_DIR}/utils/nt_mutex.h \ ${INC_DIR}/utils/nt_pthread.h \ @@ -203,6 +204,10 @@ $(OBJ_DIR)/usr/favorite_t.o : ${SRC_DIR}/usr/favorite_t.c ${INC_FILES} @ ${SHELL} prepare_proj.sh ${CC} ${CFLAGS} ${INCLUDES} -c -o $@ $< +$(OBJ_DIR)/usr/ng_word_t.o : ${SRC_DIR}/usr/ng_word_t.c ${INC_FILES} + @ ${SHELL} prepare_proj.sh + ${CC} ${CFLAGS} ${INCLUDES} -c -o $@ $< + $(OBJ_DIR)/utils/base64.o : ${SRC_DIR}/utils/base64.c ${INC_FILES} @ ${SHELL} prepare_proj.sh ${CC} ${CFLAGS} ${INCLUDES} -c -o $@ $< diff --git a/Makefile.in b/Makefile.in index 431edef..1ae18b6 100644 --- a/Makefile.in +++ b/Makefile.in @@ -4,7 +4,6 @@ # You may need to install then. #Option for development -#CFLAGS = -g -Wall -DDEBUG ${DEFS} ${CDEF} -DNT_CLOUD #CFLAGS = -g -Wall -DDEBUG ${DEFS} ${CDEF} -DNT_CLOUD -DNT_NET_IPV6 #Option for release 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 \ ${OBJ_DIR}/_2ch/parse_string.o \ ${OBJ_DIR}/_2ch/maru_2ch.o \ ${OBJ_DIR}/usr/favorite_t.o \ + ${OBJ_DIR}/usr/ng_word_t.o \ ${OBJ_DIR}/usr/usr_db_t.o \ ${OBJ_DIR}/ui/disp_board_menu.o \ ${OBJ_DIR}/ui/disp_threadlist.o \ @@ -66,6 +66,8 @@ INC_FILES = ${INC_DIR}/config.h \ ${INC_DIR}/_2ch/parse_2ch.h \ ${INC_DIR}/_2ch/search_2ch.h \ ${INC_DIR}/usr/favorite_t.h \ + ${INC_DIR}/usr/ng_word_t.h \ + ${INC_DIR}/usr/usr_db_t.h \ ${INC_DIR}/ui/disp.h \ ${INC_DIR}/ui/disp_win.h \ ${INC_DIR}/ui/disp_string.h \ @@ -79,7 +81,6 @@ INC_FILES = ${INC_DIR}/config.h \ ${INC_DIR}/utils/zip.h \ ${INC_DIR}/utils/db.h \ ${INC_DIR}/utils/text.h \ - ${INC_DIR}/usr/usr_db_t.h \ ${INC_DIR}/utils/nt_conv_char.h \ ${INC_DIR}/utils/nt_mutex.h \ ${INC_DIR}/utils/nt_pthread.h \ @@ -203,6 +204,10 @@ $(OBJ_DIR)/usr/favorite_t.o : ${SRC_DIR}/usr/favorite_t.c ${INC_FILES} @ ${SHELL} prepare_proj.sh ${CC} ${CFLAGS} ${INCLUDES} -c -o $@ $< +$(OBJ_DIR)/usr/ng_word_t.o : ${SRC_DIR}/usr/ng_word_t.c ${INC_FILES} + @ ${SHELL} prepare_proj.sh + ${CC} ${CFLAGS} ${INCLUDES} -c -o $@ $< + $(OBJ_DIR)/utils/base64.o : ${SRC_DIR}/utils/base64.c ${INC_FILES} @ ${SHELL} prepare_proj.sh ${CC} ${CFLAGS} ${INCLUDES} -c -o $@ $< diff --git a/README b/README index 3103224..3321c71 100644 --- a/README +++ b/README @@ -1,5 +1,5 @@ - ntch version 1.0.2.5 + ntch version 1.0.2.6 This file is part of ntch. @@ -27,13 +27,13 @@ Linux用 2ch専用ブラウザー ntch のインストール方法 -ダウンロードファイルを使用する場合、適当なディレクトリにntch-1.0.2.1.tgzファイルを解凍します +ダウンロードファイルを使用する場合、適当なディレクトリにntch-1.0.2.6.tgzファイルを解凍します -tar zxvf ntch-1.0.2.1.tgz +tar zxvf ntch-1.0.2.6.tgz 作成されたディレクトリに移動します -cd ntch-1.0.2.1 +cd ntch-1.0.2.6 以下のコマンドを実行して、実行ファイルを作成します @@ -61,5 +61,5 @@ sudo make install ntchは以下のライブラリィに依存しています。openssl, gdbm, ncurses, sqlite これらのライブラリのデベロップ版がビルドには必要です。 -また、Fedora18で動作確認していますので、その他のディストリビューション等では、 +また、Fedora19で動作確認していますので、その他のディストリビューション等では、 作成されたMakefileやソースファイルを編集する必要があるかもしれません。 diff --git a/config.h b/config.h index 8edb688..5dcfc02 100644 --- a/config.h +++ b/config.h @@ -141,7 +141,7 @@ #define PACKAGE_NAME "ntch" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "ntch 1.0.2.5" +#define PACKAGE_STRING "ntch 1.0.2.6" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "ntch" @@ -150,7 +150,7 @@ #define PACKAGE_URL "https://sourceforge.jp/projects/ntch/" /* Define to the version of this package. */ -#define PACKAGE_VERSION "1.0.2.5" +#define PACKAGE_VERSION "1.0.2.6" /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 diff --git a/configure b/configure index df09bdf..e1777f1 100755 --- 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.2.5. +# Generated by GNU Autoconf 2.69 for ntch 1.0.2.6. # # Report bugs to . # @@ -580,8 +580,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='ntch' PACKAGE_TARNAME='ntch' -PACKAGE_VERSION='1.0.2.5' -PACKAGE_STRING='ntch 1.0.2.5' +PACKAGE_VERSION='1.0.2.6' +PACKAGE_STRING='ntch 1.0.2.6' 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.2.5 to adapt to many kinds of systems. +\`configure' configures ntch 1.0.2.6 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.2.5:";; + short | recursive ) echo "Configuration of ntch 1.0.2.6:";; 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.2.5 +ntch configure 1.0.2.6 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.2.5, which was +It was created by ntch $as_me 1.0.2.6, which was generated by GNU Autoconf 2.69. Invocation command line was $ $0 $@ @@ -4797,7 +4797,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.2.5, which was +This file was extended by ntch $as_me 1.0.2.6, which was generated by GNU Autoconf 2.69. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -4864,7 +4864,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.2.5 +ntch config.status 1.0.2.6 configured by $0, generated by GNU Autoconf 2.69, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index e9abb2c..6e1a973 100644 --- a/configure.ac +++ b/configure.ac @@ -2,7 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ([2.69]) -AC_INIT([ntch], [1.0.2.5], [akohta001@gmail.com],[ntch],[https://sourceforge.jp/projects/ntch/]) +AC_INIT([ntch], [1.0.2.6], [akohta001@gmail.com],[ntch],[https://sourceforge.jp/projects/ntch/]) AC_CONFIG_SRCDIR([src/main.c]) AC_CONFIG_HEADERS([config.h]) diff --git a/help.txt b/help.txt index 21c0f6c..40a8fa3 100644 --- a/help.txt +++ b/help.txt @@ -1,5 +1,5 @@ - ntch version 1.0.2.5 + ntch version 1.0.2.6 This file is part of ntch. @@ -139,6 +139,32 @@ Linux用 2ch専用ブラウザー :a :autoscroll 自動スクロール j,k,f,bキー以外の入力で自動スクロール解除 k,bキーで反転スクロール + :ngwd [NG指定文字列] , :ngnm [NG指定文字列] , :ngid [NG指定文字列] + ngwd レス本文に対するNG指定  + 文字列には後述する方法で正規表現を指定出来ます。 + 文字列を省略すると、現在設定されている全ての + NGWORDをエディターで表示しますので、これを直接 + 編集できます。 + ngnm, ngid それぞれレスの名前欄、IDに対するNGの指定です。 + 指定方法はngwdと同様です + NG文字列に正規表現を指定する方法 + 指定したい正規表現をスラッシュ'/'で囲んで指定します。 + 例 + :ngwd /(L|l)inux/ 左はLinuxとlinuxにマッチします。 + :ngwd /ですか\\? $/ 行末が「ですか?」で終わる文字列に + にマッチします。 + ?マークをエスケープすることと、 + 2chのレスの行末には空白が1文字 + 付加されるていることに注意して下さい + :ngwd /windows/i スラッシュの後ろに'i'を指定すると + 大文字小文字を無視します + 左の例ではWindows, windows, WiNdOwS + などにマッチします + 先頭が'/'で始まる文字列を正規表現を使わないでNG指定する方法 + 先頭のスラッシュ'/'を円マーク'\\'でエスケープして下さい + 例 + :ngwd \\/[a-z]/ 左は正規表現を使わずに文字列として + /[a-z]/ にマッチします。 お気に入り一覧 d 選択項目をお気に入りから削除 @@ -236,7 +262,7 @@ nce-pass preference.phpで登録したユーザーパスワード クラウド設定有効時には起動時にクラウドのデータを読み込みます。 現在のお気に入りの内容でクラウドのデータを明示的に更新したい場合は、 お気に入り一覧で、以下のコマンドを入力します -:upload 現在のお気に入りを全てアップロード +:upload 現在のお気に入り、NGワードの設定を全てアップロード :upload board 現在の板のお気に入りをアップロード :upload thread 現在のスレッドのお気に入りをアップロード - +:upload ng 現在のNGワードの設定をアップロード diff --git a/src/cloud/nt_cloud.c b/src/cloud/nt_cloud.c index 3c3a200..db0c32b 100644 --- a/src/cloud/nt_cloud.c +++ b/src/cloud/nt_cloud.c @@ -30,6 +30,7 @@ #include "utils/nt_std_t.h" #include "utils/text.h" #include "utils/file.h" +#include "utils/nt_pthread.h" #include "utils/base64.h" #include "utils/crypt.h" #include "utils/nt_conv_char.h" @@ -42,6 +43,10 @@ static BOOL nt_cloud_edit_lines_file(nt_cloud_handle handle, static BOOL nt_cloud_upload_file_local(nt_cloud_handle handle, const char *file_name, nt_link_tp lines, int depth); static nt_cloud_handle g_cloud_handle = NULL; +static nt_pthread_result_t upload_file_pthread_func(void *param); +static BOOL nt_cloud_edit_lines_file_async(nt_cloud_handle handle, + const char *file_name, nt_link_tp lines, const char *php_file); +static nt_pthread_result_t edit_lines_file_pthread_func(void *param); nt_cloud_handle nt_cloud_get_handle(){ if(!g_cloud_handle) @@ -215,6 +220,102 @@ BOOL nt_cloud_delete_lines_from_file(nt_cloud_handle handle, { return nt_cloud_edit_lines_file(handle, file_name, lines, NT_CLOUD_DELETE_LINES_FILE_PHP, 0); } +BOOL nt_cloud_insert_lines_into_file_async(nt_cloud_handle handle, + const char *file_name, nt_link_tp lines) +{ + return nt_cloud_edit_lines_file_async( + handle, file_name, lines, NT_CLOUD_INSERT_LINES_FILE_PHP); +} +BOOL nt_cloud_delete_lines_from_file_async(nt_cloud_handle handle, + const char *file_name, nt_link_tp lines) +{ + return nt_cloud_edit_lines_file_async( + handle, file_name, lines, NT_CLOUD_DELETE_LINES_FILE_PHP); +} + + +static BOOL nt_cloud_edit_lines_file_async(nt_cloud_handle handle, + const char *file_name, nt_link_tp lines, const char *php_file) +{ + nt_link_tp param; + nt_pthread_handle h_pthread; + char *cptr; + + cptr = nt_str_clone(file_name); + if(!cptr){ + return FALSE; + } + + param = nt_link_add_data(NULL, handle); + if(!param){ + free(cptr); + return FALSE; + } + if(NULL == nt_link_add_data(param, cptr)){ + nt_all_link_free(param, NULL); + free(cptr); + return FALSE; + } + if(NULL == nt_link_add_data(param, php_file)){ + nt_all_link_free(param, NULL); + free(cptr); + return FALSE; + } + if(NULL == nt_link_add_data(param, lines)){ + nt_all_link_free(param, NULL); + free(cptr); + return FALSE; + } + nt_cloud_add_ref(handle); + + h_pthread = nt_pthread_alloc( + edit_lines_file_pthread_func, param, NULL); + if(!h_pthread){ + nt_cloud_release_ref(handle); + nt_all_link_free(param, NULL); + free(cptr); + return FALSE; + } + + if(!nt_pthread_put_que(h_pthread)){ + nt_pthread_release_ref(h_pthread); + nt_cloud_release_ref(handle); + nt_all_link_free(param, NULL); + free(cptr); + return FALSE; + } + nt_pthread_release_ref(h_pthread); + return TRUE; +} + +static nt_pthread_result_t edit_lines_file_pthread_func(void *param) +{ + nt_pthread_result_t result; + nt_link_tp linkp, lines; + char *file_name, *php_file_name; + nt_cloud_handle h_cloud; + + + result.code = 0; + result.data = NULL; + + linkp = (nt_link_tp)param; + if(4 != nt_link_num(linkp)){ + nt_all_link_free(linkp, NULL); + return result; + } + h_cloud = linkp->data; + file_name = linkp->next->data; + php_file_name = linkp->next->next->data; + lines = linkp->next->next->next->data; + (void)nt_cloud_edit_lines_file(h_cloud, + file_name, lines, php_file_name, 0); + nt_cloud_release_ref(h_cloud); + nt_all_link_free(lines, free); + nt_all_link_free(linkp, NULL); + free(file_name); + return result; +} static BOOL nt_cloud_edit_lines_file(nt_cloud_handle handle, 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, file_name, lines, 0); } +BOOL nt_cloud_upload_file_async(nt_cloud_handle handle, + const char *file_name, nt_link_tp lines) +{ + nt_link_tp param; + nt_pthread_handle h_pthread; + char *cptr; + + cptr = nt_str_clone(file_name); + if(!cptr){ + return FALSE; + } + + param = nt_link_add_data(NULL, handle); + if(param){ + free(cptr); + return FALSE; + } + if(NULL == nt_link_add_data(param, cptr)){ + nt_all_link_free(param, NULL); + free(cptr); + return FALSE; + } + if(NULL == nt_link_add_data(param, lines)){ + nt_all_link_free(param, NULL); + free(cptr); + return FALSE; + } + nt_cloud_add_ref(handle); + + h_pthread = nt_pthread_alloc( + upload_file_pthread_func, param, NULL); + if(!h_pthread){ + nt_cloud_release_ref(handle); + nt_all_link_free(param, NULL); + free(cptr); + return FALSE; + } + + if(!nt_pthread_put_que(h_pthread)){ + nt_pthread_release_ref(h_pthread); + nt_cloud_release_ref(handle); + nt_all_link_free(param, NULL); + free(cptr); + return FALSE; + } + nt_pthread_release_ref(h_pthread); + return TRUE; +} + +static nt_pthread_result_t upload_file_pthread_func(void *param) +{ + nt_pthread_result_t result; + nt_link_tp linkp, lines; + char *file_name; + nt_cloud_handle h_cloud; + + + result.code = 0; + result.data = NULL; + + linkp = (nt_link_tp)param; + if(3 != nt_link_num(linkp)){ + nt_all_link_free(linkp, NULL); + return result; + } + h_cloud = linkp->data; + file_name = linkp->next->data; + lines = linkp->next->next->data; + (void)nt_cloud_upload_file_local(h_cloud, + file_name, lines, 0); + nt_cloud_release_ref(h_cloud); + nt_all_link_free(lines, free); + nt_all_link_free(linkp, NULL); + free(file_name); + return result; +} + + static BOOL nt_cloud_upload_file_local(nt_cloud_handle handle, const char *file_name, nt_link_tp lines, int depth) { diff --git a/src/env.c b/src/env.c index b67d97c..28f5bb6 100644 --- a/src/env.c +++ b/src/env.c @@ -40,6 +40,9 @@ char USR_LOG_DB_PATH[1024]; char USR_FAVORITE_BOARD_FILE_PATH[1024]; char USR_FAVORITE_GRP_FILE_PATH[1024]; char USR_FAVORITE_THREAD_FILE_PATH[1024]; +char USR_NG_WORD_FILE_PATH[1024]; +char USR_NG_NAME_FILE_PATH[1024]; +char USR_NG_ID_FILE_PATH[1024]; char EDITOR_CMD[1024]; int FORCE_REFRESH = 0; int THREAD_SORT_TYPE = NT_THREAD_SORT_BY_READ; @@ -130,6 +133,9 @@ int set_option(int argc, char* argv[]) sprintf(USR_FAVORITE_BOARD_FILE_PATH, "%s/fb.txt", USR_PATH); sprintf(USR_FAVORITE_GRP_FILE_PATH, "%s/ftab.txt", USR_PATH); sprintf(USR_FAVORITE_THREAD_FILE_PATH, "%s/ft.txt", USR_PATH); + sprintf(USR_NG_WORD_FILE_PATH, "%s/ngwd.txt", USR_PATH); + sprintf(USR_NG_NAME_FILE_PATH, "%s/ngnm.txt", USR_PATH); + sprintf(USR_NG_ID_FILE_PATH, "%s/ngid.txt", USR_PATH); sprintf(buf, "%s/.ntchrc", pw->pw_dir); if(!read_resource(buf)){ diff --git a/src/inc/cloud/nt_cloud.h b/src/inc/cloud/nt_cloud.h index f2255ce..6ad44da 100644 --- 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, const char *file_name, nt_link_tp lines); extern BOOL nt_cloud_delete_lines_from_file(nt_cloud_handle handle, const char *file_name, nt_link_tp lines); +extern BOOL nt_cloud_insert_lines_into_file_async(nt_cloud_handle handle, + const char *file_name, nt_link_tp lines); +extern BOOL nt_cloud_delete_lines_from_file_async(nt_cloud_handle handle, + const char *file_name, nt_link_tp lines); extern void nt_cloud_update_read_count_async(nt_cloud_handle handle, const wchar_t *board_name, const wchar_t *dat_name, diff --git a/src/inc/config.h b/src/inc/config.h index 8edb688..5dcfc02 100644 --- a/src/inc/config.h +++ b/src/inc/config.h @@ -141,7 +141,7 @@ #define PACKAGE_NAME "ntch" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "ntch 1.0.2.5" +#define PACKAGE_STRING "ntch 1.0.2.6" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "ntch" @@ -150,7 +150,7 @@ #define PACKAGE_URL "https://sourceforge.jp/projects/ntch/" /* Define to the version of this package. */ -#define PACKAGE_VERSION "1.0.2.5" +#define PACKAGE_VERSION "1.0.2.6" /* Define to 1 if you have the ANSI C header files. */ #define STDC_HEADERS 1 diff --git a/src/inc/env.h b/src/inc/env.h index a9dc8dd..ee5845d 100644 --- a/src/inc/env.h +++ b/src/inc/env.h @@ -27,6 +27,10 @@ extern char USR_LOG_DB_PATH[]; extern char USR_FAVORITE_BOARD_FILE_PATH[]; extern char USR_FAVORITE_GRP_FILE_PATH[]; extern char USR_FAVORITE_THREAD_FILE_PATH[]; +extern char USR_NG_WORD_FILE_PATH[]; +extern char USR_NG_NAME_FILE_PATH[]; +extern char USR_NG_ID_FILE_PATH[]; + extern char *RFC2898_SALT; extern int RFC2898_ITERATION; extern char *AES256_PASS; @@ -80,9 +84,11 @@ extern char *MARU_PW; #define NT_KEY_COMMAND1 ':' #define NT_KEY_COMMAND2 '/' #define NT_KEY_COMMAND3 '?' +#define NT_KEY_CMD_BASE (65536) #define NT_KEY_CMD_BOARD_UPDATE (65536 + 1) #define NT_KEY_CMD_AUTO_SCROLL (65536 + 2) #define NT_KEY_CMD_FAVORITE_UPDATE (65536 + 3) +#define NT_KEY_CMD_NGWORD_UPDATE (65536 + 4) #define NT_COMMAND1_WRITE_MSG_1 "write" #define NT_COMMAND1_WRITE_MSG_2 "w" @@ -115,8 +121,15 @@ extern char *MARU_PW; #define NT_COMMAND1_UPLOAD_BOARD2 "b" #define NT_COMMAND1_UPLOAD_THREAD1 "thread" #define NT_COMMAND1_UPLOAD_THREAD2 "t" +#define NT_COMMAND1_UPLOAD_NG_FILE1 "ng" +#define NT_COMMAND1_UPLOAD_NG_FILE2 "n" #define NT_COMMAND1_LIMIT_1 "limit" #define NT_COMMAND1_LIMIT_2 "l" +#define NT_COMMAND1_NG_WORD_1 "ngword" +#define NT_COMMAND1_NG_WORD_2 "ngwd" +#define NT_COMMAND1_NG_NAME_1 "ngname" +#define NT_COMMAND1_NG_NAME_2 "ngnm" +#define NT_COMMAND1_NG_ID_1 "ngid" extern int set_option(int argc, char* argv[]); diff --git a/src/inc/nt_string.h b/src/inc/nt_string.h index f5b40d8..3f54604 100644 --- a/src/inc/nt_string.h +++ b/src/inc/nt_string.h @@ -29,6 +29,7 @@ #define NT_INFO_DEL_FAVORITE_SUCCEEDED (L"お気に入りから削除しました") #define NT_INFO_UPLOAD_FAVORITE_SUCCEEDED (L"クラウドのお気に入りを更新しました") +#define NT_INFO_UPLOAD_NG_FILES_SUCCEEDED (L"クラウドのNGファイルを更新しました") #define NT_TEXT_UNTRACKED_LOG_NAME (L"[DAT落] ") diff --git a/src/inc/ui/disp.h b/src/inc/ui/disp.h index c36c461..3b8f26b 100644 --- a/src/inc/ui/disp.h +++ b/src/inc/ui/disp.h @@ -29,6 +29,7 @@ #include "_2ch/search_2ch.h" #include "usr/favorite_t.h" #include "usr/usr_db_t.h" +#include "usr/ng_word_t.h" #define DISP_STATE_MASK 0xff #define DISP_CMD_MASK 0xff00 @@ -61,13 +62,19 @@ #define DISP_CMD_UPLOAD_THREADS (11*256) #define DISP_CMD_REFRESH (12*256) #define DISP_CMD_REENTER (13*256) +#define DISP_CMD_EDIT_NGWORD (14*256) +#define DISP_CMD_EDIT_NGNAME (15*256) +#define DISP_CMD_EDIT_NGID (16*256) +#define DISP_CMD_UPLOAD_NG_FILES (17*256) + extern int disp_board_menu(nt_window_tp wp, nt_2ch_model_handle h_model, nt_2ch_selected_item_handle h_select); extern int disp_threadlist(nt_window_tp wp, int state, nt_2ch_selected_item_handle h_select, nt_usr_db_handle usr_db_handle); extern int disp_reslist(nt_window_tp wp, int state, - nt_2ch_selected_item_handle h_select, nt_usr_db_handle usr_db_handle); + nt_2ch_selected_item_handle h_select, nt_usr_db_handle usr_db_handle, + nt_ng_word_handle h_ng_word, nt_cloud_handle h_cloud); extern int disp_thread_search(nt_window_tp wp, int prev_state, nt_link_tp thread_list, nt_searched_thread_handle *h_sel_threadp); @@ -88,6 +95,8 @@ extern void free_search_thread_ctx(void *ptr); extern void free_favorite_ctx(void *ptr); extern void free_history_ctx(void *ptr); extern BOOL disp_editor(nt_write_data_handle h_write_data); +extern BOOL disp_editor2(const char *file_name); +extern nt_link_tp disp_editor3(nt_link_tp text_list); extern int disp_html_result(nt_write_data_handle h_write_data); #endif /* _DISP_H_ */ diff --git a/src/inc/usr/ng_word_t.h b/src/inc/usr/ng_word_t.h new file mode 100644 index 0000000..9673ea5 --- /dev/null +++ b/src/inc/usr/ng_word_t.h @@ -0,0 +1,100 @@ +/* Copyright 2014 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 . + +*/ +#ifndef _NG_WORD_T_H_ +#define _NG_WORD_T_H_ + +#include "utils/nt_std_t.h" +#include "utils/nt_mutex.h" +#ifdef NT_CLOUD +#include "cloud/nt_cloud.h" +#endif + +#define NG_ITEM_NONE 0 +#define NG_ITEM_MSG 1 +#define NG_ITEM_NAME 2 +#define NG_ITEM_ID 4 +#define NG_ITEM_ALL 7 + + +typedef struct tag_nt_ng_word_handle{ + int chk_sum; +} nt_ng_word_handle_t, *nt_ng_word_handle; + +extern int nt_ng_word_add_ref(nt_ng_word_handle handle); +extern int nt_ng_word_release_ref(nt_ng_word_handle handle); + +extern nt_mutex_handle nt_ng_get_mutex(nt_ng_word_handle handle); +extern nt_mutex_handle nt_ng_word_get_mutex(nt_ng_word_handle handle); +extern nt_mutex_handle nt_ng_name_get_mutex(nt_ng_word_handle handle); +extern nt_mutex_handle nt_ng_id_get_mutex(nt_ng_word_handle handle); + +extern nt_ng_word_handle nt_ng_word_load( +#ifdef NT_CLOUD + nt_cloud_handle h_cloud, +#endif + const char *ng_word_file_name, + const char *ng_name_file_name, + const char *ng_id_file_name + ); +extern BOOL nt_ng_word_save(nt_ng_word_handle handle, + const char *ng_word_file_name, + const char *ng_name_file_name, + const char *ng_id_file_name + ); + +#ifdef NT_CLOUD +extern BOOL nt_ng_word_upload_cloud( + nt_cloud_handle h_cloud, nt_ng_word_handle h_ng_word); +extern BOOL nt_ng_word_add_ng_word(nt_cloud_handle h_cloud, + nt_ng_word_handle handle, const char *ng_word); +extern BOOL nt_ng_word_add_ng_name(nt_cloud_handle h_cloud, + nt_ng_word_handle handle, const char *ng_name); +extern BOOL nt_ng_word_add_ng_id(nt_cloud_handle h_cloud, + nt_ng_word_handle handle, const char *ng_id); +extern BOOL nt_ng_word_set_words( + nt_ng_word_handle handle, nt_link_tp text_list, + nt_cloud_handle h_cloud); +extern BOOL nt_ng_word_set_names( + nt_ng_word_handle handle, nt_link_tp text_list, + nt_cloud_handle h_cloud); +extern BOOL nt_ng_word_set_ids( + nt_ng_word_handle handle, nt_link_tp text_list, + nt_cloud_handle h_cloud); + +#else +extern BOOL nt_ng_word_add_ng_word( + nt_ng_word_handle handle, const char *ng_word); +extern BOOL nt_ng_word_add_ng_name( + nt_ng_word_handle handle, const char *ng_name); +extern BOOL nt_ng_word_add_ng_id( + nt_ng_word_handle handle, const char *ng_id); +extern BOOL nt_ng_word_set_words(nt_ng_word_handle handle, nt_link_tp text_list); +extern BOOL nt_ng_word_set_names(nt_ng_word_handle handle, nt_link_tp text_list); +extern BOOL nt_ng_word_set_ids(nt_ng_word_handle handle, nt_link_tp text_list); + +#endif +extern int ng_word_match(nt_ng_word_handle handle, + int item_type, const wchar_t *source, + wchar_t *match, size_t match_buf_len); +extern nt_link_tp nt_ng_word_get_words(nt_ng_word_handle handle); +extern nt_link_tp nt_ng_word_get_names(nt_ng_word_handle handle); +extern nt_link_tp nt_ng_word_get_ids(nt_ng_word_handle handle); + + +#endif /* _NG_WORD_T_H_ */ + diff --git a/src/inc/utils/nt_std_t.h b/src/inc/utils/nt_std_t.h index 4001cf5..c97b7ca 100644 --- a/src/inc/utils/nt_std_t.h +++ b/src/inc/utils/nt_std_t.h @@ -28,6 +28,7 @@ typedef int BOOL; typedef void (*nt_memfree_fn)(void* ptr); typedef int (*nt_compare_fn)(void *lhs, void *rhs); typedef int (*nt_compare_n_fn)(int a, int b); +typedef void* (*nt_memcopy_fn)(void* ptr); typedef struct tag_nt_link_t *nt_link_tp; typedef struct tag_nt_link_t{ @@ -120,7 +121,10 @@ extern nt_link_tp nt_link_next(nt_link_tp link); extern int nt_link_num(nt_link_tp linkp); extern void* nt_link_get_by_index(nt_link_tp linkp, int index); extern void nt_all_link_free(nt_link_tp ptr, nt_memfree_fn free_func); -extern nt_link_tp nt_link_copy(nt_link_tp src_linkp); +extern nt_link_tp nt_link_copy(nt_link_tp src_linkp, nt_memcopy_fn copy_func); + +extern void* nt_link_strcpy_fnc(void *ptr); +extern void* nt_link_wcscpy_fnc(void *ptr); extern int nt_link_wcscmp_fnc(void *lhs, void *rhs); typedef struct tag_nt_key_value_t *nt_key_value_tp; diff --git a/src/main.c b/src/main.c index 7a2b94e..64f4ef3 100644 --- a/src/main.c +++ b/src/main.c @@ -47,24 +47,19 @@ #include "ui/disp.h" #include "ui/disp_win.h" #include "ui/disp_string.h" -#ifdef NT_CLOUD #include "cloud/nt_cloud.h" -#endif +#include "usr/ng_word_t.h" + #define S_SIZE (1024) extern int server_main(); static int draw_title(WINDOW *wp, const wchar_t *title, attr_t attr); -#ifdef NT_CLOUD static BOOL DoLoop(WINDOW *scrp, nt_usr_db_handle db_handle, nt_cloud_handle h_cloud, nt_favorite_handle h_favorite, - nt_favorite_grp_handle h_favorite_grp); -#else -static BOOL DoLoop(WINDOW *scrp, nt_usr_db_handle db_handle, - nt_favorite_handle h_favorite, - nt_favorite_grp_handle h_favorite_grp); -#endif + nt_favorite_grp_handle h_favorite_grp, + nt_ng_word_handle h_ng_word); static void print_error(WINDOW *wp, const wchar_t *msg); static void _2ch_selected_item_free(void *ptr) @@ -83,10 +78,9 @@ int main(int argc, char *argv[]) nt_favorite_grp_handle h_favorite_grp; nt_link_tp text_linkp, text2_linkp; const char *err_msg; -#ifdef NT_CLOUD + nt_ng_word_handle h_ng_word; nt_cloud_handle h_cloud; h_cloud = NULL; -#endif err_msg = NULL; setlocale(LC_ALL, "ja_JP.UTF-8"); @@ -129,7 +123,6 @@ int main(int argc, char *argv[]) goto ERROR_TRAP; } -#ifdef NT_CLOUD if(nt_crypt_lib_init(RFC2898_SALT, RFC2898_ITERATION, AES256_PASS, &err_msg)){ if(NCE_AUTH_URL && NCE_ID && NCE_PASS){ @@ -141,7 +134,6 @@ int main(int argc, char *argv[]) sleep(1); } } -#endif if(!nt_2ch_model_init()){ fputs("Failed to read board menu data.\n", stderr); @@ -167,11 +159,9 @@ int main(int argc, char *argv[]) } text_linkp = NULL; -#ifdef NT_CLOUD if(h_cloud){ text_linkp = nt_cloud_download_file(h_cloud, "fb.txt"); } -#endif if(!text_linkp) text_linkp = nt_read_text_file(USR_FAVORITE_BOARD_FILE_PATH); if(text_linkp){ @@ -179,13 +169,11 @@ int main(int argc, char *argv[]) nt_all_link_free(text_linkp, free); } text_linkp = NULL; -#ifdef NT_CLOUD if(h_cloud){ text_linkp = nt_cloud_download_file(h_cloud, "ft.txt"); nt_cloud_query_favorite_attributes_async(h_cloud, usr_db_handle); //nt_cloud_query_attributes(h_cloud, usr_db_handle, 0); } -#endif if(!text_linkp) text_linkp = nt_read_text_file(USR_FAVORITE_THREAD_FILE_PATH); if(text_linkp){ @@ -193,19 +181,28 @@ int main(int argc, char *argv[]) nt_all_link_free(text_linkp, free); } + h_ng_word = nt_ng_word_load(h_cloud, + USR_NG_WORD_FILE_PATH, + USR_NG_NAME_FILE_PATH, + USR_NG_ID_FILE_PATH); + cbreak(); noecho(); -#ifdef NT_CLOUD - if(DoLoop(scrp, usr_db_handle, h_cloud, h_favorite, h_favorite_grp)) -#else - if(DoLoop(scrp, usr_db_handle, h_favorite, h_favorite_grp)) -#endif + if(DoLoop(scrp, usr_db_handle, h_cloud, h_favorite, h_favorite_grp, h_ng_word)) result = 0; echo(); nocbreak(); + if(h_ng_word){ + nt_ng_word_save(h_ng_word, + USR_NG_WORD_FILE_PATH, + USR_NG_NAME_FILE_PATH, + USR_NG_ID_FILE_PATH); + nt_ng_word_release_ref(h_ng_word); + } + text_linkp = nt_favorite_retrieve_boards(h_favorite); if(text_linkp){ nt_write_text_file(USR_FAVORITE_BOARD_FILE_PATH, text_linkp); @@ -244,11 +241,9 @@ ERROR_TRAP: nt_timer_lib_finish(); -#ifdef NT_CLOUD nt_crypt_lib_finish(); if(h_cloud) nt_cloud_release_ref(h_cloud); -#endif nt_env_free(); return (result); } @@ -267,16 +262,11 @@ static int auto_update_timer_func(int id) return TIMER_ID_AUTO_UPDATE_NONE; } -#ifdef NT_CLOUD static BOOL DoLoop(WINDOW *scrp, nt_usr_db_handle db_handle, nt_cloud_handle h_cloud, nt_favorite_handle h_favorite, - nt_favorite_grp_handle h_favorite_grp) -#else -static BOOL DoLoop(WINDOW *scrp, nt_usr_db_handle db_handle, - nt_favorite_handle h_favorite, - nt_favorite_grp_handle h_favorite_grp) -#endif + nt_favorite_grp_handle h_favorite_grp, + nt_ng_word_handle h_ng_word) { int ch, state, num; int disp_state, nresult; @@ -369,14 +359,12 @@ static BOOL DoLoop(WINDOW *scrp, nt_usr_db_handle db_handle, h_favorite_board = nt_favorite_board_alloc( h_favorite, board_name); if(h_favorite_board){ -#ifdef NT_CLOUD linkp = nt_link_add_data(NULL, (void*)board_name); if(linkp){ if(h_cloud) nt_cloud_insert_lines_into_file(h_cloud, "fb.txt", linkp); free(linkp); } -#endif nt_favorite_board_release_ref(h_favorite_board); //favorite_dump(h_favorite); } @@ -423,14 +411,12 @@ static BOOL DoLoop(WINDOW *scrp, nt_usr_db_handle db_handle, nt_2ch_selected_item_get_board_name(h_sel_items), nt_2ch_selected_item_get_thread_title(h_sel_items)); if(h_favorite_thread){ -#ifdef NT_CLOUD linkp = NULL; if(nt_favorite_retrieve_thread(h_favorite_thread, &linkp)){ if(h_cloud) nt_cloud_insert_lines_into_file(h_cloud, "ft.txt", linkp); nt_all_link_free(linkp, free); } -#endif nt_favorite_thread_release_ref(h_favorite_thread); //favorite_dump(h_favorite); status_msg = NT_INFO_ADD_FAVORITE_SUCCEEDED; @@ -507,7 +493,7 @@ static BOOL DoLoop(WINDOW *scrp, nt_usr_db_handle db_handle, LINES - num, COLS, num, 0)) goto END_WHILE; rwinp->key = ch; - state = disp_reslist(rwinp, state, h_sel_items, db_handle); + state = disp_reslist(rwinp, state, h_sel_items, db_handle, h_ng_word, h_cloud); auto_scrolling = FALSE; if(DISP_CMD(state)){ if(DISP_CMD(state) == DISP_CMD_AUTO_SCROLL){ @@ -516,6 +502,7 @@ static BOOL DoLoop(WINDOW *scrp, nt_usr_db_handle db_handle, h_timer_auto_scroll, NT_AUTO_SCROLL_INTERVAL); } auto_scrolling = TRUE; + state = DISP_STATE_RESLIST; }else if(DISP_CMD(state) == DISP_CMD_REFRESH){ state = DISP_STATE_RESLIST; ch = NT_KEY_NONE; @@ -531,8 +518,50 @@ static BOOL DoLoop(WINDOW *scrp, nt_usr_db_handle db_handle, status_msg = NT_INFO_REFRESH_THREAD_SUCCESS; wclear(scrp); continue; + }else if(DISP_CMD(state) == DISP_CMD_REENTER){ + DISP_CLR_CMD(state); + ch = NT_KEY_NONE; + continue; + }else if(DISP_CMD(state) == DISP_CMD_EDIT_NGWORD){ + ch = NT_KEY_NONE; + if(!h_ng_word) + break; + linkp = nt_ng_word_get_words(h_ng_word); + linkp = disp_editor3(linkp); + if(linkp && nt_ng_word_set_words(h_ng_word, linkp, h_cloud)){ + ch = NT_KEY_CMD_NGWORD_UPDATE; + } + DISP_CLR_CMD(state); + keypad(stdscr, true); + wclear(scrp); + continue; + }else if(DISP_CMD(state) == DISP_CMD_EDIT_NGNAME){ + ch = NT_KEY_NONE; + if(!h_ng_word) + break; + linkp = nt_ng_word_get_names(h_ng_word); + linkp = disp_editor3(linkp); + if(linkp && nt_ng_word_set_names(h_ng_word, linkp, h_cloud)){ + ch = NT_KEY_CMD_NGWORD_UPDATE; + } + DISP_CLR_CMD(state); + keypad(stdscr, true); + wclear(scrp); + continue; + }else if(DISP_CMD(state) == DISP_CMD_EDIT_NGID){ + ch = NT_KEY_NONE; + if(!h_ng_word) + break; + linkp = nt_ng_word_get_ids(h_ng_word); + linkp = disp_editor3(linkp); + if(linkp && nt_ng_word_set_ids(h_ng_word, linkp, h_cloud)){ + ch = NT_KEY_CMD_NGWORD_UPDATE; + } + DISP_CLR_CMD(state); + keypad(stdscr, true); + wclear(scrp); + continue; } - DISP_CLR_CMD(state); } if(!auto_scrolling){ nt_timer_set_interval(h_timer_auto_scroll, -1); @@ -723,7 +752,6 @@ static BOOL DoLoop(WINDOW *scrp, nt_usr_db_handle db_handle, if(DISP_CMD(state) == DISP_CMD_DEL_FAVORITE_BOARD){ if(nt_favorite_board_remove(handle)){ h_favorite_board = (nt_favorite_board_handle)handle; -#ifdef NT_CLOUD if(h_cloud){ linkp = nt_link_add_data(NULL, (void*)nt_favorite_board_get_name(h_favorite_board)); @@ -732,7 +760,6 @@ static BOOL DoLoop(WINDOW *scrp, nt_usr_db_handle db_handle, free(linkp); } } -#endif nt_favorite_board_release_ref(h_favorite_board); status_msg = NT_INFO_DEL_FAVORITE_SUCCEEDED; }else{ @@ -741,7 +768,6 @@ static BOOL DoLoop(WINDOW *scrp, nt_usr_db_handle db_handle, }else if(DISP_CMD(state) == DISP_CMD_DEL_FAVORITE_THREAD){ if(nt_favorite_thread_remove(handle)){ h_favorite_thread = (nt_favorite_thread_handle)handle; -#ifdef NT_CLOUD if(h_cloud){ linkp = NULL; if(nt_favorite_retrieve_thread(h_favorite_thread, &linkp)){ @@ -749,7 +775,6 @@ static BOOL DoLoop(WINDOW *scrp, nt_usr_db_handle db_handle, nt_all_link_free(linkp, free); } } -#endif nt_favorite_thread_release_ref(h_favorite_thread); status_msg = NT_INFO_DEL_FAVORITE_SUCCEEDED; }else{ @@ -786,7 +811,6 @@ static BOOL DoLoop(WINDOW *scrp, nt_usr_db_handle db_handle, status_msg = NT_INFO_REFRESH_FAVORITE_SUCCESS; wclear(scrp); continue; -#ifdef NT_CLOUD }else if(h_cloud){ if(DISP_CMD(state) == DISP_CMD_UPLOAD_ALL || DISP_CMD(state) == DISP_CMD_UPLOAD_BOARDS){ @@ -813,8 +837,13 @@ static BOOL DoLoop(WINDOW *scrp, nt_usr_db_handle db_handle, } } } + if(DISP_CMD(state) == DISP_CMD_UPLOAD_ALL || + DISP_CMD(state) == DISP_CMD_UPLOAD_NG_FILES){ + if(nt_ng_word_upload_cloud(h_cloud, h_ng_word)){ + status_msg = NT_INFO_UPLOAD_FAVORITE_SUCCEEDED; + } + } disp_state = state = DISP_STATE_FAVORITE; -#endif }else{ disp_state = state = DISP_STATE_FAVORITE; } diff --git a/src/ui/disp_editor.c b/src/ui/disp_editor.c index 65629ff..e4401ee 100644 --- a/src/ui/disp_editor.c +++ b/src/ui/disp_editor.c @@ -29,12 +29,81 @@ #include "_2ch/_2ch.h" #include "utils/nt_std_t.h" #include "utils/text.h" +#include "utils/file.h" #include "ui/disp.h" static BOOL read_editor(FILE *fp, nt_write_data_handle h_write_data, char *buf_reuse, size_t buf_len); +BOOL disp_editor2(const char *file_name) +{ + char buf[1024*2]; + int ret; + + sprintf(buf, "%s %s", EDITOR_CMD, file_name); + ret = system(buf); + if (WIFSIGNALED(ret) && + (WTERMSIG(ret) == SIGINT || + WTERMSIG(ret) == SIGQUIT)) + return FALSE; + return TRUE; +} + +BOOL nt_link_cmp(nt_link_tp l, nt_link_tp r, nt_compare_fn cmp_func) +{ + nt_link_tp lp, rp; + lp = l; + rp = r; + do{ + if(0 != cmp_func(lp->data, rp->data)) + return FALSE; + lp = lp->next; + rp = rp->next; + }while(l != lp || r != rp); + return (l == lp && r == rp); +} + +nt_link_tp disp_editor3(nt_link_tp text_list) +{ + FILE *tmp_fp; + pid_t pid; + char fname[512]; + char buf[128]; + int ret; + nt_link_tp out_linkp; + pid = getpid(); + + sprintf(fname, "%s/txt%d.tmp", LOG_PATH, pid); + if(!text_list){ + tmp_fp = fopen(fname, "w"); + if(!tmp_fp) + return FALSE; + fclose(tmp_fp); + }else{ + if(!nt_write_text_file(fname, text_list)) + return NULL; + } + + sprintf(buf, "%s %s", EDITOR_CMD, fname); + ret = system(buf); + if (WIFSIGNALED(ret) && + (WTERMSIG(ret) == SIGINT || + WTERMSIG(ret) == SIGQUIT)) + return NULL; + + out_linkp = nt_read_text_file(fname); + if(!out_linkp) + return NULL; + + if(nt_link_cmp(out_linkp, text_list, nt_link_wcscmp_fnc)){ + nt_all_link_free(out_linkp, free); + return NULL; + } + return out_linkp; +} + + BOOL disp_editor(nt_write_data_handle h_write_data) { FILE *tmp_fp; diff --git a/src/ui/disp_favorite.c b/src/ui/disp_favorite.c index ea09d6e..af657b0 100644 --- a/src/ui/disp_favorite.c +++ b/src/ui/disp_favorite.c @@ -37,6 +37,7 @@ #define NT_CMD_UPLOAD_BOARDS 2 #define NT_CMD_UPLOAD_THREADS 3 #define NT_CMD_DISP_HISTORY 4 +#define NT_CMD_UPLOAD_NG_FILES 5 typedef struct tag_favorite_ctx_t *favorite_ctx_tp; typedef struct tag_favorite_ctx_t { @@ -121,6 +122,8 @@ int disp_favorite(nt_window_tp wp, return DISP_CMD_UPLOAD_BOARDS; case NT_CMD_UPLOAD_THREADS: return DISP_CMD_UPLOAD_THREADS; + case NT_CMD_UPLOAD_NG_FILES: + return DISP_CMD_UPLOAD_NG_FILES; case NT_CMD_DISP_HISTORY: return DISP_STATE_HISTORY; } @@ -491,6 +494,9 @@ static int parse_cmd1(const char *param) }else if(0 == strncmp(start, NT_COMMAND1_UPLOAD_THREAD1,len) || 0 == strncmp(start, NT_COMMAND1_UPLOAD_THREAD2,len)){ return NT_CMD_UPLOAD_THREADS; + }else if(0 == strncmp(start, NT_COMMAND1_UPLOAD_NG_FILE1,len) || + 0 == strncmp(start, NT_COMMAND1_UPLOAD_NG_FILE2,len)){ + return NT_CMD_UPLOAD_NG_FILES; } return NT_CMD_ERR; diff --git a/src/ui/disp_history.c b/src/ui/disp_history.c index 362ed02..51b3b26 100644 --- 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, if(!nt_mutex_unlock(h_mutex)){ assert(0); } - if(h_map) + if(h_map){ *update_board_list = nt_map_get_values(h_map); + nt_map_free(h_map, NULL); + } return TRUE; } diff --git a/src/ui/disp_reslist.c b/src/ui/disp_reslist.c index 48792c0..828b399 100644 --- a/src/ui/disp_reslist.c +++ b/src/ui/disp_reslist.c @@ -43,6 +43,12 @@ #define NT_CMD_FAVORITE 6 #define NT_CMD_HISTORY 7 #define NT_CMD_AUTO_SCROLL 8 +#define NT_CMD_ADD_NGWORD 9 +#define NT_CMD_ADD_NGNAME 10 +#define NT_CMD_ADD_NGID 11 +#define NT_CMD_EDT_NGWORD 12 +#define NT_CMD_EDT_NGNAME 13 +#define NT_CMD_EDT_NGID 14 #define AUTO_SCROLL_NONE 0 #define AUTO_SCROLL_UP -1 @@ -91,18 +97,21 @@ static BOOL reslist_clone(nt_thread_handle h_thread, ctx_reslist_tp ctxp); static void int_ptr_free(void *ptr); static int parse_cmd1(const char *param, const char **end); static BOOL search_line_asc(regex_t *regexp, nt_link_tp reslistp, - int *sel_res_no, int *sel_res_line, int column); + int *sel_res_no, int *sel_res_line, int column, + nt_ng_word_handle h_ngword); static BOOL search_line_desc(regex_t *regexp, ctx_reslist_tp ctxp, nt_link_tp reslistp, - int *sel_res_no, int *sel_res_line, int column); + int *sel_res_no, int *sel_res_line, int column, + nt_ng_word_handle h_ngword); static int parse_res_msg(nt_link_tp disp_res_list, - res_data_tp res_datap, size_t colmns); + res_data_tp res_datap, size_t colmns, nt_ng_word_handle h_ngword); static void res_msg_free(void *ptr); static nt_link_tp get_cited_num_list(nt_link_tp res_listp, int seq_no); static BOOL reslist_copy(ctx_reslist_tp ctxp, ctx_reslist_tp copy_ctxp, nt_link_tp num_listp); static ctx_reslist_tp init_sub_context(ctx_reslist_tp ctxp, nt_link_tp num_listp); static void free_reslist_sub_ctx(void *ptr); +static void free_disp_lines_ctx(void *ptr); static nt_link_tp parse_tree_list(ctx_reslist_tp ctxp, const char *param); static nt_link_tp parse_id_list(ctx_reslist_tp ctxp, const char *param); 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, wchar_t *buf, size_t buf_len); int disp_reslist(nt_window_tp wp, int prev_state, nt_2ch_selected_item_handle h_select, - nt_usr_db_handle usr_db_handle) + nt_usr_db_handle usr_db_handle, nt_ng_word_handle h_ng_word, nt_cloud_handle h_cloud) { ctx_reslist_tp ctxp, child_ctxp; 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_ } } - if(prev_state != DISP_STATE_RESLIST) + if(prev_state != DISP_STATE_RESLIST && + prev_state < NT_KEY_CMD_BASE) ctxp->prev_state = prev_state; ch = wp->key; @@ -168,7 +178,7 @@ int disp_reslist(nt_window_tp wp, int prev_state, nt_2ch_selected_item_handle h_ while(clistp != ctxp->res_disp_list){ res_datap = (res_data_tp)clistp->data; if(!res_datap->msg_line_linkp){ - parse_res_msg(ctxp->res_disp_list, res_datap, wp->cols-5); + parse_res_msg(ctxp->res_disp_list, res_datap, wp->cols-5, h_ng_word); } 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_ if(search_asc){ if(search_line_asc(&(ctxp->regex),ctxp->res_disp_list, &ctxp->sel_res_no, &ctxp->sel_res_line, - wp->cols - 5)){ + wp->cols - 5, h_ng_word)){ adjust = TRUE; } }else{ if(search_line_desc(&(ctxp->regex),ctxp, ctxp->res_disp_list, &ctxp->sel_res_no, &ctxp->sel_res_line, - wp->cols - 5)){ + wp->cols - 5, h_ng_word)){ adjust = TRUE; } } @@ -366,7 +376,7 @@ int disp_reslist(nt_window_tp wp, int prev_state, nt_2ch_selected_item_handle h_ res_datap = (res_data_tp)clistp->data; //resp = (nt_res_tp)clistp->data; if(!res_datap->msg_line_linkp){ - parse_res_msg(ctxp->res_disp_list, res_datap, wp->cols-5); + parse_res_msg(ctxp->res_disp_list, res_datap, wp->cols-5, h_ng_word); } if(res_datap->msg_header_line_num <= 0){ 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_ } ctxp->cur_res_offset = 0; break; + case NT_CMD_ADD_NGWORD: + nt_ng_word_add_ng_word(h_cloud, h_ng_word, endp); + free_disp_lines_ctx(wp->data); + return DISP_CMD_REENTER | DISP_STATE_RESLIST; + case NT_CMD_ADD_NGNAME: + nt_ng_word_add_ng_name(h_cloud, h_ng_word, endp); + free_disp_lines_ctx(wp->data); + return DISP_CMD_REENTER | DISP_STATE_RESLIST; + case NT_CMD_ADD_NGID: + nt_ng_word_add_ng_id(h_cloud, h_ng_word, endp); + free_disp_lines_ctx(wp->data); + return DISP_CMD_REENTER | DISP_STATE_RESLIST; + case NT_CMD_EDT_NGWORD: + free_disp_lines_ctx(wp->data); + return DISP_CMD_EDIT_NGWORD | DISP_STATE_RESLIST; + case NT_CMD_EDT_NGNAME: + free_disp_lines_ctx(wp->data); + return DISP_CMD_EDIT_NGNAME | DISP_STATE_RESLIST; + case NT_CMD_EDT_NGID: + free_disp_lines_ctx(wp->data); + return DISP_CMD_EDIT_NGID | DISP_STATE_RESLIST; default: if(cmd == NT_CMD_TREE){ 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_ break; res_datap = (res_data_tp)clistp->data; if(!res_datap->msg_line_linkp){ - parse_res_msg(ctxp->res_disp_list, res_datap, wp->cols-5); + parse_res_msg(ctxp->res_disp_list, res_datap, wp->cols-5, h_ng_word); } if(res_datap->msg_header_line_num <= 0){ 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_ break; res_datap = (res_data_tp)clistp->data; if(!res_datap->msg_line_linkp){ - parse_res_msg(ctxp->res_disp_list, res_datap, wp->cols-5); + parse_res_msg(ctxp->res_disp_list, res_datap, wp->cols-5, h_ng_word); } if(res_datap->msg_header_line_num <= 0){ 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_ for( ; i > 0; i--){ res_datap = (res_data_tp)clistp->data; if(!res_datap->msg_line_linkp){ - parse_res_msg(ctxp->res_disp_list, res_datap, wp->cols-5); + parse_res_msg(ctxp->res_disp_list, res_datap, wp->cols-5, h_ng_word); } if(res_datap->msg_header_line_num <= 0){ 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_ for( ; i < ctxp->res_num; i++){ res_datap = (res_data_tp)clistp->data; if(!res_datap->msg_line_linkp){ - parse_res_msg(ctxp->res_disp_list, res_datap, wp->cols-5); + parse_res_msg(ctxp->res_disp_list, res_datap, wp->cols-5, h_ng_word); } if(res_datap->msg_header_line_num <= 0){ 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_ if(rows == wp->lines) break; if(!res_datap->msg_line_linkp){ - parse_res_msg(ctxp->res_disp_list, res_datap, wp->cols-5); + parse_res_msg(ctxp->res_disp_list, res_datap, wp->cols-5, h_ng_word); } if(0 == res_datap->msg_line_num) continue; @@ -935,6 +966,35 @@ static int parse_cmd1(const char *param, const char **end) 0 == strncmp(NT_COMMAND1_AUTOSCROLL_2,param, strlen(NT_COMMAND1_AUTOSCROLL_2))){ return NT_CMD_AUTO_SCROLL; + }else if(0 == strncmp(NT_COMMAND1_NG_WORD_1,param,len) || + 0 == strncmp(NT_COMMAND1_NG_WORD_2,param, len)){ + if(!nt_strtok(*end, ' ', &start, end)) + return NT_CMD_EDT_NGWORD; + + len = *end - start; + if(len <= 0) + return NT_CMD_EDT_NGWORD; + *end = start; + return NT_CMD_ADD_NGWORD; + }else if(0 == strncmp(NT_COMMAND1_NG_NAME_1,param,len) || + 0 == strncmp(NT_COMMAND1_NG_NAME_2,param, len)){ + if(!nt_strtok(*end, ' ', &start, end)) + return NT_CMD_EDT_NGNAME; + + len = *end - start; + if(len <= 0) + return NT_CMD_EDT_NGNAME; + *end = start; + return NT_CMD_ADD_NGNAME; + }else if(0 == strncmp(NT_COMMAND1_NG_ID_1,param,len)){ + if(!nt_strtok(*end, ' ', &start, end)) + return NT_CMD_EDT_NGID; + + len = *end - start; + if(len <= 0) + return NT_CMD_EDT_NGID; + *end = start; + return NT_CMD_ADD_NGID; } return NT_CMD_NONE; } @@ -1035,6 +1095,20 @@ static ctx_reslist_tp init_sub_context(ctx_reslist_tp ctxp, nt_link_tp num_listp return child_ctxp; } +static const wchar_t *get_id(const wchar_t *source) +{ + const wchar_t *cptr; + if(!source) + return NULL; + cptr = wcsstr(source, L"ID:"); + if(!cptr) + return NULL; + cptr += 3; + if(cptr[0] == L'\0' || cptr[0] == L'?') + return NULL; + return cptr; +} + static BOOL reslist_clone(nt_thread_handle h_thread, ctx_reslist_tp ctxp) { nt_enum_handle h_enum_res; @@ -1131,6 +1205,36 @@ void free_reslist_ctx(void *ptr) } free(ptr); } + +static void free_disp_lines_ctx(void *ptr) +{ + ctx_reslist_tp ctxp; + nt_stack_tp stackp; + nt_link_tp linkp; + res_data_tp res_datap; + if(!ptr) + return; + ctxp = (ctx_reslist_tp)ptr; + if(ctxp->res_disp_list){ + linkp = ctxp->res_disp_list; + do{ + res_datap = (res_data_tp)linkp->data; + if(res_datap->msg_line_linkp){ + free(res_datap->msg_line_linkp->data); + nt_all_link_free(res_datap->msg_line_linkp, NULL); + res_datap->msg_line_linkp = NULL; + } + res_datap->msg_line_num = 0; + linkp = linkp->next; + }while(linkp != ctxp->res_disp_list); + } + stackp = ctxp->child_ctx_stackp; + if(stackp){ + nt_stack_free(stackp, free_reslist_sub_ctx); + ctxp->child_ctx_stackp = NULL; + } +} + static void free_reslist_sub_ctx(void *ptr) { ctx_reslist_tp ctxp; @@ -1223,11 +1327,14 @@ static nt_link_tp get_cited_num_list(nt_link_tp res_listp, int seq_no) } static int parse_res_msg(nt_link_tp disp_res_list, - res_data_tp res_datap, size_t colmns) + res_data_tp res_datap, size_t colmns, + nt_ng_word_handle h_ngword) { - int i, len, start, lines; + int i, len, start, lines, nwrite; wchar_t ch; wchar_t *buf, *cptr, *srcp, *wrk_buf; + const wchar_t *name, *id, *misc; + wchar_t match[256]; int offset; nt_link_tp linkp; int consume_colmns; @@ -1240,8 +1347,47 @@ static int parse_res_msg(nt_link_tp disp_res_list, //res_msg_free(res_datap); res_datap->msg_line_num = 0; - - len = wcslen(res_datap->res_msg); + + name = nt_res_get_name(res_datap->h_res); + misc = nt_res_get_misc(res_datap->h_res); + if(misc) + id = get_id(misc); + else + id = NULL; + cptr = NULL; + if(name && NG_ITEM_NAME == + ng_word_match(h_ngword, NG_ITEM_NAME, name, + match, sizeof(match)/sizeof(wchar_t))){ + cptr = L"NGNAME:"; + }else if(id && NG_ITEM_ID == + ng_word_match(h_ngword, NG_ITEM_ID, id, + match, sizeof(match)/sizeof(wchar_t))){ + cptr = L"NGID:"; + }else if(NG_ITEM_MSG == ng_word_match(h_ngword, NG_ITEM_MSG, + res_datap->res_msg, + match, sizeof(match)/sizeof(wchar_t))){ + cptr = L"NGWORD:"; + } + if(cptr){ + len = wcslen(cptr) + wcslen(match) + 1; + buf = malloc(len*sizeof(wchar_t)); + if(!buf) + return 0; + swprintf(buf, len, L"%ls%ls", cptr, match); + nwrite = nt_get_wc_count_within_colmns(buf, colmns); + if(nwrite <= 0){ + free(buf); + return 0; + } + buf[nwrite] = L'\0'; + res_datap->msg_line_num = 1; + res_datap->msg_line_linkp = nt_link_add_data(NULL, buf); + return 1; + } + + srcp = res_datap->res_msg; + + len = wcslen(srcp); if(len == 0) return 0; buf_size = len + delta; @@ -1253,7 +1399,6 @@ static int parse_res_msg(nt_link_tp disp_res_list, return 0; buf_idx = 0; - srcp = res_datap->res_msg; lines = 0; start = 0; @@ -1340,7 +1485,7 @@ END_FOR: } static BOOL search_line_asc(regex_t *regexp, nt_link_tp reslistp, - int *sel_res_no, int *sel_res_line, int column) + int *sel_res_no, int *sel_res_line, int column, nt_ng_word_handle h_ngword) { nt_link_tp clistp, listp; //nt_res_tp resp; @@ -1370,7 +1515,7 @@ static BOOL search_line_asc(regex_t *regexp, nt_link_tp reslistp, res_datap = (res_data_tp)clistp->data; //resp = res_datap->resp; if(!res_datap->msg_line_linkp) - parse_res_msg(reslistp, res_datap, column); + parse_res_msg(reslistp, res_datap, column, h_ngword); listp = res_datap->msg_line_linkp; line = 0; do{ @@ -1402,7 +1547,7 @@ static BOOL search_line_asc(regex_t *regexp, nt_link_tp reslistp, res_datap = (res_data_tp)clistp->data; if(!res_datap->msg_line_linkp) - parse_res_msg(reslistp, res_datap, column); + parse_res_msg(reslistp, res_datap, column, h_ngword); listp = res_datap->msg_line_linkp; line = 0; do{ @@ -1429,7 +1574,8 @@ static BOOL search_line_asc(regex_t *regexp, nt_link_tp reslistp, static BOOL search_line_desc(regex_t *regexp, ctx_reslist_tp ctxp, nt_link_tp reslistp, - int *sel_res_no, int *sel_res_line, int column) + int *sel_res_no, int *sel_res_line, int column, + nt_ng_word_handle h_ngword) { nt_link_tp clistp, listp; //nt_res_tp resp; @@ -1461,7 +1607,7 @@ static BOOL search_line_desc(regex_t *regexp, ctx_reslist_tp ctxp, res_datap = (res_data_tp)clistp->data; //resp = res_datap->resp; if(!res_datap->msg_line_linkp) - parse_res_msg(reslistp, res_datap, column); + parse_res_msg(reslistp, res_datap, column, h_ngword); listp = res_datap->msg_line_linkp->prev; line = res_datap->msg_line_num - 1; do{ @@ -1494,7 +1640,7 @@ static BOOL search_line_desc(regex_t *regexp, ctx_reslist_tp ctxp, res_datap = (res_data_tp)clistp->data; //resp = (nt_res_tp)clistp->data; if(!res_datap->msg_line_linkp) - parse_res_msg(reslistp, res_datap, column); + parse_res_msg(reslistp, res_datap, column, h_ngword); listp = res_datap->msg_line_linkp->prev; line = res_datap->msg_line_num - 1; do{ diff --git a/src/usr/favorite_t.c b/src/usr/favorite_t.c index 2e30e46..15ce850 100644 --- 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( nt_board_handle h_board; nt_mutex_handle h_mutex; nt_link_tp res_linkp, tmp_linkp, board_name_linkp; - const wchar_t *board_name, *cptr; + const wchar_t *board_name; h_mutex = nt_favorite_get_mutex(h_favorite); if(!h_mutex){ @@ -1372,10 +1372,10 @@ nt_link_tp nt_favorite_get_update_board_list( if(!board_name) continue; if(board_name_linkp){ - cptr = (const wchar_t*)nt_link_find( - board_name_linkp, (void*)board_name, nt_link_wcscmp_fnc); - if(cptr) + if(nt_link_find(board_name_linkp, + (void*)board_name, nt_link_wcscmp_fnc)){ continue; + } } //fwprintf(stderr, L"%ls\n", board_name); h_board = nt_get_board_by_name(h_model, board_name, &h_category); diff --git a/src/usr/ng_word_t.c b/src/usr/ng_word_t.c new file mode 100644 index 0000000..8bdaefb --- /dev/null +++ b/src/usr/ng_word_t.c @@ -0,0 +1,791 @@ +/* Copyright 2014 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 . + +*/ +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#include "usr/ng_word_t.h" +#include "usr/usr_db_t.h" +#include "utils/text.h" +#include "utils/file.h" +#include "utils/nt_conv_char.h" + +#define NT_NG_WORD_CHK_SUM (1678428) + +#define NT_NG_ROOT_MUTEX_KEY (L"ng") +#define NT_NG_WORD_MUTEX_KEY (L"ng_word") +#define NT_NG_NAME_MUTEX_KEY (L"ng_name") +#define NT_NG_ID_MUTEX_KEY (L"ng_id") + + +typedef struct tag_nt_ng_word_t *nt_ng_word_tp; +typedef struct tag_nt_ng_word_t { + nt_ng_word_handle_t handle; + int ref_count; + wchar_t *key; + nt_link_tp ng_words; + nt_link_tp ng_names; + nt_link_tp ng_ids; + nt_link_tp ng_word_patterns; + nt_link_tp ng_name_patterns; + nt_link_tp ng_id_patterns; + nt_link_tp ng_word_reg_patterns; + nt_link_tp ng_name_reg_patterns; + nt_link_tp ng_id_reg_patterns; +} nt_ng_word_t; + +static nt_mutex_handle local_ng_word_get_mutex( + const wchar_t *key, nt_ng_word_handle handle); +static nt_ng_word_handle nt_ng_word_alloc(); +static BOOL ng_word_add( + nt_cloud_handle h_cloud, const char *cloud_file_name, + nt_ng_word_handle handle, + const char *ng_word, + nt_link_tp *org_linkpp, + nt_link_tp *text_linkpp, + nt_link_tp *regx_linkpp); +static wchar_t *parse_plain_text(const wchar_t *source); +static regex_t *get_regx_pattern(const char *source); +static BOOL word_match_local(nt_ng_word_tp ng_wordp, + const wchar_t *source, + nt_link_tp patterns, + nt_link_tp reg_patterns, + wchar_t *match_buf, size_t match_buf_len); + + +static wchar_t *parse_plain_text(const wchar_t *source){ + if(!source || source[0] == L'\0') + return NULL; + + if(source[0] == L'\\' && + source[0] == L'/'){ + return nt_w_str_clone(source+1); + }else{ + return nt_w_str_clone(source); + } +} + +static regex_t *get_regx_pattern(const char *source) +{ + int len, cflags; + char *cptr; + char buf[256]; + regex_t *regp; + + if(!source || '\0' == source[0]) + return NULL; + + if('/' != source[0]) + return NULL; + + cptr = strrchr (source, '/'); + if(!cptr || cptr == source) + return NULL; + cflags = REG_NEWLINE | REG_EXTENDED; + if(cptr[1] == 'i') + cflags |= REG_ICASE; + + len = cptr - source - 1; + if(len >= sizeof(buf)-1) + return NULL; + strncpy(buf, source+1, len); + buf[len] = '\0'; + + regp = malloc(sizeof(regex_t)); + if(!regp){ + return NULL; + } + if(0 != regcomp(regp, buf, cflags)){ + free(regp); + return NULL; + } + return regp; +} + +nt_link_tp nt_ng_word_get_words(nt_ng_word_handle handle) +{ + nt_ng_word_tp ng_wordp; + assert(handle); + assert(handle->chk_sum == NT_NG_WORD_CHK_SUM); + ng_wordp = (nt_ng_word_tp)handle; + assert(ng_wordp->ref_count > 0); + return ng_wordp->ng_words; +} + +nt_link_tp nt_ng_word_get_names(nt_ng_word_handle handle) +{ + nt_ng_word_tp ng_wordp; + assert(handle); + assert(handle->chk_sum == NT_NG_WORD_CHK_SUM); + ng_wordp = (nt_ng_word_tp)handle; + assert(ng_wordp->ref_count > 0); + return ng_wordp->ng_names; +} + +nt_link_tp nt_ng_word_get_ids(nt_ng_word_handle handle) +{ + nt_ng_word_tp ng_wordp; + assert(handle); + assert(handle->chk_sum == NT_NG_WORD_CHK_SUM); + ng_wordp = (nt_ng_word_tp)handle; + assert(ng_wordp->ref_count > 0); + return ng_wordp->ng_ids; +} + +static void reg_free(void *ptr){ + regex_t *regp; + regp = (regex_t*)ptr; + regfree(regp); + free(regp); +} + +BOOL nt_ng_word_set_words(nt_ng_word_handle handle, + nt_link_tp text_list, nt_cloud_handle h_cloud) +{ + nt_ng_word_tp ng_wordp; + nt_link_tp linkp; + wchar_t *cptr; + char buf[256]; + + assert(handle); + assert(handle->chk_sum == NT_NG_WORD_CHK_SUM); + ng_wordp = (nt_ng_word_tp)handle; + assert(ng_wordp->ref_count > 0); + if(ng_wordp->ng_words) + nt_all_link_free(ng_wordp->ng_words, free); + if(ng_wordp->ng_word_patterns) + nt_all_link_free(ng_wordp->ng_word_patterns, free); + if(ng_wordp->ng_word_reg_patterns) + nt_all_link_free(ng_wordp->ng_word_reg_patterns, reg_free); + ng_wordp->ng_words = NULL; + ng_wordp->ng_word_patterns = NULL; + ng_wordp->ng_word_reg_patterns = NULL; + if(text_list){ + linkp = text_list; + do{ + cptr = (wchar_t*)linkp->data; + if((size_t)-1 != wcstombs(buf, cptr, sizeof(buf))){ + nt_ng_word_add_ng_word(NULL, &ng_wordp->handle, buf); + } + linkp = linkp->next; + }while(linkp != text_list); + nt_all_link_free(text_list, free); + if(h_cloud) + nt_cloud_upload_file(h_cloud, + "ngwd.txt", ng_wordp->ng_words); + } + return TRUE; +} + +BOOL nt_ng_word_set_names(nt_ng_word_handle handle, + nt_link_tp text_list, nt_cloud_handle h_cloud) +{ + nt_ng_word_tp ng_wordp; + nt_link_tp linkp; + wchar_t *cptr; + char buf[256]; + + assert(handle); + assert(handle->chk_sum == NT_NG_WORD_CHK_SUM); + ng_wordp = (nt_ng_word_tp)handle; + assert(ng_wordp->ref_count > 0); + if(ng_wordp->ng_names) + nt_all_link_free(ng_wordp->ng_names, free); + if(ng_wordp->ng_name_patterns) + nt_all_link_free(ng_wordp->ng_name_patterns, free); + if(ng_wordp->ng_name_reg_patterns) + nt_all_link_free(ng_wordp->ng_name_reg_patterns, reg_free); + ng_wordp->ng_names = NULL; + ng_wordp->ng_name_patterns = NULL; + ng_wordp->ng_name_reg_patterns = NULL; + if(text_list){ + linkp = text_list; + do{ + cptr = (wchar_t*)linkp->data; + if((size_t)-1 != wcstombs(buf, cptr, sizeof(buf))){ + nt_ng_word_add_ng_name(NULL, &ng_wordp->handle, buf); + } + linkp = linkp->next; + }while(linkp != text_list); + nt_all_link_free(text_list, free); + if(h_cloud) + nt_cloud_upload_file(h_cloud, + "ngnm.txt", ng_wordp->ng_names); + } + return TRUE; +} + +BOOL nt_ng_word_set_ids(nt_ng_word_handle handle, + nt_link_tp text_list, nt_cloud_handle h_cloud) +{ + nt_ng_word_tp ng_wordp; + nt_link_tp linkp; + wchar_t *cptr; + char buf[256]; + + assert(handle); + assert(handle->chk_sum == NT_NG_WORD_CHK_SUM); + ng_wordp = (nt_ng_word_tp)handle; + assert(ng_wordp->ref_count > 0); + if(ng_wordp->ng_ids) + nt_all_link_free(ng_wordp->ng_ids, free); + if(ng_wordp->ng_id_patterns) + nt_all_link_free(ng_wordp->ng_id_patterns, free); + if(ng_wordp->ng_id_reg_patterns) + nt_all_link_free(ng_wordp->ng_id_reg_patterns, reg_free); + ng_wordp->ng_ids = NULL; + ng_wordp->ng_id_patterns = NULL; + ng_wordp->ng_id_reg_patterns = NULL; + if(text_list){ + linkp = text_list; + do{ + cptr = (wchar_t*)linkp->data; + if((size_t)-1 != wcstombs(buf, cptr, sizeof(buf))){ + nt_ng_word_add_ng_id(NULL, &ng_wordp->handle, buf); + } + linkp = linkp->next; + }while(linkp != text_list); + nt_all_link_free(text_list, free); + if(h_cloud) + nt_cloud_upload_file(h_cloud, + "ngid.txt", ng_wordp->ng_ids); + } + return TRUE; +} + +nt_ng_word_handle nt_ng_word_load( + nt_cloud_handle h_cloud, + const char *ng_word_file_name, + const char *ng_name_file_name, + const char *ng_id_file_name + ) +{ + nt_ng_word_tp ng_wordp; + nt_link_tp text_linkp, linkp; + wchar_t *cptr; + char buf[256]; + + ng_wordp = (nt_ng_word_tp)nt_ng_word_alloc(); + if(!ng_wordp) + return NULL; + text_linkp = NULL; + if(h_cloud) + text_linkp = nt_cloud_download_file(h_cloud, "ngwd.txt"); + if(!text_linkp) + text_linkp = nt_read_text_file(ng_word_file_name); + if(text_linkp){ + linkp = text_linkp; + do{ + cptr = (wchar_t*)linkp->data; + if((size_t)-1 != wcstombs(buf, cptr, sizeof(buf))){ + nt_ng_word_add_ng_word(NULL, &ng_wordp->handle, buf); + } + linkp = linkp->next; + }while(linkp != text_linkp); + nt_all_link_free(text_linkp, free); + } + text_linkp = NULL; + if(h_cloud) + text_linkp = nt_cloud_download_file(h_cloud, "ngnm.txt"); + if(!text_linkp) + text_linkp = nt_read_text_file(ng_name_file_name); + if(text_linkp){ + linkp = text_linkp; + do{ + cptr = (wchar_t*)linkp->data; + if((size_t)-1 != wcstombs(buf, cptr, sizeof(buf))){ + nt_ng_word_add_ng_name(NULL, &ng_wordp->handle, buf); + } + linkp = linkp->next; + }while(linkp != text_linkp); + nt_all_link_free(text_linkp, free); + } + text_linkp = NULL; + if(h_cloud) + text_linkp = nt_cloud_download_file(h_cloud, "ngid.txt"); + if(!text_linkp) + text_linkp = nt_read_text_file(ng_id_file_name); + if(text_linkp){ + linkp = text_linkp; + do{ + cptr = (wchar_t*)linkp->data; + if((size_t)-1 != wcstombs(buf, cptr, sizeof(buf))){ + nt_ng_word_add_ng_id(NULL, &ng_wordp->handle, buf); + } + linkp = linkp->next; + }while(linkp != text_linkp); + nt_all_link_free(text_linkp, free); + } + + return &ng_wordp->handle; +} + +BOOL nt_ng_word_save(nt_ng_word_handle handle, + const char *ng_word_file_name, + const char *ng_name_file_name, + const char *ng_id_file_name + ) +{ + nt_ng_word_tp ng_wordp; + nt_mutex_handle h_mutex; + + assert(handle); + assert(handle->chk_sum == NT_NG_WORD_CHK_SUM); + ng_wordp = (nt_ng_word_tp)handle; + assert(ng_wordp->ref_count > 0); + + h_mutex = nt_ng_get_mutex(handle); + if(h_mutex) + nt_mutex_lock(h_mutex); + + if(ng_wordp->ng_words) + nt_write_text_file(ng_word_file_name, ng_wordp->ng_words); + if(ng_wordp->ng_names) + nt_write_text_file(ng_name_file_name, ng_wordp->ng_names); + if(ng_wordp->ng_ids) + nt_write_text_file(ng_id_file_name, ng_wordp->ng_ids); + + if(h_mutex) + nt_mutex_unlock(h_mutex); + return TRUE; +} + +BOOL nt_ng_word_add_ng_word( + nt_cloud_handle h_cloud, + nt_ng_word_handle handle, const char *ng_word) +{ + nt_ng_word_tp ng_wordp; + nt_mutex_handle h_mutex; + BOOL bret; + assert(handle); + assert(handle->chk_sum == NT_NG_WORD_CHK_SUM); + ng_wordp = (nt_ng_word_tp)handle; + assert(ng_wordp->ref_count > 0); + h_mutex = nt_ng_word_get_mutex(handle); + if(h_mutex) + nt_mutex_lock(h_mutex); + bret = ng_word_add( + h_cloud, "ngwd.txt", + handle, ng_word, + &ng_wordp->ng_words, + &ng_wordp->ng_word_patterns, + &ng_wordp->ng_word_reg_patterns); + if(h_mutex) + nt_mutex_unlock(h_mutex); + return bret; +} + +BOOL nt_ng_word_add_ng_name( + nt_cloud_handle h_cloud, + nt_ng_word_handle handle, const char *ng_name) +{ + nt_ng_word_tp ng_wordp; + nt_mutex_handle h_mutex; + BOOL bret; + assert(handle); + assert(handle->chk_sum == NT_NG_WORD_CHK_SUM); + ng_wordp = (nt_ng_word_tp)handle; + assert(ng_wordp->ref_count > 0); + h_mutex = nt_ng_name_get_mutex(handle); + if(h_mutex) + nt_mutex_lock(h_mutex); + bret = ng_word_add( + h_cloud, "ngnm.txt", + handle, ng_name, + &ng_wordp->ng_names, + &ng_wordp->ng_name_patterns, + &ng_wordp->ng_name_reg_patterns); + if(h_mutex) + nt_mutex_unlock(h_mutex); + return bret; +} + +BOOL nt_ng_word_add_ng_id( + nt_cloud_handle h_cloud, + nt_ng_word_handle handle, const char *ng_id) +{ + nt_ng_word_tp ng_wordp; + nt_mutex_handle h_mutex; + BOOL bret; + assert(handle); + assert(handle->chk_sum == NT_NG_WORD_CHK_SUM); + ng_wordp = (nt_ng_word_tp)handle; + assert(ng_wordp->ref_count > 0); + h_mutex = nt_ng_id_get_mutex(handle); + if(h_mutex) + nt_mutex_lock(h_mutex); + bret = ng_word_add( + h_cloud, "ngid.txt", + handle, ng_id, + &ng_wordp->ng_ids, + &ng_wordp->ng_id_patterns, + &ng_wordp->ng_id_reg_patterns); + if(h_mutex) + nt_mutex_unlock(h_mutex); + return bret; +} + +static BOOL ng_word_add( + nt_cloud_handle h_cloud, const char *cloud_file_name, + nt_ng_word_handle handle, + const char *ng_word, + nt_link_tp *org_linkpp, + nt_link_tp *text_linkpp, + nt_link_tp *regx_linkpp) +{ + int len; + wchar_t wbuf[1024]; + wchar_t *cptr; + nt_link_tp linkp; + regex_t *regp; + + if(!ng_word || (0 == (len = strlen(ng_word)))) + return FALSE; + + if(-1 == mbstowcs(wbuf, ng_word, sizeof(wbuf))) + return FALSE; + + if(*org_linkpp){ + cptr = (wchar_t*)nt_link_find( + *org_linkpp, (void*)wbuf, nt_link_wcscmp_fnc); + if(cptr) + return TRUE; + } + + if(NULL == (cptr = nt_w_str_clone(wbuf))) + return FALSE; + linkp = nt_link_add_data(*org_linkpp, cptr); + if(!linkp){ + free(cptr); + return FALSE; + } + if(!(*org_linkpp)) + *org_linkpp = linkp; + + if(h_cloud){ + cptr = nt_w_str_clone(wbuf); + if(cptr){ + linkp = nt_link_add_data(NULL, (void*)cptr); + if(linkp){ + nt_cloud_insert_lines_into_file_async(h_cloud, cloud_file_name, linkp); + } + } + } + + if(NULL != (regp = get_regx_pattern(ng_word))){ + linkp = nt_link_add_data(*regx_linkpp, regp); + if(!linkp){ + regfree(regp); + free(regp); + return FALSE; + } + if(!(*regx_linkpp)) + *regx_linkpp = linkp; + return TRUE; + } + if(NULL != (cptr = parse_plain_text(wbuf))){ + linkp = nt_link_add_data(*text_linkpp, cptr); + if(!linkp){ + free(cptr); + return FALSE; + } + if(!(*text_linkpp)) + *text_linkpp = linkp; + return TRUE; + } + + return FALSE; +} + +int ng_word_match(nt_ng_word_handle handle, + int item_type, const wchar_t *source, + wchar_t *match_buf, size_t match_buf_len) +{ + nt_ng_word_tp ng_wordp; + + //assert(match); + assert(handle); + assert(handle->chk_sum == NT_NG_WORD_CHK_SUM); + ng_wordp = (nt_ng_word_tp)handle; + assert(ng_wordp->ref_count > 0); + if(item_type & NG_ITEM_MSG){ + if(word_match_local(ng_wordp, source, + ng_wordp->ng_word_patterns, + ng_wordp->ng_word_reg_patterns, + match_buf, match_buf_len)){ + return NG_ITEM_MSG; + } + }else if(item_type & NG_ITEM_NAME){ + if(word_match_local(ng_wordp, source, + ng_wordp->ng_name_patterns, + ng_wordp->ng_name_reg_patterns, + match_buf, match_buf_len)){ + return NG_ITEM_NAME; + } + }else if(item_type & NG_ITEM_ID){ + if(word_match_local(ng_wordp, source, + ng_wordp->ng_id_patterns, + ng_wordp->ng_id_reg_patterns, + match_buf, match_buf_len)){ + return NG_ITEM_ID; + } + } + return NG_ITEM_NONE; +} + +static BOOL word_match_local(nt_ng_word_tp ng_wordp, + const wchar_t *source, + nt_link_tp patterns, + nt_link_tp reg_patterns, + wchar_t *match_buf, size_t match_buf_len) +{ + nt_link_tp linkp; + wchar_t *cptr1, *cptr2; + regex_t *regp; + regmatch_t match[2]; + char *ptr; + int len; + + if(patterns){ + linkp = patterns; + do{ + cptr1 = (wchar_t*)linkp->data; + if(NULL != (cptr2 = wcsstr(source, cptr1))){ + if(match_buf_len > wcslen(cptr1)) + wcscpy(match_buf, cptr1); + else + match_buf[0] = L'\0'; + return TRUE; + } + linkp = linkp->next; + }while(linkp != patterns); + } + if(reg_patterns){ + len = wcslen(source); + if(len == 0) + goto EXIT_NG_ITEM_MSG; + ptr = malloc((len+1)*3);/*max utf-8 char size*/ + if(!ptr) + goto EXIT_NG_ITEM_MSG; + if((size_t)-1 == wcstombs(ptr, source, (len+1)*3)){ + free(ptr); + goto EXIT_NG_ITEM_MSG; + } + linkp = reg_patterns; + do{ + regp = (regex_t*)linkp->data; + if(0 == regexec(regp, ptr, + sizeof(match)/sizeof(regmatch_t), + match, 0)){ + if(match[0].rm_so > -1){ + len = match[0].rm_eo - match[0].rm_so; + if(match_buf_len > len){ + ptr[match[0].rm_eo] = '\0'; + if((size_t)-1 == mbstowcs( + match_buf, + ptr + match[0].rm_so, + match_buf_len)){ + match_buf[0] = L'\0'; + } + }else{ + match_buf[0] = L'\0'; + } + }else{ + match_buf[0] = L'\0'; + } + free(ptr); + return TRUE; + } + linkp = linkp->next; + }while(linkp != reg_patterns); + free(ptr); + } +EXIT_NG_ITEM_MSG: + return FALSE; +} + + +static nt_ng_word_handle nt_ng_word_alloc() +{ + nt_ng_word_tp ng_wordp = + malloc(sizeof(nt_ng_word_t)); + if(!ng_wordp) + return NULL; + + ng_wordp->handle.chk_sum = NT_NG_WORD_CHK_SUM; + ng_wordp->ng_words = NULL; + ng_wordp->ng_names = NULL; + ng_wordp->ng_word_patterns = NULL; + ng_wordp->ng_name_patterns = NULL; + ng_wordp->ng_id_patterns = NULL; + ng_wordp->ng_word_reg_patterns = NULL; + ng_wordp->ng_name_reg_patterns = NULL; + ng_wordp->ng_id_reg_patterns = NULL; + + ng_wordp->ng_ids = NULL; + ng_wordp->ref_count = 1; + ng_wordp->key = NT_NG_ROOT_MUTEX_KEY; + return (nt_ng_word_handle)&ng_wordp->handle; +} + + +nt_mutex_handle nt_ng_get_mutex(nt_ng_word_handle handle) +{ + nt_mutex_handle h_mutex; + nt_ng_word_tp ng_wordp; + + assert(handle); + assert(handle->chk_sum == NT_NG_WORD_CHK_SUM); + ng_wordp = (nt_ng_word_tp)handle; + assert(ng_wordp->ref_count > 0); + + nt_ng_word_add_ref(handle); + + h_mutex = nt_mutex_get_one_time_handle(ng_wordp->key); + + nt_ng_word_release_ref(handle); + if(!h_mutex){ + return NULL; + } + return h_mutex; +} + +static nt_mutex_handle local_ng_word_get_mutex( + const wchar_t *key, nt_ng_word_handle handle) +{ + nt_mutex_handle h_mutex; + nt_ng_word_tp ng_wordp; + + assert(handle); + assert(handle->chk_sum == NT_NG_WORD_CHK_SUM); + ng_wordp = (nt_ng_word_tp)handle; + assert(ng_wordp->ref_count > 0); + + nt_ng_word_add_ref(handle); + + h_mutex = nt_mutex_get_one_time_handle(ng_wordp->key); + + nt_ng_word_release_ref(handle); + if(!h_mutex){ + return NULL; + } + if(!nt_mutex_add_moniker(h_mutex, key)){ + return NULL; + } + return h_mutex; +} + +nt_mutex_handle nt_ng_word_get_mutex(nt_ng_word_handle handle) +{ + return local_ng_word_get_mutex(NT_NG_WORD_MUTEX_KEY, handle); +} +nt_mutex_handle nt_ng_name_get_mutex(nt_ng_word_handle handle) +{ + return local_ng_word_get_mutex(NT_NG_NAME_MUTEX_KEY, handle); +} +nt_mutex_handle nt_ng_id_get_mutex(nt_ng_word_handle handle) +{ + return local_ng_word_get_mutex(NT_NG_ID_MUTEX_KEY, handle); +} + + +int nt_ng_word_add_ref(nt_ng_word_handle handle) +{ + nt_ng_word_tp ng_wordp; + assert(handle); + assert(handle->chk_sum == NT_NG_WORD_CHK_SUM); + ng_wordp = (nt_ng_word_tp)handle; + assert(ng_wordp->ref_count > 0); + return ++ng_wordp->ref_count; +} + + +int nt_ng_word_release_ref(nt_ng_word_handle handle) +{ + nt_ng_word_tp ng_wordp; + assert(handle); + assert(handle->chk_sum == NT_NG_WORD_CHK_SUM); + ng_wordp = (nt_ng_word_tp)handle; + assert(ng_wordp->ref_count > 0); + ng_wordp->ref_count--; + if(0 != ng_wordp->ref_count) + return ng_wordp->ref_count; + + + if(ng_wordp->ng_words) + nt_all_link_free(ng_wordp->ng_words, free); + if(ng_wordp->ng_word_patterns) + nt_all_link_free(ng_wordp->ng_word_patterns, free); + if(ng_wordp->ng_word_reg_patterns) + nt_all_link_free(ng_wordp->ng_word_reg_patterns, reg_free); + if(ng_wordp->ng_names) + nt_all_link_free(ng_wordp->ng_names, free); + if(ng_wordp->ng_name_patterns) + nt_all_link_free(ng_wordp->ng_name_patterns, free); + if(ng_wordp->ng_name_reg_patterns) + nt_all_link_free(ng_wordp->ng_name_reg_patterns, reg_free); + if(ng_wordp->ng_ids) + nt_all_link_free(ng_wordp->ng_ids, free); + if(ng_wordp->ng_id_patterns) + nt_all_link_free(ng_wordp->ng_id_patterns, free); + if(ng_wordp->ng_id_reg_patterns) + nt_all_link_free(ng_wordp->ng_id_reg_patterns, reg_free); + free(ng_wordp); + return 0; +} + +BOOL nt_ng_word_upload_cloud(nt_cloud_handle h_cloud, nt_ng_word_handle h_ng_word) +{ + nt_ng_word_tp ng_wordp; + nt_link_tp empty_linkp; + assert(h_ng_word); + assert(h_ng_word->chk_sum == NT_NG_WORD_CHK_SUM); + ng_wordp = (nt_ng_word_tp)h_ng_word; + assert(ng_wordp->ref_count > 0); + + empty_linkp = nt_link_add_data(NULL, L""); + + if(ng_wordp->ng_words){ + nt_cloud_upload_file(h_cloud, "ngwd.txt", ng_wordp->ng_words); + }else if(empty_linkp){ + nt_cloud_upload_file(h_cloud, "ngwd.txt", empty_linkp); + } + + if(ng_wordp->ng_names){ + nt_cloud_upload_file(h_cloud, "ngnm.txt", ng_wordp->ng_names); + }else if(empty_linkp){ + nt_cloud_upload_file(h_cloud, "ngnm.txt", empty_linkp); + } + if(ng_wordp->ng_ids){ + nt_cloud_upload_file(h_cloud, "ngid.txt", ng_wordp->ng_ids); + }else if(empty_linkp){ + nt_cloud_upload_file(h_cloud, "ngid.txt", empty_linkp); + } + + if(empty_linkp) + nt_all_link_free(empty_linkp, NULL); + return TRUE; +} + diff --git a/src/utils/nt_std_t.c b/src/utils/nt_std_t.c index 4c91e27..67927b4 100644 --- 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) return link->next; } -nt_link_tp nt_link_copy(nt_link_tp src_linkp) +nt_link_tp nt_link_copy(nt_link_tp src_linkp, nt_memcopy_fn copy_func) { nt_link_tp srcp, resultp, workp; + void *ptr; + assert(src_linkp); srcp = src_linkp; resultp = NULL; do{ - workp = nt_link_add_data(resultp, srcp->data); + if(!copy_func){ + workp = nt_link_add_data(resultp, srcp->data); + }else{ + ptr = (copy_func)(srcp->data); + if(ptr) + workp = nt_link_add_data(resultp, ptr); + else + workp = NULL; + } if(!workp){ if(resultp) nt_all_link_free(resultp, NULL); @@ -521,6 +531,31 @@ nt_link_tp nt_link_copy(nt_link_tp src_linkp) return resultp; } +void* nt_link_strcpy_fnc(void *ptr) +{ + char *cptr, *p; + int len; + cptr = (char*)ptr; + len = strlen(cptr); + p = malloc(len+1); + if(!p) + return NULL; + strcpy(p, cptr); + return p; +} +void* nt_link_wcscpy_fnc(void *ptr) +{ + wchar_t *cptr, *p; + int len; + cptr = (wchar_t*)ptr; + len = wcslen(cptr); + p = malloc((len+1)*sizeof(wchar_t)); + if(!p) + return NULL; + wcscpy(p, cptr); + return p; +} + int nt_link_wcscmp_fnc(void *lhs, void *rhs) { return wcscmp((const wchar_t *)lhs, (const wchar_t *)rhs);