All pastes #259827 Raw Edit

Miscellany

public text v1 · immutable
#259827 ·published 2006-11-27 20:02 UTC
rendered paste body
diff -r -u --exclude=.svn trunk/Makefile.am trunk.xming/Makefile.am
--- trunk/Makefile.am	2006-11-27 19:21:05.000000000 +0100
+++ trunk.xming/Makefile.am	2006-11-27 15:50:53.000000000 +0100
@@ -26,11 +26,7 @@
 openpbx_SOURCES 	= main.c
 openpbx_LDADD		= ${top_builddir}/corelib/libopenpbx.la $(LIBLTDL)
 
-if WANT_INTERNAL_LIBEDIT
-openpbx_LDADD		+= ${top_builddir}/editline/src/libedit.la
-else
-openpbx_LDADD		+= -ledit
-endif
+openpbx_LDADD		+= -lreadline
 
 openpbx_CFLAGS 	=  -fomit-frame-pointer -Wall -Wstrict-prototypes 
 openpbx_CFLAGS	+= -Wmissing-prototypes -Wmissing-declarations -I$(top_srcdir)/include $(AM_CFLAGS)
@@ -40,9 +36,6 @@
 EXTRA_DIST = openpbx.sgml $(man_MANS) substitute.mak
 
 SUBDIRS =   libltdl libs
-if WANT_INTERNAL_LIBEDIT
-SUBDIRS +=  editline
-endif
 SUBDIRS +=  stdtime @SQLITE3_SUBDIR@ include corelib . pbx funcs
 SUBDIRS +=  cdr apps codecs formats channels ogi utils res configs
 
Only in trunk.xming/: Makefile.in
Only in trunk.xming/: aclocal.m4
Only in trunk.xming/apps: Makefile.in
Only in trunk.xming/apps/conference: Makefile.in
Only in trunk.xming/apps/icd: .deps
Only in trunk.xming/apps/icd: Makefile
Only in trunk.xming/apps/icd: Makefile.in
Only in trunk.xming/: autom4te.cache
Only in trunk.xming/cdr: Makefile.in
Only in trunk.xming/channels: Makefile.in
Only in trunk.xming/channels/fax: Makefile.in
Only in trunk.xming/channels/iax2: Makefile.in
Only in trunk.xming/channels/misdn: Makefile.in
Only in trunk.xming/channels/sccp: Makefile.in
Only in trunk.xming/codecs: Makefile.in
Only in trunk.xming/: config.guess
Only in trunk.xming/: config.sub
Only in trunk.xming/configs: Makefile.in
Only in trunk.xming/: configure
diff -r -u --exclude=.svn trunk/configure.ac trunk.xming/configure.ac
--- trunk/configure.ac	2006-11-27 19:21:05.000000000 +0100
+++ trunk.xming/configure.ac	2006-11-27 15:46:55.000000000 +0100
@@ -562,43 +562,18 @@
 	[AC_HELP_STRING([--with-spandsp-libs],[Location of SpanDSP library files.])],
 	[LDFLAGS="$LDFLAGS -L${withval}"])
 
-AC_CHECK_HEADERS([spandsp.h],[HAVE_SPANDSP_H=1],[AC_MSG_ERROR(SpanDSP version 0.0.3pre26 or newer is required to compile OpenPBX.org.)])
+AC_CHECK_HEADERS([spandsp.h],[HAVE_SPANDSP_H=1],[AC_MSG_ERROR(SpanDSP version 0.0.3pre25 or newer is required to compile OpenPBX.org.)])
 
