aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSteve Slaven <bpk@hoopajoo.net>2005-03-21 20:49:24 (GMT)
committerSteve Slaven <bpk@hoopajoo.net>2005-03-21 20:49:24 (GMT)
commit22e6d965aa95a519d2b5672ee2c888785fc524ee (patch)
tree13db9f59127a2b9169acfe7d10e707b2264e7133
parentabe994ae16b892106e0b36d7be5bfd7e1100075c (diff)
downloadpowwow-22e6d965aa95a519d2b5672ee2c888785fc524ee.zip
powwow-22e6d965aa95a519d2b5672ee2c888785fc524ee.tar.gz
powwow-22e6d965aa95a519d2b5672ee2c888785fc524ee.tar.bz2
Wide character (locale) support from Dain, changed output of the compiled
options line since there are more compile time options now
-rw-r--r--cmd2.c2
-rwxr-xr-xconfigure144
-rw-r--r--configure.in1
-rw-r--r--main.c61
-rw-r--r--tty.c152
-rw-r--r--tty.h34
6 files changed, 359 insertions, 35 deletions
diff --git a/cmd2.c b/cmd2.c
index 301d9ae..06892ed 100644
--- a/cmd2.c
+++ b/cmd2.c
@@ -1059,7 +1059,7 @@ static int get_one_char __P1 (int,timeout)
errmsg("select");
return -1;
}
- while ((err = tty_read(tty_read_fd, &c, 1)) < 0 && errno == EINTR)
+ while ((err = tty_read(&c, 1)) < 0 && errno == EINTR)
;
if (err != 1) {
errmsg("read from tty");
diff --git a/configure b/configure
index 913b228..de08f52 100755
--- a/configure
+++ b/configure
@@ -3869,6 +3869,150 @@ fi
done
+if test "${ac_cv_header_locale_h+set}" = set; then
+ echo "$as_me:$LINENO: checking for locale.h" >&5
+echo $ECHO_N "checking for locale.h... $ECHO_C" >&6
+if test "${ac_cv_header_locale_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_locale_h" >&5
+echo "${ECHO_T}$ac_cv_header_locale_h" >&6
+else
+ # Is the header compilable?
+echo "$as_me:$LINENO: checking locale.h usability" >&5
+echo $ECHO_N "checking locale.h usability... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+$ac_includes_default
+#include <locale.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+ (eval $ac_compile) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } &&
+ { ac_try='test -z "$ac_c_werror_flag" || test ! -s conftest.err'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; } &&
+ { ac_try='test -s conftest.$ac_objext'
+ { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5
+ (eval $ac_try) 2>&5
+ ac_status=$?
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); }; }; then
+ ac_header_compiler=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ac_header_compiler=no
+fi
+rm -f conftest.err conftest.$ac_objext conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6
+
+# Is the header present?
+echo "$as_me:$LINENO: checking locale.h presence" >&5
+echo $ECHO_N "checking locale.h presence... $ECHO_C" >&6
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h. */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h. */
+#include <locale.h>
+_ACEOF
+if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5
+ (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1
+ ac_status=$?
+ grep -v '^ *+' conftest.er1 >conftest.err
+ rm -f conftest.er1
+ cat conftest.err >&5
+ echo "$as_me:$LINENO: \$? = $ac_status" >&5
+ (exit $ac_status); } >/dev/null; then
+ if test -s conftest.err; then
+ ac_cpp_err=$ac_c_preproc_warn_flag
+ ac_cpp_err=$ac_cpp_err$ac_c_werror_flag
+ else
+ ac_cpp_err=
+ fi
+else
+ ac_cpp_err=yes
+fi
+if test -z "$ac_cpp_err"; then
+ ac_header_preproc=yes
+else
+ echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+ ac_header_preproc=no
+fi
+rm -f conftest.err conftest.$ac_ext
+echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6
+
+# So? What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+ yes:no: )
+ { echo "$as_me:$LINENO: WARNING: locale.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: locale.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+ { echo "$as_me:$LINENO: WARNING: locale.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: locale.h: proceeding with the compiler's result" >&2;}
+ ac_header_preproc=yes
+ ;;
+ no:yes:* )
+ { echo "$as_me:$LINENO: WARNING: locale.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: locale.h: present but cannot be compiled" >&2;}
+ { echo "$as_me:$LINENO: WARNING: locale.h: check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: locale.h: check for missing prerequisite headers?" >&2;}
+ { echo "$as_me:$LINENO: WARNING: locale.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: locale.h: see the Autoconf documentation" >&2;}
+ { echo "$as_me:$LINENO: WARNING: locale.h: section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: locale.h: section \"Present But Cannot Be Compiled\"" >&2;}
+ { echo "$as_me:$LINENO: WARNING: locale.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: locale.h: proceeding with the preprocessor's result" >&2;}
+ { echo "$as_me:$LINENO: WARNING: locale.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: locale.h: in the future, the compiler will take precedence" >&2;}
+ (
+ cat <<\_ASBOX
+## ------------------------------------------ ##
+## Report this to the AC_PACKAGE_NAME lists. ##
+## ------------------------------------------ ##
+_ASBOX
+ ) |
+ sed "s/^/$as_me: WARNING: /" >&2
+ ;;
+esac
+echo "$as_me:$LINENO: checking for locale.h" >&5
+echo $ECHO_N "checking for locale.h... $ECHO_C" >&6
+if test "${ac_cv_header_locale_h+set}" = set; then
+ echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+ ac_cv_header_locale_h=$ac_header_preproc
+fi
+echo "$as_me:$LINENO: result: $ac_cv_header_locale_h" >&5
+echo "${ECHO_T}$ac_cv_header_locale_h" >&6
+
+fi
+if test $ac_cv_header_locale_h = yes; then
+ cat >>confdefs.h <<\_ACEOF
+#define USE_LOCALE 1
+_ACEOF
+
+fi
+
+
# Checks for typedefs, structures, and compiler characteristics.
echo "$as_me:$LINENO: checking for an ANSI C-conforming const" >&5
diff --git a/configure.in b/configure.in
index 89f0a27..15da9b6 100644
--- a/configure.in
+++ b/configure.in
@@ -39,6 +39,7 @@ AC_CHECK_LIB(dl,dlopen)
# Checks for header files.
AC_CHECK_HEADERS([stdlib.h unistd.h])
+AC_CHECK_HEADER(locale.h,AC_DEFINE(USE_LOCALE))
# Checks for typedefs, structures, and compiler characteristics.
AC_C_CONST
diff --git a/main.c b/main.c
index 5afb94f..c160504 100644
--- a/main.c
+++ b/main.c
@@ -30,9 +30,19 @@
* #define POWWOW_DIR "/home/gustav/powwow"
*/
-#define POWWOW_VERSION VERSION ", Copyright 2000-2005 by Cosmos\n" \
- " Copyright 2005 by bpk - http://hoopajoo.net\n" \
- "(contributions by Yorick, Vivriel, Thuzzle, Ilie, Fror, Dain)\n"
+#ifdef USE_LOCALE
+ #define POWWOW_HACKERS "Yorick, Vivriel, Thuzzle, Ilie, Fr\363r, D\341in"
+ #define COPYRIGHT "\251 "
+#else
+ #define POWWOW_HACKERS "Yorick, Vivriel, Thuzzle, Ilie, Fror, Dain"
+ #define COPYRIGHT ""
+#endif
+
+#define POWWOW_VERSION VERSION \
+ ", Copyright 2000-2005 by Cosmos\n" \
+ "Copyright 2005 by bpk - http://hoopajoo.net\n" \
+ "(contributions by " POWWOW_HACKERS ")\n"
+
#define HELPNAME "powwow.help"
#define COPYNAME "COPYING"
@@ -56,6 +66,10 @@
#include <memory.h>
#include <unistd.h>
+#ifdef USE_LOCALE
+#include <locale.h>
+#endif
+
/* are these really needed? */
extern int errno;
extern int select();
@@ -227,7 +241,13 @@ int main __P2 (int,argc, char **,argv)
int i;
int read_file = 0; /* GH: if true, powwow was started with
* a file argument, and initstr shall be ran */
-
+
+#ifdef USE_LOCALE
+ if (!setlocale(LC_ALL, "")) {
+ fprintf(stderr, "Failed setlocale(LC_ALL, \"C\")\n");
+ }
+#endif
+
/* initializations */
initstr[0] = 0;
memzero(conn_list, sizeof(conn_list));
@@ -399,26 +419,33 @@ under certain conditions; type \"#help copyright\" for details.\n"
*/
void printver __P0 (void)
{
- tty_printf("Powwow version %s\n%s (%s, %s)%s\n", POWWOW_VERSION,
-#if __STDC__
- "compiled " __TIME__ " " __DATE__,
-#else
- "",
-#endif
+ tty_printf("Powwow version %s\nOptions: %s%s\n", POWWOW_VERSION,
#ifdef USE_VT100
- "vt100-only",
+ "vt100-only,"
#else
- "termcaps",
+ "termcaps,"
#endif
#ifdef USE_SGTTY
- "BSD sgtty",
+ " BSD sgtty,"
#else
- "termios",
+ " termios,"
#endif
#ifdef USE_REGEXP
- ""
+ " regexp,"
+#else
+ " no regexp,"
+#endif
+#ifdef USE_LOCALE
+ " locale,"
+#endif
+#ifdef HAVE_LIBDL
+ " modules,"
+#endif
+ ,
+#if __STDC__
+ " compiled " __TIME__ " " __DATE__
#else
- " no regexp"
+ " uknown compile date"
#endif
);
}
@@ -1282,7 +1309,7 @@ static void get_user_input __P0 (void)
if (!(linemode & (LM_NOECHO | LM_CHAR))) /* line mode, local echo */
chunk = BUFSIZE;
- while ((j = tty_read(tty_read_fd, c, chunk)) < 0 && errno == EINTR)
+ while ((j = tty_read(c, chunk)) < 0 && errno == EINTR)
;
if (j <= 0 || (chunk == 1 && j != chunk))
syserr("read from tty");
diff --git a/tty.c b/tty.c
index 0ac7b3c..7053407 100644
--- a/tty.c
+++ b/tty.c
@@ -9,13 +9,22 @@
* (at your option) any later version.
*
*/
+#include <errno.h>
+#include <fcntl.h>
+#include <limits.h>
+#include <stdarg.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <time.h>
#include <sys/types.h>
+#include <time.h>
#include <unistd.h>
+#ifdef USE_LOCALE
+#include <wchar.h>
+#include <locale.h>
+#endif
+
#include "defines.h"
#include "main.h"
#include "edit.h"
@@ -133,6 +142,9 @@ char *tty_modebold = modebold, *tty_modeblink = modeblink,
int tty_read_fd = 0;
static int wrapglitch = 0;
+#ifdef USE_LOCALE
+FILE *tty_read_stream, *tty_write_stream;
+#endif
#ifdef USE_SGTTY
static struct sgttyb ttybsave;
@@ -289,6 +301,12 @@ void tty_sig_winch_bottomhalf __P0 (void)
*/
void tty_bootstrap __P0 (void)
{
+#ifdef USE_LOCALE
+ tty_read_stream = stdin;
+ tty_write_stream = stdout;
+ fcntl(tty_read_fd, F_SETFL, O_NONBLOCK | fcntl(tty_read_fd, F_GETFL));
+#endif
+
#ifndef USE_VT100
struct tc_init_node {
char cap[4], *buf;
@@ -772,3 +790,135 @@ void input_insert_follow_chars __P2 (char *,str, int,n)
tty_gotoxy_opt(CURCOL(p), cl, CURCOL(pos), CURLINE(pos));
}
+#ifdef USE_LOCALE
+/* curses wide character support by Dain */
+
+void tty_puts __P ((const char *s))
+{
+ while (*s)
+ putwc((unsigned char)*s++, tty_write_stream);
+}
+
+void tty_putc __P ((char c))
+{
+ putwc((unsigned char)c, tty_write_stream);
+}
+
+
+void tty_printf __P ((const char *format, ...))
+{
+ char buf[1024], *bufp = buf;
+ va_list va;
+ int res;
+
+ char *old_locale = strdup(setlocale(LC_ALL, NULL));
+
+ setlocale(LC_ALL, "C");
+
+ va_start(va, format);
+ res = vsnprintf(buf, sizeof buf, format, va);
+ va_end(va);
+
+ if (res >= sizeof buf) {
+ bufp = alloca(res + 1);
+ va_start(va, format);
+ vsprintf(bufp, format, va);
+ va_end(va);
+ }
+
+ setlocale(LC_ALL, old_locale);
+ free(old_locale);
+
+ tty_puts(bufp);
+}
+
+static char tty_in_buf[MB_LEN_MAX + 1];
+static int tty_in_buf_used = 0;
+
+int tty_has_chars __P ((void))
+{
+ return !!tty_in_buf_used;
+}
+
+int tty_read __P ((char *buf, size_t count))
+{
+ int result = 0;
+ int converted;
+ wchar_t wc;
+
+ if (count && tty_in_buf_used) {
+ converted = mbtowc(&wc, tty_in_buf, tty_in_buf_used);
+ if (converted >= 0)
+ goto another;
+ }
+
+ while (count) {
+ int should_read = sizeof tty_in_buf - tty_in_buf_used;
+ int did_read = read(tty_read_fd, tty_in_buf + tty_in_buf_used,
+ should_read);
+
+ if (did_read < 0 && errno == EINTR)
+ continue;
+ if (did_read <= 0)
+ break;
+
+ tty_in_buf_used += did_read;
+
+ converted = mbtowc(&wc, tty_in_buf, tty_in_buf_used);
+ if (converted < 0)
+ break;
+
+ another:
+ if (converted == 0)
+ converted = 1;
+
+ if (!(wc & ~0xff)) {
+ *buf++ = (unsigned char)wc;
+ --count;
+ ++result;
+ }
+
+ tty_in_buf_used -= converted;
+ memmove(tty_in_buf, tty_in_buf + converted, tty_in_buf_used);
+
+ if (count == 0)
+ break;
+
+ converted = mbtowc(&wc, tty_in_buf, tty_in_buf_used);
+ if (converted >= 0 && tty_in_buf_used)
+ goto another;
+
+ if (did_read < should_read)
+ break;
+ }
+
+ return result;
+}
+
+
+void tty_gets __P ((char *s, int size))
+{
+ wchar_t *ws = alloca(size * sizeof *ws);
+
+ if (!fgetws(ws, size, stdin))
+ return;
+
+ while (*ws) {
+ if (!(*ws & ~0xff))
+ *s++ = (unsigned char)*ws;
+ ++ws;
+ }
+}
+
+void tty_flush __P ((void))
+{
+ fflush(tty_write_stream);
+}
+
+void tty_raw_write __P ((char *data, int len))
+{
+ tty_flush();
+ write(1, data, len);
+}
+
+#endif /* USE_LOCALE */
diff --git a/tty.h b/tty.h
index ab22d90..ca4b554 100644
--- a/tty.h
+++ b/tty.h
@@ -25,28 +25,30 @@ void input_overtype_follow __P ((char c));
void input_insert_follow_chars __P ((char *str, int n));
void input_moveto __P ((int new_pos));
-#if 1
+#ifndef USE_LOCALE
#define tty_puts(s) fputs((s), stdout)
/* printf("%s", (s)); would be as good */
-#define tty_putc(c) putc((int)(char)(c), stdout)
-#define tty_printf printf
-#define tty_read read
-#define tty_gets(s,size) fgets((s), (size), stdin)
-#define tty_flush() fflush(stdout)
-#define tty_raw_write(s,size) do { tty_flush(); write(1, (s), (size)); } while (0)
-#else /* !1 */
+#define tty_putc(c) putc((unsigned char)(c), stdout)
+#define tty_printf printf
+#define tty_read(buf, cnt) read(tty_read_fd, (buf), (cnt))
+#define tty_gets(s,size) fgets((s), (size), stdin)
+#define tty_flush() fflush(stdout)
+#define tty_raw_write(s,size) do { tty_flush(); write(1, (s), (size)); } while (0)
-void tty_puts __P ((char *s));
-void tty_putc __P ((char c));
-void tty_printf __P ((const char *format, ...));
-int tty_read __P ((int fd, char *buf, size_t count));
-void tty_gets __P ((char *s, int size));
-void tty_flush __P ((void));
-void tty_raw_write __P ((char *data, int len));
+#else /* USE_LOCALE */
-#endif /* 1 */
+void tty_puts __P ((const char *s));
+void tty_putc __P ((char c));
+void tty_printf __P ((const char *format, ...));
+int tty_read __P ((char *buf, size_t count));
+void tty_gets __P ((char *s, int size));
+void tty_flush __P ((void));
+void tty_raw_write __P ((char *data, int len));
+int tty_has_chars __P ((void));
+
+#endif /* USE_LOCALE */
#endif /* _TTY_H_ */