-AC_CHECK_HEADERS([spandsp/t38_core.h],[HAVE_SPANDSP_T38_H=1],[AC_MSG_ERROR(SpanDSP does not appear to be new enough. You must have version 0.0.3pre26 or newer to compile OpenPBX.org.)],
+AC_CHECK_HEADERS([spandsp/t38_core.h],[HAVE_SPANDSP_T38_H=1],[AC_MSG_ERROR(SpanDSP does not appear to be new enough. You must have version 0.0.3pre25 or newer to compile OpenPBX.org.)],
 [#ifdef HAVE_SPANDSP_H
 #include <spandsp.h>
 #endif
 ])
 
-AC_CHECK_LIB([spandsp],[fax_set_transmit_on_idle],[HAVE_LIBSPANDSP=1],[AC_MSG_ERROR(SpanDSP does not appear to be new enough. You must have version 0.0.3pre26 or newer to comple OpenPBX.org.)],[-ltiff])
+AC_CHECK_LIB([spandsp],[fax_set_transmit_on_idle],[HAVE_LIBSPANDSP=1],[AC_MSG_ERROR(SpanDSP does not appear to be new enough. You must have version 0.0.3pre25 or newer to comple OpenPBX.org.)],[-ltiff])
 
 dnl ###########################################################################
 
-dnl Enable internal libedit
-AC_ARG_ENABLE(internal_libedit,
-	[AC_HELP_STRING([--enable-internal_libedit],[build with internal libedit (default=no)])],,[enable_internal_libedit="no"])
-
-if test "${enable_internal_libedit}" != "no"; then
-   AC_DEFINE([USE_INTERNAL_LIBEDIT],[],[Build with internal libedit.])
-fi
-
-AM_CONDITIONAL([WANT_INTERNAL_LIBEDIT],[test "${enable_internal_libedit}" != "no"])
-
-if test "${enable_internal_libedit}" = "no"; then
-
-AC_ARG_WITH([editline-includes],
-	[AC_HELP_STRING([--with-editline-includes],[Location of editline include files.])],
-	[CFLAGS="$CFLAGS -I${withval}"])
-
-AC_ARG_WITH([tiff-libs],
-	[AC_HELP_STRING([--with-editline-libs],[Location of editline library files.])],
-	[LDFLAGS="$LDFLAGS -L${withval}"])
-
-AC_CHECK_HEADERS([editline/readline.h histedit.h],,[AC_MSG_ERROR(libedit is required to compile OpenPBX.org. See http://www.thrysoee.dk/editline/)])
-AC_CHECK_LIB([edit],[el_init],,[AC_MSG_ERROR(libedit is required to compile OpenPBX.org. See http://www.thrysoee.dk/editline/ or use --enable-internal-libedit)])
-
-fi
-
 dnl ###########################################################################
 dnl ###########################################################################
 dnl ###
@@ -2120,9 +2095,9 @@
 ######
 AC_CONFIG_SUBDIRS(libltdl)
 
-if test "${enable_internal_libedit}" = "yes"; then
-AC_CONFIG_SUBDIRS(editline)
-fi
+#if test "${enable_internal_libedit}" = "yes"; then
+#AC_CONFIG_SUBDIRS(editline)
+#fi
 
 AC_OUTPUT([Makefile
 		 include/Makefile
diff -r -u --exclude=.svn trunk/corelib/Makefile.am trunk.xming/corelib/Makefile.am
--- trunk/corelib/Makefile.am	2006-11-27 19:20:06.000000000 +0100
+++ trunk.xming/corelib/Makefile.am	2006-11-27 15:49:16.000000000 +0100
@@ -28,11 +28,7 @@
 libopenpbx_la_LIBADD 	+= ${top_builddir}/stdtime/libtime.la 
 libopenpbx_la_LIBADD 	+= ${top_builddir}/corelib/jitterbuffer/libopbxjb.la
 
-if WANT_INTERNAL_LIBEDIT
-libopenpbx_la_LIBADD 	+= ${top_builddir}/editline/src/libedit.la 
-else
-libopenpbx_la_LIBADD	+= -ledit
-endif
+libopenpbx_la_LIBADD	+= -lreadline
 
 if WANT_SRTP
 libopenpbx_la_LIBADD	+= -lsrtp
Only in trunk.xming/corelib: Makefile.in
diff -r -u --exclude=.svn trunk/corelib/cli.c trunk.xming/corelib/cli.c
--- trunk/corelib/cli.c	2006-11-27 19:20:06.000000000 +0100
+++ trunk.xming/corelib/cli.c	2006-11-27 15:25:58.000000000 +0100
@@ -50,7 +50,7 @@
 #ifdef USE_INTERNAL_LIBEDIT
 #include "editline/readline/readline.h"
 #else
-#include <editline/readline.h>
+#include <readline/readline.h>
 #endif
 
 extern unsigned long global_fin, global_fout;
Only in trunk.xming/corelib/jitterbuffer: Makefile.in
diff -r -u --exclude=.svn trunk/corelib/openpbx.c trunk.xming/corelib/openpbx.c
--- trunk/corelib/openpbx.c	2006-11-27 19:20:06.000000000 +0100
+++ trunk.xming/corelib/openpbx.c	2006-11-27 19:17:36.000000000 +0100
@@ -123,7 +123,9 @@
 #ifdef USE_INTERNAL_LIBEDIT
 #include "editline/src/histedit.h"
 #else
-#include <histedit.h>
+//#include <histedit.h>
+#include <readline/readline.h>
+#include <readline/history.h>
 #endif
 
 /* defines various compile-time defaults */
@@ -190,17 +192,16 @@
 time_t opbx_startuptime;
 time_t opbx_lastreloadtime;
 
-static History *el_hist = NULL;
-static EditLine *el = NULL;
+int is_rl_initilized = 0;
+//static History *el_hist = NULL;
+//static EditLine *el = NULL;
 static char *remotehostname;
 
 struct console consoles[OPBX_MAX_CONNECTS];
 
 char defaultlanguage[MAX_LANGUAGE] = DEFAULT_LANGUAGE;
 
-static int opbx_el_add_history(char *);
-static int opbx_el_read_history(char *);
-static int opbx_el_write_history(char *);
+static inline char* history_filename(char* buf);
 
 char opbx_config_OPBX_CONFIG_DIR[OPBX_CONFIG_MAX_PATH];
 char opbx_config_OPBX_CONFIG_FILE[OPBX_CONFIG_MAX_PATH];
@@ -874,14 +875,12 @@
 		}
 	}
 	if (option_console || option_remote) {
-		if (getenv("HOME")) 
-			snprintf(filename, sizeof(filename), "%s/.openpbx_history", getenv("HOME"));
-		if (!opbx_strlen_zero(filename))
-			opbx_el_write_history(filename);
-		if (el != NULL)
-			el_end(el);
-		if (el_hist != NULL)
-			history_end(el_hist);
+		if (!opbx_strlen_zero(history_filename(filename))) {
+			int rc = write_history(filename);
+			if ((rc != 0) && option_verbose && option_console) {
+				opbx_verbose("Failed to write history file %s: %s\n", filename, strerror(rc));
+			}
+		}
 	}
 	if (option_verbose)
 		opbx_verbose("Executing last minute cleanups\n");
@@ -991,7 +990,7 @@
 	fflush(stdout);
 	/* Called when readline data is available */
 	if (s && !opbx_all_zeros(s))
-		opbx_el_add_history(s);
+		add_history(s);
 	/* Give the console access to the shell */
 	if (s) {
 		/* The real handler for bang */
@@ -1011,7 +1010,7 @@
 	int ret = 0;
 	/* Called when readline data is available */
 	if (s && !opbx_all_zeros(s))
-		opbx_el_add_history(s);
+		add_history(s);
 	/* Give the console access to the shell */
 	if (s) {
 		/* The real handler for bang */
@@ -1168,7 +1167,8 @@
 #endif /* ! LOW_MEMORY */
 };
 
-static int opbx_el_read_char(EditLine *el, char *cp)
+//static int opbx_el_read_char(EditLine *el, char *cp)
+static int read_char(char *cp)
 {
 	int num_read=0;
 	int lastpos=0;
@@ -1235,7 +1235,8 @@
 				write(STDOUT_FILENO, "\r", 1);
 			write(STDOUT_FILENO, buf, res);
 			if ((buf[res-1] == '\n') || (buf[res-2] == '\n')) {
-				*cp = CC_REFRESH;
+//				*cp = CC_REFRESH;
+				rl_redisplay(); /* TODO: too many refresh-s? */
 				return(1);
 			} else {
 				lastpos = 1;
@@ -1247,179 +1248,190 @@
 	return (0);
 }
 
-static char *cli_prompt(EditLine *el)
+static char *cli_prompt(void)
 {
-	static char prompt[200];
-	char *pfmt;
-	int color_used=0;
-	char term_code[20];
-
-	if ((pfmt = getenv("OPENPBX_PROMPT"))) {
-		char *t = pfmt, *p = prompt;
-		memset(prompt, 0, sizeof(prompt));
-		while (*t != '\0' && *p < sizeof(prompt)) {
-			if (*t == '%') {
-				char hostname[MAXHOSTNAMELEN]="";
-				int i;
-				struct timeval tv;
-				struct tm tm;
+        static char prompt[200];
+        char *pfmt;
+        int color_used=0;
+        char term_code[20];
+
+        if ((pfmt = getenv("OPENPBX_PROMPT"))) {
+                char *t = pfmt, *p = prompt;
+                memset(prompt, 0, sizeof(prompt));
+                while (*t != '\0' && *p < sizeof(prompt)) {
+                        if (*t == '%') {
+                                char hostname[MAXHOSTNAMELEN]="";
+                                int i;
+                                struct timeval tv;
+                                struct tm tm;
 #ifdef linux
-				FILE *LOADAVG;
+                                FILE *LOADAVG;
 #endif
-				int fgcolor = COLOR_WHITE, bgcolor = COLOR_BLACK;
-
-				t++;
-				switch (*t) {
-					case 'C': /* color */
-						t++;
-						if (sscanf(t, "%d;%d%n", &fgcolor, &bgcolor, &i) == 2) {
-							strncat(p, opbx_term_color_code(term_code, fgcolor, bgcolor, sizeof(term_code)),sizeof(prompt) - strlen(prompt) - 1);
-							t += i - 1;
-						} else if (sscanf(t, "%d%n", &fgcolor, &i) == 1) {
-							strncat(p, opbx_term_color_code(term_code, fgcolor, 0, sizeof(term_code)),sizeof(prompt) - strlen(prompt) - 1);
-							t += i - 1;
-						}
+                                int fgcolor = COLOR_WHITE, bgcolor = COLOR_BLACK;
 
-						/* If the color has been reset correctly, then there's no need to reset it later */
-						if ((fgcolor == COLOR_WHITE) && (bgcolor == COLOR_BLACK)) {
-							color_used = 0;
-						} else {
-							color_used = 1;
-						}
-						break;
-					case 'd': /* date */
-						memset(&tm, 0, sizeof(struct tm));
-						tv = opbx_tvnow();
-						if (localtime_r(&(tv.tv_sec), &tm)) {
-							strftime(p, sizeof(prompt) - strlen(prompt), "%Y-%m-%d", &tm);
-						}
-						break;
-					case 'h': /* hostname */
-						if (!gethostname(hostname, sizeof(hostname) - 1)) {
-							strncat(p, hostname, sizeof(prompt) - strlen(prompt) - 1);
-						} else {
-							strncat(p, "localhost", sizeof(prompt) - strlen(prompt) - 1);
-						}
-						break;
-					case 'H': /* short hostname */
-						if (!gethostname(hostname, sizeof(hostname) - 1)) {
-							for (i=0;i<sizeof(hostname);i++) {
-								if (hostname[i] == '.') {
-									hostname[i] = '\0';
-									break;
-								}
-							}
-							strncat(p, hostname, sizeof(prompt) - strlen(prompt) - 1);
-						} else {
-							strncat(p, "localhost", sizeof(prompt) - strlen(prompt) - 1);
-						}
-						break;
+                                t++;
+                                switch (*t) {
+                                        case 'C': /* color */
+                                                t++;
+                                                if (sscanf(t, "%d;%d%n", &fgcolor, &bgcolor, &i) == 2) {
+                                                        strncat(p, opbx_term_color_code(term_code, fgcolor, bgcolor, sizeof(term_code)),sizeof(prompt) - strlen(prompt) - 1);
+                                                        t += i - 1;
+                                                } else if (sscanf(t, "%d%n", &fgcolor, &i) == 1) {
+                                                        strncat(p, opbx_term_color_code(term_code, fgcolor, 0, sizeof(term_code)),sizeof(prompt) - strlen(prompt) - 1);
+                                                        t += i - 1;
+                                                }
+
+                                                /* If the color has been reset correctly, then there's no need to reset it later */
+                                                if ((fgcolor == COLOR_WHITE) && (bgcolor == COLOR_BLACK)) {
+                                                        color_used = 0;
+                                                } else {
+                                                        color_used = 1;
+                                                }
+                                                break;
+                                        case 'd': /* date */
+                                                memset(&tm, 0, sizeof(struct tm));
+                                                tv = opbx_tvnow();
+                                                if (localtime_r(&(tv.tv_sec), &tm)) {
+                                                        strftime(p, sizeof(prompt) - strlen(prompt), "%Y-%m-%d", &tm);
+                                                }
+                                                break;
+                                        case 'h': /* hostname */
+                                                if (!gethostname(hostname, sizeof(hostname) - 1)) {
+                                                        strncat(p, hostname, sizeof(prompt) - strlen(prompt) - 1);
+                                                } else {
+                                                        strncat(p, "localhost", sizeof(prompt) - strlen(prompt) - 1);
+                                                }
+                                                break;
+                                        case 'H': /* short hostname */
+                                                if (!gethostname(hostname, sizeof(hostname) - 1)) {
+                                                        for (i=0;i<sizeof(hostname);i++) {
+                                                                if (hostname[i] == '.') {
+                                                                        hostname[i] = '\0';
+                                                                        break;
+                                                                }
+                                                        }
+                                                        strncat(p, hostname, sizeof(prompt) - strlen(prompt) - 1);
+                                                } else {
+                                                        strncat(p, "localhost", sizeof(prompt) - strlen(prompt) - 1);
+                                                }
+                                                break;
 #ifdef linux
-					case 'l': /* load avg */
-						t++;
-						if ((LOADAVG = fopen("/proc/loadavg", "r"))) {
-							float avg1, avg2, avg3;
-							int actproc, totproc, npid, which;
-							fscanf(LOADAVG, "%f %f %f %d/%d %d",
-								&avg1, &avg2, &avg3, &actproc, &totproc, &npid);
-							if (sscanf(t, "%d", &which) == 1) {
-								switch (which) {
-									case 1:
-										snprintf(p, sizeof(prompt) - strlen(prompt), "%.2f", avg1);
-										break;
-									case 2:
-										snprintf(p, sizeof(prompt) - strlen(prompt), "%.2f", avg2);
-										break;
-									case 3:
-										snprintf(p, sizeof(prompt) - strlen(prompt), "%.2f", avg3);
-										break;
-									case 4:
-										snprintf(p, sizeof(prompt) - strlen(prompt), "%d/%d", actproc, totproc);
-										break;
-									case 5:
-										snprintf(p, sizeof(prompt) - strlen(prompt), "%d", npid);
-										break;
-								}
-							}
-						}
-						break;
+                                        case 'l': /* load avg */
+                                                t++;
+                                                if ((LOADAVG = fopen("/proc/loadavg", "r"))) {
+                                                        float avg1, avg2, avg3;
+                                                        int actproc, totproc, npid, which;
+                                                        fscanf(LOADAVG, "%f %f %f %d/%d %d",
+                                                                &avg1, &avg2, &avg3, &actproc, &totproc, &npid);
+                                                        if (sscanf(t, "%d", &which) == 1) {
+                                                                switch (which) {
+                                                                        case 1:
+                                                                                snprintf(p, sizeof(prompt) - strlen(prompt), "%.2f", avg1);
+                                                                                break;
+                                                                        case 2:
+                                                                                snprintf(p, sizeof(prompt) - strlen(prompt), "%.2f", avg2);
+                                                                                break;
+                                                                        case 3:
+                                                                                snprintf(p, sizeof(prompt) - strlen(prompt), "%.2f", avg3);
+                                                                                break;
+                                                                        case 4:
+                                                                                snprintf(p, sizeof(prompt) - strlen(prompt), "%d/%d", actproc, totproc);
+                                                                                break;
+                                                                        case 5:
+                                                                                snprintf(p, sizeof(prompt) - strlen(prompt), "%d", npid);
+                                                                                break;
+                                                                }
+                                                        }
+                                                }
+                                                break;
 #endif
-					case 't': /* time */
-						memset(&tm, 0, sizeof(struct tm));
-						tv = opbx_tvnow();
-						if (localtime_r(&(tv.tv_sec), &tm)) {
-							strftime(p, sizeof(prompt) - strlen(prompt), "%H:%M:%S", &tm);
-						}
-						break;
-					case '#': /* process console or remote? */
-						if (! option_remote) {
-							strncat(p, "#", sizeof(prompt) - strlen(prompt) - 1);
-						} else {
-							strncat(p, ">", sizeof(prompt) - strlen(prompt) - 1);
-						}
-						break;
-					case '%': /* literal % */
-						strncat(p, "%", sizeof(prompt) - strlen(prompt) - 1);
-						break;
-					case '\0': /* % is last character - prevent bug */
-						t--;
-						break;
-				}
-				while (*p != '\0') {
-					p++;
-				}
-				t++;
-			} else {
-				*p = *t;
-				p++;
-				t++;
-			}
-		}
-		if (color_used) {
-			/* Force colors back to normal at end */
-			opbx_term_color_code(term_code, COLOR_WHITE, COLOR_BLACK, sizeof(term_code));
-			if (strlen(term_code) > sizeof(prompt) - strlen(prompt)) {
-				strncat(prompt + sizeof(prompt) - strlen(term_code) - 1, term_code, strlen(term_code));
-			} else {
-				strncat(p, term_code, sizeof(term_code));
-			}
-		}
-	} else if (remotehostname)
-		snprintf(prompt, sizeof(prompt), OPENPBX_PROMPT2, remotehostname);
-	else
-		snprintf(prompt, sizeof(prompt), OPENPBX_PROMPT);
-
-	return(prompt);	
+                                        case 't': /* time */
+                                                memset(&tm, 0, sizeof(struct tm));
+                                                tv = opbx_tvnow();
+                                                if (localtime_r(&(tv.tv_sec), &tm)) {
+                                                        strftime(p, sizeof(prompt) - strlen(prompt), "%H:%M:%S", &tm);
+                                                }
+                                                break;
+                                        case '#': /* process console or remote? */
+                                                if (! option_remote) {
+                                                        strncat(p, "#", sizeof(prompt) - strlen(prompt) - 1);
+                                                } else {
+                                                        strncat(p, ">", sizeof(prompt) - strlen(prompt) - 1);
+                                                }
+                                                break;
+                                        case '%': /* literal % */
+                                                strncat(p, "%", sizeof(prompt) - strlen(prompt) - 1);
+                                                break;
+                                        case '\0': /* % is last character - prevent bug */
+                                                t--;
+                                                break;
+                                }
+                                while (*p != '\0') {
+                                        p++;
+                                }
+                                t++;
+                        } else {
+                                *p = *t;
+                                p++;
+                                t++;
+                        }
+                }
+                if (color_used) {
+                        /* Force colors back to normal at end */
+                        opbx_term_color_code(term_code, COLOR_WHITE, COLOR_BLACK, sizeof(term_code));
+                        if (strlen(term_code) > sizeof(prompt) - strlen(prompt)) {
+                                strncat(prompt + sizeof(prompt) - strlen(term_code) - 1, term_code, strlen(term_code));
+                        } else {
+                                strncat(p, term_code, sizeof(term_code));
+                        }
+                }
+        } else if (remotehostname)
+                snprintf(prompt, sizeof(prompt), OPENPBX_PROMPT2, remotehostname);
+        else
+                snprintf(prompt, sizeof(prompt), OPENPBX_PROMPT);
+
+        return(prompt);
 }
 
-static char **opbx_el_strtoarr(char *buf)
-{
-	char **match_list = NULL, *retstr;
-	size_t match_list_len;
-	int matches = 0;
-
-	match_list_len = 1;
-	while ( (retstr = strsep(&buf, " ")) != NULL) {
 
-		if (!strcmp(retstr, OPBX_CLI_COMPLETE_EOF))
-			break;
-		if (matches + 1 >= match_list_len) {
-			match_list_len <<= 1;
-			match_list = realloc(match_list, match_list_len * sizeof(char *));
-		}
 
-		match_list[matches++] = strdup(retstr);
+/***********************************
+ * Readline functions
+ * ********************************/
+
+#define FILENAME_LEN 80
+/* returns the history filename. Caller should allocate buffer 
++ *
++ * filename is set to "" in case of an empty $HOME
++ * */
+static inline char* history_filename(char* buf)
+{
+	if (getenv("HOME")) {
+		snprintf(buf, FILENAME_LEN, "%s/.openpbx_history", getenv("HOME"));
+	} else {
+		buf[0] = '\0';
 	}
+	return buf;
+}
 
-	if (!match_list)
-		return (char **) NULL;
-
-	if (matches>= match_list_len)
-		match_list = realloc(match_list, (match_list_len + 1) * sizeof(char *));
-
-	match_list[matches] = (char *) NULL;
+/* Initilize all readline-related  Does nothing if called after first init
+ * and thus can safely be called again (once the first one has ended)
+ *
++ * TODO: where can it fail? return an error? */
+static int init_readline(void)
+{
+	static int is_init = 0; /* Did we get here already? */
+	char filename[FILENAME_LEN];
+	
+	if (is_init)
+		return is_init;
 
-	return match_list;
+	using_history();
+	read_history(history_filename(filename));
+	
+	is_init = 1;
+	
+	return is_init;
 }
 
 static int opbx_el_sort_compare(const void *i1, const void *i2)
@@ -1480,179 +1492,40 @@
 }
 
 
-static char *cli_complete(EditLine *el, int ch)
-{
-	int len=0;
-	char *ptr;
-	int nummatches = 0;
-	char **matches;
-	int retval = CC_ERROR;
-	char buf[2048];
-	int res;
-
-	LineInfo *lf = (LineInfo *)el_line(el);
-
-	*(char *)lf->cursor = '\0';
-	ptr = (char *)lf->cursor;
-	if (ptr) {
-		while (ptr > lf->buffer) {
-			if (isspace(*ptr)) {
-				ptr++;
-				break;
-			}
-			ptr--;
-		}
-	}
-
-	len = lf->cursor - ptr;
-
-	if (option_remote) {
-		snprintf(buf, sizeof(buf),"_COMMAND NUMMATCHES \"%s\" \"%s\"", lf->buffer, ptr); 
-		fdprint(opbx_consock, buf);
-		res = read(opbx_consock, buf, sizeof(buf));
-		buf[res] = '\0';
-		nummatches = atoi(buf);
-
-		if (nummatches > 0) {
-			char *mbuf;
-			int mlen = 0, maxmbuf = 2048;
-			/* Start with a 2048 byte buffer */
-			mbuf = malloc(maxmbuf);
-			if (!mbuf)
-				return (char *)(CC_ERROR);
-			snprintf(buf, sizeof(buf),"_COMMAND MATCHESARRAY \"%s\" \"%s\"", lf->buffer, ptr); 
-			fdprint(opbx_consock, buf);
-			res = 0;
-			mbuf[0] = '\0';
-			while (!strstr(mbuf, OPBX_CLI_COMPLETE_EOF) && res != -1) {
-				if (mlen + 1024 > maxmbuf) {
-					/* Every step increment buffer 1024 bytes */
-					maxmbuf += 1024;
-					mbuf = realloc(mbuf, maxmbuf);
-					if (!mbuf)
-						return (char *)(CC_ERROR);
-				}
-				/* Only read 1024 bytes at a time */
-				res = read(opbx_consock, mbuf + mlen, 1024);
-				if (res > 0)
-					mlen += res;
-			}
-			mbuf[mlen] = '\0';
-
-			matches = opbx_el_strtoarr(mbuf);
-			free(mbuf);
-		} else
-			matches = (char **) NULL;
-
-
-	} else {
-
-		nummatches = opbx_cli_generatornummatches((char *)lf->buffer,ptr);
-		matches = opbx_cli_completion_matches((char *)lf->buffer,ptr);
-	}
-
-	if (matches) {
-		int i;
-		int matches_num, maxlen, match_len;
-
-		if (matches[0][0] != '\0') {
-			el_deletestr(el, (int) len);
-			el_insertstr(el, matches[0]);
-			retval = CC_REFRESH;
-		}
-
-		if (nummatches == 1) {
-			/* Found an exact match */
-			el_insertstr(el, " ");
-			retval = CC_REFRESH;
-		} else {
-			/* Must be more than one match */
-			for (i=1, maxlen=0; matches[i]; i++) {
-				match_len = strlen(matches[i]);
-				if (match_len > maxlen)
-					maxlen = match_len;
-			}
-			matches_num = i - 1;
-			if (matches_num >1) {
-				fprintf(stdout, "\n");
-				opbx_cli_display_match_list(matches, nummatches, maxlen);
-				retval = CC_REDISPLAY;
-			} else { 
-				el_insertstr(el," ");
-				retval = CC_REFRESH;
-			}
-		}
-	free(matches);
-	}
-
-	return (char *)(long)retval;
-}
-
-static int opbx_el_initialize(void)
-{
-	HistEvent ev;
-	char *editor = getenv("OPBX_EDITOR");
-
-	if (el != NULL)
-		el_end(el);
-	if (el_hist != NULL)
-		history_end(el_hist);
-
-	el = el_init("openpbx", stdin, stdout, stderr);
-	el_set(el, EL_PROMPT, cli_prompt);
-
-	el_set(el, EL_EDITMODE, 1);		
-	el_set(el, EL_EDITOR, editor ? editor : "emacs");		
-	el_hist = history_init();
-	if (!el || !el_hist)
-		return -1;
-
-	/* setup history with 100 entries */
-	history(el_hist, &ev, H_SETSIZE, 100);
-
-	el_set(el, EL_HIST, history, el_hist);
-
-	el_set(el, EL_ADDFN, "ed-complete", "Complete argument", cli_complete);
-	/* Bind <tab> to command completion */
-	el_set(el, EL_BIND, "^I", "ed-complete", NULL);
-	/* Bind ? to command completion */
-	el_set(el, EL_BIND, "?", "ed-complete", NULL);
-	/* Bind ^D to redisplay */
-	el_set(el, EL_BIND, "^D", "ed-redisplay", NULL);
-
-	return 0;
-}
-
-static int opbx_el_add_history(char *buf)
-{
-	HistEvent ev;
-
-	if (el_hist == NULL || el == NULL)
-		opbx_el_initialize();
-	if (strlen(buf) > 256)
-		return 0;
-	return (history(el_hist, &ev, H_ENTER, buf));
-}
-
-static int opbx_el_write_history(char *filename)
-{
-	HistEvent ev;
-
-	if (el_hist == NULL || el == NULL)
-		opbx_el_initialize();
-
-	return (history(el_hist, &ev, H_SAVE, filename));
-}
-
-static int opbx_el_read_history(char *filename)
-{
-	HistEvent ev;
-
-	if (el_hist == NULL || el == NULL)
-		opbx_el_initialize();
-
-	return (history(el_hist, &ev, H_LOAD, filename));
-}
+//static int opbx_el_initialize(void)
+//{
+//	HistEvent ev;
+//	char *editor = getenv("OPBX_EDITOR");
+//
+//	if (el != NULL)
+//		el_end(el);
+//	if (el_hist != NULL)
+//		history_end(el_hist);
+//
+//	el = el_init("openpbx", stdin, stdout, stderr);
+//	el_set(el, EL_PROMPT, cli_prompt);
+//
+//	el_set(el, EL_EDITMODE, 1);		
+//	el_set(el, EL_EDITOR, editor ? editor : "emacs");		
+//	el_hist = history_init();
+//	if (!el || !el_hist)
+//		return -1;
+//
+//	/* setup history with 100 entries */
+//	history(el_hist, &ev, H_SETSIZE, 100);
+//
+//	el_set(el, EL_HIST, history, el_hist);
+//
+//	el_set(el, EL_ADDFN, "ed-complete", "Complete argument", cli_complete);
+//	/* Bind <tab> to command completion */
+//	el_set(el, EL_BIND, "^I", "ed-complete", NULL);
+//	/* Bind ? to command completion */
+//	el_set(el, EL_BIND, "?", "ed-complete", NULL);
+//	/* Bind ^D to redisplay */
+//	el_set(el, EL_BIND, "^D", "ed-redisplay", NULL);
+//
+//	return 0;
+//}
 
 static void opbx_remotecontrol(char * data)
 {
@@ -1690,16 +1563,7 @@
 	fdprint(opbx_consock, tmp);
 	opbx_verbose("Connected to OpenPBX %s currently running on %s (pid = %d)\n", version, hostname, pid);
 	remotehostname = hostname;
-	if (getenv("HOME")) 
-		snprintf(filename, sizeof(filename), "%s/.openpbx_history", getenv("HOME"));
-	if (el_hist == NULL || el == NULL)
-		opbx_el_initialize();
-
-	el_set(el, EL_GETCFN, opbx_el_read_char);
-
-	if (!opbx_strlen_zero(filename))
-		opbx_el_read_history(filename);
-
+	init_readline();
 	if (option_exec && data) {  /* hack to print output then exit if openpbx -rx is used */
 		char tempchar;
 		struct pollfd fds[0];
@@ -1707,12 +1571,12 @@
 		fds[0].events = POLLIN;
 		fds[0].revents = 0;
 		while(poll(fds, 1, 100) > 0) {
-			opbx_el_read_char(el, &tempchar);
+			read_char(&tempchar);
 		}
 		return;
 	}
 	for(;;) {
-		ebuf = (char *)el_gets(el, &num);
+		ebuf = readline(cli_prompt());
 
 		if (!opbx_strlen_zero(ebuf)) {
 			if (ebuf[strlen(ebuf)-1] == '\n')
@@ -2218,11 +2082,7 @@
 	
 
 	if (option_console) {
-		if (el_hist == NULL || el == NULL)
-			opbx_el_initialize();
-
-		if (!opbx_strlen_zero(filename))
-			opbx_el_read_history(filename);
+		init_readline();
 	}
 
 	if (opbx_tryconnect()) {
@@ -2400,7 +2260,7 @@
 		set_title(title);
 
 		for (;;) {
-			buf = (char *)el_gets(el, &num);
+			buf = readline(cli_prompt());
 			if (buf) {
 				if (buf[strlen(buf)-1] == '\n')
 					buf[strlen(buf)-1] = '\0';
Only in trunk.xming/corelib: openpbx.c.orig
diff -r -u --exclude=.svn trunk/corelib/pbx.c trunk.xming/corelib/pbx.c
--- trunk/corelib/pbx.c	2006-11-27 19:20:06.000000000 +0100
+++ trunk.xming/corelib/pbx.c	2006-11-27 01:13:08.000000000 +0100
@@ -37,7 +37,7 @@
 
 #include "openpbx.h"
 
-OPENPBX_FILE_VERSION("$HeadURL: svn+ssh://svn@svn.openpbx.org/openpbx/trunk/corelib/pbx.c $", "$Revision: 2149 $")
+OPENPBX_FILE_VERSION("$HeadURL: svn+ssh://svn@svn.openpbx.org/openpbx/trunk/corelib/pbx.c $", "$Revision: 2137 $")
 
 #include "openpbx/lock.h"
 #include "openpbx/cli.h"
@@ -6771,16 +6771,6 @@
     res = opbx_parseable_goto(chan, (const char *) data);
     if (!res && (option_verbose > 2))
         opbx_verbose( VERBOSE_PREFIX_3 "Goto (%s,%s,%d)\n", chan->context,chan->exten, chan->priority+1);
-
-    //OSX users don't want this even for testing.
-#ifndef __Darwin
-    // The following usleep is added to relax dialplan execution.
-    // When doing small loops with lots of iteration, this usleep
-    // allows theother threads to execute smoothly.
-    // This will for sure dramatically slow down benchmarks but
-    // will improve performance under load or in particular circumstances.
-    usleep(1);
-#endif
     return res;
 }
 
diff -r -u --exclude=.svn trunk/debian/changelog trunk.xming/debian/changelog
--- trunk/debian/changelog	2006-11-27 19:20:06.000000000 +0100
+++ trunk.xming/debian/changelog	2006-11-27 01:13:08.000000000 +0100
@@ -1,4 +1,4 @@
-openpbx (0.2.0-trunk-2146) opo; urgency=low
+openpbx (0.2.0-trunk-2144) opo; urgency=low
 
   * Added ODBC support
   * Added chan_bluetooth support
Only in trunk.xming/: depcomp
diff -r -u --exclude=.svn trunk/doc/WHY_HASHING trunk.xming/doc/WHY_HASHING
--- trunk/doc/WHY_HASHING	2006-11-27 19:20:33.000000000 +0100
+++ trunk.xming/doc/WHY_HASHING	2006-11-27 01:13:30.000000000 +0100
@@ -163,64 +163,3 @@
 using linear searches on linked lists and arrays.
 
 benjk, August 2006
-
-
-
-
-
-***************************************************************************
-         PERFORMANCE NOTICE - PLEASE READ WHEN BENCHMARKING
-***************************************************************************
-
-In pbx.c file, exactly in function
-
-static int pbx_builtin_goto(struct opbx_channel *chan, void *data)
-
-we have added a call to usleep(1);
-
-This means that every time that a Goto, GotoIf ot similar command is 
-executed in the dialplan, a microsecond sleep is added to the execution time.
-
-This wouldn't be a major performance problem and surely it isn't.
-
-Let's take a sample dialplan for doing tests (thanks to Royk):
-
-[proc-speedtest]
-exten => s,1,Answer
-exten => s,n,PlayTones(ring)
-exten => s,n,Wait(1)
-exten => s,n,Set(iterations=$[ 100000 ])
-exten => s,n,Set(i=1)
-exten => s,n,Verbose(Begin-of-speedtest)
-exten => s,n,Wait(2)
-exten => s,n,Set(time1=${EPOCH})
-
-exten => s,n(iterate),GotoIf($[ ${i}<${iterations} ]?next:last)
-exten => s,n(next),Set(i=$[ ${i}+1 ])
-exten => s,n,Goto(iterate)
-
-exten => s,n(last),Set(time2=${EPOCH})
-exten => s,n,Verbose(Finish-of-speedtest)
-exten => s,n,Verbose(The time diff is $[${time2} - ${time1} ] seconds)
-exten => s,n,Verbose(Which means that the priorities/sec = $[ 4 * ${iterations} / (${time2} - ${time1}) ] )
-exten => s,n,Wait(1)
-exten => s,n,SayNumber($[ 4 * ${iterations} / (${time2} - ${time1}) ] )
-exten => s,n,Hangup
-
-Without the usleep() call, it would execute on my PC at about 60k iterations per second.
-The drawback is that the playtone isn't played at all because all the CPU is dedicated to
-the dialplan loop.
-
-Adding the call to the usleep() performance tests would fall down to about 1000 ips.
-This is dued to the fact that when usleep is called, the other threads are allowed 
-to wake up and execute and it's likely to take more than 1 microsecond.
-
-Fortunately, under load, the usleep() call will allow all the threads to run smoothly 
-without any particular issue.
-
-Please note that this big performance reduction is so evident only in this case because 
-the call to Goto() or GotoIf() is called 2 times in a 3 line loop.
-
-Under normal circumstances, the use of goto is far less important.
-
-CtRiX, November 2006
Only in trunk.xming/editline: Makefile.in
Only in trunk.xming/editline: aclocal.m4
Only in trunk.xming/editline: autom4te.cache
Only in trunk.xming/editline: config.guess
Only in trunk.xming/editline: config.h.in~
Only in trunk.xming/editline: config.sub
Only in trunk.xming/editline: configure
Only in trunk.xming/editline: ltmain.sh
Only in trunk.xming/editline/src: Makefile.in
Only in trunk.xming/formats: Makefile.in
Only in trunk.xming/funcs: Makefile.in
Only in trunk.xming/include: Makefile.in
Only in trunk.xming/include: confdefs.h.in
Only in trunk.xming/include: confdefs.h.in~
Only in trunk.xming/include/openpbx: Makefile.in
Only in trunk.xming/: install-sh
Only in trunk.xming/: libltdl
Only in trunk.xming/libs: Makefile.in
Only in trunk.xming/: ltmain.sh
Only in trunk.xming/: missing
Only in trunk.xming/ogi: Makefile.in
Only in trunk.xming/pbx: Makefile.in
diff -r -u --exclude=.svn trunk/pbx/pbx_ael.c trunk.xming/pbx/pbx_ael.c
--- trunk/pbx/pbx_ael.c	2006-11-27 19:20:09.000000000 +0100
+++ trunk.xming/pbx/pbx_ael.c	2006-11-27 01:13:09.000000000 +0100
@@ -50,10 +50,10 @@
 
 static char expr_output[2096];
 
-/* these functions are in ../opbx_expr2.fl */
+/* these functions are in ../ast_expr2.fl */
 
 	
-#ifdef __OPBX_DEBUG_MALLOC
+#ifdef __AST_DEBUG_MALLOC
 static void FREE(void *ptr)
 {
 	free(ptr);
@@ -99,9 +99,9 @@
 void check_pval(pval *item, struct argapp *apps, int in_globals);
 void check_pval_item(pval *item, struct argapp *apps, int in_globals);
 void check_switch_expr(pval *item, struct argapp *apps);
-void opbx_expr_register_extra_error_info(char *errmsg);
-void opbx_expr_clear_extra_error_info(void);
-int  opbx_expr(char *expr, char *buf, int length);
+void ast_expr_register_extra_error_info(char *errmsg);
+void ast_expr_clear_extra_error_info(void);
+int  ast_expr(char *expr, char *buf, int length);
 struct pval *find_macro(char *name);
 struct pval *find_context(char *name);
 struct pval *find_context(char *name);
@@ -114,7 +114,7 @@
 void gen_prios(struct ael_extension *exten, char *label, pval *statement, struct ael_extension *mother_exten );
 void set_priorities(struct ael_extension *exten);
 void add_extensions(struct ael_extension *exten, struct opbx_context *context);
-void opbx_compile_ael2(struct opbx_context **local_contexts, struct pval *root);
+void ast_compile_ael2(struct opbx_context **local_contexts, struct pval *root);
 void destroy_pval(pval *item);
 void destroy_pval_item(pval *item);
 int is_float(char *arg );
@@ -2192,9 +2192,9 @@
 		/* the RHS of a vardec is encapsulated in a $[] expr. Is it legal? */
 		if( !in_globals ) { /* don't check stuff inside the globals context; no wrapping in $[ ] there... */
 			snprintf(errmsg,sizeof(errmsg), "file %s, line %d, columns %d-%d, variable declaration expr '%s':", config, item->startline, item->startcol, item->endcol, item->u2.val);
-			opbx_expr_register_extra_error_info(errmsg);
-			opbx_expr(item->u2.val, expr_output, sizeof(expr_output));
-			opbx_expr_clear_extra_error_info();
+			ast_expr_register_extra_error_info(errmsg);
+			ast_expr(item->u2.val, expr_output, sizeof(expr_output));
+			ast_expr_clear_extra_error_info();
 			if ( strpbrk(item->u2.val,"~!-+<>=*/&^") && !strstr(item->u2.val,"${") ) {
 				opbx_log(LOG_WARNING,"Warning: file %s, line %d-%d: expression %s has operators, but no variables. Interesting...\n",
 						item->filename, item->startline, item->endline, item->u2.val);
@@ -2233,16 +2233,16 @@
 				   item->u4.for_statements == a pval list of statements in the for ()
 		*/
 		snprintf(errmsg,sizeof(errmsg),"file %s, line %d, columns %d-%d, for test expr '%s':", config, item->startline, item->startcol, item->endcol, item->u2.for_test);
-		opbx_expr_register_extra_error_info(errmsg);
+		ast_expr_register_extra_error_info(errmsg);
 
 		strp = strchr(item->u1.for_init, '=');
 		if (strp) {
-			opbx_expr(strp+1, expr_output, sizeof(expr_output));
+			ast_expr(strp+1, expr_output, sizeof(expr_output));
 		}
-		opbx_expr(item->u2.for_test, expr_output, sizeof(expr_output));
+		ast_expr(item->u2.for_test, expr_output, sizeof(expr_output));
 		strp = strchr(item->u3.for_inc, '=');
 		if (strp) {
-			opbx_expr(strp+1, expr_output, sizeof(expr_output));
+			ast_expr(strp+1, expr_output, sizeof(expr_output));
 		}
 		if ( strpbrk(item->u2.for_test,"~!-+<>=*/&^") && !strstr(item->u2.for_test,"${") ) {
 			opbx_log(LOG_WARNING,"Warning: file %s, line %d-%d: expression %s has operators, but no variables. Interesting...\n",
@@ -2257,7 +2257,7 @@
 		check_expr2_input(item,item->u2.for_test);
 		check_expr2_input(item,item->u3.for_inc);
 		
-		opbx_expr_clear_extra_error_info();
+		ast_expr_clear_extra_error_info();
 		check_pval(item->u4.for_statements, apps,in_globals);
 		break;
 			
@@ -2267,9 +2267,9 @@
 				   item->u2.statements == a pval list of statements in the while ()
 		*/
 		snprintf(errmsg,sizeof(errmsg),"file %s, line %d, columns %d-%d, while expr '%s':", config, item->startline, item->startcol, item->endcol, item->u1.str);
-		opbx_expr_register_extra_error_info(errmsg);
-		opbx_expr(item->u1.str, expr_output, sizeof(expr_output));
-		opbx_expr_clear_extra_error_info();
+		ast_expr_register_extra_error_info(errmsg);
+		ast_expr(item->u1.str, expr_output, sizeof(expr_output));
+		ast_expr_clear_extra_error_info();
 		if ( strpbrk(item->u1.str,"~!-+<>=*/&^") && !strstr(item->u1.str,"${") ) {
 			opbx_log(LOG_WARNING,"Warning: file %s, line %d-%d: expression %s has operators, but no variables. Interesting...\n",
 					item->filename, item->startline, item->endline, item->u1.str);
@@ -2302,9 +2302,9 @@
 											   (could be zero)
 		*/
 		snprintf(errmsg,sizeof(errmsg),"file %s, line %d, columns %d-%d, random expr '%s':", config, item->startline, item->startcol, item->endcol, item->u1.str);
-		opbx_expr_register_extra_error_info(errmsg);
-		opbx_expr(item->u1.str, expr_output, sizeof(expr_output));
-		opbx_expr_clear_extra_error_info();
+		ast_expr_register_extra_error_info(errmsg);
+		ast_expr(item->u1.str, expr_output, sizeof(expr_output));
+		ast_expr_clear_extra_error_info();
 		if ( strpbrk(item->u1.str,"~!-+<>=*/&^") && !strstr(item->u1.str,"${") ) {
 			opbx_log(LOG_WARNING,"Warning: file %s, line %d-%d: random expression '%s' has operators, but no variables. Interesting...\n",
 					item->filename, item->startline, item->endline, item->u1.str);
@@ -2345,9 +2345,9 @@
 											   (could be zero)
 		*/
 		snprintf(errmsg,sizeof(errmsg),"file %s, line %d, columns %d-%d, if expr '%s':", config, item->startline, item->startcol, item->endcol, item->u1.str);
-		opbx_expr_register_extra_error_info(errmsg);
-		opbx_expr(item->u1.str, expr_output, sizeof(expr_output));
-		opbx_expr_clear_extra_error_info();
+		ast_expr_register_extra_error_info(errmsg);
+		ast_expr(item->u1.str, expr_output, sizeof(expr_output));
+		ast_expr_clear_extra_error_info();
 		if ( strpbrk(item->u1.str,"~!-+<>=*/&^") && !strstr(item->u1.str,"${") ) {
 			opbx_log(LOG_WARNING,"Warning: file %s, line %d-%d: expression '%s' has operators, but no variables. Interesting...\n",
 					item->filename, item->startline, item->endline, item->u1.str);
@@ -2430,8 +2430,8 @@
 	struct argapp *apps=0;
 
 #ifdef AAL_ARGCHECK
-	rfilename = alloca(10 + strlen(opbx_config_OPBX_VAR_DIR));
-	sprintf(rfilename, "%s/applist", opbx_config_OPBX_VAR_DIR);
+	rfilename = alloca(10 + strlen(ast_config_AST_VAR_DIR));
+	sprintf(rfilename, "%s/applist", ast_config_AST_VAR_DIR);
 	
 	apps = argdesc_parse(rfilename, &argapp_errs); /* giveth */
 #endif
@@ -3282,7 +3282,7 @@
 }
 
 
-void opbx_compile_ael2(struct opbx_context **local_contexts, struct pval *root)
+void ast_compile_ael2(struct opbx_context **local_contexts, struct pval *root)
 {
 	pval *p,*p2;
 	struct opbx_context *context;
@@ -3466,7 +3466,7 @@
 	ael2_semantic_check(parse_tree, &sem_err, &sem_warn, &sem_note);
 	if (errs == 0 && sem_err == 0) {
 		opbx_log(LOG_NOTICE, "AEL load process: checked config file name '%s'.\n", rfilename);
-		opbx_compile_ael2(&local_contexts, parse_tree);
+		ast_compile_ael2(&local_contexts, parse_tree);
 		opbx_log(LOG_NOTICE, "AEL load process: compiled config file name '%s'.\n", rfilename);
 		
 		opbx_merge_contexts_and_delete(&local_contexts, registrar);
Only in trunk.xming/res: Makefile.in
Only in trunk.xming/sqlite3-embedded: Makefile.in
Only in trunk.xming/stdtime: Makefile.in
Only in trunk.xming/utils: Makefile.in