summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSteve Langasek <vorlon@debian.org>2018-09-25 18:09:57 +0000
committerSteve Langasek <vorlon@debian.org>2018-09-25 18:09:57 +0000
commit69655f449e92e084124567be02e586bd907cb024 (patch)
treef08bf6b283c3fd2e068615e6ce6612d9b548b573 /src
parent96fd3f2d6c95d48a0676a23c1aaae6b45d6e4943 (diff)
parent2b2cc5a50fc4a4a71c9a722c6e70a46916504e3e (diff)
New upstream release
Diffstat (limited to 'src')
-rw-r--r--src/Makefile533
-rw-r--r--src/Makefile.in413
-rw-r--r--src/cmd.h8
-rw-r--r--src/cmd_bcp.c537
-rw-r--r--src/cmd_buf.c32
-rw-r--r--src/cmd_connect.c1125
-rw-r--r--src/cmd_do.c101
-rw-r--r--src/cmd_exit.c15
-rw-r--r--src/cmd_for.c1
-rw-r--r--src/cmd_func.c8
-rw-r--r--src/cmd_go.c43
-rw-r--r--src/cmd_history.c167
-rw-r--r--src/cmd_if.c16
-rw-r--r--src/cmd_input.c516
-rw-r--r--src/cmd_jobs.c4
-rw-r--r--src/cmd_lock.c16
-rw-r--r--src/cmd_loop.c6
-rw-r--r--src/cmd_misc.c6
-rw-r--r--src/cmd_read.c48
-rw-r--r--src/cmd_reconnect.c17
-rw-r--r--src/cmd_reset.c11
-rw-r--r--src/cmd_run.c230
-rw-r--r--src/cmd_shell.c86
-rw-r--r--src/config.h85
-rw-r--r--src/config.h.in205
-rw-r--r--src/config.h.nt85
-rw-r--r--src/dsp.c193
-rw-r--r--src/dsp.h75
-rw-r--r--src/dsp_conv.c415
-rw-r--r--src/dsp_csv.c7
-rw-r--r--src/dsp_desc.c440
-rw-r--r--src/dsp_html.c30
-rw-r--r--src/dsp_meta.c74
-rw-r--r--src/dsp_pretty.c10
-rw-r--r--src/dsp_x.c25
-rwxr-xr-xsrc/sqshbin568296 -> 0 bytes
-rw-r--r--src/sqsh_buf.c8
-rw-r--r--src/sqsh_config.h18
-rw-r--r--src/sqsh_ctx.c334
-rw-r--r--src/sqsh_ctx.h21
-rw-r--r--src/sqsh_debug.c19
-rw-r--r--src/sqsh_debug.h3
-rw-r--r--src/sqsh_env.c97
-rw-r--r--src/sqsh_env.h3
-rw-r--r--src/sqsh_expand.c334
-rw-r--r--src/sqsh_expand.h3
-rw-r--r--src/sqsh_getopt.c9
-rw-r--r--src/sqsh_global.c21
-rw-r--r--src/sqsh_global.h24
-rw-r--r--src/sqsh_history.c238
-rw-r--r--src/sqsh_init.c62
-rw-r--r--src/sqsh_job.c174
-rw-r--r--src/sqsh_main.c282
-rw-r--r--src/sqsh_parser/Makefile.in31
-rw-r--r--src/sqsh_parser/sqsh_parser.c129
-rw-r--r--src/sqsh_parser/sqsh_parser.h65
-rw-r--r--src/sqsh_parser/tsql.c970
-rw-r--r--src/sqsh_parser/tsql.h5
-rw-r--r--src/sqsh_parser/tsql.l69
-rw-r--r--src/sqsh_parser/tsql.y25
-rw-r--r--src/sqsh_parser/tsql.yy.c2097
-rw-r--r--src/sqsh_readline.c1073
-rw-r--r--src/sqsh_readline.h30
-rw-r--r--src/var.h88
-rw-r--r--src/var_ctlib.c7
-rw-r--r--src/var_debug.c17
-rw-r--r--src/var_dsp.c319
-rw-r--r--src/var_misc.c156
-rw-r--r--src/var_passwd.c10
-rw-r--r--src/var_readline.c11
70 files changed, 8865 insertions, 3470 deletions
diff --git a/src/Makefile b/src/Makefile
deleted file mode 100644
index a845ecf..0000000
--- a/src/Makefile
+++ /dev/null
@@ -1,533 +0,0 @@
-#
-# Makefile.in,v 1.4 1996/02/15 02:18:28 gray Exp
-#
-
-# The following list of sqshrc files will be executed by sqsh upon
-# startup. This allows for system-wide defaults to be set in a
-# common directory. If you don't want a global sqshrc just comment
-# out SQSHRC_GLOBAL, below.
-
-SQSHRC_GLOBAL = /usr/local/etc/sqshrc
-SQSHRC_PATH = "$(SQSHRC_GLOBAL):$${HOME}/.sqshrc"
-
-# The following variables are configurable by the user. Typically
-# these include things that GNU autoconf has a little trouble
-# figuring out for itself.
-
-SYBASE_OCOS = /opt/sybase/OCS-15_0
-SYBASE_INCDIR = -I$(SYBASE_OCOS)/include
-SYBASE_LIBDIR = -L$(SYBASE_OCOS)/lib
-
-#
-# The following set of CT-LIB libraries were determined automatically
-# by 'configure'. For most systems configure looks up the required
-# libraries by looking at the name of the OS (although this doesn't
-# mean it got them right), however if the line below ends with the
-# word "Guess", then 'configure' didn't have an entry for your operating
-# system and it took a best guess to figure out which libraries you
-# need. In either case, there may be problems, so look this line over
-# and if it doesn't work, compare it to the libraries located in
-# $SYBASE/samples/ctlibrary.
-#
-# The listings below show suggested libraries for Operating Systems
-# that frequently fail to be recognized by 'configure':
-#
-# SCO: -lblk -lct -lcs -lcomn -ltcl -ltli -lnsl_s -lintl -m -lsocket
-# Dynix: -lblk -lct -lcs -lcomn -ltcl -ltli -lnsl -lintl -lm -lseq
-#
-SYBASE_LIBS = -lsybblk -lsybcs -lsybct -lsybtcl -lsybcomn -lsybintl -ldl -lm
-
-#
-# If you have the GNU readline library available, uncomment the
-# following definitions and make sure the lib directory and
-# include directories are correct.
-#
-DEF_READLINE = -DUSE_READLINE -DOLD_READLINE
-READLINE_LIBDIR = # -L/lib
-READLINE_INCDIR = # -I/usr/include
-
-#
-# On most systems, -lreadline and -lcurses is enough to link with
-# the readline library. However on a few systems you may need to
-# link with termcap rather than curses, and on other systems (such
-# as certain Solaris installations), you may need to link in -lucb
-# to get around some BSD specifics dealing with the termcap library.
-#
-READLINE_LIBS = -lreadline -lcurses
-
-#
-# Motif Support - The `configure' motif support logic for sqsh
-# isn't exactly perfected yet. If --with-motif was run, the
-# following what `configure' guessed at for the location
-# for your Motif includes and libs. Note that if MOTIF_INCDIR
-# and MOTIF_LIBDIR are commented out, then the X_INCDIR and
-# X_LIBDIR will be used, below.
-#
-# Note that on some systems -lXpm may need to be added to
-# MOTIF_LIBS.
-#
-DEF_MOTIF = # -DUSE_MOTIF
-MOTIF_INCDIR =
-MOTIF_LIBDIR =
-MOTIF_LIBS =
-
-#
-# X Windows Support
-#
-# The following variables configure whether or not X windows
-# support is compiled into sqsh (this allows a result set to
-# be displayed in a separate window). If '--with-x' was sup-
-# plied to 'configure' then most of the variables should be
-# filled in for you (read INSTALL). If '--with-x' was not
-# supplied or '--without-x' was supplied then The following
-# lines should be commented out.
-#
-DEF_X11 = # -DUSE_X11
-X_INCDIR = # -I/usr/X11R6/include
-X_LIBDIR = # -L/usr/X11R6/lib
-X_LIBS = $(MOTIF_LIBS) # -lXaw -lXt -lXext -lXmu -lX11
-
-#
-# Undefine the following line to turn off bcp support in sqsh. This
-# feature allows a result set to be redirected (bcp'ed) to another
-# server. Since this is a new feature, if you get compile errors on
-# cmd_bcp.c, mail me a copy of the error message(s) (gray@voicenet.com)
-# and uncomment this line.
-#
-#DEF_NOBCP = -DNO_BCP
-
-#
-# As of sqsh-1.4, the $password value will never expand to a clear-text
-# copy of the users password. If you wish to keep the old behavior
-# (which did show the clear-text password), uncomment the following
-# define. Note that this applies to the new $lock password as well.
-#
-#DEF_INSECURE = -DINSECURE
-
-#
-# The following define turns on a work-around for a rather pernicious
-# bug in CT-Lib having to do with the way that async i/o signals are
-# delivered. If, while running sqsh, pipes tend to lose data or don't
-# display anything at all, like:
-#
-# 1> sp_who
-# 2> go | more
-# 1>
-#
-# you probably have the bug. First, PLEASE e-mail me (gray@voicenet.com)
-# and I'll give you a description of what is going on so you can call
-# tech support: I am trying to get them to fix the problem, but they
-# are moving at a snails pace. Then, when you have done that, un-
-# comment the following line, which will attempt to install a work-
-# around for the problem.
-#
-# Please, do not uncomment this line unless you have reproduced the
-# behavior described above.
-#
-#DEF_BUGFIX = -DCTLIB_SIGPOLL_BUG
-
-#
-# Uncommenting the following line turns on debugging support. Turning
-# this feature on will increase the size of sqsh by about 12K, and
-# will probably slow it down nominally. When enabled, various debugging
-# messages may be turned on and off using the -l flag or the $debug
-# environment variable. There is probably no reason to enable this
-# unless you are debugging a problem or are interested in what is
-# going on under the hood.
-#
-#DEF_DEBUG = -DDEBUG
-
-#
-# End of user configuration section.
-#
-
-prefix = /usr/local
-src_dir = .
-exec_prefix = ${prefix}
-bin_dir = $(exec_prefix)/bin
-inc_dir = $(prefix)/include
-lib_dir = $(exec_prefix)/lib
-man_src = $(src_dir)/doc
-man_dir = $(prefix)/man
-
-INSTALL = $(src_dir)/autoconf/install-sh
-INSTALL_PROG = $(INSTALL) -c
-INSTALL_DIR = $(INSTALL) -d
-INSTALL_DATA = $(INSTALL) -c -m 644
-INSTALL_MAN = $(src_dir)/autoconf/install-man
-
-CC = gcc
-DEBUG =
-DEFINES = -DSQSH_RC='${SQSHRC_PATH}' $(DEF_READLINE) \
- $(DEF_NOBCP) $(DEF_DEBUG) $(DEF_INSECURE) $(DEF_X11) \
- $(DEF_MOTIF) $(DEF_BUGFIX)
-INCLUDE_DIRS = $(X_INCDIR) $(MOTIF_INCDIR) $(SYBASE_INCDIR) $(READLINE_INCDIR)
-LIB_DIRS = $(X_LIBDIR) $(MOTIF_INCDIR) $(SYBASE_LIBDIR) $(READLINE_LIBDIR)
-CFLAGS = -g -O2 $(DEBUG) $(DEFINES) $(INCLUDE_DIRS)
-CPPFLAGS =
-LDFLAGS = $(DEBUG) $(LIB_DIRS)
-LIBS = $(SYBASE_LIBS) $(X_LIBS) $(READLINE_LIBS)
-
-# The follow define information about the components that make up
-# the actual program.
-
-TARGET = sqsh
-
-CMDS = \
- cmd_alias.o cmd_bcp.o cmd_buf.o cmd_connect.o cmd_do.o \
- cmd_echo.o cmd_exit.o cmd_for.o cmd_func.o cmd_go.o \
- cmd_help.o cmd_history.o cmd_if.o cmd_input.o cmd_jobs.o \
- cmd_kill.o cmd_lock.o cmd_loop.o cmd_misc.o cmd_read.o \
- cmd_reconnect.o cmd_redraw.o cmd_reset.o cmd_return.o cmd_rpc.o \
- cmd_set.o cmd_shell.o cmd_show.o cmd_sleep.o cmd_wait.o \
- cmd_warranty.o cmd_while.o
-
-DISPLAYS = \
- dsp.o dsp_bcp.o dsp_csv.o dsp_conv.o dsp_desc.o dsp_horiz.o \
- dsp_html.o dsp_meta.o dsp_none.o dsp_out.o dsp_pretty.o \
- dsp_vert.o dsp_x.o
-
-VARS = \
- var_ctlib.o var_date.o var_debug.o var_dsp.o var_hist.o \
- var_misc.o var_passwd.o var_readline.o var_thresh.o
-
-CORE = \
- sqsh_alias.o sqsh_args.o sqsh_avl.o sqsh_buf.o sqsh_cmd.o \
- sqsh_compat.o sqsh_ctx.o sqsh_debug.o sqsh_env.o sqsh_error.o \
- sqsh_expand.o sqsh_fd.o sqsh_filter.o sqsh_fork.o sqsh_func.o \
- sqsh_getopt.o sqsh_global.o sqsh_history.o sqsh_init.o \
- sqsh_job.o sqsh_readline.o sqsh_sig.o sqsh_sigcld.o sqsh_stdin.o \
- sqsh_strchr.o sqsh_tok.o sqsh_varbuf.o
-
-OBJS = $(CMDS) $(VARS) $(DISPLAYS) $(CORE)
-
-MAN_PAGES = sqsh.1
-SRCS = $(OBJS:.o=.c)
-HEADERS =
-
-$(TARGET) : $(OBJS) sqsh_main.o
- $(CC) $(LDFLAGS) $(OBJS) sqsh_main.o $(LIBS) -o $@
-
-sqsh_test : $(OBJS) sqsh_test.o
- $(CC) $(LDFLAGS) $(OBJS) sqsh_test.o $(LIBS) -o $@
-
-sig_test : sqsh_debug.o sqsh_error.o sqsh_sig.c
- $(CC) $(LDFLAGS) $(DEF_DEBUG) -DSIG_TEST sqsh_debug.o sqsh_error.o \
- sqsh_sig.c -o sig_test
-
-clean :
- rm -f *.o $(TARGET) sqsh_test sig_test
-
-realclean : clean
- rm -f config.cache config.log config.status
-
-distclean : realclean
- rm -f Makefile config.h core
-
-#
-# The following absolutely disgusting list of dependancies was
-# automatically generated via 'gcc -MM'
-#
-cmd_alias.o: cmd_alias.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h sqsh_global.h sqsh_env.h sqsh_cmd.h \
- sqsh_avl.h sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h \
- sqsh_history.h sqsh_alias.h dsp.h sqsh_func.h cmd.h
-cmd_bcp.o: cmd_bcp.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
- sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h sqsh_job.h sqsh_args.h \
- sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h dsp.h \
- sqsh_func.h sqsh_expand.h sqsh_error.h sqsh_getopt.h sqsh_sig.h cmd.h
-cmd_buf.o: cmd_buf.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
- sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h sqsh_job.h sqsh_args.h \
- sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h dsp.h \
- sqsh_func.h sqsh_error.h sqsh_getopt.h sqsh_buf.h sqsh_stdin.h cmd.h
-cmd_connect.o: cmd_connect.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h sqsh_global.h sqsh_env.h sqsh_cmd.h \
- sqsh_avl.h sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h \
- sqsh_history.h sqsh_alias.h dsp.h sqsh_func.h sqsh_getopt.h \
- sqsh_init.h sqsh_stdin.h cmd.h
-cmd_do.o: cmd_do.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
- sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h sqsh_job.h sqsh_args.h \
- sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h dsp.h \
- sqsh_func.h sqsh_expand.h sqsh_error.h sqsh_sig.h sqsh_buf.h \
- sqsh_readline.h sqsh_getopt.h sqsh_stdin.h cmd.h cmd_misc.h \
- cmd_input.h
-cmd_echo.o: cmd_echo.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h \
- sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h \
- sqsh_alias.h dsp.h sqsh_func.h cmd.h
-cmd_exit.o: cmd_exit.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_cmd.h sqsh_avl.h cmd.h sqsh_varbuf.h
-cmd_for.o: cmd_for.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
- sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h sqsh_job.h sqsh_args.h \
- sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h dsp.h \
- sqsh_func.h sqsh_expand.h sqsh_error.h sqsh_sig.h sqsh_buf.h \
- sqsh_readline.h sqsh_getopt.h sqsh_stdin.h cmd.h cmd_misc.h \
- cmd_input.h
-cmd_func.o: cmd_func.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h \
- sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h \
- sqsh_alias.h dsp.h sqsh_func.h sqsh_expand.h sqsh_error.h sqsh_sig.h \
- sqsh_getopt.h sqsh_buf.h sqsh_stdin.h sqsh_readline.h cmd.h \
- cmd_misc.h cmd_input.h
-cmd_go.o: cmd_go.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
- sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h sqsh_job.h sqsh_args.h \
- sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h dsp.h \
- sqsh_func.h sqsh_expand.h sqsh_error.h sqsh_getopt.h sqsh_buf.h \
- sqsh_filter.h sqsh_stdin.h cmd.h cmd_misc.h
-cmd_help.o: cmd_help.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h \
- sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h \
- sqsh_alias.h dsp.h sqsh_func.h sqsh_error.h cmd.h
-cmd_history.o: cmd_history.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h sqsh_global.h sqsh_env.h sqsh_cmd.h \
- sqsh_avl.h sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h \
- sqsh_history.h sqsh_alias.h dsp.h sqsh_func.h cmd.h
-cmd_if.o: cmd_if.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
- sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h sqsh_job.h sqsh_args.h \
- sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h dsp.h \
- sqsh_func.h sqsh_expand.h sqsh_error.h sqsh_sig.h sqsh_getopt.h \
- sqsh_buf.h sqsh_stdin.h sqsh_readline.h cmd.h cmd_misc.h cmd_input.h
-cmd_input.o: cmd_input.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h \
- sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h \
- sqsh_alias.h dsp.h sqsh_func.h sqsh_expand.h sqsh_error.h sqsh_sig.h \
- sqsh_readline.h sqsh_stdin.h cmd.h cmd_misc.h cmd_input.h
-cmd_jobs.o: cmd_jobs.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h \
- sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h \
- sqsh_alias.h dsp.h sqsh_func.h cmd.h
-cmd_kill.o: cmd_kill.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h sqsh_global.h sqsh_env.h sqsh_cmd.h \
- sqsh_avl.h sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h \
- sqsh_history.h sqsh_alias.h dsp.h sqsh_func.h cmd.h
-cmd_lock.o: cmd_lock.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_cmd.h sqsh_avl.h sqsh_global.h sqsh_env.h \
- sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h \
- sqsh_alias.h dsp.h sqsh_func.h sqsh_error.h cmd.h
-cmd_loop.o: cmd_loop.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h \
- sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h \
- sqsh_alias.h dsp.h sqsh_func.h sqsh_error.h sqsh_getopt.h \
- sqsh_readline.h sqsh_stdin.h cmd.h cmd_misc.h cmd_input.h
-cmd_misc.o: cmd_misc.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h \
- sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h \
- sqsh_alias.h dsp.h sqsh_func.h sqsh_expand.h sqsh_error.h cmd.h \
- cmd_misc.h
-cmd_read.o: cmd_read.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h \
- sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h \
- sqsh_alias.h dsp.h sqsh_func.h sqsh_error.h sqsh_getopt.h \
- sqsh_readline.h sqsh_stdin.h cmd.h
-cmd_reconnect.o: cmd_reconnect.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h \
- sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h \
- sqsh_alias.h dsp.h sqsh_func.h cmd.h
-cmd_redraw.o: cmd_redraw.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_cmd.h sqsh_avl.h cmd.h sqsh_varbuf.h
-cmd_reset.o: cmd_reset.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h \
- sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h \
- sqsh_alias.h dsp.h sqsh_func.h cmd.h
-cmd_return.o: cmd_return.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_cmd.h sqsh_avl.h sqsh_env.h sqsh_global.h \
- sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h \
- sqsh_alias.h dsp.h sqsh_func.h cmd.h
-cmd_rpc.o: cmd_rpc.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
- sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h sqsh_job.h sqsh_args.h \
- sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h dsp.h \
- sqsh_func.h sqsh_expand.h sqsh_error.h sqsh_getopt.h sqsh_sig.h \
- sqsh_stdin.h cmd.h
-cmd_set.o: cmd_set.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
- sqsh_error.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h \
- sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h \
- sqsh_alias.h dsp.h sqsh_func.h cmd.h
-cmd_shell.o: cmd_shell.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h sqsh_varbuf.h sqsh_global.h sqsh_env.h \
- sqsh_cmd.h sqsh_avl.h sqsh_job.h sqsh_args.h sqsh_sigcld.h \
- sqsh_history.h sqsh_alias.h dsp.h sqsh_func.h cmd.h
-cmd_show.o: cmd_show.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h sqsh_global.h sqsh_env.h sqsh_cmd.h \
- sqsh_avl.h sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h \
- sqsh_history.h sqsh_alias.h dsp.h sqsh_func.h cmd.h
-cmd_sleep.o: cmd_sleep.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_cmd.h sqsh_avl.h cmd.h sqsh_varbuf.h
-cmd_wait.o: cmd_wait.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h sqsh_global.h sqsh_env.h sqsh_cmd.h \
- sqsh_avl.h sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h \
- sqsh_history.h sqsh_alias.h dsp.h sqsh_func.h sqsh_stdin.h cmd.h
-cmd_warranty.o: cmd_warranty.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h \
- sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h \
- sqsh_alias.h dsp.h sqsh_func.h cmd.h
-cmd_while.o: cmd_while.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h \
- sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h \
- sqsh_alias.h dsp.h sqsh_func.h sqsh_expand.h sqsh_error.h sqsh_sig.h \
- sqsh_getopt.h sqsh_buf.h sqsh_stdin.h sqsh_readline.h sqsh_tok.h \
- cmd.h cmd_misc.h cmd_input.h
-dsp.o: dsp.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
- sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h sqsh_job.h sqsh_args.h \
- sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h dsp.h \
- sqsh_func.h sqsh_error.h sqsh_sig.h
-dsp_bcp.o: dsp_bcp.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
- sqsh_error.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h \
- sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h \
- sqsh_alias.h dsp.h sqsh_func.h
-dsp_csv.o: dsp_csv.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
- sqsh_error.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h \
- sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h \
- sqsh_alias.h dsp.h sqsh_func.h
-dsp_conv.o: dsp_conv.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h dsp.h
-dsp_desc.o: dsp_desc.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h sqsh_global.h sqsh_env.h sqsh_cmd.h \
- sqsh_avl.h sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h \
- sqsh_history.h sqsh_alias.h dsp.h sqsh_func.h
-dsp_horiz.o: dsp_horiz.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h sqsh_global.h sqsh_env.h sqsh_cmd.h \
- sqsh_avl.h sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h \
- sqsh_history.h sqsh_alias.h dsp.h sqsh_func.h
-dsp_html.o: dsp_html.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h sqsh_global.h sqsh_env.h sqsh_cmd.h \
- sqsh_avl.h sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h \
- sqsh_history.h sqsh_alias.h dsp.h sqsh_func.h
-dsp_meta.o: dsp_meta.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h dsp.h
-dsp_none.o: dsp_none.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h sqsh_global.h sqsh_env.h sqsh_cmd.h \
- sqsh_avl.h sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h \
- sqsh_history.h sqsh_alias.h dsp.h sqsh_func.h
-dsp_out.o: dsp_out.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
- sqsh_error.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h \
- sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h \
- sqsh_alias.h dsp.h sqsh_func.h
-dsp_pretty.o: dsp_pretty.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h sqsh_global.h sqsh_env.h sqsh_cmd.h \
- sqsh_avl.h sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h \
- sqsh_history.h sqsh_alias.h dsp.h sqsh_func.h
-dsp_vert.o: dsp_vert.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h sqsh_global.h sqsh_env.h sqsh_cmd.h \
- sqsh_avl.h sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h \
- sqsh_history.h sqsh_alias.h dsp.h sqsh_func.h
-dsp_x.o: dsp_x.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
- sqsh_error.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h \
- sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h \
- sqsh_alias.h dsp.h sqsh_func.h
-sqsh_alias.o: sqsh_alias.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h sqsh_alias.h sqsh_varbuf.h sqsh_avl.h
-sqsh_args.o: sqsh_args.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h sqsh_args.h
-sqsh_avl.o: sqsh_avl.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h sqsh_avl.h
-sqsh_buf.o: sqsh_buf.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h \
- sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h \
- sqsh_alias.h dsp.h sqsh_func.h sqsh_error.h sqsh_stdin.h sqsh_buf.h
-sqsh_cmd.o: sqsh_cmd.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h sqsh_avl.h sqsh_cmd.h
-sqsh_compat.o: sqsh_compat.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h sqsh_sig.h
-sqsh_ctx.o: sqsh_ctx.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h sqsh_ctx.h sqsh_varbuf.h dsp.h
-sqsh_debug.o: sqsh_debug.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h
-sqsh_env.o: sqsh_env.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h sqsh_env.h
-sqsh_error.o: sqsh_error.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h
-sqsh_expand.o: sqsh_expand.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h sqsh_varbuf.h sqsh_env.h sqsh_global.h \
- sqsh_cmd.h sqsh_avl.h sqsh_job.h sqsh_args.h sqsh_sigcld.h \
- sqsh_history.h sqsh_alias.h dsp.h sqsh_func.h sqsh_fd.h sqsh_expand.h \
- sqsh_strchr.h sqsh_sig.h
-sqsh_fd.o: sqsh_fd.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
- sqsh_sigcld.h sqsh_env.h sqsh_global.h sqsh_cmd.h sqsh_avl.h \
- sqsh_job.h sqsh_args.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h \
- dsp.h sqsh_func.h sqsh_error.h sqsh_fd.h
-sqsh_filter.o: sqsh_filter.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_fd.h sqsh_sig.h sqsh_varbuf.h sqsh_error.h \
- sqsh_filter.h
-sqsh_fork.o: sqsh_fork.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h \
- sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h \
- sqsh_alias.h dsp.h sqsh_func.h sqsh_error.h sqsh_fork.h
-sqsh_func.o: sqsh_func.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h sqsh_avl.h sqsh_func.h
-sqsh_getopt.o: sqsh_getopt.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h sqsh_varbuf.h sqsh_global.h sqsh_env.h \
- sqsh_cmd.h sqsh_avl.h sqsh_job.h sqsh_args.h sqsh_sigcld.h \
- sqsh_history.h sqsh_alias.h dsp.h sqsh_func.h sqsh_getopt.h
-sqsh_global.o: sqsh_global.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h \
- sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h \
- sqsh_alias.h dsp.h sqsh_func.h
-sqsh_history.o: sqsh_history.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h sqsh_history.h sqsh_varbuf.h
-sqsh_init.o: sqsh_init.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h sqsh_global.h sqsh_env.h sqsh_cmd.h \
- sqsh_avl.h sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h \
- sqsh_history.h sqsh_alias.h dsp.h sqsh_func.h sqsh_expand.h \
- sqsh_readline.h sqsh_stdin.h sqsh_init.h cmd.h var.h alias.h
-sqsh_job.o: sqsh_job.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h sqsh_fd.h sqsh_tok.h sqsh_varbuf.h \
- sqsh_cmd.h sqsh_avl.h sqsh_global.h sqsh_env.h sqsh_job.h sqsh_args.h \
- sqsh_sigcld.h sqsh_history.h sqsh_alias.h dsp.h sqsh_func.h \
- sqsh_fork.h sqsh_expand.h sqsh_strchr.h sqsh_getopt.h sqsh_sig.h
-sqsh_main.o: sqsh_main.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_error.h \
- sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h sqsh_varbuf.h \
- sqsh_history.h sqsh_alias.h dsp.h sqsh_func.h sqsh_getopt.h \
- sqsh_init.h sqsh_fd.h sqsh_readline.h sqsh_expand.h sqsh_sig.h \
- sqsh_stdin.h cmd.h
-sqsh_readline.o: sqsh_readline.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h sqsh_global.h sqsh_env.h sqsh_cmd.h \
- sqsh_avl.h sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h \
- sqsh_history.h sqsh_alias.h dsp.h sqsh_func.h sqsh_stdin.h \
- sqsh_readline.h
-sqsh_sig.o: sqsh_sig.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h sqsh_sig.h
-sqsh_sigcld.o: sqsh_sigcld.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h sqsh_sig.h sqsh_sigcld.h
-sqsh_stdin.o: sqsh_stdin.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_sigcld.h sqsh_env.h sqsh_global.h sqsh_cmd.h \
- sqsh_avl.h sqsh_job.h sqsh_args.h sqsh_varbuf.h sqsh_history.h \
- sqsh_alias.h dsp.h sqsh_func.h sqsh_error.h sqsh_stdin.h
-sqsh_strchr.o: sqsh_strchr.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_strchr.h sqsh_error.h
-sqsh_test.o: sqsh_test.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_varbuf.h sqsh_filter.h
-sqsh_tok.o: sqsh_tok.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h sqsh_tok.h sqsh_varbuf.h
-sqsh_varbuf.o: sqsh_varbuf.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_varbuf.h sqsh_error.h
-var_ctlib.o: var_ctlib.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h \
- sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h \
- sqsh_alias.h dsp.h sqsh_func.h sqsh_error.h sqsh_fd.h var.h
-var_date.o: var_date.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_env.h sqsh_error.h sqsh_global.h sqsh_cmd.h \
- sqsh_avl.h sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h \
- sqsh_history.h sqsh_alias.h dsp.h sqsh_func.h var.h
-var_debug.o: var_debug.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_env.h sqsh_error.h sqsh_global.h sqsh_cmd.h \
- sqsh_avl.h sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h \
- sqsh_history.h sqsh_alias.h dsp.h sqsh_func.h var.h
-var_dsp.o: var_dsp.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
- sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h sqsh_job.h sqsh_args.h \
- sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h dsp.h \
- sqsh_func.h sqsh_error.h sqsh_fd.h var.h
-var_hist.o: var_hist.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_env.h sqsh_error.h sqsh_global.h sqsh_cmd.h \
- sqsh_avl.h sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h \
- sqsh_history.h sqsh_alias.h dsp.h sqsh_func.h var.h
-var_misc.o: var_misc.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_env.h sqsh_error.h sqsh_stdin.h var.h
-var_passwd.o: var_passwd.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_env.h sqsh_global.h sqsh_cmd.h sqsh_avl.h \
- sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h \
- sqsh_alias.h dsp.h sqsh_func.h sqsh_error.h var.h
-var_readline.o: var_readline.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_env.h sqsh_error.h var.h
-var_thresh.o: var_thresh.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_env.h sqsh_error.h var.h
diff --git a/src/Makefile.in b/src/Makefile.in
index 6bac214..93c822a 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -3,8 +3,8 @@
#
# The following list of sqshrc files will be executed by sqsh upon
-# startup. This allows for system-wide defaults to be set in a
-# common directory. If you don't want a global sqshrc just comment
+# startup. This allows for system-wide defaults to be set in a
+# common directory. If you don't want a global sqshrc just comment
# out SQSHRC_GLOBAL, below.
sysconfdir = @sysconfdir@
@@ -26,13 +26,13 @@ SYBASE_LIBDIR = @SYBASE_LIBDIR@
# word "Guess", then 'configure' didn't have an entry for your operating
# system and it took a best guess to figure out which libraries you
# need. In either case, there may be problems, so look this line over
-# and if it doesn't work, compare it to the libraries located in
+# and if it doesn't work, compare it to the libraries located in
# $SYBASE/samples/ctlibrary.
#
# The listings below show suggested libraries for Operating Systems
# that frequently fail to be recognized by 'configure':
#
-# SCO: -lblk -lct -lcs -lcomn -ltcl -ltli -lnsl_s -lintl -m -lsocket
+# SCO: -lblk -lct -lcs -lcomn -ltcl -ltli -lnsl_s -lintl -m -lsocket
# Dynix: -lblk -lct -lcs -lcomn -ltcl -ltli -lnsl -lintl -lm -lseq
#
SYBASE_LIBS = @SYBASE_LIBS@ @SYBASE_OS@
@@ -54,7 +54,7 @@ DEF_READLINE = @DEF_READLINE@
READLINE_LIBS = @READLINE_LIBS@
#
-# Motif Support - The `configure' motif support logic for sqsh
+# Motif Support - The `configure' motif support logic for sqsh
# isn't exactly perfected yet. If --with-motif was run, the
# following what `configure' guessed at for the location
# for your Motif includes and libs. Note that if MOTIF_INCDIR
@@ -114,7 +114,7 @@ X_LIBS = @ATHENA_LIBS@ $(MOTIF_LIBS) @X_LIBS@
#
# you probably have the bug. First, PLEASE e-mail me (gray@voicenet.com)
# and I'll give you a description of what is going on so you can call
-# tech support: I am trying to get them to fix the problem, but they
+# tech support: I am trying to get them to fix the problem, but they
# are moving at a snails pace. Then, when you have done that, un-
# comment the following line, which will attempt to install a work-
# around for the problem.
@@ -133,13 +133,14 @@ X_LIBS = @ATHENA_LIBS@ $(MOTIF_LIBS) @X_LIBS@
# unless you are debugging a problem or are interested in what is
# going on under the hood.
#
-#DEF_DEBUG = -DDEBUG
+DEF_DEBUG = @DEF_DEBUG@
#
# End of user configuration section.
#
prefix = @prefix@
+datarootdir = @datarootdir@
src_dir = @srcdir@
exec_prefix = @exec_prefix@
bin_dir = $(exec_prefix)/bin
@@ -156,16 +157,15 @@ INSTALL_DATA = $(INSTALL) -c -m 644
INSTALL_MAN = $(src_dir)/autoconf/install-man
CC = @CC@
-DEBUG =
DEFINES = -DSQSH_RC='${SQSHRC_PATH}' $(DEF_READLINE) \
$(DEF_NOBCP) $(DEF_DEBUG) $(DEF_INSECURE) $(DEF_X11) \
$(DEF_MOTIF) $(DEF_BUGFIX) @DEF_POSIX@ @DEF_AIX_FIX@
INCLUDE_DIRS = $(X_INCDIR) $(MOTIF_INCDIR) $(SYBASE_INCDIR) $(READLINE_INCDIR)
LIB_DIRS = $(X_LIBDIR) $(MOTIF_INCDIR) $(SYBASE_LIBDIR) $(READLINE_LIBDIR)
-CFLAGS = @CFLAGS@ $(DEBUG) $(DEFINES) $(INCLUDE_DIRS)
+CFLAGS = @CFLAGS@ $(DEFINES) $(INCLUDE_DIRS)
CPPFLAGS = @CPPFLAGS@
-LDFLAGS = $(DEBUG) $(LIB_DIRS)
-LIBS = $(SYBASE_LIBS) $(X_LIBS) $(READLINE_LIBS) @LIBS@
+LDFLAGS = @LDFLAGS@ $(LIB_DIRS)
+LIBS = $(SYBASE_LIBS) $(X_LIBS) $(READLINE_LIBS) @LIBS@ @SQSH_PARSE_LIB@
# The follow define information about the components that make up
# the actual program.
@@ -178,7 +178,7 @@ CMDS = \
cmd_help.o cmd_history.o cmd_if.o cmd_input.o cmd_jobs.o \
cmd_kill.o cmd_lock.o cmd_loop.o cmd_misc.o cmd_read.o \
cmd_reconnect.o cmd_redraw.o cmd_reset.o cmd_return.o cmd_rpc.o \
- cmd_set.o cmd_shell.o cmd_show.o cmd_sleep.o cmd_wait.o \
+ cmd_run.o cmd_set.o cmd_shell.o cmd_show.o cmd_sleep.o cmd_wait.o \
cmd_warranty.o cmd_while.o
DISPLAYS = \
@@ -192,7 +192,7 @@ VARS = \
CORE = \
sqsh_alias.o sqsh_args.o sqsh_avl.o sqsh_buf.o sqsh_cmd.o \
- sqsh_compat.o sqsh_ctx.o sqsh_debug.o sqsh_env.o sqsh_error.o \
+ sqsh_compat.o sqsh_debug.o sqsh_env.o sqsh_error.o \
sqsh_expand.o sqsh_fd.o sqsh_filter.o sqsh_fork.o sqsh_func.o \
sqsh_getopt.o sqsh_global.o sqsh_history.o sqsh_init.o \
sqsh_job.o sqsh_readline.o sqsh_sig.o sqsh_sigcld.o sqsh_stdin.o \
@@ -202,7 +202,7 @@ OBJS = $(CMDS) $(VARS) $(DISPLAYS) $(CORE)
MAN_PAGES = sqsh.1
SRCS = $(OBJS:.o=.c)
-HEADERS =
+HEADERS =
$(TARGET) : $(OBJS) sqsh_main.o
$(CC) $(LDFLAGS) $(OBJS) sqsh_main.o $(LIBS) -o $@
@@ -223,14 +223,14 @@ realclean : clean
distclean : realclean
rm -f Makefile config.h core
-#
+#
# The following absolutely disgusting list of dependancies was
# automatically generated via 'gcc -MM'
#
cmd_alias.o: cmd_alias.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h sqsh_global.h sqsh_env.h sqsh_cmd.h \
- sqsh_avl.h sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h \
- sqsh_history.h sqsh_alias.h dsp.h sqsh_func.h cmd.h
+ sqsh_debug.h sqsh_error.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h \
+ sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h \
+ sqsh_alias.h dsp.h sqsh_func.h cmd.h
cmd_bcp.o: cmd_bcp.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h sqsh_job.h sqsh_args.h \
sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h dsp.h \
@@ -238,219 +238,221 @@ cmd_bcp.o: cmd_bcp.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
cmd_buf.o: cmd_buf.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h sqsh_job.h sqsh_args.h \
sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h dsp.h \
- sqsh_func.h sqsh_error.h sqsh_getopt.h sqsh_buf.h sqsh_stdin.h cmd.h
+ sqsh_func.h sqsh_error.h sqsh_getopt.h sqsh_buf.h sqsh_stdin.h \
+ sqsh_expand.h sqsh_init.h cmd.h
cmd_connect.o: cmd_connect.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h sqsh_global.h sqsh_env.h sqsh_cmd.h \
- sqsh_avl.h sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h \
- sqsh_history.h sqsh_alias.h dsp.h sqsh_func.h sqsh_getopt.h \
- sqsh_init.h sqsh_stdin.h cmd.h
+ sqsh_debug.h sqsh_error.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h \
+ sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h \
+ sqsh_alias.h dsp.h sqsh_func.h sqsh_getopt.h sqsh_init.h sqsh_sig.h \
+ sqsh_stdin.h cmd.h sqsh_expand.h
cmd_do.o: cmd_do.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h sqsh_job.h sqsh_args.h \
sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h dsp.h \
sqsh_func.h sqsh_expand.h sqsh_error.h sqsh_sig.h sqsh_buf.h \
- sqsh_readline.h sqsh_getopt.h sqsh_stdin.h cmd.h cmd_misc.h \
- cmd_input.h
-cmd_echo.o: cmd_echo.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h \
- sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h \
- sqsh_alias.h dsp.h sqsh_func.h cmd.h
-cmd_exit.o: cmd_exit.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_cmd.h sqsh_avl.h cmd.h sqsh_varbuf.h
+ sqsh_readline.h sqsh_getopt.h sqsh_stdin.h cmd.h cmd_misc.h cmd_input.h
+cmd_echo.o: cmd_echo.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
+ sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h sqsh_job.h sqsh_args.h \
+ sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h dsp.h \
+ sqsh_func.h cmd.h
+cmd_exit.o: cmd_exit.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
+ sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h sqsh_job.h sqsh_args.h \
+ sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h dsp.h \
+ sqsh_func.h cmd.h
cmd_for.o: cmd_for.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h sqsh_job.h sqsh_args.h \
sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h dsp.h \
sqsh_func.h sqsh_expand.h sqsh_error.h sqsh_sig.h sqsh_buf.h \
- sqsh_readline.h sqsh_getopt.h sqsh_stdin.h cmd.h cmd_misc.h \
- cmd_input.h
-cmd_func.o: cmd_func.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h \
- sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h \
- sqsh_alias.h dsp.h sqsh_func.h sqsh_expand.h sqsh_error.h sqsh_sig.h \
- sqsh_getopt.h sqsh_buf.h sqsh_stdin.h sqsh_readline.h cmd.h \
- cmd_misc.h cmd_input.h
+ sqsh_readline.h sqsh_getopt.h sqsh_stdin.h cmd.h cmd_misc.h cmd_input.h
+cmd_func.o: cmd_func.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
+ sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h sqsh_job.h sqsh_args.h \
+ sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h dsp.h \
+ sqsh_func.h sqsh_expand.h sqsh_error.h sqsh_sig.h sqsh_getopt.h \
+ sqsh_buf.h sqsh_stdin.h sqsh_readline.h cmd.h cmd_misc.h cmd_input.h
cmd_go.o: cmd_go.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h sqsh_job.h sqsh_args.h \
sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h dsp.h \
sqsh_func.h sqsh_expand.h sqsh_error.h sqsh_getopt.h sqsh_buf.h \
sqsh_filter.h sqsh_stdin.h cmd.h cmd_misc.h
-cmd_help.o: cmd_help.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h \
- sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h \
- sqsh_alias.h dsp.h sqsh_func.h sqsh_error.h cmd.h
+cmd_help.o: cmd_help.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
+ sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h sqsh_job.h sqsh_args.h \
+ sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h dsp.h \
+ sqsh_func.h sqsh_error.h cmd.h
cmd_history.o: cmd_history.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h sqsh_global.h sqsh_env.h sqsh_cmd.h \
- sqsh_avl.h sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h \
- sqsh_history.h sqsh_alias.h dsp.h sqsh_func.h cmd.h
+ sqsh_debug.h sqsh_error.h sqsh_getopt.h sqsh_global.h sqsh_env.h \
+ sqsh_cmd.h sqsh_avl.h sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h \
+ sqsh_history.h sqsh_alias.h dsp.h sqsh_func.h cmd.h sqsh_expand.h
cmd_if.o: cmd_if.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h sqsh_job.h sqsh_args.h \
sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h dsp.h \
sqsh_func.h sqsh_expand.h sqsh_error.h sqsh_sig.h sqsh_getopt.h \
sqsh_buf.h sqsh_stdin.h sqsh_readline.h cmd.h cmd_misc.h cmd_input.h
cmd_input.o: cmd_input.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h \
- sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h \
- sqsh_alias.h dsp.h sqsh_func.h sqsh_expand.h sqsh_error.h sqsh_sig.h \
- sqsh_readline.h sqsh_stdin.h cmd.h cmd_misc.h cmd_input.h
-cmd_jobs.o: cmd_jobs.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h \
- sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h \
- sqsh_alias.h dsp.h sqsh_func.h cmd.h
-cmd_kill.o: cmd_kill.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h sqsh_global.h sqsh_env.h sqsh_cmd.h \
- sqsh_avl.h sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h \
- sqsh_history.h sqsh_alias.h dsp.h sqsh_func.h cmd.h
-cmd_lock.o: cmd_lock.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_cmd.h sqsh_avl.h sqsh_global.h sqsh_env.h \
- sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h \
- sqsh_alias.h dsp.h sqsh_func.h sqsh_error.h cmd.h
-cmd_loop.o: cmd_loop.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h \
- sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h \
- sqsh_alias.h dsp.h sqsh_func.h sqsh_error.h sqsh_getopt.h \
- sqsh_readline.h sqsh_stdin.h cmd.h cmd_misc.h cmd_input.h
-cmd_misc.o: cmd_misc.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h \
- sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h \
- sqsh_alias.h dsp.h sqsh_func.h sqsh_expand.h sqsh_error.h cmd.h \
- cmd_misc.h
-cmd_read.o: cmd_read.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h \
- sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h \
- sqsh_alias.h dsp.h sqsh_func.h sqsh_error.h sqsh_getopt.h \
- sqsh_readline.h sqsh_stdin.h cmd.h
+ sqsh_debug.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h sqsh_job.h \
+ sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h \
+ dsp.h sqsh_func.h sqsh_expand.h sqsh_error.h sqsh_sig.h sqsh_readline.h \
+ sqsh_stdin.h cmd.h cmd_misc.h cmd_input.h
+cmd_jobs.o: cmd_jobs.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
+ sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h sqsh_job.h sqsh_args.h \
+ sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h dsp.h \
+ sqsh_func.h cmd.h
+cmd_kill.o: cmd_kill.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
+ sqsh_error.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h sqsh_job.h \
+ sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h \
+ dsp.h sqsh_func.h cmd.h
+cmd_lock.o: cmd_lock.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
+ sqsh_cmd.h sqsh_avl.h sqsh_global.h sqsh_env.h sqsh_job.h sqsh_args.h \
+ sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h dsp.h \
+ sqsh_func.h sqsh_error.h cmd.h
+cmd_loop.o: cmd_loop.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
+ sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h sqsh_job.h sqsh_args.h \
+ sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h dsp.h \
+ sqsh_func.h sqsh_error.h sqsh_getopt.h sqsh_readline.h sqsh_stdin.h \
+ cmd.h cmd_misc.h cmd_input.h
+cmd_misc.o: cmd_misc.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
+ sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h sqsh_job.h sqsh_args.h \
+ sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h dsp.h \
+ sqsh_func.h sqsh_expand.h sqsh_error.h cmd.h cmd_misc.h
+cmd_read.o: cmd_read.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
+ sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h sqsh_job.h sqsh_args.h \
+ sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h dsp.h \
+ sqsh_func.h sqsh_error.h sqsh_getopt.h sqsh_readline.h sqsh_stdin.h \
+ cmd.h
cmd_reconnect.o: cmd_reconnect.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h \
- sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h \
- sqsh_alias.h dsp.h sqsh_func.h cmd.h
+ sqsh_debug.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h sqsh_job.h \
+ sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h \
+ dsp.h sqsh_func.h cmd.h
cmd_redraw.o: cmd_redraw.c sqsh_config.h config.h sqsh_compat.h \
sqsh_debug.h sqsh_cmd.h sqsh_avl.h cmd.h sqsh_varbuf.h
cmd_reset.o: cmd_reset.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h \
- sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h \
- sqsh_alias.h dsp.h sqsh_func.h cmd.h
+ sqsh_debug.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h sqsh_job.h \
+ sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h \
+ dsp.h sqsh_func.h cmd.h
cmd_return.o: cmd_return.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_cmd.h sqsh_avl.h sqsh_env.h sqsh_global.h \
- sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h \
- sqsh_alias.h dsp.h sqsh_func.h cmd.h
+ sqsh_debug.h sqsh_cmd.h sqsh_avl.h sqsh_env.h sqsh_global.h sqsh_job.h \
+ sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h \
+ dsp.h sqsh_func.h cmd.h
cmd_rpc.o: cmd_rpc.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h sqsh_job.h sqsh_args.h \
sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h dsp.h \
sqsh_func.h sqsh_expand.h sqsh_error.h sqsh_getopt.h sqsh_sig.h \
sqsh_stdin.h cmd.h
+cmd_run.o: cmd_run.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
+ sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h sqsh_job.h sqsh_args.h \
+ sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h dsp.h \
+ sqsh_func.h sqsh_error.h sqsh_getopt.h sqsh_readline.h sqsh_stdin.h \
+ cmd.h cmd_misc.h cmd_input.h
cmd_set.o: cmd_set.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
- sqsh_error.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h \
- sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h \
- sqsh_alias.h dsp.h sqsh_func.h cmd.h
+ sqsh_error.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h sqsh_job.h \
+ sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h \
+ dsp.h sqsh_func.h cmd.h
cmd_shell.o: cmd_shell.c sqsh_config.h config.h sqsh_compat.h \
sqsh_debug.h sqsh_error.h sqsh_varbuf.h sqsh_global.h sqsh_env.h \
sqsh_cmd.h sqsh_avl.h sqsh_job.h sqsh_args.h sqsh_sigcld.h \
sqsh_history.h sqsh_alias.h dsp.h sqsh_func.h cmd.h
-cmd_show.o: cmd_show.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h sqsh_global.h sqsh_env.h sqsh_cmd.h \
- sqsh_avl.h sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h \
- sqsh_history.h sqsh_alias.h dsp.h sqsh_func.h cmd.h
+cmd_show.o: cmd_show.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
+ sqsh_error.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h sqsh_job.h \
+ sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h \
+ dsp.h sqsh_func.h cmd.h
cmd_sleep.o: cmd_sleep.c sqsh_config.h config.h sqsh_compat.h \
sqsh_debug.h sqsh_cmd.h sqsh_avl.h cmd.h sqsh_varbuf.h
-cmd_wait.o: cmd_wait.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h sqsh_global.h sqsh_env.h sqsh_cmd.h \
- sqsh_avl.h sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h \
- sqsh_history.h sqsh_alias.h dsp.h sqsh_func.h sqsh_stdin.h cmd.h
+cmd_wait.o: cmd_wait.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
+ sqsh_error.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h sqsh_job.h \
+ sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h \
+ dsp.h sqsh_func.h sqsh_stdin.h cmd.h
cmd_warranty.o: cmd_warranty.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h \
- sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h \
- sqsh_alias.h dsp.h sqsh_func.h cmd.h
+ sqsh_debug.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h sqsh_job.h \
+ sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h \
+ dsp.h sqsh_func.h cmd.h
cmd_while.o: cmd_while.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h \
- sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h \
- sqsh_alias.h dsp.h sqsh_func.h sqsh_expand.h sqsh_error.h sqsh_sig.h \
- sqsh_getopt.h sqsh_buf.h sqsh_stdin.h sqsh_readline.h sqsh_tok.h \
- cmd.h cmd_misc.h cmd_input.h
+ sqsh_debug.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h sqsh_job.h \
+ sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h \
+ dsp.h sqsh_func.h sqsh_expand.h sqsh_error.h sqsh_sig.h sqsh_getopt.h \
+ sqsh_buf.h sqsh_stdin.h sqsh_readline.h sqsh_tok.h cmd.h cmd_misc.h \
+ cmd_input.h
+dsp_bcp.o: dsp_bcp.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
+ sqsh_error.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h sqsh_job.h \
+ sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h \
+ dsp.h sqsh_func.h
dsp.o: dsp.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h sqsh_job.h sqsh_args.h \
sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h dsp.h \
sqsh_func.h sqsh_error.h sqsh_sig.h
-dsp_bcp.o: dsp_bcp.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
- sqsh_error.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h \
- sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h \
- sqsh_alias.h dsp.h sqsh_func.h
+dsp_conv.o: dsp_conv.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
+ sqsh_error.h dsp.h
dsp_csv.o: dsp_csv.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
- sqsh_error.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h \
- sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h \
- sqsh_alias.h dsp.h sqsh_func.h
-dsp_conv.o: dsp_conv.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h dsp.h
-dsp_desc.o: dsp_desc.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h sqsh_global.h sqsh_env.h sqsh_cmd.h \
- sqsh_avl.h sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h \
- sqsh_history.h sqsh_alias.h dsp.h sqsh_func.h
+ sqsh_error.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h sqsh_job.h \
+ sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h \
+ dsp.h sqsh_func.h
+dsp_desc.o: dsp_desc.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
+ sqsh_error.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h sqsh_job.h \
+ sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h \
+ dsp.h sqsh_func.h
dsp_horiz.o: dsp_horiz.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h sqsh_global.h sqsh_env.h sqsh_cmd.h \
- sqsh_avl.h sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h \
- sqsh_history.h sqsh_alias.h dsp.h sqsh_func.h
-dsp_html.o: dsp_html.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h sqsh_global.h sqsh_env.h sqsh_cmd.h \
- sqsh_avl.h sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h \
- sqsh_history.h sqsh_alias.h dsp.h sqsh_func.h
-dsp_meta.o: dsp_meta.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h dsp.h
-dsp_none.o: dsp_none.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h sqsh_global.h sqsh_env.h sqsh_cmd.h \
- sqsh_avl.h sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h \
- sqsh_history.h sqsh_alias.h dsp.h sqsh_func.h
-dsp_out.o: dsp_out.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
- sqsh_error.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h \
+ sqsh_debug.h sqsh_error.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h \
sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h \
sqsh_alias.h dsp.h sqsh_func.h
+dsp_html.o: dsp_html.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
+ sqsh_error.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h sqsh_job.h \
+ sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h \
+ dsp.h sqsh_func.h
+dsp_meta.o: dsp_meta.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
+ sqsh_error.h dsp.h
+dsp_none.o: dsp_none.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
+ sqsh_error.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h sqsh_job.h \
+ sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h \
+ dsp.h sqsh_func.h
+dsp_out.o: dsp_out.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
+ sqsh_error.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h sqsh_job.h \
+ sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h \
+ dsp.h sqsh_func.h
dsp_pretty.o: dsp_pretty.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h sqsh_global.h sqsh_env.h sqsh_cmd.h \
- sqsh_avl.h sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h \
- sqsh_history.h sqsh_alias.h dsp.h sqsh_func.h
-dsp_vert.o: dsp_vert.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h sqsh_global.h sqsh_env.h sqsh_cmd.h \
- sqsh_avl.h sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h \
- sqsh_history.h sqsh_alias.h dsp.h sqsh_func.h
-dsp_x.o: dsp_x.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
- sqsh_error.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h \
+ sqsh_debug.h sqsh_error.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h \
sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h \
sqsh_alias.h dsp.h sqsh_func.h
+dsp_vert.o: dsp_vert.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
+ sqsh_error.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h sqsh_job.h \
+ sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h \
+ dsp.h sqsh_func.h
+dsp_x.o: dsp_x.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
+ sqsh_error.h sqsh_expand.h sqsh_varbuf.h sqsh_global.h sqsh_env.h \
+ sqsh_cmd.h sqsh_avl.h sqsh_job.h sqsh_args.h sqsh_sigcld.h \
+ sqsh_history.h sqsh_alias.h dsp.h sqsh_func.h sqsh_init.h
sqsh_alias.o: sqsh_alias.c sqsh_config.h config.h sqsh_compat.h \
sqsh_debug.h sqsh_error.h sqsh_alias.h sqsh_varbuf.h sqsh_avl.h
sqsh_args.o: sqsh_args.c sqsh_config.h config.h sqsh_compat.h \
sqsh_debug.h sqsh_error.h sqsh_args.h
-sqsh_avl.o: sqsh_avl.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h sqsh_avl.h
-sqsh_buf.o: sqsh_buf.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h \
- sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h \
- sqsh_alias.h dsp.h sqsh_func.h sqsh_error.h sqsh_stdin.h sqsh_buf.h
-sqsh_cmd.o: sqsh_cmd.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h sqsh_avl.h sqsh_cmd.h
+sqsh_avl.o: sqsh_avl.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
+ sqsh_error.h sqsh_avl.h
+sqsh_buf.o: sqsh_buf.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
+ sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h sqsh_job.h sqsh_args.h \
+ sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h dsp.h \
+ sqsh_func.h sqsh_error.h sqsh_stdin.h sqsh_buf.h sqsh_readline.h
+sqsh_cmd.o: sqsh_cmd.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
+ sqsh_error.h sqsh_avl.h sqsh_cmd.h
sqsh_compat.o: sqsh_compat.c sqsh_config.h config.h sqsh_compat.h \
sqsh_debug.h sqsh_error.h sqsh_sig.h
-sqsh_ctx.o: sqsh_ctx.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h sqsh_ctx.h sqsh_varbuf.h dsp.h
sqsh_debug.o: sqsh_debug.c sqsh_config.h config.h sqsh_compat.h \
sqsh_debug.h sqsh_error.h
-sqsh_env.o: sqsh_env.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h sqsh_env.h
+sqsh_env.o: sqsh_env.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
+ sqsh_error.h sqsh_env.h
sqsh_error.o: sqsh_error.c sqsh_config.h config.h sqsh_compat.h \
sqsh_debug.h sqsh_error.h
sqsh_expand.o: sqsh_expand.c sqsh_config.h config.h sqsh_compat.h \
sqsh_debug.h sqsh_error.h sqsh_varbuf.h sqsh_env.h sqsh_global.h \
sqsh_cmd.h sqsh_avl.h sqsh_job.h sqsh_args.h sqsh_sigcld.h \
sqsh_history.h sqsh_alias.h dsp.h sqsh_func.h sqsh_fd.h sqsh_expand.h \
- sqsh_strchr.h sqsh_sig.h
+ sqsh_strchr.h sqsh_sig.h sqsh_readline.h
sqsh_fd.o: sqsh_fd.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
- sqsh_sigcld.h sqsh_env.h sqsh_global.h sqsh_cmd.h sqsh_avl.h \
- sqsh_job.h sqsh_args.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h \
- dsp.h sqsh_func.h sqsh_error.h sqsh_fd.h
+ sqsh_sigcld.h sqsh_env.h sqsh_global.h sqsh_cmd.h sqsh_avl.h sqsh_job.h \
+ sqsh_args.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h dsp.h sqsh_func.h \
+ sqsh_error.h sqsh_fd.h
sqsh_filter.o: sqsh_filter.c sqsh_config.h config.h sqsh_compat.h \
sqsh_debug.h sqsh_fd.h sqsh_sig.h sqsh_varbuf.h sqsh_error.h \
sqsh_filter.h
sqsh_fork.o: sqsh_fork.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h \
- sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h \
- sqsh_alias.h dsp.h sqsh_func.h sqsh_error.h sqsh_fork.h
+ sqsh_debug.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h sqsh_job.h \
+ sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h \
+ dsp.h sqsh_func.h sqsh_error.h sqsh_fork.h
sqsh_func.o: sqsh_func.c sqsh_config.h config.h sqsh_compat.h \
sqsh_debug.h sqsh_error.h sqsh_avl.h sqsh_func.h
sqsh_getopt.o: sqsh_getopt.c sqsh_config.h config.h sqsh_compat.h \
@@ -458,34 +460,35 @@ sqsh_getopt.o: sqsh_getopt.c sqsh_config.h config.h sqsh_compat.h \
sqsh_cmd.h sqsh_avl.h sqsh_job.h sqsh_args.h sqsh_sigcld.h \
sqsh_history.h sqsh_alias.h dsp.h sqsh_func.h sqsh_getopt.h
sqsh_global.o: sqsh_global.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h \
- sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h \
- sqsh_alias.h dsp.h sqsh_func.h
+ sqsh_debug.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h sqsh_job.h \
+ sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h \
+ dsp.h sqsh_func.h
sqsh_history.o: sqsh_history.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h sqsh_history.h sqsh_varbuf.h
+ sqsh_debug.h sqsh_error.h sqsh_expand.h sqsh_varbuf.h sqsh_global.h \
+ sqsh_env.h sqsh_cmd.h sqsh_avl.h sqsh_job.h sqsh_args.h sqsh_sigcld.h \
+ sqsh_history.h sqsh_alias.h dsp.h sqsh_func.h
sqsh_init.o: sqsh_init.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h sqsh_global.h sqsh_env.h sqsh_cmd.h \
- sqsh_avl.h sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h \
- sqsh_history.h sqsh_alias.h dsp.h sqsh_func.h sqsh_expand.h \
- sqsh_readline.h sqsh_stdin.h sqsh_init.h cmd.h var.h alias.h
-sqsh_job.o: sqsh_job.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h sqsh_fd.h sqsh_tok.h sqsh_varbuf.h \
- sqsh_cmd.h sqsh_avl.h sqsh_global.h sqsh_env.h sqsh_job.h sqsh_args.h \
- sqsh_sigcld.h sqsh_history.h sqsh_alias.h dsp.h sqsh_func.h \
- sqsh_fork.h sqsh_expand.h sqsh_strchr.h sqsh_getopt.h sqsh_sig.h
+ sqsh_debug.h sqsh_error.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h \
+ sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h \
+ sqsh_alias.h dsp.h sqsh_func.h sqsh_expand.h sqsh_readline.h \
+ sqsh_stdin.h sqsh_init.h cmd.h var.h alias.h
+sqsh_job.o: sqsh_job.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
+ sqsh_error.h sqsh_fd.h sqsh_init.h sqsh_tok.h sqsh_varbuf.h sqsh_cmd.h \
+ sqsh_avl.h sqsh_global.h sqsh_env.h sqsh_job.h sqsh_args.h sqsh_sigcld.h \
+ sqsh_history.h sqsh_alias.h dsp.h sqsh_func.h sqsh_fork.h sqsh_expand.h \
+ sqsh_strchr.h sqsh_getopt.h sqsh_sig.h
sqsh_main.o: sqsh_main.c sqsh_config.h config.h sqsh_compat.h \
sqsh_debug.h sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_error.h \
sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h sqsh_varbuf.h \
- sqsh_history.h sqsh_alias.h dsp.h sqsh_func.h sqsh_getopt.h \
- sqsh_init.h sqsh_fd.h sqsh_readline.h sqsh_expand.h sqsh_sig.h \
- sqsh_stdin.h cmd.h
+ sqsh_history.h sqsh_alias.h dsp.h sqsh_func.h sqsh_getopt.h sqsh_init.h \
+ sqsh_fd.h sqsh_readline.h sqsh_expand.h sqsh_sig.h sqsh_stdin.h cmd.h
sqsh_readline.o: sqsh_readline.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h sqsh_global.h sqsh_env.h sqsh_cmd.h \
- sqsh_avl.h sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h \
- sqsh_history.h sqsh_alias.h dsp.h sqsh_func.h sqsh_stdin.h \
- sqsh_readline.h
-sqsh_sig.o: sqsh_sig.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h sqsh_sig.h
+ sqsh_debug.h sqsh_env.h sqsh_error.h sqsh_expand.h sqsh_varbuf.h \
+ sqsh_global.h sqsh_cmd.h sqsh_avl.h sqsh_job.h sqsh_args.h sqsh_sigcld.h \
+ sqsh_history.h sqsh_alias.h dsp.h sqsh_func.h sqsh_init.h \
+ sqsh_readline.h sqsh_stdin.h sqsh_parser/sqsh_parser.h
+sqsh_sig.o: sqsh_sig.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
+ sqsh_error.h sqsh_sig.h
sqsh_sigcld.o: sqsh_sigcld.c sqsh_config.h config.h sqsh_compat.h \
sqsh_debug.h sqsh_error.h sqsh_sig.h sqsh_sigcld.h
sqsh_stdin.o: sqsh_stdin.c sqsh_config.h config.h sqsh_compat.h \
@@ -496,37 +499,39 @@ sqsh_strchr.o: sqsh_strchr.c sqsh_config.h config.h sqsh_compat.h \
sqsh_debug.h sqsh_strchr.h sqsh_error.h
sqsh_test.o: sqsh_test.c sqsh_config.h config.h sqsh_compat.h \
sqsh_debug.h sqsh_varbuf.h sqsh_filter.h
-sqsh_tok.o: sqsh_tok.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_error.h sqsh_tok.h sqsh_varbuf.h
+sqsh_tok.o: sqsh_tok.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
+ sqsh_error.h sqsh_tok.h sqsh_varbuf.h
sqsh_varbuf.o: sqsh_varbuf.c sqsh_config.h config.h sqsh_compat.h \
sqsh_debug.h sqsh_varbuf.h sqsh_error.h
var_ctlib.o: var_ctlib.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h \
- sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h \
- sqsh_alias.h dsp.h sqsh_func.h sqsh_error.h sqsh_fd.h var.h
-var_date.o: var_date.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_env.h sqsh_error.h sqsh_global.h sqsh_cmd.h \
- sqsh_avl.h sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h \
- sqsh_history.h sqsh_alias.h dsp.h sqsh_func.h var.h
+ sqsh_debug.h sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h sqsh_job.h \
+ sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h \
+ dsp.h sqsh_func.h sqsh_error.h sqsh_fd.h var.h sqsh_expand.h
+var_date.o: var_date.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
+ sqsh_env.h sqsh_error.h sqsh_global.h sqsh_cmd.h sqsh_avl.h sqsh_job.h \
+ sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h \
+ dsp.h sqsh_func.h var.h
var_debug.o: var_debug.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_env.h sqsh_error.h sqsh_global.h sqsh_cmd.h \
- sqsh_avl.h sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h \
- sqsh_history.h sqsh_alias.h dsp.h sqsh_func.h var.h
+ sqsh_debug.h sqsh_env.h sqsh_error.h sqsh_global.h sqsh_cmd.h sqsh_avl.h \
+ sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h \
+ sqsh_alias.h dsp.h sqsh_func.h var.h
var_dsp.o: var_dsp.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
sqsh_global.h sqsh_env.h sqsh_cmd.h sqsh_avl.h sqsh_job.h sqsh_args.h \
sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h dsp.h \
sqsh_func.h sqsh_error.h sqsh_fd.h var.h
-var_hist.o: var_hist.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_env.h sqsh_error.h sqsh_global.h sqsh_cmd.h \
+var_hist.o: var_hist.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
+ sqsh_env.h sqsh_error.h sqsh_global.h sqsh_cmd.h sqsh_avl.h sqsh_job.h \
+ sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h \
+ dsp.h sqsh_func.h var.h
+var_misc.o: var_misc.c sqsh_config.h config.h sqsh_compat.h sqsh_debug.h \
+ sqsh_env.h sqsh_error.h sqsh_stdin.h var.h sqsh_global.h sqsh_cmd.h \
sqsh_avl.h sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h \
- sqsh_history.h sqsh_alias.h dsp.h sqsh_func.h var.h
-var_misc.o: var_misc.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_env.h sqsh_error.h sqsh_stdin.h var.h
+ sqsh_history.h sqsh_alias.h dsp.h sqsh_func.h sqsh_fd.h sqsh_expand.h
var_passwd.o: var_passwd.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_env.h sqsh_global.h sqsh_cmd.h sqsh_avl.h \
- sqsh_job.h sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h \
- sqsh_alias.h dsp.h sqsh_func.h sqsh_error.h var.h
+ sqsh_debug.h sqsh_env.h sqsh_global.h sqsh_cmd.h sqsh_avl.h sqsh_job.h \
+ sqsh_args.h sqsh_sigcld.h sqsh_varbuf.h sqsh_history.h sqsh_alias.h \
+ dsp.h sqsh_func.h sqsh_error.h var.h
var_readline.o: var_readline.c sqsh_config.h config.h sqsh_compat.h \
- sqsh_debug.h sqsh_env.h sqsh_error.h var.h
+ sqsh_debug.h sqsh_env.h sqsh_error.h sqsh_readline.h var.h
var_thresh.o: var_thresh.c sqsh_config.h config.h sqsh_compat.h \
sqsh_debug.h sqsh_env.h sqsh_error.h var.h
diff --git a/src/cmd.h b/src/cmd.h
index ade19d9..0662345 100644
--- a/src/cmd.h
+++ b/src/cmd.h
@@ -96,6 +96,10 @@ int cmd_return _ANSI_ARGS(( int, char** )) ;
int cmd_break _ANSI_ARGS(( int, char** )) ;
int cmd_for _ANSI_ARGS(( int, char** )) ;
int cmd_snace _ANSI_ARGS(( int, char** )) ;
+int cmd_run _ANSI_ARGS(( int, char** )) ;
+int cmd_lcd _ANSI_ARGS(( int, char** )) ; /* sqsh-2.5 local change dir */
+int cmd_pwd _ANSI_ARGS(( int, char** )) ; /* sqsh-2.5 show current dir */
+int cmd_ls _ANSI_ARGS(( int, char** )) ; /* sqsh-2.5 list files in current dir */
#ifdef SQSH_INIT
/*
@@ -164,6 +168,10 @@ static cmd_entry_t sg_cmd_entry[] = {
{ "\\buf-append",NULL, cmd_buf_append },
{ "\\buf-del", NULL, cmd_buf_del }, /* sqsh-2.1.6 feature */
{ "\\snace", NULL, cmd_snace }, /* sqsh-2.1.7 */
+ { "\\run", NULL, cmd_run }, /* sqsh-2.5 */
+ { "\\lcd", NULL, cmd_lcd }, /* sqsh-2.5 */
+ { "\\pwd", NULL, cmd_pwd }, /* sqsh-2.5 */
+ { "\\ls", NULL, cmd_ls }, /* sqsh-2.5 */
{ ":r", NULL, cmd_buf_load },
{ "vi", NULL, cmd_buf_edit },
{ "emacs", NULL, cmd_buf_edit },
diff --git a/src/cmd_bcp.c b/src/cmd_bcp.c
index 0c56b76..9f50f34 100644
--- a/src/cmd_bcp.c
+++ b/src/cmd_bcp.c
@@ -24,6 +24,7 @@
*/
#include <stdio.h>
#include <ctpublic.h>
+#include <ctype.h>
#include <bkpublic.h>
#include "sqsh_config.h"
#include "sqsh_global.h"
@@ -39,7 +40,7 @@
/*-- Current Version --*/
#if !defined(lint) && !defined(__LINT__)
-static char RCS_Id[] = "$Id: cmd_bcp.c,v 1.10 2010/03/28 11:46:05 mpeppler Exp $";
+static char RCS_Id[] = "$Id: cmd_bcp.c,v 1.21 2014/04/04 08:22:38 mwesdorp Exp $";
USE(RCS_Id)
#endif /* !defined(lint) */
@@ -54,12 +55,18 @@ USE(RCS_Id)
/*
* sg_interrupted: This variable is set by the bcp_signal() signal
- * handler and is to be polled periodically to determine if
+ * handler and is to be polled periodically to determine if
* a signal has been recieved.
*/
static int sg_interrupted = False;
/*
+ * sg_error: This variable is set by the callback functions and is
+ * used when the init command returns an error.
+ */
+static int sg_error = False;
+
+/*
* sg_bcp_connection: This variable is used by the signal handler
* to determine which connection needs to be canceled.
*/
@@ -112,20 +119,29 @@ static void bcp_signal _ANSI_ARGS(( int, void* ));
static bcp_data_t* bcp_data_bind _ANSI_ARGS(( CS_COMMAND*, CS_INT ));
static CS_INT bcp_data_xfer _ANSI_ARGS(( bcp_data_t*, CS_COMMAND*, CS_BLKDESC* ));
static void bcp_data_destroy _ANSI_ARGS(( bcp_data_t* ));
-static CS_RETCODE bcp_server_cb
+static CS_RETCODE bcp_server_cb
_ANSI_ARGS(( CS_CONTEXT*, CS_CONNECTION*, CS_SERVERMSG* ))
-#if defined(_CYGWIN32_)
+#if defined(__CYGWIN__)
__attribute__ ((stdcall))
-#endif /* _CYGWIN32_ */
+#endif /* __CYGWIN__ */
;
static CS_RETCODE bcp_client_cb
_ANSI_ARGS(( CS_CONTEXT*, CS_CONNECTION*, CS_CLIENTMSG* ))
-#if defined(_CYGWIN32_)
+#if defined(__CYGWIN__)
__attribute__ ((stdcall))
-#endif /* _CYGWIN32_ */
+#endif /* __CYGWIN__ */
;
+#if defined(CS_SSLVALIDATE_CB)
+static CS_RETCODE validate_srvname_cb
+ _ANSI_ARGS(( CS_VOID*, CS_SSLCERT*, CS_INT, CS_INT ))
+#if defined(__CYGWIN__)
+ __attribute__ ((stdcall))
+#endif /* __CYGWIN__ */
+ ;
+#endif
+
int cmd_bcp( argc, argv )
int argc ;
char *argv[] ;
@@ -144,6 +160,8 @@ int cmd_bcp( argc, argv )
extern char* sqsh_optarg; /* Value of option */
int opt; /* Current option */
char *bcp_table; /* Table to bcp into */
+ char *bcp_partition; /* Partition name to bcp into */
+ int bcp_slicenum; /* Partition number to bcp into */
char *cmd_sql; /* SQL command to send to server */
int rows_in_batch; /* Rows processed in batch */
int total_rows; /* Total rows processing */
@@ -157,6 +175,7 @@ int cmd_bcp( argc, argv )
CS_BOOL bcp_on = CS_TRUE; /* Flag to turn on bulk login */
CS_INT i;
CS_INT con_status;
+ char *cp;
/*
* The following variables need to be initialized to check if
@@ -183,6 +202,17 @@ int cmd_bcp( argc, argv )
int batchsize = -1; /* Copy all rows in one batch */
int have_error = False;
CS_BOOL have_identity = CS_FALSE;
+#if defined (CS_NOCHARSETCNV_REQD) && defined (BLK_CONV)
+ CS_BOOL char_convert = CS_FALSE; /* Used with -T option (transit) */
+ CS_BOOL transit = CS_FALSE; /* Disable client character conversion */
+#endif
+
+ /*
+ * sqsh-2.1.9 - Feature BCP execute an initialization command
+ */
+ char *init_cmd = NULL; /* BCP init command option */
+ CS_COMMAND *bcp_cmd_init = NULL; /* Command sent to server */
+ CS_RETCODE retcode; /* return code */
/*
* Retrieve value of variables used to configure the connection.
@@ -199,16 +229,16 @@ int cmd_bcp( argc, argv )
env_get( g_env, "hostname", &hostname );
env_get( g_env, "packet_size", &packet_size );
- while ((opt = sqsh_getopt( argc, argv, "A:b:I:J:m:NP;S:U:Xz:" )) != EOF)
+ while ((opt = sqsh_getopt( argc, argv, "A:b:I:i:J:m:NP;S:TU:Xz:" )) != EOF)
{
- switch (opt)
+ switch (opt)
{
case 'A':
packet_size = sqsh_optarg;
break;
case 'b':
- if ((batchsize = atoi(sqsh_optarg)) <= 0)
+ if ((batchsize = atoi(sqsh_optarg)) <= 0)
{
fprintf(stderr, "\\bcp: -b: Invalid value '%s'\n", sqsh_optarg);
return CMD_FAIL;
@@ -223,18 +253,22 @@ int cmd_bcp( argc, argv )
}
break;
+ case 'i' :
+ init_cmd = sqsh_optarg;
+ break;
+
case 'J' :
charset = sqsh_optarg;
break;
case 'm':
- if ((maxerrors = atoi(sqsh_optarg)) <= 0)
+ if ((maxerrors = atoi(sqsh_optarg)) <= 0)
{
fprintf(stderr, "\\bcp: -m: Invalid value '%s'\n", sqsh_optarg);
return CMD_FAIL;
}
break;
-
+
case 'N':
have_identity = CS_TRUE;
break;
@@ -247,7 +281,16 @@ int cmd_bcp( argc, argv )
server = sqsh_optarg;
break;
- case 'U' :
+ case 'T' :
+#if defined (CS_NOCHARSETCNV_REQD) && defined (BLK_CONV)
+ transit = CS_TRUE;
+#else
+ fprintf(stderr, "\\bcp: -T: Transit option is not supported by bulkcopy library\n");
+ fprintf(stderr, "\\bcp: -T: Parameter will be ignored\n");
+#endif
+ break;
+
+ case 'U' :
username = sqsh_optarg;
break;
@@ -267,15 +310,15 @@ int cmd_bcp( argc, argv )
/*
* If there isn't a table name left on the command line, or an
- * invalid argument was supplied, then print out usage
+ * invalid argument was supplied, then print out usage
* information.
*/
- if ((argc - sqsh_optind) != 1 || have_error)
+ if ((argc - sqsh_optind) != 1 || have_error)
{
- fprintf(stderr,
- "Use: \\bcp [-A packsetsize] [-b batchsize] [-I interfaces]\n"
+ fprintf(stderr,
+ "Use: \\bcp [-A packsetsize] [-b batchsize] [-I interfaces] [-i initcmd]\n"
" [-J charset] [-m maxerrors] [-N] [-P password]\n"
- " [-S server] [-U username] [-X] [-z language] table_name\n");
+ " [-S server] [-T] [-U username] [-X] [-z language] table_name\n");
return CMD_FAIL;
}
@@ -285,12 +328,21 @@ int cmd_bcp( argc, argv )
bcp_table = argv[sqsh_optind];
/*
+ * sqsh-2.2.0 - Feature enable BCP_IN into a specific partition of a partitioned table
+ */
+ if ((bcp_partition = strchr(bcp_table, (int) ':')) != NULL)
+ {
+ *bcp_partition++ = '\0';
+ }
+
+ /*
* Now, install our signal handlers. At this point, all code should
* perform a goto {return_fail or return_interrupt} to return an error
* condition. This is important in order to clean up the signal
* handlers and various other data structures created.
*/
sg_interrupted = False;
+ sg_error = False;
sg_bcp_connection = NULL;
sig_save();
@@ -302,20 +354,20 @@ int cmd_bcp( argc, argv )
* remote database (that we are bcp'ing too), lets launch our
* query and see if it is valid.
*/
- if (expand == NULL || *expand != '0')
+ if (expand == NULL || *expand != '0')
{
/*
* Temporarily create a buffer in which to store the expanded
* SQL buffer.
*/
- if ((exp_buf = varbuf_create(512)) == NULL)
+ if ((exp_buf = varbuf_create(512)) == NULL)
{
fprintf(stderr, "\\bcp: varbuf_create: %s\n", sqsh_get_errstr());
goto return_fail;
}
if (sqsh_expand( varbuf_getstr( g_sqlbuf ), exp_buf,
- EXP_STRIPESC|EXP_COMMENT|EXP_COLUMNS ) == False)
+ EXP_STRIPESC|EXP_COMMENT|EXP_COLUMNS ) == False)
{
fprintf(stderr, "\\bcp: sqsh_expand: %s\n", sqsh_get_errstr());
goto return_fail;
@@ -323,7 +375,7 @@ int cmd_bcp( argc, argv )
cmd_sql = varbuf_getstr( exp_buf );
- }
+ }
else
{
cmd_sql = varbuf_getstr( g_sqlbuf );
@@ -342,6 +394,27 @@ int cmd_bcp( argc, argv )
/*-- Find the appropriate BLK_VERSION_xxx value --*/
/*-- sqsh-2.1.7 - Make it compile with freetds-0.82 --*/
+ /*-- sqsh-2.1.9 - Added version BLK_VERSION_157 --*/
+ /*-- sqsh-2.5.16 - Added version BLK_VERSION_160 --*/
+#if defined(CS_VERSION_160)
+ if(blk_ver == -1 && g_cs_ver == CS_VERSION_160) {
+#if defined(BLK_VERSION_160)
+ blk_ver = BLK_VERSION_160;
+#else
+ blk_ver = BLK_VERSION_110;
+#endif
+ }
+#endif
+#if defined(CS_VERSION_157)
+ if(blk_ver == -1 && g_cs_ver == CS_VERSION_157) {
+#if defined(BLK_VERSION_157)
+ blk_ver = BLK_VERSION_157;
+#else
+ blk_ver = BLK_VERSION_110;
+#endif
+ }
+#endif
+
#if defined(CS_VERSION_155)
if(blk_ver == -1 && g_cs_ver == CS_VERSION_155) {
#if defined(BLK_VERSION_155)
@@ -402,6 +475,9 @@ int cmd_bcp( argc, argv )
goto return_fail;
}
+ /* sqsh-2.5 - Feature p2f, reset g_p2fc before a new batch is started */
+ g_p2fc = 0;
+
/*-- Send command to server --*/
if (ct_send( bcp_cmd ) != CS_SUCCEED)
{
@@ -411,7 +487,7 @@ int cmd_bcp( argc, argv )
if (sg_interrupted)
goto return_interrupt;
-
+
/*
* If we have reached this point, then everything looks like it
* went OK, so it is now time to create a new connection to the
@@ -441,7 +517,7 @@ int cmd_bcp( argc, argv )
CS_SERVERMSG_CB, /* Type */
(CS_VOID*)bcp_server_cb /* Callback Pointer */
) != CS_SUCCEED)
- goto return_fail;
+ goto return_fail;
/*-- Set Bulk Login --*/
if (ct_con_props( bcp_con, /* Connection */
@@ -450,7 +526,7 @@ int cmd_bcp( argc, argv )
(CS_VOID*)&bcp_on, /* Buffer */
CS_UNUSED, /* Buffer Lenth */
(CS_INT*)NULL /* Output Length */
- ) != CS_SUCCEED)
+ ) != CS_SUCCEED)
{
fprintf( stderr, "\\bcp: Unable to mark connection for BCP\n" );
goto return_fail;
@@ -463,9 +539,9 @@ int cmd_bcp( argc, argv )
(CS_VOID*)username, /* Buffer */
CS_NULLTERM, /* Buffer Lenth */
(CS_INT*)NULL /* Output Length */
- ) != CS_SUCCEED)
+ ) != CS_SUCCEED)
{
- fprintf( stderr,
+ fprintf( stderr,
"\\bcp: Unable to set username to '%s' for BCP connection\n",
username );
goto return_fail;
@@ -478,7 +554,7 @@ int cmd_bcp( argc, argv )
(CS_VOID*)password, /* Buffer */
(password == NULL)?CS_UNUSED:CS_NULLTERM,
(CS_INT*)NULL /* Output Length */
- ) != CS_SUCCEED)
+ ) != CS_SUCCEED)
{
fprintf( stderr, "\\bcp: Unable to set password BCP connection\n" );
goto return_fail;
@@ -491,9 +567,9 @@ int cmd_bcp( argc, argv )
(CS_VOID*)"sqsh-bcp", /* Buffer */
CS_NULLTERM, /* Buffer Lenth */
(CS_INT*)NULL /* Output Length */
- ) != CS_SUCCEED)
+ ) != CS_SUCCEED)
{
- fprintf( stderr,
+ fprintf( stderr,
"\\bcp: Unable to set appname to 'sqsh-bcp' for BCP connection\n" );
goto return_fail;
}
@@ -501,14 +577,14 @@ int cmd_bcp( argc, argv )
/*-- Hostname --*/
if (hostname != NULL && *hostname != '\0') {
if (ct_con_props( bcp_con, /* Connection */
- CS_SET, /* Action */
- CS_HOSTNAME, /* Property */
- (CS_VOID*)hostname, /* Buffer */
- CS_NULLTERM, /* Buffer Length */
- (CS_INT*)NULL /* Output Length */
- ) != CS_SUCCEED)
+ CS_SET, /* Action */
+ CS_HOSTNAME, /* Property */
+ (CS_VOID*)hostname, /* Buffer */
+ CS_NULLTERM, /* Buffer Length */
+ (CS_INT*)NULL /* Output Length */
+ ) != CS_SUCCEED)
{
- fprintf( stderr,
+ fprintf( stderr,
"\\bcp: Unable to set hostname to '%s' for BCP connection\n",
hostname );
goto return_fail;
@@ -519,15 +595,15 @@ int cmd_bcp( argc, argv )
if (packet_size != NULL) {
i = atoi(packet_size);
if (ct_con_props( bcp_con, /* Connection */
- CS_SET, /* Action */
- CS_PACKETSIZE, /* Property */
- (CS_VOID*)&i, /* Buffer */
- CS_UNUSED, /* Buffer Length */
- (CS_INT*)NULL /* Output Length */
- ) != CS_SUCCEED)
+ CS_SET, /* Action */
+ CS_PACKETSIZE, /* Property */
+ (CS_VOID*)&i, /* Buffer */
+ CS_UNUSED, /* Buffer Length */
+ (CS_INT*)NULL /* Output Length */
+ ) != CS_SUCCEED)
{
- fprintf( stderr,
- "\\bcp: Unable to set packetsize to %d for BCP connection\n",
+ fprintf( stderr,
+ "\\bcp: Unable to set packetsize to %d for BCP connection\n",
(int)i );
goto return_fail;
}
@@ -537,18 +613,61 @@ int cmd_bcp( argc, argv )
if (encryption != NULL && *encryption == '1') {
i = CS_TRUE;
if (ct_con_props( bcp_con, /* Connection */
- CS_SET, /* Action */
- CS_SEC_ENCRYPTION, /* Property */
- (CS_VOID*)&i, /* Buffer */
- CS_UNUSED, /* Buffer Length */
- (CS_INT*)NULL /* Output Length */
- ) != CS_SUCCEED)
+ CS_SET, /* Action */
+ CS_SEC_ENCRYPTION, /* Property */
+ (CS_VOID*)&i, /* Buffer */
+ CS_UNUSED, /* Buffer Length */
+ (CS_INT*)NULL /* Output Length */
+ ) != CS_SUCCEED)
+ {
+ fprintf( stderr,
+ "\\bcp: Unable to set password encryption for BCP connection\n" );
+ goto return_fail;
+ }
+
+#if defined (CS_SEC_EXTENDED_ENCRYPTION)
+ /*
+ * sqsh-2.1.9: Enable extended password encryption to be able to
+ * connect to ASE servers with 'net password encryption reqd'
+ * configured to 2 (RSA).
+ */
+ if (ct_con_props( bcp_con, /* Connection */
+ CS_SET, /* Action */
+ CS_SEC_EXTENDED_ENCRYPTION, /* Property */
+ (CS_VOID*)&i, /* Buffer */
+ CS_UNUSED, /* Buffer Length */
+ (CS_INT*)NULL /* Output Length */
+ ) != CS_SUCCEED)
+ {
+ fprintf( stderr,
+ "\\bcp: Unable to set extended password encryption for BCP connection\n" );
+ goto return_fail;
+ }
+#endif
+ }
+
+#if defined (CS_NOCHARSETCNV_REQD) && defined (BLK_CONV)
+ /*
+ * sqsh-2.2.0 - Disable character set conversion by client
+ * when in transit bulk transfer is requested (-T option)
+ */
+ if (transit == CS_TRUE)
+ {
+ char_convert = CS_TRUE;
+ if (ct_con_props( bcp_con, /* Connection */
+ CS_SET, /* Action */
+ CS_NOCHARSETCNV_REQD, /* Property */
+ (CS_VOID*)&char_convert, /* Buffer */
+ CS_UNUSED, /* Buffer Length */
+ (CS_INT*)NULL /* Output Length */
+ ) != CS_SUCCEED)
{
- fprintf( stderr,
- "\\bcp: Unable to set enable encryption for BCP connection\n" );
+ fprintf( stderr,
+ "\\bcp: Unable to set CS_NOCHARSETCONV_REQD for BCP connection\n" );
goto return_fail;
}
}
+#endif
/*
* The following section initializes all locale type information.
@@ -557,7 +676,7 @@ int cmd_bcp( argc, argv )
*/
if (cs_loc_alloc( g_context, &bcp_locale ) != CS_SUCCEED)
{
- fprintf( stderr,
+ fprintf( stderr,
"\\bcp: Unable to allocate locale for BCP connection\n" );
goto return_fail;
}
@@ -565,14 +684,14 @@ int cmd_bcp( argc, argv )
/*-- Initialize --*/
if (cs_locale( g_context, /* Context */
CS_SET, /* Action */
- bcp_locale, /* Locale Structure */
+ bcp_locale, /* Locale Structure */
CS_LC_ALL, /* Property */
- (CS_CHAR*)NULL, /* Buffer */
+ (CS_CHAR*)NULL, /* Buffer */
CS_UNUSED, /* Buffer Length */
(CS_INT*)NULL /* Output Length */
- ) != CS_SUCCEED)
+ ) != CS_SUCCEED)
{
- fprintf( stderr,
+ fprintf( stderr,
"\\bcp: Unable to initialize locale for BCP connection\n" );
goto return_fail;
}
@@ -582,13 +701,13 @@ int cmd_bcp( argc, argv )
if (cs_locale( g_context, /* Context */
CS_SET, /* Action */
bcp_locale, /* Locale Structure */
- CS_SYB_LANG, /* Property */
- (CS_CHAR*)language, /* Buffer */
- CS_NULLTERM, /* Buffer Length */
- (CS_INT*)NULL /* Output Length */
- ) != CS_SUCCEED)
+ CS_SYB_LANG, /* Property */
+ (CS_CHAR*)language, /* Buffer */
+ CS_NULLTERM, /* Buffer Length */
+ (CS_INT*)NULL /* Output Length */
+ ) != CS_SUCCEED)
{
- fprintf( stderr,
+ fprintf( stderr,
"\\bcp: Unable to set language to '%s' for BCP connection\n",
language );
goto return_fail;
@@ -600,13 +719,13 @@ int cmd_bcp( argc, argv )
if (cs_locale( g_context, /* Context */
CS_SET, /* Action */
bcp_locale, /* Locale Structure */
- CS_SYB_CHARSET, /* Property */
- (CS_CHAR*)charset, /* Buffer */
- CS_NULLTERM, /* Buffer Length */
- (CS_INT*)NULL /* Output Length */
- ) != CS_SUCCEED)
+ CS_SYB_CHARSET, /* Property */
+ (CS_CHAR*)charset, /* Buffer */
+ CS_NULLTERM, /* Buffer Length */
+ (CS_INT*)NULL /* Output Length */
+ ) != CS_SUCCEED)
{
- fprintf( stderr,
+ fprintf( stderr,
"\\bcp: Unable to set charset to '%s' for BCP connection\n",
charset );
goto return_fail;
@@ -615,17 +734,51 @@ int cmd_bcp( argc, argv )
/*-- Locale Property --*/
if (ct_con_props( bcp_con, /* Connection */
- CS_SET, /* Action */
- CS_LOC_PROP, /* Property */
- (CS_VOID*)bcp_locale, /* Buffer */
- CS_UNUSED, /* Buffer Length */
- (CS_INT*)NULL /* Output Length */
- ) != CS_SUCCEED)
+ CS_SET, /* Action */
+ CS_LOC_PROP, /* Property */
+ (CS_VOID*)bcp_locale, /* Buffer */
+ CS_UNUSED, /* Buffer Length */
+ (CS_INT*)NULL /* Output Length */
+ ) != CS_SUCCEED)
{
fprintf( stderr, "\\bcp: Unable to set locale for BCP connection\n" );
goto return_fail;
}
+#if defined(CS_SERVERADDR) && defined(CS_TDS_50)
+ if ( server != NULL && (cp = strchr(server, ':')) != NULL )
+ {
+ char *cp2;
+
+ *cp = ' ';
+ if ( (cp2 = strchr(cp+1, ':')) != NULL) /* Optional filter specified? */
+ *cp2 = ' ';
+
+ if (ct_con_props( bcp_con,
+ CS_SET,
+ CS_SERVERADDR,
+ (CS_VOID*)server,
+ CS_NULLTERM,
+ (CS_INT*)NULL
+ ) != CS_SUCCEED)
+ goto return_fail;
+
+ if (cp2 != NULL)
+ *cp2 = '\0'; /* Remove optional filter from the servername */
+ *cp = ':'; /* Put a ':' back into the display servername */
+
+#if defined(CS_SSLVALIDATE_CB)
+ if (ct_callback( g_context, /* Context */
+ (CS_CONNECTION*)NULL, /* Connection */
+ CS_SET, /* Action */
+ CS_SSLVALIDATE_CB, /* Type */
+ (CS_VOID*)validate_srvname_cb /* Callback Pointer */
+ ) != CS_SUCCEED)
+ goto return_fail;
+#endif
+ }
+#endif
+
/*-- Now, connect --*/
if (ct_connect( bcp_con,
server,
@@ -662,10 +815,37 @@ int cmd_bcp( argc, argv )
}
}
#endif /* CTLIB_SIGPOLL_BUG */
-
+
/*-- Inform signal handler of connection --*/
sg_bcp_connection = bcp_con;
+ /*
+ * sqsh-2.1.9 - Feature BCP execute an initialization command
+ * Process the initialization command provided in init_cmd
+ */
+ if (init_cmd != NULL)
+ {
+ if ((retcode = ct_cmd_alloc(bcp_con, &bcp_cmd_init)) != CS_SUCCEED || sg_error == True)
+ {
+ fprintf( stderr, "\\bcp: ct_cmd_alloc failed. (retcode=%d, sg_error=%d)\n", (int) retcode, sg_error );
+ goto return_fail;
+ }
+
+ if ((retcode = ct_command(bcp_cmd_init, CS_LANG_CMD, init_cmd, CS_NULLTERM, CS_UNUSED) != CS_SUCCEED) ||
+ sg_error == True)
+ {
+ fprintf( stderr, "\\bcp: ct_command() for init_cmd failed. (retcode=%d, sg_error=%d)\n",
+ (int) retcode, sg_error);
+ goto return_fail;
+ }
+
+ if ( dsp_cmd (stdout, bcp_cmd_init, init_cmd, 0) != DSP_SUCCEED || sg_error == True)
+ {
+ fprintf( stderr, "\\bcp: Execution of initialization command failed.\n");
+ goto return_fail;
+ }
+ }
+
/*-- Allocate a block descriptor --*/
DBG(sqsh_debug(DEBUG_BCP, "bcp: blk_alloc(blk_ver)\n");)
@@ -674,7 +854,7 @@ int cmd_bcp( argc, argv )
fprintf( stderr, "\\bcp: Unable to allocate bulk descriptor\n" );
goto return_fail;
}
-
+
/*
* Configure whether or not this connection is to contain the
* value for the identity column in a result set. We default
@@ -685,10 +865,10 @@ int cmd_bcp( argc, argv )
if (blk_props( bcp_desc, /* Descriptor */
CS_SET, /* Action */
BLK_IDENTITY, /* Property */
- (CS_VOID*)&have_identity, /* Buffer */
- CS_UNUSED, /* Buffer Length*/
+ (CS_VOID*)&have_identity, /* Buffer */
+ CS_UNUSED, /* Buffer Length*/
(CS_INT*)NULL /* Output Length */
- ) == CS_FAIL)
+ ) != CS_SUCCEED)
{
fprintf( stderr, "\\bcp: Unable to set BLK_IDENTITY option to %s\n",
have_identity == CS_TRUE ? "CS_TRUE" : "CS_FALSE" );
@@ -696,11 +876,79 @@ int cmd_bcp( argc, argv )
}
}
+#if defined (CS_NOCHARSETCNV_REQD) && defined (BLK_CONV)
+ /*
+ * sqsh-2.2.0 - Disable character set conversion by client
+ * when in transit bulk transfer is requested (-T option)
+ */
+ if (transit == CS_TRUE)
+ {
+ char_convert = CS_FALSE;
+ if (blk_props( bcp_desc, /* Descriptor */
+ CS_SET, /* Action */
+ BLK_CONV, /* Property */
+ (CS_VOID*)&char_convert, /* Buffer */
+ CS_UNUSED, /* Buffer Length*/
+ (CS_INT*)NULL /* Output Length */
+ ) != CS_SUCCEED)
+ {
+ fprintf( stderr, "\\bcp: Unable to set BLK_CONV option to CS_FALSE\n");
+ goto return_fail;
+ }
+ }
+#endif
+
+ /*
+ * sqsh-2.2.0 - Feature enable BCP_IN into a specific partition of a partitioned table
+ */
+ if (bcp_partition != NULL)
+ {
+ if (isdigit( (int) *bcp_partition))
+ {
+ bcp_slicenum = atoi (bcp_partition);
+#if defined (BLK_SLICENUM)
+ if (blk_props( bcp_desc, /* Descriptor */
+ CS_SET, /* Action */
+ BLK_SLICENUM, /* Property */
+ (CS_VOID*)&bcp_slicenum, /* Buffer */
+ CS_UNUSED, /* Buffer Length*/
+ (CS_INT*)NULL /* Output Length */
+ ) != CS_SUCCEED)
+ {
+ fprintf( stderr, "\\bcp: Unable to set BLK_SLICENUM option\n");
+ goto return_fail;
+ }
+#else
+ fprintf(stderr, "\\bcp: The build version of Bulk Library does not (fully) support table partitioning.\n");
+ fprintf(stderr, "\\bcp: The specified slice number '%d' will be ignored.\n", bcp_slicenum);
+#endif
+ }
+ else
+ {
+#if defined (BLK_PARTITION)
+ if (blk_props( bcp_desc, /* Descriptor */
+ CS_SET, /* Action */
+ BLK_PARTITION, /* Property */
+ (CS_VOID*)bcp_partition, /* Buffer */
+ strlen(bcp_partition), /* Buffer Length*/
+ (CS_INT*)NULL /* Output Length */
+ ) != CS_SUCCEED)
+ {
+ fprintf( stderr, "\\bcp: Unable to set BLK_PARTITION option\n");
+ goto return_fail;
+ }
+#else
+ fprintf(stderr, "\\bcp: The build version of Bulk Library does not (fully) support table partitioning.\n");
+ fprintf(stderr, "\\bcp: The specified partition name '%s' will be ignored.\n", bcp_partition);
+#endif
+ }
+ }
+
/*-- Initialize the bulk copy --*/
DBG(sqsh_debug(DEBUG_BCP, "bcp: blk_init(CS_BLK_IN,'%s',%d)\n",
bcp_table, strlen(bcp_table));)
- if (blk_init( bcp_desc, CS_BLK_IN, bcp_table,
+ if (blk_init( bcp_desc, CS_BLK_IN, bcp_table,
strlen(bcp_table) ) != CS_SUCCEED)
{
fprintf( stderr, "\\bcp: Unable to initialize bulk copy on table '%s'\n",
@@ -709,7 +957,7 @@ int cmd_bcp( argc, argv )
}
fprintf(stderr, "\nStarting copy...\n" );
-
+
/*
* Allrightythen. We have already sent the command to retrieve
* data through g_dbproc, and have succesfully created bcp_dbproc
@@ -724,7 +972,7 @@ int cmd_bcp( argc, argv )
{
if (sg_interrupted)
goto return_interrupt;
-
+
if (return_code != CS_SUCCEED)
break;
@@ -742,8 +990,8 @@ int cmd_bcp( argc, argv )
if ((bcp_dat = bcp_data_bind( bcp_cmd, result_type )) == NULL)
goto return_fail;
- while ((return_code =
- bcp_data_xfer( bcp_dat,
+ while ((return_code =
+ bcp_data_xfer( bcp_dat,
bcp_cmd,
bcp_desc )) != CS_END_DATA)
{
@@ -790,18 +1038,18 @@ int cmd_bcp( argc, argv )
}
} /* while (bcp_data_xfer()) */
break;
-
+
case CS_PARAM_RESULT:
case CS_STATUS_RESULT:
case CS_COMPUTE_RESULT:
- while ((return_code = ct_fetch( bcp_cmd, CS_UNUSED, CS_UNUSED,
+ while ((return_code = ct_fetch( bcp_cmd, CS_UNUSED, CS_UNUSED,
CS_UNUSED, &nrows )) == CS_SUCCEED);
-
+
if (return_code != CS_END_DATA)
{
fprintf( stderr,
"\\bcp: Error discarding extraneous result sets\n" );
-
+
goto return_fail;
}
break;
@@ -812,7 +1060,7 @@ int cmd_bcp( argc, argv )
}
- if (rows_in_batch > 0)
+ if (rows_in_batch > 0)
{
DBG(sqsh_debug(DEBUG_BCP, "bcp: FINAL: blk_done(CS_BLK_BATCH)\n");)
if (blk_done( bcp_desc,
@@ -825,9 +1073,9 @@ int cmd_bcp( argc, argv )
if (sg_interrupted)
goto return_interrupt;
- if (nrows != rows_in_batch)
+ if (nrows != rows_in_batch)
{
- if (++nerrors == maxerrors)
+ if (++nerrors == maxerrors)
goto return_fail;
}
total_rows += nrows;
@@ -840,11 +1088,11 @@ int cmd_bcp( argc, argv )
goto return_fail;
gettimeofday( &tv_end, NULL );
-
+
if (rows_in_batch != 0)
fprintf(stderr,"Batch successfully bulk-copied to SQL Server\n");
- fprintf( stderr, "\n%d row%s copied.\n", total_rows,
+ fprintf( stderr, "\n%d row%s copied.\n", total_rows,
(total_rows != 1) ? "s" : "" );
/* add check for non-zero number of rows passed to avoid
@@ -852,11 +1100,11 @@ int cmd_bcp( argc, argv )
patch by Onno van der Linden */
if(total_rows > 0) {
secs = ELAPSED_SEC(tv_start,tv_end);
- fprintf( stderr,
+ fprintf( stderr,
"Clock Time (sec.): Total = %-.4f Avg = %-.4f (%.2f rows per sec.)\n",
secs, secs / (double)total_rows, (double)total_rows / secs );
}
-
+
return_code = CMD_RESETBUF;
goto leave;
@@ -887,7 +1135,7 @@ return_fail:
/*-- If connected, disconnect --*/
if (con_status == CS_CONSTAT_CONNECTED)
- {
+ {
if (bcp_desc != NULL)
{
DBG(sqsh_debug(DEBUG_ERROR, "bcp: Cancelling bcp batch.\n");)
@@ -898,7 +1146,8 @@ return_fail:
ct_cancel( bcp_con, (CS_COMMAND*)NULL, CS_CANCEL_ALL );
DBG(sqsh_debug(DEBUG_ERROR, "bcp: Closing bcp connection.\n");)
- ct_close( bcp_con, CS_FORCE_CLOSE );
+ if (ct_close( bcp_con, CS_UNUSED ) != CS_SUCCEED)
+ ct_close( bcp_con, CS_FORCE_CLOSE );
}
ct_con_drop( bcp_con );
@@ -940,23 +1189,27 @@ leave:
if (bcp_cmd != NULL)
ct_cmd_drop( bcp_cmd );
-
+
+ if (bcp_cmd_init != NULL)
+ ct_cmd_drop( bcp_cmd_init );
+
if (bcp_desc != NULL)
{
DBG(sqsh_debug(DEBUG_BCP, "bcp: blk_drop()\n");)
blk_drop( bcp_desc );
}
-
+
if (bcp_con != NULL)
{
- ct_close( bcp_con, CS_FORCE_CLOSE );
+ if (ct_close( bcp_con, CS_UNUSED ) != CS_SUCCEED)
+ ct_close( bcp_con, CS_FORCE_CLOSE );
ct_con_drop( bcp_con );
}
if (bcp_locale != NULL)
cs_loc_drop( g_context, bcp_locale );
- sig_restore();
+ sig_restore();
return return_code;
}
@@ -984,7 +1237,7 @@ static bcp_data_t* bcp_data_bind ( cmd, result_type )
d = (bcp_data_t*)calloc( 1, sizeof( bcp_data_t ) );
c = (bcp_col_t*)calloc( ncols, sizeof( bcp_col_t ) );
- if (d == NULL || c == NULL)
+ if (d == NULL || c == NULL)
{
fprintf( stderr, "bcp_data_bind: Memory allocation failure.\n" );
if (d != NULL)
@@ -999,9 +1252,9 @@ static bcp_data_t* bcp_data_bind ( cmd, result_type )
d->d_ncols = ncols;
d->d_cols = c;
- for (i = 0; i < ncols; i++)
+ for (i = 0; i < ncols; i++)
d->d_cols[i].c_data = NULL;
-
+
for (i = 0; i < ncols; i++)
{
c = &d->d_cols[i];
@@ -1010,9 +1263,9 @@ static bcp_data_t* bcp_data_bind ( cmd, result_type )
c->c_nullind = 0;
/*-- Get description for column --*/
- if (ct_describe( cmd, i+1, &c->c_format ) != CS_SUCCEED)
+ if (ct_describe( cmd, i+1, &c->c_format ) != CS_SUCCEED)
{
- fprintf( stderr,
+ fprintf( stderr,
"bcp_data_bind: Unable to fetch column %d description\n",
(int) i+1 );
bcp_data_destroy( d );
@@ -1029,14 +1282,14 @@ static bcp_data_t* bcp_data_bind ( cmd, result_type )
/*-- Bind to the data space --*/
if (ct_bind( cmd, /* Command */
- i + 1, /* Item */
- &c->c_format, /* Format */
- (CS_VOID*)c->c_data, /* Buffer */
- (CS_INT*)&c->c_len, /* Data Copied */
- &c->c_nullind /* NULL Indicator */
- ) != CS_SUCCEED)
+ i + 1, /* Item */
+ &c->c_format, /* Format */
+ (CS_VOID*)c->c_data, /* Buffer */
+ (CS_INT*)&c->c_len, /* Data Copied */
+ &c->c_nullind /* NULL Indicator */
+ ) != CS_SUCCEED)
{
- fprintf( stderr,
+ fprintf( stderr,
"bcp_data_bind: Unable to bind column %d\n",
(int) i+1 );
bcp_data_destroy( d );
@@ -1062,7 +1315,7 @@ static CS_INT bcp_data_xfer( d, cmd, blkdesc )
CS_UNUSED, /* Offset */
CS_UNUSED, /* Option */
&nrows );
-
+
if (return_code != CS_SUCCEED)
{
return return_code;
@@ -1094,14 +1347,14 @@ static CS_INT bcp_data_xfer( d, cmd, blkdesc )
c->c_prevnullind = c->c_nullind;
if (blk_bind( blkdesc, /* Block Descriptor */
- i + 1, /* Column Number */
- &c->c_format, /* Data Format */
- (CS_VOID*)c->c_data, /* Buffer */
- &c->c_len, /* Buffer Length */
- &c->c_nullind ) != CS_SUCCEED)
+ i + 1, /* Column Number */
+ &c->c_format, /* Data Format */
+ (CS_VOID*)c->c_data, /* Buffer */
+ &c->c_len, /* Buffer Length */
+ &c->c_nullind ) != CS_SUCCEED)
{
- fprintf( stderr,
- "bcp_data_xfer: Unable to bind results for column %d\n",
+ fprintf( stderr,
+ "bcp_data_xfer: Unable to bind results for column %d\n",
(int) i+1 );
return CS_FAIL;
}
@@ -1111,7 +1364,7 @@ static CS_INT bcp_data_xfer( d, cmd, blkdesc )
DBG(sqsh_debug(DEBUG_BCP, "bcp: blk_rowxfer()\n");)
if (blk_rowxfer( blkdesc ) != CS_SUCCEED)
{
- fprintf( stderr,
+ fprintf( stderr,
"bcp_data_xfer: Unable to transfer row to remote SQL Server\n" );
return CS_FAIL;
}
@@ -1183,7 +1436,7 @@ static CS_RETCODE bcp_server_cb (ctx, con, msg)
* Ignore "database changed", or "language changed" messages from
* the server.
*/
- if( msg->msgnumber == 5701 || /* database context change */
+ if( msg->msgnumber == 5701 || /* database context change */
msg->msgnumber == 5703 || /* language changed */
msg->msgnumber == 5704 ) /* charset changed */
{
@@ -1196,12 +1449,12 @@ static CS_RETCODE bcp_server_cb (ctx, con, msg)
* If the severity is something other than 0 or the msg number is
* 0 (user informational messages).
*/
- if (msg->severity >= 0 || msg->msgnumber == 0)
+ if (msg->severity >= 0 || msg->msgnumber == 0)
{
/*
* If the message was something other than informational, and
* the severity was greater than 0, then print information to
- * stderr with a little pre-amble information. According to
+ * stderr with a little pre-amble information. According to
* the Sybase System Administrator's guide, severity level 10
* messages should not display severity information.
*/
@@ -1218,8 +1471,10 @@ static CS_RETCODE bcp_server_cb (ctx, con, msg)
fprintf( stderr, "\n" );
fprintf( stderr, "%s\n", msg->text );
fflush( stderr );
+
+ sg_error = True;
}
- else
+ else
{
/*
* Otherwise, it is just an informational (e.g. print) message
@@ -1261,5 +1516,31 @@ static CS_RETCODE bcp_client_cb ( ctx, con, msg )
fprintf( stderr, "%s\n", msg->msgstring );
fflush( stderr ) ;
+ sg_error = True;
+
return CS_SUCCEED ;
}
+
+#if defined(CS_SSLVALIDATE_CB)
+/*
+ * sqsh-2.5 - Validate the servername in a host:port:ssl type of connection
+ * to be valid for the chosen certificate if the servername does
+ * not match the CN in the certificate.
+ */
+static CS_RETCODE validate_srvname_cb (userdata, certptr, certcount, valid)
+ CS_VOID *userdata;
+ CS_SSLCERT *certptr;
+ CS_INT certcount;
+ CS_INT valid;
+{
+ if (valid == CS_SSL_INVALID_MISMATCHNAME)
+ {
+ return CS_SSL_VALID_CERT;
+ }
+ else
+ {
+ return valid;
+ }
+}
+#endif
+
diff --git a/src/cmd_buf.c b/src/cmd_buf.c
index 9435432..9a29d2f 100644
--- a/src/cmd_buf.c
+++ b/src/cmd_buf.c
@@ -34,11 +34,12 @@
#include "sqsh_buf.h"
#include "sqsh_stdin.h"
#include "sqsh_expand.h" /* sqsh-2.1.6 */
+#include "sqsh_init.h" /* sqsh-2.1.6 */
#include "cmd.h"
/*-- Current Version --*/
#if !defined(lint) && !defined(__LINT__)
-static char RCS_Id[] = "$Id: cmd_buf.c,v 1.4 2010/01/26 15:03:50 mwesdorp Exp $" ;
+static char RCS_Id[] = "$Id: cmd_buf.c,v 1.6 2013/04/18 11:54:43 mwesdorp Exp $" ;
USE(RCS_Id)
#endif /* !defined(lint) */
@@ -348,8 +349,8 @@ int cmd_buf_load( argc, argv )
* If we don't have any arguments on the command line, or we have too
* many arguments, then print usage.
*/
- if (have_error == True ||
- (argc - sqsh_optind) < 1 ||
+ if (have_error == True ||
+ (argc - sqsh_optind) < 1 ||
(argc - sqsh_optind) > 2)
{
fprintf( stderr, "\\buf-load [-a] filename [dest-buf]\n" );
@@ -409,7 +410,7 @@ int cmd_buf_show( argc, argv )
* structure. Oh well. Anyway, here I just blast through the
* hash table, displaying anything I run across.
*/
- count = 0 ;
+ count = 0 ;
for( i = 0; i < g_buf->env_hsize; i++ ) {
for( v = g_buf->env_htable[i]; v != NULL; v = v->var_nxt ) {
@@ -418,7 +419,7 @@ int cmd_buf_show( argc, argv )
line = v->var_value ;
while( (nl = strchr( line, '\n' )) != NULL ) {
- printf( " %*.*s\n", nl - line, nl - line, line ) ;
+ printf( " %*.*s\n", (int) (nl - line), (int) (nl - line), line ) ;
line = nl + 1 ;
}
@@ -434,9 +435,9 @@ int cmd_buf_show( argc, argv )
* If the user requested that we show a particular buffer and
* we couldn't find it, then print an error message.
*/
- if( buf_name != NULL && count == 0 ) {
- fprintf( stderr, "\\buf-show: Buffer %s does not exist\n", buf_name ) ;
- return CMD_FAIL ;
+ if( buf_name != NULL && count == 0 ) {
+ fprintf( stderr, "\\buf-show: Buffer %s does not exist\n", buf_name ) ;
+ return CMD_FAIL ;
}
return CMD_LEAVEBUF ;
@@ -459,7 +460,7 @@ int cmd_buf_edit( argc, argv )
extern char *sqsh_optarg ;
extern int sqsh_optind ;
int c ;
- varbuf_t *exp_buf; /* sqsh-2.1.6 feature */
+ varbuf_t *exp_buf = NULL; /* sqsh-2.1.6 feature */
/*
* The editor can only be run in interactive mode.
@@ -515,16 +516,16 @@ int cmd_buf_edit( argc, argv )
* Now, we need to make sure that the buffers that we want to read
* from and write to actually exist.
*/
- if (buf_can_put( write_buf ) == False)
+ if (buf_can_put( write_buf ) == False)
{
- fprintf( stderr, "\\buf-edit: %s\n", sqsh_get_errstr() );
- return CMD_FAIL;
+ fprintf( stderr, "\\buf-edit: %s\n", sqsh_get_errstr() );
+ return CMD_FAIL;
}
/*
* Attempt to retrieve the name of the editor from our environment.
*/
- if (strcmp(argv[0], "edit" ) == 0 ||
+ if (strcmp(argv[0], "edit" ) == 0 ||
strcmp(argv[0], "\\edit" ) == 0 ||
strcmp(argv[0], "\\buf-edit" ) == 0)
{
@@ -560,7 +561,8 @@ int cmd_buf_edit( argc, argv )
* the same program.
*/
sprintf( path, "%s/sqsh-edit.%d.sql", tmp_dir, (int)getpid() );
- varbuf_destroy( exp_buf ); /* sqsh-2.1.6 feature */
+ if (exp_buf != NULL)
+ varbuf_destroy( exp_buf ); /* sqsh-2.1.6 feature */
/*
* Attempt to save the read buffer into the file that we built.
@@ -581,7 +583,7 @@ int cmd_buf_edit( argc, argv )
/*
* Run the editor.
*/
- system(str);
+ c = system(str);
if (buf_load( write_buf, path, False ) == False)
{
diff --git a/src/cmd_connect.c b/src/cmd_connect.c
index 0805abf..e1d35cb 100644
--- a/src/cmd_connect.c
+++ b/src/cmd_connect.c
@@ -24,8 +24,10 @@
*/
#include <stdio.h>
#include <ctype.h>
+#include <setjmp.h>
#include <ctpublic.h>
#include "sqsh_config.h"
+#include "sqsh_debug.h"
#include "sqsh_error.h"
#include "sqsh_global.h"
#include "sqsh_getopt.h"
@@ -33,13 +35,14 @@
#include "sqsh_cmd.h"
#include "sqsh_job.h"
#include "sqsh_init.h"
+#include "sqsh_sig.h"
#include "sqsh_stdin.h"
#include "cmd.h"
#include "sqsh_expand.h" /* sqsh-2.1.6 */
/*-- Current Version --*/
#if !defined(lint) && !defined(__LINT__)
-static char RCS_Id[] = "$Id: cmd_connect.c,v 1.22 2010/03/28 11:46:05 mpeppler Exp $";
+static char RCS_Id[] = "$Id: cmd_connect.c,v 1.40 2014/04/04 08:22:38 mwesdorp Exp $";
USE(RCS_Id)
#endif /* !defined(lint) */
@@ -67,45 +70,51 @@ static int sg_login_failed = False;
static int timeouts;
/*-- Local Prototypes --*/
-static CS_RETCODE syb_server_cb
+static CS_RETCODE syb_server_cb
_ANSI_ARGS(( CS_CONTEXT*, CS_CONNECTION*, CS_SERVERMSG* ))
-#if defined(_CYGWIN32_)
+#if defined(__CYGWIN__)
__attribute__ ((stdcall))
-#endif /* _CYGWIN32_ */
+#endif /* __CYGWIN__ */
;
-static CS_RETCODE syb_client_cb
+static CS_RETCODE syb_client_cb
_ANSI_ARGS(( CS_CONTEXT*, CS_CONNECTION*, CS_CLIENTMSG* ))
-#if defined(_CYGWIN32_)
+#if defined(__CYGWIN__)
__attribute__ ((stdcall))
-#endif /* _CYGWIN32_ */
+#endif /* __CYGWIN__ */
;
static CS_RETCODE syb_cs_cb
_ANSI_ARGS(( CS_CONTEXT*, CS_CLIENTMSG* ))
-#if defined(_CYGWIN32_)
+#if defined(__CYGWIN__)
__attribute__ ((stdcall))
-#endif /* _CYGWIN32_ */
+#endif /* __CYGWIN__ */
;
+#if defined(CS_SSLVALIDATE_CB)
+static CS_RETCODE validate_srvname_cb
+ _ANSI_ARGS(( CS_VOID*, CS_SSLCERT*, CS_INT, CS_INT ))
+#if defined(__CYGWIN__)
+ __attribute__ ((stdcall))
+#endif /* __CYGWIN__ */
+ ;
+#endif
+
static int wrap_print _ANSI_ARGS(( FILE*, char* )) ;
static int check_opt_capability _ANSI_ARGS(( CS_CONNECTION * ));
/* sqsh-2.1.6 - New function SetNetAuth */
static CS_RETCODE SetNetAuth _ANSI_ARGS(( CS_CONNECTION *,
- CS_CHAR *, CS_CHAR *, CS_CHAR *, CS_CHAR *))
-#if defined(_CYGWIN32_)
- __attribute__ ((stdcall))
-#endif /* _CYGWIN32_ */
- ;
+ CS_CHAR *, CS_CHAR *, CS_CHAR *, CS_CHAR *));
/* sqsh-2.1.7 - New function ShowNetAuthCredExp */
static CS_RETCODE ShowNetAuthCredExp _ANSI_ARGS((CS_CONNECTION *,
- CS_CHAR *))
-#if defined(_CYGWIN32_)
- __attribute__ ((stdcall))
-#endif /* _CYGWIN32_ */
- ;
+ CS_CHAR *));
+
+/* sqsh-2.2.0 - Signal handler to respond to SIGINT during cmd_connect */
+static JMP_BUF sg_jmp_buf;
+static int sg_interrupted;
+static void connect_run_sigint ( int, void *);
/*
* cmd_connect:
@@ -143,8 +152,6 @@ int cmd_connect( argc, argv )
char *password ;
char *server ;
char *interfaces ;
- char *colsep ;
- char *width ;
char *packet_size ;
char *autouse ;
char *session ;
@@ -160,10 +167,11 @@ int cmd_connect( argc, argv )
extern char *sqsh_optarg ;
extern int sqsh_optind ;
char use_database[128] ;
+ char *usedbcheck ;
int c ;
int have_error = False ;
int preserve_context = True ;
- char orig_password[64];
+ char orig_password[SQSH_PASSLEN+1];
int password_changed = False;
char sqlbuf[64];
char passbuf[64];
@@ -183,6 +191,12 @@ int cmd_connect( argc, argv )
CS_BOOL NetAuthRequired;
varbuf_t *exp_buf = NULL;
+ /* sqsh-2.2.0 - New variables for TDS debugging with ct_debug() */
+#if defined(DEBUG) && defined(CS_SET_DBG_FILE) && defined(CS_SET_PROTOCOL_FILE)
+ char *debug_tds_logdata;
+ char *debug_tds_capture;
+#endif
+
#if defined(CTLIB_SIGPOLL_BUG) && defined(F_SETOWN)
int ctlib_fd;
#endif
@@ -216,164 +230,176 @@ int cmd_connect( argc, argv )
/*
* Parse the command line options.
* sqsh-2.1.6 - New options added and case evaluation neatly ordered.
+ * sqsh-2.2.0 - -J option added. -I requires an optarg.
*/
- while ((c = sqsh_getopt( argc, argv, "cD:I;K:n:N:P;Q:R:S:T:U:V;Z;" )) != EOF)
+ while ((c = sqsh_getopt( argc, argv, "A:cD:G:I:J:K:n:N:P;Q:R:S:T:U:V;XZ;z:" )) != EOF)
{
- switch( c )
+ switch( c )
{
- case 'c' :
- preserve_context = False ;
- break ;
- case 'D' :
- if (env_put( g_env, "database", sqsh_optarg,
- ENV_F_TRAN ) == False)
- {
- fprintf( stderr, "\\connect: -D: %s\n",
- sqsh_get_errstr() );
- have_error = True;
- }
- break;
- case 'I' :
- if (env_put( g_env, "interfaces", sqsh_optarg,
- ENV_F_TRAN ) == False)
- {
- fprintf( stderr, "\\connect: -I: %s\n",
- sqsh_get_errstr() );
- have_error = True;
- }
- break ;
- case 'K' : /* sqsh-2.1.6 */
- if (env_put( g_env, "keytab_file", sqsh_optarg,
- ENV_F_TRAN ) == False)
- {
- fprintf( stderr, "\\connect: -K: %s\n",
- sqsh_get_errstr() );
- have_error = True;
- }
- break ;
- case 'n' :
- if (env_put( g_env, "chained", sqsh_optarg,
- ENV_F_TRAN ) == False)
- {
- fprintf( stderr, "\\connect: -n: %s\n",
- sqsh_get_errstr() );
- have_error = True;
- }
- break ;
- case 'N' : /* sqsh-2.1.5 */
- if (env_put( g_env, "appname", sqsh_optarg,
- ENV_F_TRAN ) == False) {
- fprintf( stderr, "\\connect: -N: %s\n",
- sqsh_get_errstr() );
- have_error = True;
- }
- break;
- case 'P' :
- if(g_password_set == True && g_password != NULL)
- strcpy( orig_password, g_password );
- password_changed = True;
-
- if (env_put( g_env, "password", sqsh_optarg,
- ENV_F_TRAN ) == False)
- {
- fprintf( stderr, "\\connect: -P: %s\n",
- sqsh_get_errstr() );
- have_error = True;
- }
- break;
- case 'Q' : /* sqsh-2.1.6 */
- if (env_put( g_env, "query_timeout", sqsh_optarg,
- ENV_F_TRAN ) == False)
- {
- fprintf( stderr, "\\connect: -Q: %s\n",
- sqsh_get_errstr() );
- have_error = True;
- }
- break ;
- case 'R' : /* sqsh-2.1.6 */
- if (env_put( g_env, "principal", sqsh_optarg,
- ENV_F_TRAN ) == False)
- {
- fprintf( stderr, "\\connect: -R: %s\n",
- sqsh_get_errstr() );
- have_error = True;
- }
- break ;
- case 'S' :
- if (env_put( g_env, "DSQUERY", sqsh_optarg,
- ENV_F_TRAN ) == False)
- {
- fprintf( stderr, "\\connect: -S: %s\n",
- sqsh_get_errstr() );
- have_error = True;
- }
- break ;
- case 'T' : /* sqsh-2.1.6 */
- if (env_put( g_env, "login_timeout", sqsh_optarg,
- ENV_F_TRAN ) == False)
- {
- fprintf( stderr, "\\connect: -T: %s\n",
- sqsh_get_errstr() );
- have_error = True;
- }
- break ;
- case 'U' :
- if (env_put( g_env, "username", sqsh_optarg,
- ENV_F_TRAN ) == False)
- {
- fprintf( stderr, "\\connect: -U: %s\n",
- sqsh_get_errstr() );
- have_error = True;
- }
- break ;
- case 'V' : /* sqsh-2.1.6 */
- if (sqsh_optarg == NULL || *sqsh_optarg == '\0')
- return_code = env_put( g_env, "secure_options", "u", ENV_F_TRAN);
- else
- return_code = env_put( g_env, "secure_options", sqsh_optarg, ENV_F_TRAN);
-
- if (return_code == False)
- {
- fprintf( stderr, "\\connect: -V: %s\n",
- sqsh_get_errstr() );
- have_error = True;
- }
- break ;
- case 'Z' : /* sqsh-2.1.6 */
- if (sqsh_optarg == NULL || *sqsh_optarg == '\0')
- return_code = env_put( g_env, "secmech", "default", ENV_F_TRAN);
- else
- return_code = env_put( g_env, "secmech", sqsh_optarg, ENV_F_TRAN);
-
- if (return_code == False)
- {
- fprintf( stderr, "\\connect: -Z: %s\n",
- sqsh_get_errstr() );
- have_error = True;
- }
- break ;
-
- default :
- fprintf( stderr, "\\connect: %s\n", sqsh_get_errstr() ) ;
- have_error = True ;
- break ;
+ case 'A' : /* sqsh-2.2.0 - Option added */
+ if (env_put( g_env, "packet_size", sqsh_optarg, ENV_F_TRAN ) == False)
+ {
+ fprintf( stderr, "\\connect: -A: %s\n", sqsh_get_errstr() );
+ have_error = True;
+ }
+ break;
+ case 'c' :
+ preserve_context = False ;
+ break ;
+ case 'D' :
+ if (env_put( g_env, "database", sqsh_optarg, ENV_F_TRAN ) == False)
+ {
+ fprintf( stderr, "\\connect: -D: %s\n", sqsh_get_errstr() );
+ have_error = True;
+ }
+ break;
+ case 'G' : /* sqsh-2.2.0 - Option added */
+ if (env_put( g_env, "tds_version", sqsh_optarg, ENV_F_TRAN ) == False)
+ {
+ fprintf( stderr, "\\connect: -G: %s\n", sqsh_get_errstr() );
+ have_error = True;
+ }
+ break;
+ case 'I' :
+ if (env_put( g_env, "interfaces", sqsh_optarg, ENV_F_TRAN ) == False)
+ {
+ fprintf( stderr, "\\connect: -I: %s\n", sqsh_get_errstr() );
+ have_error = True;
+ }
+ break ;
+ case 'J' : /* sqsh-2.2.0 - Option added */
+ if (env_put( g_env, "charset", sqsh_optarg, ENV_F_TRAN ) == False)
+ {
+ fprintf( stderr, "\\connect: -J: %s\n", sqsh_get_errstr() );
+ have_error = True;
+ }
+ break ;
+ case 'K' : /* sqsh-2.1.6 */
+ if (env_put( g_env, "keytab_file", sqsh_optarg, ENV_F_TRAN ) == False)
+ {
+ fprintf( stderr, "\\connect: -K: %s\n", sqsh_get_errstr() );
+ have_error = True;
+ }
+ break ;
+ case 'n' :
+ if (env_put( g_env, "chained", sqsh_optarg, ENV_F_TRAN ) == False)
+ {
+ fprintf( stderr, "\\connect: -n: %s\n", sqsh_get_errstr() );
+ have_error = True;
+ }
+ break ;
+ case 'N' : /* sqsh-2.1.5 */
+ if (env_put( g_env, "appname", sqsh_optarg, ENV_F_TRAN ) == False)
+ {
+ fprintf( stderr, "\\connect: -N: %s\n", sqsh_get_errstr() );
+ have_error = True;
+ }
+ break;
+ case 'P' :
+ if (g_password_set == True && g_password != NULL)
+ strcpy( orig_password, g_password );
+ password_changed = True;
+
+ if (env_put( g_env, "password", sqsh_optarg, ENV_F_TRAN ) == False)
+ {
+ fprintf( stderr, "\\connect: -P: %s\n", sqsh_get_errstr() );
+ have_error = True;
+ }
+ break;
+ case 'Q' : /* sqsh-2.1.6 */
+ if (env_put( g_env, "query_timeout", sqsh_optarg, ENV_F_TRAN ) == False)
+ {
+ fprintf( stderr, "\\connect: -Q: %s\n", sqsh_get_errstr() );
+ have_error = True;
+ }
+ break ;
+ case 'R' : /* sqsh-2.1.6 */
+ if (env_put( g_env, "principal", sqsh_optarg, ENV_F_TRAN ) == False)
+ {
+ fprintf( stderr, "\\connect: -R: %s\n", sqsh_get_errstr() );
+ have_error = True;
+ }
+ break ;
+ case 'S' :
+ if (env_put( g_env, "DSQUERY", sqsh_optarg, ENV_F_TRAN ) == False)
+ {
+ fprintf( stderr, "\\connect: -S: %s\n", sqsh_get_errstr() );
+ have_error = True;
+ }
+ break ;
+ case 'T' : /* sqsh-2.1.6 */
+ if (env_put( g_env, "login_timeout", sqsh_optarg, ENV_F_TRAN ) == False)
+ {
+ fprintf( stderr, "\\connect: -T: %s\n", sqsh_get_errstr() );
+ have_error = True;
+ }
+ break ;
+ case 'U' :
+ if (env_put( g_env, "username", sqsh_optarg, ENV_F_TRAN ) == False)
+ {
+ fprintf( stderr, "\\connect: -U: %s\n", sqsh_get_errstr() );
+ have_error = True;
+ }
+ break ;
+ case 'V' : /* sqsh-2.1.6 */
+ if (sqsh_optarg == NULL || *sqsh_optarg == '\0')
+ return_code = env_put( g_env, "secure_options", "u", ENV_F_TRAN);
+ else
+ return_code = env_put( g_env, "secure_options", sqsh_optarg, ENV_F_TRAN);
+
+ if (return_code == False)
+ {
+ fprintf( stderr, "\\connect: -V: %s\n", sqsh_get_errstr() );
+ have_error = True;
+ }
+ break ;
+ case 'X' : /* sqsh-2.1.9 */
+ if (env_put( g_env, "encryption", "1", ENV_F_TRAN ) == False)
+ {
+ fprintf( stderr, "\\connect: -X: %s\n", sqsh_get_errstr() );
+ have_error = True;
+ }
+ break ;
+ case 'z' : /* sqsh-2.2.0 - Option added */
+ if (env_put( g_env, "language", sqsh_optarg, ENV_F_TRAN ) == False)
+ {
+ fprintf( stderr, "\\connect: -z: %s\n", sqsh_get_errstr() );
+ have_error = True;
+ }
+ break ;
+ case 'Z' : /* sqsh-2.1.6 */
+ if (sqsh_optarg == NULL || *sqsh_optarg == '\0')
+ return_code = env_put( g_env, "secmech", "default", ENV_F_TRAN);
+ else
+ return_code = env_put( g_env, "secmech", sqsh_optarg, ENV_F_TRAN);
+ if (return_code == False)
+ {
+ fprintf( stderr, "\\connect: -Z: %s\n", sqsh_get_errstr() );
+ have_error = True;
+ }
+ break ;
+
+ default :
+ fprintf( stderr, "\\connect: %s\n", sqsh_get_errstr() ) ;
+ have_error = True ;
+ break ;
}
}
/*
- * If there are any options left on the end of the line, then
- * we have an error.
+ * If there are any options left on the end of the line, then we have an error.
* sqsh-2.1.6 - New options added to the list.
+ * sqsh-2.2.0 - -J charset added to the list.
*/
- if( have_error || sqsh_optind != argc )
+ if( have_error || sqsh_optind != argc )
{
- fprintf( stderr,
- "Use: \\connect [-c] [-I interfaces] [-U username] [-P pwd] [-S server]\n"
- " [-D database ] [-N appname] [-n {on|off}] [-Q query_timeout]\n"
- " [-T login_timeout] [-K keytab_file] [-R principal]\n"
- " [-V [bcdimoqru]] [-Z [secmech|default|none]]\n"
+ fprintf( stderr,
+ "Use: \\connect [-A packet size] [-c] [-I interfaces] [-U username] [-P pwd] [-S server]\n"
+ " [-D database ] [-G tds version] [-J charset] [-N appname] [-n {on|off}]\n"
+ " [-Q query_timeout] [-T login_timeout] [-K keytab_file] [-R principal]\n"
+ " [-V [bcdimoqru]] [-X] [-z language] [-Z [secmech|default|none]]\n"
) ;
-
+
env_rollback( g_env );
return CMD_FAIL;
}
@@ -387,8 +413,6 @@ int cmd_connect( argc, argv )
env_get( g_env, "username", &username ) ;
env_get( g_env, "DSQUERY", &server ) ;
env_get( g_env, "interfaces", &interfaces ) ;
- env_get( g_env, "width", &width ) ;
- env_get( g_env, "colsep", &colsep ) ;
env_get( g_env, "packet_size", &packet_size ) ;
env_get( g_env, "autouse", &autouse ) ;
env_get( g_env, "database", &database ) ;
@@ -419,6 +443,16 @@ int cmd_connect( argc, argv )
sqsh_exit( 255 );
}
+ /*
+ * sqsh-2.2.0 - Install a signal handler to catch SIGINT during cmd_connect.
+ * The current signals are saved first and restored at the end of cmd_connect.
+ */
+ sig_save();
+ sig_install( SIGINT, connect_run_sigint, (void *) NULL, 0);
+ sg_interrupted = False;
+ if (SETJMP( sg_jmp_buf ) != 0)
+ goto connect_fail;
+
/*
* If the $session variable is set and the path that it contains
* is a valid path name, then we want to execute the contents of
@@ -430,14 +464,14 @@ int cmd_connect( argc, argv )
if (sqsh_expand( session, exp_buf, 0 ) != False)
{
session = varbuf_getstr( exp_buf );
- if (session != NULL && access( session, R_OK ) != -1)
+ if (session != NULL && access( session, R_OK ) != -1)
{
DBG(sqsh_debug(DEBUG_ENV, "cmd_connect: session file is %s.\n",
session);)
cp = malloc (strlen(session) + 12) ;
sprintf (cp, "\\loop -n %s", session);
if ((jobset_run( g_jobset, cp, &exit_status )) == -1 ||
- exit_status == CMD_FAIL)
+ exit_status == CMD_FAIL)
{
fprintf( stderr, "%s\n", sqsh_get_errstr() );
free (cp);
@@ -476,7 +510,7 @@ int cmd_connect( argc, argv )
secmech = NULL;
secure_options = NULL;
}
- if ((secmech != NULL && *secmech != '\0') ||
+ if ((secmech != NULL && *secmech != '\0') ||
(secure_options != NULL && *secure_options != '\0'))
{
NetAuthRequired = CS_TRUE;
@@ -504,7 +538,7 @@ int cmd_connect( argc, argv )
* If we don't have a password to use (i.e. the $password isn't set
* or -P was not supplied), then ask the user for one.
*/
- if (g_password_set == False)
+ else if (g_password_set == False)
{
len = sqsh_getinput( "Password: ", passbuf, sizeof(passbuf), 0);
@@ -529,9 +563,10 @@ int cmd_connect( argc, argv )
* database, then that indicates that we are to automatically
* connect to $database prior to returning.
*/
- if( preserve_context && database != NULL && *database != '\0' )
+ if( preserve_context && database != NULL && *database != '\0' )
{
- strncpy( use_database, database , 127) ;
+ strncpy( use_database, database, sizeof(use_database)-1 ) ;
+ use_database[sizeof(use_database)-1] = '\0';
autouse = use_database ;
}
@@ -549,29 +584,47 @@ int cmd_connect( argc, argv )
if (g_context == NULL)
{
/*-- Allocate a new context structure --*/
- /*-- mpeppler 4/9/2004
+ /*-- mpeppler 4/9/2004
we loop through the CS_VERSION_xxx values to try
to use the highest one we find */
- retcode = CS_FAIL;
+ retcode = CS_FAIL;
#if defined(CS_CURRENT_VERSION)
- if(retcode != CS_SUCCEED) {
- g_cs_ver = CS_CURRENT_VERSION;
- retcode = cs_ctx_alloc(g_cs_ver, &g_context);
-}
+ if(retcode != CS_SUCCEED) {
+ g_cs_ver = CS_CURRENT_VERSION;
+ retcode = cs_ctx_alloc(g_cs_ver, &g_context);
+ }
+#endif
+#if defined(CS_VERSION_160)
+ if(retcode != CS_SUCCEED) {
+ g_cs_ver = CS_VERSION_160;
+ retcode = cs_ctx_alloc(g_cs_ver, &g_context);
+ }
+#endif
+#if defined(CS_VERSION_157)
+ if(retcode != CS_SUCCEED) {
+ g_cs_ver = CS_VERSION_157;
+ retcode = cs_ctx_alloc(g_cs_ver, &g_context);
+ }
+#endif
+#if defined(CS_VERSION_155)
+ if(retcode != CS_SUCCEED) {
+ g_cs_ver = CS_VERSION_155;
+ retcode = cs_ctx_alloc(g_cs_ver, &g_context);
+ }
#endif
#if defined(CS_VERSION_150)
if(retcode != CS_SUCCEED) {
- g_cs_ver = CS_VERSION_150;
- retcode = cs_ctx_alloc(g_cs_ver, &g_context);
- }
+ g_cs_ver = CS_VERSION_150;
+ retcode = cs_ctx_alloc(g_cs_ver, &g_context);
+ }
#endif
#if defined(CS_VERSION_125)
if(retcode != CS_SUCCEED) {
- g_cs_ver = CS_VERSION_125;
- retcode = cs_ctx_alloc(g_cs_ver, &g_context);
- }
+ g_cs_ver = CS_VERSION_125;
+ retcode = cs_ctx_alloc(g_cs_ver, &g_context);
+ }
#endif
#if defined(CS_VERSION_120)
if(retcode != CS_SUCCEED) {
@@ -590,6 +643,8 @@ int cmd_connect( argc, argv )
g_cs_ver = CS_VERSION_100;
retcode = cs_ctx_alloc(g_cs_ver, &g_context);
}
+ DBG(sqsh_debug(DEBUG_TDS, "cmd_connect: g_cs_ver (CS_VERSION) set to: %d\n", g_cs_ver);)
+
if (retcode != CS_SUCCEED) /* nothing worked... */
goto connect_fail;
@@ -600,32 +655,32 @@ int cmd_connect( argc, argv )
(CS_VOID*)syb_cs_cb, /* Buffer */
CS_UNUSED, /* Buffer length */
(CS_INT*)NULL /* Output length */
- ) != CS_SUCCEED)
+ ) != CS_SUCCEED)
{
fprintf( stderr, "\\connect: Unable to install message callback\n" );
goto connect_fail;
}
-
+
/*-- Initialize the context --*/
if (ct_init( g_context, g_cs_ver ) != CS_SUCCEED)
goto connect_fail;
if (ct_callback( g_context, /* Context */
- (CS_CONNECTION*)NULL, /* Connection */
- CS_SET, /* Action */
- CS_CLIENTMSG_CB, /* Type */
- (CS_VOID*)syb_client_cb /* Callback Pointer */
- ) != CS_SUCCEED)
+ (CS_CONNECTION*)NULL, /* Connection */
+ CS_SET, /* Action */
+ CS_CLIENTMSG_CB, /* Type */
+ (CS_VOID*)syb_client_cb /* Callback Pointer */
+ ) != CS_SUCCEED)
goto connect_fail;
if (ct_callback( g_context, /* Context */
- (CS_CONNECTION*)NULL, /* Connection */
- CS_SET, /* Action */
- CS_SERVERMSG_CB, /* Type */
- (CS_VOID*)syb_server_cb /* Callback Pointer */
- ) != CS_SUCCEED)
+ (CS_CONNECTION*)NULL, /* Connection */
+ CS_SET, /* Action */
+ CS_SERVERMSG_CB, /* Type */
+ (CS_VOID*)syb_server_cb /* Callback Pointer */
+ ) != CS_SUCCEED)
goto connect_fail;
-
+
/*
* Set the I/O type to syncronous (things would really freak out
* in an async environment).
@@ -633,12 +688,12 @@ int cmd_connect( argc, argv )
#if !defined(_WINDOZE_)
netio_type = CS_SYNC_IO;
if (ct_config( g_context, /* Context */
- CS_SET, /* Action */
- CS_NETIO, /* Property */
- (CS_VOID*)&netio_type, /* Buffer */
- CS_UNUSED, /* Buffer Length */
- NULL /* Output Length */
- ) != CS_SUCCEED)
+ CS_SET, /* Action */
+ CS_NETIO, /* Property */
+ (CS_VOID*)&netio_type, /* Buffer */
+ CS_UNUSED, /* Buffer Length */
+ NULL /* Output Length */
+ ) != CS_SUCCEED)
goto connect_fail;
#endif
@@ -658,7 +713,7 @@ int cmd_connect( argc, argv )
{
DBG(sqsh_debug(DEBUG_ERROR, "ct_config: Failed to set CS_TIMEOUT to %d seconds.\n", SybTimeOut);)
goto connect_fail;
- }
+ }
DBG(sqsh_debug(DEBUG_ERROR, "ct_config: CS_TIMEOUT set to %d seconds.\n", SybTimeOut);)
}
@@ -672,7 +727,7 @@ int cmd_connect( argc, argv )
CS_UNUSED, /* Buffer Length */
NULL /* Output Length */
) != CS_SUCCEED)
- {
+ {
DBG(sqsh_debug(DEBUG_ERROR, "ct_config: Failed to set CS_LOGIN_TIMEOUT to %d seconds.\n", SybTimeOut);)
goto connect_fail;
}
@@ -699,7 +754,7 @@ int cmd_connect( argc, argv )
(CS_VOID*)cp, /* Buffer */
CS_NULLTERM, /* Buffer Length */
NULL /* Output Length */
- ) != CS_SUCCEED)
+ ) != CS_SUCCEED)
goto connect_fail;
}
else
@@ -747,7 +802,7 @@ int cmd_connect( argc, argv )
{
fprintf( stderr, "sqsh: Error expanding $keytab_file: %s\n",
sqsh_get_errstr() );
- cp = NULL;
+ cp = NULL;
}
}
else
@@ -788,7 +843,7 @@ int cmd_connect( argc, argv )
) != CS_SUCCEED)
goto connect_fail;
}
-
+
if (tds_version != NULL && *tds_version != '\0') /* sqsh-2.1.6 fix on *tds_version */
{
if (strcmp(tds_version, "4.0") == 0)
@@ -802,7 +857,7 @@ int cmd_connect( argc, argv )
else if (strcmp(tds_version, "5.0") == 0)
version = CS_TDS_50;
#if !defined(CS_TDS_50)
- /* Then we use freetds */
+ /* Then we use freetds which uses enum instead of defines */
else if (strcmp(tds_version, "7.0") == 0)
version = CS_TDS_70;
else if (strcmp(tds_version, "8.0") == 0)
@@ -811,21 +866,21 @@ int cmd_connect( argc, argv )
else version = CS_TDS_50; /* default version */
- if (ct_con_props(g_connection, CS_SET, CS_TDS_VERSION,
+ if (ct_con_props(g_connection, CS_SET, CS_TDS_VERSION,
(CS_VOID*)&version, CS_UNUSED, (CS_INT*)NULL) != CS_SUCCEED)
goto connect_fail;
}
/*-- Hostname --*/
- if (hostname != NULL && *hostname != '\0')
+ if (hostname != NULL && *hostname != '\0')
{
if (ct_con_props( g_connection, /* Connection */
- CS_SET, /* Action */
- CS_HOSTNAME, /* Property */
- (CS_VOID*)hostname, /* Buffer */
- CS_NULLTERM, /* Buffer Length */
- (CS_INT*)NULL /* Output Length */
- ) != CS_SUCCEED)
+ CS_SET, /* Action */
+ CS_HOSTNAME, /* Property */
+ (CS_VOID*)hostname, /* Buffer */
+ CS_NULLTERM, /* Buffer Length */
+ (CS_INT*)NULL /* Output Length */
+ ) != CS_SUCCEED)
goto connect_fail;
}
@@ -834,27 +889,44 @@ int cmd_connect( argc, argv )
{
i = atoi(packet_size);
if (ct_con_props( g_connection, /* Connection */
- CS_SET, /* Action */
- CS_PACKETSIZE, /* Property */
- (CS_VOID*)&i, /* Buffer */
- CS_UNUSED, /* Buffer Length */
- (CS_INT*)NULL /* Output Length */
- ) != CS_SUCCEED)
+ CS_SET, /* Action */
+ CS_PACKETSIZE, /* Property */
+ (CS_VOID*)&i, /* Buffer */
+ CS_UNUSED, /* Buffer Length */
+ (CS_INT*)NULL /* Output Length */
+ ) != CS_SUCCEED)
goto connect_fail;
}
/*-- Encryption --*/
- if (encryption != NULL && *encryption == '1')
+ if (encryption != NULL && *encryption == '1')
{
i = CS_TRUE;
if (ct_con_props( g_connection, /* Connection */
- CS_SET, /* Action */
- CS_SEC_ENCRYPTION, /* Property */
- (CS_VOID*)&i, /* Buffer */
- CS_UNUSED, /* Buffer Length */
- (CS_INT*)NULL /* Output Length */
- ) != CS_SUCCEED)
+ CS_SET, /* Action */
+ CS_SEC_ENCRYPTION, /* Property */
+ (CS_VOID*)&i, /* Buffer */
+ CS_UNUSED, /* Buffer Length */
+ (CS_INT*)NULL /* Output Length */
+ ) != CS_SUCCEED)
goto connect_fail;
+
+#if defined(CS_SEC_EXTENDED_ENCRYPTION)
+ /*
+ * sqsh-2.1.9: Enable extended password encryption to be able to
+ * connect to ASE servers with 'net password encryption reqd'
+ * configured to 2 (RSA).
+ */
+ if (ct_con_props( g_connection, /* Connection */
+ CS_SET, /* Action */
+ CS_SEC_EXTENDED_ENCRYPTION, /* Property */
+ (CS_VOID*)&i, /* Buffer */
+ CS_UNUSED, /* Buffer Length */
+ (CS_INT*)NULL /* Output Length */
+ ) != CS_SUCCEED)
+ goto connect_fail;
+#endif
+
}
/*
@@ -868,69 +940,187 @@ int cmd_connect( argc, argv )
/*-- Initialize --*/
if (cs_locale( g_context, /* Context */
CS_SET, /* Action */
- locale, /* Locale Structure */
+ locale, /* Locale Structure */
CS_LC_ALL, /* Property */
- (CS_CHAR*)NULL, /* Buffer */
+ (CS_CHAR*)NULL, /* Buffer */
CS_UNUSED, /* Buffer Length */
(CS_INT*)NULL /* Output Length */
- ) != CS_SUCCEED)
+ ) != CS_SUCCEED)
goto connect_fail;
/*-- Language --*/
- if( language != NULL && *language != '\0' )
+ if( language != NULL && *language != '\0' )
{
- if (cs_locale( g_context, /* Context */
- CS_SET, /* Action */
- locale, /* Locale Structure */
- CS_SYB_LANG, /* Property */
- (CS_CHAR*)language, /* Buffer */
- CS_NULLTERM, /* Buffer Length */
- (CS_INT*)NULL /* Output Length */
- ) != CS_SUCCEED)
+ if (cs_locale( g_context, /* Context */
+ CS_SET, /* Action */
+ locale, /* Locale Structure */
+ CS_SYB_LANG, /* Property */
+ (CS_CHAR*)language, /* Buffer */
+ CS_NULLTERM, /* Buffer Length */
+ (CS_INT*)NULL /* Output Length */
+ ) != CS_SUCCEED)
goto connect_fail;
}
/*-- Character Set --*/
- if (charset != NULL && *charset != '\0') /* sqsh-2.1.6 sanity check */
+ if (charset != NULL && *charset != '\0') /* sqsh-2.1.6 sanity check */
{
- if (cs_locale( g_context, /* Context */
- CS_SET, /* Action */
- locale, /* Locale Structure */
- CS_SYB_CHARSET, /* Property */
- (CS_CHAR*)charset, /* Buffer */
- CS_NULLTERM, /* Buffer Length */
- (CS_INT*)NULL /* Output Length */
- ) != CS_SUCCEED)
+ if (cs_locale( g_context, /* Context */
+ CS_SET, /* Action */
+ locale, /* Locale Structure */
+ CS_SYB_CHARSET, /* Property */
+ (CS_CHAR*)charset, /* Buffer */
+ CS_NULLTERM, /* Buffer Length */
+ (CS_INT*)NULL /* Output Length */
+ ) != CS_SUCCEED)
goto connect_fail;
}
/*-- Locale Property --*/
- if (ct_con_props( g_connection, /* Connection */
- CS_SET, /* Action */
- CS_LOC_PROP, /* Property */
- (CS_VOID*)locale, /* Buffer */
- CS_UNUSED, /* Buffer Length */
- (CS_INT*)NULL /* Output Length */
- ) != CS_SUCCEED)
+ if (ct_con_props( g_connection, /* Connection */
+ CS_SET, /* Action */
+ CS_LOC_PROP, /* Property */
+ (CS_VOID*)locale, /* Buffer */
+ CS_UNUSED, /* Buffer Length */
+ (CS_INT*)NULL /* Output Length */
+ ) != CS_SUCCEED)
goto connect_fail;
/* Handle case where server is defined as host:port */
-#if defined(CS_SERVERADDR)
- if(server && (cp = strchr(server, ':'))) {
- if(*cp)
- *cp = ' ';
-
- /* fprintf(stderr, "Using %s for CS_SERVERADDR\n", server);*/
-
- if (ct_con_props( g_connection, CS_SET, CS_SERVERADDR,
- (CS_VOID*)server,
- CS_NULLTERM, (CS_INT*)NULL) != CS_SUCCEED)
- goto connect_fail;
+ /*
+ * sqsh-2.5 - Work around a bug in FreeTDS and do not call ct_con_props
+ * for server:port connections but let ct_connect handle it.
+ * OpenClient supports an optional filter that can be specified as third
+ * parameter like host:port:filter. Filters are defined in libtcl.cfg.
+ */
+#if defined(CS_SERVERADDR) && defined(CS_TDS_50)
+ if ( server != NULL && (cp = strchr(server, ':')) != NULL )
+ {
+ char *cp2;
+
+ *cp = ' ';
+ if ( (cp2 = strchr(cp+1, ':')) != NULL) /* Optional filter specified? */
+ *cp2 = ' ';
+
+ if (ct_con_props( g_connection,
+ CS_SET,
+ CS_SERVERADDR,
+ (CS_VOID*)server,
+ CS_NULLTERM,
+ (CS_INT*)NULL
+ ) != CS_SUCCEED)
+ goto connect_fail;
+
+ if (cp2 != NULL)
+ *cp2 = '\0'; /* Remove optional filter from the servername */
+ *cp = ':'; /* Put a ':' back into the display servername */
+
+#if defined(CS_SSLVALIDATE_CB)
+ if (ct_callback( g_context, /* Context */
+ (CS_CONNECTION*)NULL, /* Connection */
+ CS_SET, /* Action */
+ CS_SSLVALIDATE_CB, /* Type */
+ (CS_VOID*)validate_srvname_cb /* Callback Pointer */
+ ) != CS_SUCCEED)
+ goto connect_fail;
+#endif
+ }
+#endif
+
+#if defined(DEBUG) && defined(CS_SET_DBG_FILE) && defined(CS_SET_PROTOCOL_FILE)
+ /*
+ * sqsh-2.2.0 - Setup TDS debugging using a logdata file and or a capture file
+ * for tracing TDS packets.
+ */
+ if ( sqsh_debug_show (DEBUG_TDS) )
+ {
+ /*
+ * Note, this requires the CT-lib development libraries to be linked/loaded with sqsh.
+ */
+ env_get (g_env, "debug_tds_logdata", &debug_tds_logdata);
+ if (debug_tds_logdata != NULL && *debug_tds_logdata != '\0')
+ {
+ if (sqsh_expand( debug_tds_logdata, exp_buf, 0 ) != False)
+ {
+ cp = varbuf_getstr( exp_buf );
+ if (ct_debug ( g_context, /* Context */
+ NULL, /* Connection */
+ CS_SET_DBG_FILE, /* Action */
+ CS_UNUSED, /* Flag */
+ cp, /* Buffer value */
+ CS_NULLTERM /* String '\0' terminated */
+ ) != CS_SUCCEED)
+ fprintf (stderr, "\\connect: ct_debug - Unable to set CS_SET_DBG_FILE to %s\n", cp);
+ else
+ {
+ fprintf (stdout, "\\connect: ct_debug - Successfully set CS_SET_DBG_FILE to %s\n", cp);
+
+ if (ct_debug ( g_context, /* Context */
+ g_connection, /* Connection */
+ CS_SET_FLAG, /* Action */
+ CS_DBG_ALL, /* Flag */
+ NULL, /* Buffer value */
+ CS_UNUSED /* Buffer length */
+ ) != CS_SUCCEED)
+ fprintf (stderr, "\\connect: ct_debug - Unable to set flag CS_DBG_ALL\n");
+ else
+ fprintf (stdout, "\\connect: ct_debug - Flag CS_DBG_ALL successfully set\n");
+ }
+ }
+ else
+ {
+ fprintf( stderr, "sqsh: Error expanding $debug_tds_logdata: %s\n", sqsh_get_errstr() );
+ }
+ }
+
+ /*
+ * For protocol tracing regular CT-lib libraries will do.
+ * The created trace file can be decoded using Ribo.
+ */
+ env_get (g_env, "debug_tds_capture", &debug_tds_capture);
+ if (debug_tds_capture != NULL && *debug_tds_capture != '\0')
+ {
+ if (sqsh_expand( debug_tds_capture, exp_buf, 0 ) != False)
+ {
+ cp = varbuf_getstr( exp_buf );
+ if (ct_debug ( NULL, /* Context */
+ g_connection, /* Connection */
+ CS_SET_PROTOCOL_FILE, /* Action */
+ CS_UNUSED, /* Flag */
+ cp, /* Buffer value */
+ CS_NULLTERM /* String '\0' terminated */
+ ) != CS_SUCCEED)
+ fprintf (stderr, "\\connect: ct_debug - Unable to set CS_SET_PROTOCOL_FILE to %s\n", cp);
+ else
+ {
+ fprintf (stdout, "\\connect: ct_debug - Successfully set CS_SET_PROTOCOL_FILE to %s\n", cp);
+ if (ct_debug ( NULL, /* Context */
+ g_connection, /* Connection */
+ CS_SET_FLAG, /* Action */
+ CS_DBG_PROTOCOL, /* Flag */
+ NULL, /* Buffer value */
+ CS_UNUSED /* Buffer length */
+ ) != CS_SUCCEED)
+ fprintf (stderr, "\\connect: ct_debug - Unable to set falg CS_DBG_PROTOCOL\n");
+ else
+ fprintf (stdout, "\\connect: ct_debug - Flag CS_DBG_PROTOCOL successfully set\n");
+ }
+ }
+ else
+ {
+ fprintf( stderr, "sqsh: Error expanding $debug_tds_capture: %s\n", sqsh_get_errstr() );
+ }
+ }
+ }
+#elif defined(DEBUG)
+ if ( sqsh_debug_show (DEBUG_TDS) )
+ {
+ fprintf( stderr, "\\connect: ct_debug - TDS debugging is not supported in this version of CT-lib\n" );
}
#endif
/*
- * We sit in a loop and attempt to connect while we are getting
+ * We sit in a loop and attempt to connect while we are getting
* "Login failed" messages.
*/
do
@@ -947,10 +1137,15 @@ int cmd_connect( argc, argv )
* error handlers.
*/
if (ct_connect( g_connection, server,
- (server == NULL)?CS_UNUSED:CS_NULLTERM ) != CS_SUCCEED)
+ (server == NULL) ? CS_UNUSED : CS_NULLTERM ) != CS_SUCCEED)
{
- if (*password_retry != '1' || !sqsh_stdin_isatty() ||
- sg_login_failed != True)
+ /*
+ * sqsh-2.1.9: Check for g_interactive instead of sqsh_stdin_isatty()
+ * because that may not be determined at this point. Do not prompt
+ * for a password if Network authentication is used but just failed.
+ */
+ if (*password_retry != '1' || g_interactive == False ||
+ sg_login_failed != True || NetAuthRequired == True)
{
goto connect_fail;
}
@@ -980,6 +1175,7 @@ int cmd_connect( argc, argv )
}
}
while (sg_login_failed == True);
+ sg_login = False;
/* XXX */
/* ct_cancel(g_connection, NULL, CS_CANCEL_ALL); */
@@ -994,12 +1190,12 @@ int cmd_connect( argc, argv )
* that CT-Lib uses a file descriptor as its communication mechanism.
*/
if (ct_con_props( g_connection, /* Connection */
- CS_GET, /* Action */
- CS_ENDPOINT, /* Property */
- (CS_VOID*)&ctlib_fd, /* Buffer */
- CS_UNUSED, /* Buffer Length */
- (CS_INT*)NULL /* Output Length */
- ) != CS_SUCCEED)
+ CS_GET, /* Action */
+ CS_ENDPOINT, /* Property */
+ (CS_VOID*)&ctlib_fd, /* Buffer */
+ CS_UNUSED, /* Buffer Length */
+ (CS_INT*)NULL /* Output Length */
+ ) != CS_SUCCEED)
{
fprintf( stderr, "\\connect: WARNING: Unable to fetch CT-Lib file\n" );
fprintf( stderr, "\\connect: descriptor to work around SIGPOLL bug.\n" );
@@ -1010,18 +1206,18 @@ int cmd_connect( argc, argv )
* Here is the cruxt of the situation. Async I/O works by delivering
* the signal SIGPOLL or SIGIO every time a socket is ready to do
* some work (either send or receive data). Normally, this signal
- * will only be delivered to the process that requested the
+ * will only be delivered to the process that requested the
* facility. Unfortunately, on some platforms, CT-Lib is explicitly
* requesting that the signal be sent to every process in the same
* process group! This means that when sqsh spawns a child process
* during a pipe (e.g. "go | more") the child process will receive
- * the SIGPOLL signal as well as sqsh...and, since 99% of the
+ * the SIGPOLL signal as well as sqsh...and, since 99% of the
* programs out there don't know how to deal with SIGPOLL, they
* will simply exit. Not a good situation.
*/
if (fcntl( ctlib_fd, F_SETOWN, getpid() ) == -1)
{
- fprintf( stderr,
+ fprintf( stderr,
"\\connect: WARNING: Cannot work around CT-Lib SIGPOLL bug: %s\n",
strerror(errno) );
}
@@ -1039,37 +1235,37 @@ int cmd_connect( argc, argv )
CS_TDS_VERSION, /* Property */
(CS_VOID*)&version, /* Buffer */
CS_UNUSED, /* Buffer Length */
- (CS_INT*)NULL ) == CS_SUCCEED)
- {
- switch (version) {
- case CS_TDS_40:
- env_set( g_env, "tds_version", "4.0" );
- break;
- case CS_TDS_42:
- env_set( g_env, "tds_version", "4.2" );
- break;
- case CS_TDS_46:
- env_set( g_env, "tds_version", "4.6" );
- break;
- case CS_TDS_495:
- env_set( g_env, "tds_version", "4.9.5" );
- break;
- case CS_TDS_50:
- env_set( g_env, "tds_version", "5.0" );
- break;
+ (CS_INT*)NULL
+ ) == CS_SUCCEED)
+ {
+ switch (version) {
+ case CS_TDS_40:
+ env_set( g_env, "tds_version", "4.0" );
+ break;
+ case CS_TDS_42:
+ env_set( g_env, "tds_version", "4.2" );
+ break;
+ case CS_TDS_46:
+ env_set( g_env, "tds_version", "4.6" );
+ break;
+ case CS_TDS_495:
+ env_set( g_env, "tds_version", "4.9.5" );
+ break;
+ case CS_TDS_50:
+ env_set( g_env, "tds_version", "5.0" );
+ break;
#if !defined(CS_TDS_50)
- case CS_TDS_70:
- env_set( g_env, "tds_version", "7.0" );
- break;
- case CS_TDS_80:
- env_set( g_env, "tds_version", "8.0" );
- break;
+ case CS_TDS_70:
+ env_set( g_env, "tds_version", "7.0" );
+ break;
+ case CS_TDS_80:
+ env_set( g_env, "tds_version", "8.0" );
+ break;
#endif
- default:
- env_set( g_env, "tds_version", "unknown" );
- }
- }
-
+ default:
+ env_set( g_env, "tds_version", "unknown" );
+ }
+ }
}
/*
@@ -1082,10 +1278,8 @@ int cmd_connect( argc, argv )
}
/*-- If autouse has been set, use it --*/
- if (autouse != NULL && *autouse != '\0')
+ if (autouse != NULL && *autouse != '\0')
{
- CS_INT ret = CS_SUCCEED;
-
if (ct_cmd_alloc( g_connection, &cmd ) != CS_SUCCEED)
goto connect_succeed;
@@ -1096,24 +1290,33 @@ int cmd_connect( argc, argv )
sqlbuf, /* Buffer */
CS_NULLTERM, /* Buffer Length */
CS_UNUSED /* Options */
- ) != CS_SUCCEED)
+ ) != CS_SUCCEED)
{
ct_cmd_drop( cmd );
- goto connect_succeed;
+ goto connect_fail;
}
- if (ct_send( cmd ) != CS_SUCCEED)
+ if (ct_send( cmd ) != CS_SUCCEED)
{
ct_cmd_drop( cmd );
- goto connect_succeed;
+ goto connect_fail;
}
- while (ct_results( cmd, &result_type ) != CS_END_RESULTS) {
- if(result_type == CS_CMD_FAIL)
- ret = CS_FAIL;
- }
+ while (ct_results( cmd, &result_type ) != CS_END_RESULTS);
ct_cmd_drop( cmd );
+ /*
+ * sqsh-2.4 - Check in batch mode if the -D <database> is correctly set.
+ * Otherwise, abort to prevent script execution in wrong default
+ * database.
+ */
+ env_get ( g_env, "database", &database ) ; /* Need to refresh var pointer */
+ env_get ( g_env, "usedbcheck", &usedbcheck ) ;
+ if (g_interactive != True && *usedbcheck == '1' && strcmp (autouse, database) != 0)
+ {
+ fprintf (stderr, "sqsh: ERROR: Unable to use database '%s' in batch mode\n", autouse);
+ sqsh_exit(254);
+ }
}
connect_succeed:
@@ -1131,14 +1334,14 @@ connect_succeed:
/* Set chained mode, if necessary. */
if ( chained != NULL && *chained != '\0') /* sqsh-2.1.6 sanity check */
{
- if ( check_opt_capability( g_connection ) )
+ if ( check_opt_capability( g_connection ) )
{
CS_BOOL value = (*chained == '1' ? CS_TRUE : CS_FALSE);
retcode = ct_options( g_connection, CS_SET, CS_OPT_CHAINXACTS,
&value, CS_UNUSED, NULL);
if (retcode != CS_SUCCEED)
{
- fprintf (stderr,
+ fprintf (stderr,
"\\connect: WARNING: Unable to set transaction mode %s\n",
(*chained == '1' ? "on" : "off"));
}
@@ -1165,16 +1368,16 @@ connect_fail:
}
/*-- Clean up the connection if established --*/
- if (g_connection != NULL)
+ if (g_connection != NULL && sg_interrupted == False)
{
-
/*-- Find out if the we are connected or not --*/
if (ct_con_props( g_connection, /* Connection */
CS_GET, /* Action */
CS_CON_STATUS, /* Property */
(CS_VOID*)&con_status, /* Buffer */
CS_UNUSED, /* Buffer Length */
- (CS_INT*)NULL ) != CS_SUCCEED)
+ (CS_INT*)NULL
+ ) != CS_SUCCEED)
{
DBG(sqsh_debug(DEBUG_ERROR, "connect: Unable to get con status.\n");)
con_status = CS_CONSTAT_CONNECTED;
@@ -1184,7 +1387,8 @@ connect_fail:
if (con_status == CS_CONSTAT_CONNECTED)
{
DBG(sqsh_debug(DEBUG_ERROR, "connect: Closing connection\n");)
- ct_close( g_connection, CS_FORCE_CLOSE );
+ if (ct_close( g_connection, CS_UNUSED ) != CS_SUCCEED)
+ ct_close( g_connection, CS_FORCE_CLOSE );
}
else
{
@@ -1196,19 +1400,22 @@ connect_fail:
ct_con_drop( g_connection );
}
- if (locale != NULL)
+ if (sg_interrupted == False)
{
- DBG(sqsh_debug(DEBUG_ERROR, "connect: Dropping locale\n");)
- cs_loc_drop( g_context, locale );
- }
+ if (locale != NULL)
+ {
+ DBG(sqsh_debug(DEBUG_ERROR, "connect: Dropping locale\n");)
+ cs_loc_drop( g_context, locale );
+ }
- if (g_context != NULL)
- {
- DBG(sqsh_debug(DEBUG_ERROR, "connect: Dropping context\n");)
- ct_exit( g_context, CS_FORCE_EXIT );
- cs_ctx_drop( g_context );
+ if (g_context != NULL)
+ {
+ DBG(sqsh_debug(DEBUG_ERROR, "connect: Dropping context\n");)
+ if (ct_exit( g_context, CS_UNUSED ) != CS_SUCCEED)
+ ct_exit( g_context, CS_FORCE_EXIT );
+ cs_ctx_drop( g_context );
+ }
}
-
g_connection = NULL;
g_context = NULL;
return_code = CMD_FAIL;
@@ -1218,7 +1425,7 @@ connect_leave:
if ( exp_buf != NULL)
varbuf_destroy( exp_buf );
- sg_login = False;
+ sig_restore();
return return_code;
}
@@ -1247,12 +1454,16 @@ int cmd_snace( argc, argv )
static int check_opt_capability( g_connection )
CS_CONNECTION *g_connection;
{
- CS_BOOL val;
- CS_RETCODE ret = ct_capability(g_connection, CS_GET,
- CS_CAP_REQUEST,
- CS_OPTION_GET, (CS_VOID*)&val);
- if(ret != CS_SUCCEED || val == CS_FALSE)
- return 0;
+ CS_BOOL val;
+ CS_RETCODE ret;
+
+ ret = ct_capability( g_connection,
+ CS_GET,
+ CS_CAP_REQUEST,
+ CS_OPTION_GET, (CS_VOID*)&val
+ );
+ if (ret != CS_SUCCEED || val == CS_FALSE)
+ return 0;
return 1;
}
@@ -1277,11 +1488,11 @@ static int wrap_print( outfile, str )
cur_end = str + min(len, width) ;
end = str + len ;
- while( len > 0 && cur_end <= end )
+ while( len > 0 && cur_end <= end )
{
/*-- Move backwards until we hit whitespace --*/
- if( cur_end < end )
+ if( cur_end < end )
{
while( cur_end != start && !(isspace((int)*cur_end)) )
--cur_end ;
@@ -1290,10 +1501,10 @@ static int wrap_print( outfile, str )
if( cur_end == start )
cur_end = start + (min(len, width)) ;
}
-
+
/*-- Print out the line --*/
fprintf( outfile, "%*.*s", (int)(cur_end - start),
- (int)(cur_end - start),
+ (int)(cur_end - start),
start ) ;
if (*(cur_end-1) != '\n')
@@ -1331,13 +1542,19 @@ static CS_RETCODE syb_server_cb (ctx, con, msg)
char var_value[31];
int i;
char *c;
+ /* sqsh-2.5 - New variables to support feature p2f */
+ char *p2faxm;
+ int p2faxm_int;
+ char *p2fname;
+ FILE *dest_fp;
+ int p2fstat = False;
/*
* Record last error in $?
*/
if (msg->severity > 10)
{
- sprintf( var_value, "%d", msg->msgnumber );
+ sprintf( var_value, "%d", (int) msg->msgnumber );
env_set( g_internal_env, "?", var_value );
}
@@ -1348,11 +1565,11 @@ static CS_RETCODE syb_server_cb (ctx, con, msg)
* appropriate variable.
*/
if( msg->msgnumber == 5701 || /* database context change */
- msg->msgnumber == 5703 || /* language changed */
- msg->msgnumber == 5704 ) /* charset changed */
+ msg->msgnumber == 5703 || /* language changed */
+ msg->msgnumber == 5704 ) /* charset changed */
{
- if (msg->text != NULL && (c = strchr( msg->text, '\'' )) != NULL)
+ if (msg->text != NULL && (c = strchr( msg->text, '\'' )) != NULL)
{
i = 0;
for( ++c; i <= 30 && *c != '\0' && *c != '\''; ++c )
@@ -1366,10 +1583,14 @@ static CS_RETCODE syb_server_cb (ctx, con, msg)
*/
if (strcmp( var_value, "<NULL>" ) != 0)
{
- switch (msg->msgnumber)
+ switch (msg->msgnumber)
{
- case 5701 :
+ case 5701 :
env_set( g_env, "database", var_value );
+#if defined(USE_READLINE)
+ /* sqsh-2.1.8 - Feature dynamic keyword load */
+ env_set( g_internal_env, "keyword_refresh", "1" );
+#endif
break;
case 5703 :
env_set( g_env, "language", var_value );
@@ -1386,9 +1607,14 @@ static CS_RETCODE syb_server_cb (ctx, con, msg)
}
/*
- * If we got a login failed message, then record it as such as return.
+ * If we got a login failed message, then record it as such and return.
+ * sqsh-2.1.8 : Fix password_retry for Sybase RepServer and Microsoft MSSQL connections.
+ * We also need to check for sg_login == True, i.e. we are in the middle of a login attempt.
*/
- if (msg->msgnumber == 4002)
+ if (sg_login == True && (msg->msgnumber == 1017 || /* DCO/ECDA Oracle */
+ msg->msgnumber == 4002 || /* Sybase ASE/ASA/IQ */
+ msg->msgnumber == 14021 || /* Sybase RepServer */
+ msg->msgnumber == 18456)) /* Microsoft MSSQL */
{
wrap_print( stderr, msg->text );
sg_login_failed = True;
@@ -1397,7 +1623,7 @@ static CS_RETCODE syb_server_cb (ctx, con, msg)
/*
* Retrieve the threshold severity level for ignoring errors.
- * If the variable is set and severity is less than the
+ * If the variable is set and severity is less than the
* threshold, then return without printing out the message.
*/
env_get( g_env, "thresh_display", &thresh_display );
@@ -1409,37 +1635,63 @@ static CS_RETCODE syb_server_cb (ctx, con, msg)
* If the severity is something other than 0 or the msg number is
* 0 (user informational messages).
*/
- if (msg->severity >= 0 || msg->msgnumber == 10)
+ if (msg->severity >= 0 || msg->msgnumber == 10)
{
/*
+ * sqsh-2.5 : Implementation of p2f feature.
+ * When the number of messages handled by this callback handler exceeds the limit specified in p2faxm,
+ * and a file is provided in $p2fname and is succesfully opened and we are in interactive mode, then
+ * write the remaining messages from the current batch to this file instead of on screen.
+ * Note that global variable g_p2fc will be reset to zero for each new batch in dsp.c.
+ */
+ env_get( g_env, "p2faxm", &p2faxm );
+ p2faxm_int = (p2faxm != NULL) ? atoi(p2faxm) : 0;
+ if (++g_p2fc > p2faxm_int &&
+ p2faxm_int > 0 &&
+ g_p2f_fp != NULL &&
+ g_interactive == True)
+ {
+ if (g_p2fc == p2faxm_int + 1) {
+ env_get( g_env, "p2fname", &p2fname );
+ fprintf (stderr,"Warning: Number of printed server messages exceeds p2faxm=%d limit for current batch.\n", p2faxm_int);
+ fprintf (stderr," Remaining server messages will be printed to file: %s\n", p2fname);
+ fflush (stderr );
+ fprintf (g_p2f_fp, "--------\n");
+ }
+ p2fstat = True;
+ }
+
+ /*
* If the message was something other than informational, and
* the severity was greater than 0, then print information to
- * stderr with a little pre-amble information. According to
+ * stderr with a little pre-amble information. According to
* the Sybase System Administrator's guide, severity level 10
* messages should not display severity information.
*/
if (msg->msgnumber > 0 && msg->severity > 10)
{
- fprintf( stderr, "Msg %d, Level %d, State %d\n",
+ dest_fp = (p2fstat == True) ? g_p2f_fp : stderr;
+ fprintf( dest_fp, "Msg %d, Level %d, State %d\n",
(int)msg->msgnumber, (int)msg->severity, (int)msg->state );
if (msg->svrnlen > 0)
- fprintf( stderr, "Server '%s'", (char*)msg->svrname );
+ fprintf( dest_fp, "Server '%s'", (char*)msg->svrname );
if (msg->proclen > 0)
- fprintf( stderr, ", Procedure '%s'", (char*)msg->proc );
+ fprintf( dest_fp, ", Procedure '%s'", (char*)msg->proc );
if( msg->line > 0 )
- fprintf( stderr, ", Line %d", (int)msg->line );
- fprintf( stderr, "\n" );
- wrap_print( stderr, msg->text );
- fflush( stderr );
+ fprintf( dest_fp, ", Line %d", (int)msg->line );
+ fprintf( dest_fp, "\n" );
+ wrap_print( dest_fp, msg->text );
+ fflush( dest_fp );
}
- else
+ else
{
/*
* Otherwise, it is just an informational (e.g. print) message
* from the server, so send it to stdout.
*/
- wrap_print( stdout, msg->text );
- fflush( stdout );
+ dest_fp = (p2fstat == True) ? g_p2f_fp : stdout;
+ wrap_print( dest_fp, msg->text );
+ fflush( dest_fp );
}
}
}
@@ -1450,7 +1702,7 @@ static CS_RETCODE syb_server_cb (ctx, con, msg)
*/
env_get( g_env, "thresh_fail", &thresh_fail );
- if (thresh_fail != NULL && msg->severity >= (CS_INT)atoi(thresh_fail))
+ if (thresh_fail != NULL && msg->severity >= (CS_INT)atoi(thresh_fail))
{
DBG(sqsh_debug(DEBUG_ERROR,
"syb_server_cb: thresh_fail = %s, severity = %d, incrementing batch_failcount\n",
@@ -1476,13 +1728,17 @@ static CS_RETCODE syb_cs_cb ( ctx, msg )
/*
* If this is the "The attempt to connect to the server failed"
* message and we previously got a "Login Failed" message from
- * the server, then ignore it.
+ * the server (44), then ignore it.
+ *
+ * sqsh-2.1.9: The same for the freetds "Adaptive Server connection failed"
+ * message number 34. Also check for g_interactive and display the Client
+ * Message if the session is not interactive.
*/
- if (CS_NUMBER(msg->msgnumber) == 44 && sg_login_failed == True)
+ if ((CS_NUMBER(msg->msgnumber) == 34 || CS_NUMBER(msg->msgnumber) == 44)
+ && sg_login_failed == True && g_interactive == True)
{
return CS_SUCCEED;
}
-
fprintf( stderr, "Open Client Message\n" );
if (CS_NUMBER(msg->msgnumber) > 0)
@@ -1543,10 +1799,17 @@ static CS_RETCODE syb_client_cb ( ctx, con, msg )
if (sg_login == False)
{
env_get( g_env, "DSQUERY", &server ) ;
- if (CS_SEVERITY(msg->msgnumber) >= CS_SV_COMM_FAIL || ctx == NULL ||
- con == NULL)
+#if defined(CS_TDS_50)
+ if (CS_SEVERITY(msg->msgnumber) >= CS_SV_COMM_FAIL ||
+ ctx == NULL || con == NULL)
+#else
+ /* Then we use freetds which uses enum instead of defines */
+ if ((CS_SEVERITY(msg->msgnumber) >= CS_SV_COMM_FAIL &&
+ CS_SEVERITY(msg->msgnumber) <= CS_SV_FATAL) ||
+ ctx == NULL || con == NULL)
+#endif
{
- fprintf (stderr, "%s: Aborting on severity %d\n", server, CS_SEVERITY(msg->msgnumber) );
+ fprintf (stderr, "%s: Aborting on severity %d\n", server, (int) CS_SEVERITY(msg->msgnumber) );
sqsh_exit(254);
}
}
@@ -1560,14 +1823,15 @@ static CS_RETCODE syb_client_cb ( ctx, con, msg )
env_get( g_env, "DSQUERY", &server ) ;
env_get( g_env, "max_timeout", &max_timeout ) ;
if (max_timeout != NULL && *max_timeout != '\0' && atoi(max_timeout) > 0)
- if (timeouts >= atoi(max_timeout))
- {
- fprintf (stderr, "%s: Query or command timeout detected, session aborted\n", server);
- fprintf (stderr, "%s: The client connection has detected this %d time(s).\n", server, timeouts);
- fprintf (stderr, "%s: Aborting on max_timeout limit %s\n", server, max_timeout );
- sqsh_exit(254);
- }
-
+ {
+ if (timeouts >= atoi(max_timeout))
+ {
+ fprintf (stderr, "%s: Query or command timeout detected, session aborted\n", server);
+ fprintf (stderr, "%s: The client connection has detected this %d time(s).\n", server, timeouts);
+ fprintf (stderr, "%s: Aborting on max_timeout limit %s\n", server, max_timeout );
+ sqsh_exit(254);
+ }
+ }
if (ct_con_props (con, CS_GET, CS_LOGIN_STATUS, (CS_VOID *)&status, CS_UNUSED, NULL) != CS_SUCCEED)
{
fprintf (stderr,"%s: ct_con_props() failed\n", server);
@@ -1603,8 +1867,7 @@ static CS_RETCODE syb_client_cb ( ctx, con, msg )
*
* Return : CS_FAIL or CS_SUCCEED
*/
-static CS_RETCODE
-SetNetAuth (conn, principal, keytab_file, secmech, req_options)
+static CS_RETCODE SetNetAuth (conn, principal, keytab_file, secmech, req_options)
CS_CONNECTION *conn;
CS_CHAR *principal;
CS_CHAR *keytab_file;
@@ -1620,7 +1883,7 @@ SetNetAuth (conn, principal, keytab_file, secmech, req_options)
CS_BOOL OptSupported;
NET_SEC_SERVICE nss[] = {
- /*
+ /*
* CS_SEC_NETWORKAUTH must be the first entry
*/
{ CS_SEC_NETWORKAUTH, 'u', "Network user authentication (unified login)" },
@@ -1778,13 +2041,13 @@ SetNetAuth (conn, principal, keytab_file, secmech, req_options)
#endif
}
+
/*
* Function: ShowNetAuthCredExp()
*
* Show the credential expiration timeout period of a network authenticated session.
*/
-static CS_RETCODE
-ShowNetAuthCredExp (conn, cmdname)
+static CS_RETCODE ShowNetAuthCredExp (conn, cmdname)
CS_CONNECTION *conn;
CS_CHAR *cmdname;
{
@@ -1794,6 +2057,8 @@ ShowNetAuthCredExp (conn, cmdname)
char *datetime;
char dttm[32];
time_t exp_time;
+ char *fmt;
+ char *cp;
/*
* Check if current session is Network Authenticated.
@@ -1827,8 +2092,8 @@ ShowNetAuthCredExp (conn, cmdname)
return CS_FAIL;
}
- switch (CredTimeOut)
- {
+ switch (CredTimeOut)
+ {
case CS_NO_LIMIT:
fprintf (stdout, "%s: Network Authenticated session does not expire\n", cmdname);
break;
@@ -1842,13 +2107,30 @@ ShowNetAuthCredExp (conn, cmdname)
break;
default:
- env_get( g_env, "datetime", &datetime ) ;
- if (datetime == NULL || datetime[0] == '\0' || strcmp(datetime,"default") == 0)
- datetime = "%Y%m%d %H:%M:%S";
exp_time = time (NULL) + CredTimeOut;
- cftime( dttm, datetime, &exp_time ) ;
+ env_get( g_env, "datetime", &datetime ) ;
+ if (datetime == NULL || datetime[0] == '\0' || strcmp(datetime, "default") == 0)
+ {
+ cftime( dttm, "%Y%m%d %H:%M:%S", &exp_time );
+ }
+ else
+ {
+ fmt = (char *) malloc (sizeof(char) * strlen(datetime)+2);
+ for (cp = fmt; *datetime != '\0'; datetime++)
+ {
+ if (*datetime == '.' && *(datetime+1) == '%' && *(datetime+2) == 'q')
+ {
+ datetime += 2;
+ }
+ else if (*datetime != '[' && *datetime != ']')
+ *cp++ = *datetime;
+ }
+ *cp = '\0';
+ cftime( dttm, fmt, &exp_time );
+ free (fmt);
+ }
fprintf (stdout, "%s: Network Authenticated session expires at: %s (%d secs)\n",
- cmdname, dttm, CredTimeOut );
+ cmdname, dttm, (int) CredTimeOut );
}
}
else
@@ -1860,3 +2142,42 @@ ShowNetAuthCredExp (conn, cmdname)
#endif
}
+
+/*
+ * connect_run_sigint():
+ *
+ * This function is called whenever a SIGINT signal is received while processing cmd_connect.
+ * Its only real job is to return to the point where the SETJMP function was executed.
+ */
+static void connect_run_sigint (sig, user_data )
+ int sig;
+ void *user_data;
+{
+ sg_interrupted = True;
+ LONGJMP (sg_jmp_buf, 1);
+}
+
+
+#if defined(CS_SSLVALIDATE_CB)
+/*
+ * sqsh-2.5 - Validate the servername in a host:port:ssl type of connection
+ * to be valid for the chosen certificate if the servername does
+ * not match the CN in the certificate.
+ */
+static CS_RETCODE validate_srvname_cb (userdata, certptr, certcount, valid)
+ CS_VOID *userdata;
+ CS_SSLCERT *certptr;
+ CS_INT certcount;
+ CS_INT valid;
+{
+ if (valid == CS_SSL_INVALID_MISMATCHNAME)
+ {
+ return CS_SSL_VALID_CERT;
+ }
+ else
+ {
+ return valid;
+ }
+}
+#endif
+
diff --git a/src/cmd_do.c b/src/cmd_do.c
index 0956314..e44dc18 100644
--- a/src/cmd_do.c
+++ b/src/cmd_do.c
@@ -51,8 +51,8 @@ static int cmd_do_exec _ANSI_ARGS(( CS_CONNECTION*, char*,
char* ));
/*
-** sg_jmp_buf: The following buffer is used to contain the location
-** to which this module will return upon receipt of a
+** sg_jmp_buf: The following buffer is used to contain the location
+** to which this module will return upon receipt of a
** SIGINT. It is only used while waiting on input from the
** user.
*/
@@ -74,7 +74,9 @@ int cmd_do( argc, argv )
varbuf_t *do_buf;
varbuf_t *orig_sqlbuf; /* SQL Buffer upon entry */
CS_CONNECTION *orig_conn; /* Connection upon entry */
- int ret;
+ CS_CONTEXT *orig_ctxt; /* Context upon entry */
+ char orig_password[SQSH_PASSLEN+1] = ""; /* Current session password */
+ int ret = False;
int have_error = False;
int exit_status;
int do_connection = True;
@@ -86,9 +88,23 @@ int cmd_do( argc, argv )
*/
env_tran( g_env );
- while ((ch = sqsh_getopt( argc, argv, "S:U:P:D:n" )) != EOF)
+ /*
+ * sqsh-2.4 modification.
+ * This is totally utterly ugly, but the \do block may call \reconnect with a lot of
+ * parameter changes that will be committed in the global environment upon a successfull
+ * connection. If we put some of the original values on the logsave chain first, then the
+ * env_rollback call at the end of this function will eventually restore these parameter
+ * values back to the values of the current session.
+ */
+ env_get( g_env, "DSQUERY", &expand); env_put( g_env, "DSQUERY", expand, ENV_F_TRAN );
+ env_get( g_env, "database", &expand); env_put( g_env, "database", expand, ENV_F_TRAN );
+ env_get( g_env, "username", &expand); env_put( g_env, "username", expand, ENV_F_TRAN );
+ if (g_password != NULL)
+ strcpy ( orig_password, g_password);
+
+ while ((ch = sqsh_getopt( argc, argv, "S:U:P:D:n" )) != EOF)
{
- switch (ch)
+ switch (ch)
{
case 'n' :
do_connection = False;
@@ -107,14 +123,12 @@ int cmd_do( argc, argv )
ret = env_put( g_env, "database", sqsh_optarg, ENV_F_TRAN );
break;
default :
- fprintf( stderr, "\\do: -%c: Invalid option\n",
- (int)ch );
- have_error = True;
+ ret = False;
}
if (ret != True)
{
- fprintf( stderr, "\\do: -%c: %s\n", ch, sqsh_get_errstr() );
+ fprintf( stderr, "\\do: %s\n", sqsh_get_errstr() );
have_error = True;
}
}
@@ -123,9 +137,9 @@ int cmd_do( argc, argv )
** If there are any errors on the command line, or there are
** any options left over then we have an error.
*/
- if( (argc - sqsh_optind) > 0 || have_error == True)
+ if( (argc - sqsh_optind) > 0 || have_error == True)
{
- fprintf( stderr,
+ fprintf( stderr,
"Use: \\do [-n] [-S server] [-U user] [-P pass] [-D db]\n"
" -n Do not establish new connection (cannot issue SQL)\n"
" -S Perform do-loop on specified server\n"
@@ -168,7 +182,7 @@ int cmd_do( argc, argv )
}
/*
- ** Before we go any further, read the reaminder of the input
+ ** Before we go any further, read the remainder of the input
** from the user (up to \done).
*/
do_buf = varbuf_create( 512 );
@@ -196,7 +210,7 @@ int cmd_do( argc, argv )
return(CMD_FAIL);
}
- if (sqsh_expand( varbuf_getstr( g_sqlbuf ), expand_buf,
+ if (sqsh_expand( varbuf_getstr( g_sqlbuf ), expand_buf,
(EXP_STRIPESC|EXP_COMMENT|EXP_COLUMNS) ) == False)
{
fprintf( stderr, "\\do: Expansion failure: %s\n",
@@ -223,9 +237,10 @@ int cmd_do( argc, argv )
*/
orig_sqlbuf = g_sqlbuf;
orig_conn = g_connection;
+ orig_ctxt = g_context;
/*
- ** And replace then with new copies. Note that setting
+ ** And replace then with new copies. Note that setting
** g_connection to NULL will cause a new connection to be
** established for us by \connect.
*/
@@ -242,7 +257,8 @@ int cmd_do( argc, argv )
if (do_connection == True)
{
g_connection = NULL;
- if (jobset_run( g_jobset, "\\connect", &exit_status ) == -1)
+ g_context = NULL;
+ if (jobset_run( g_jobset, "\\connect", &exit_status ) == -1)
{
fprintf( stderr, "\\do: Connect failed\n" );
ret = exit_status;
@@ -254,17 +270,28 @@ int cmd_do( argc, argv )
ret = cmd_do_exec( orig_conn, sql, varbuf_getstr(do_buf) );
}
- if (do_connection == True &&
+ if (do_connection == True &&
g_connection != NULL)
{
- ct_close( g_connection, CS_FORCE_CLOSE );
+ if (ct_close( g_connection, CS_UNUSED ) != CS_SUCCEED)
+ ct_close( g_connection, CS_FORCE_CLOSE );
ct_con_drop( g_connection );
g_connection = NULL;
}
+ if (do_connection == True &&
+ g_context != NULL)
+ {
+ if (ct_exit ( g_context, CS_UNUSED) != CS_SUCCEED)
+ ct_exit ( g_context, CS_FORCE_EXIT );
+ cs_ctx_drop ( g_context );
+ g_context = NULL;
+ }
+
varbuf_destroy( g_sqlbuf );
varbuf_destroy( do_buf );
+ g_context = orig_ctxt;
g_connection = orig_conn;
g_sqlbuf = orig_sqlbuf;
@@ -272,6 +299,7 @@ int cmd_do( argc, argv )
varbuf_destroy( expand_buf );
env_rollback( g_env );
+ env_set( g_env, "password", orig_password );
return(ret);
}
@@ -289,6 +317,9 @@ static int cmd_do_exec( conn, sql, dobuf )
/*
** Save away current signal context.
+ **
+ ** sqsh-2.5: Make sure that the signal context is restored using sig_restore() prior
+ ** to every return from this function.
*/
sig_save();
@@ -314,24 +345,27 @@ static int cmd_do_exec( conn, sql, dobuf )
{
fprintf( stderr, "\\do: Error initializing command\n" );
- sig_restore();
ct_cmd_drop( cmd );
+ sig_restore();
return(CMD_FAIL);
}
+ /* sqsh-2.5 - Feature p2f, reset g_p2fc before a new batch is started */
+ g_p2fc = 0;
+
if (ct_send( cmd ) != CS_SUCCEED)
{
fprintf( stderr, "\\do: Error sending command\n" );
- sig_restore();
ct_cmd_drop( cmd );
+ sig_restore();
return(CMD_FAIL);
}
/*
** Suck in the results.
*/
- while ((retcode = ct_results( cmd, &result_type ))
+ while ((retcode = ct_results( cmd, &result_type ))
== CS_SUCCEED)
{
/*
@@ -341,6 +375,7 @@ static int cmd_do_exec( conn, sql, dobuf )
{
ct_cancel( conn, (CS_COMMAND*)NULL, CS_CANCEL_ALL );
ct_cmd_drop( cmd );
+ sig_restore();
return(CMD_INTERRUPTED);
}
@@ -355,6 +390,7 @@ static int cmd_do_exec( conn, sql, dobuf )
{
ct_cancel( conn, (CS_COMMAND*)NULL, CS_CANCEL_ALL );
ct_cmd_drop( cmd );
+ sig_restore();
if (retcode == CS_CANCELED)
{
@@ -373,6 +409,7 @@ static int cmd_do_exec( conn, sql, dobuf )
{
ct_cancel( conn, (CS_COMMAND*)NULL, CS_CANCEL_ALL );
ct_cmd_drop( cmd );
+ sig_restore();
return(CMD_FAIL);
}
@@ -381,12 +418,13 @@ static int cmd_do_exec( conn, sql, dobuf )
ct_cancel( conn, (CS_COMMAND*)NULL, CS_CANCEL_ALL );
ct_cmd_drop( cmd );
dsp_desc_destroy( desc );
+ sig_restore();
return(CMD_INTERRUPTED);
}
/*
** Save away the column description in the global table
- ** of column descriptions (these will be referenced
+ ** of column descriptions (these will be referenced
** during expansion of the sqlbuf.
*/
g_do_cols[g_do_ncols] = desc;
@@ -401,8 +439,8 @@ static int cmd_do_exec( conn, sql, dobuf )
** For each row we fetch back, we want to execute
** the dobuf.
*/
- if ((ret = cmd_input()) == CMD_FAIL ||
- ret == CMD_ABORT ||
+ if ((ret = cmd_input()) == CMD_FAIL ||
+ ret == CMD_ABORT ||
ret == CMD_INTERRUPTED ||
ret == CMD_BREAK ||
ret == CMD_RETURN)
@@ -417,6 +455,7 @@ static int cmd_do_exec( conn, sql, dobuf )
*/
if (ret == CMD_BREAK)
{
+ sig_restore();
return(CMD_LEAVEBUF);
}
@@ -424,6 +463,7 @@ static int cmd_do_exec( conn, sql, dobuf )
ct_cmd_drop( cmd );
dsp_desc_destroy( desc );
--g_do_ncols;
+ sig_restore();
return(ret);
}
@@ -434,6 +474,7 @@ static int cmd_do_exec( conn, sql, dobuf )
ct_cancel( conn, (CS_COMMAND*)NULL, CS_CANCEL_ALL );
ct_cmd_drop( cmd );
dsp_desc_destroy( desc );
+ sig_restore();
return(CMD_INTERRUPTED);
}
}
@@ -445,6 +486,7 @@ static int cmd_do_exec( conn, sql, dobuf )
{
ct_cancel( conn, (CS_COMMAND*)NULL, CS_CANCEL_ALL );
ct_cmd_drop( cmd );
+ sig_restore();
if (retcode == CS_CANCELED)
{
@@ -463,10 +505,12 @@ static int cmd_do_exec( conn, sql, dobuf )
{
ct_cancel( conn, (CS_COMMAND*)NULL, CS_CANCEL_ALL );
ct_cmd_drop( cmd );
+ sig_restore();
return(CMD_FAIL);
}
ct_cmd_drop( cmd );
+ sig_restore();
return(CMD_RESETBUF);
}
@@ -603,7 +647,7 @@ int cmd_body_input( buf )
if (*cp == '\\')
{
++cp;
- for(i = 0; i < (sizeof(cmd)-1) && *cp != '\0' &&
+ for(i = 0; i < (sizeof(cmd)-1) && *cp != '\0' &&
isalpha((int)*cp); ++i, ++cp)
{
cmd[i] = *cp;
@@ -629,9 +673,10 @@ int cmd_body_input( buf )
prompt_indent[i] = '\0';
env_put( g_env, "prompt_indent", prompt_indent, ENV_F_TRAN );
}
- else if ((strcmp( cmd, "do" ) == 0) ||
- strcmp( cmd, "func" ) == 0 ||
- strcmp( cmd, "while" ) == 0)
+ else if ( strcmp( cmd, "do" ) == 0 ||
+ strcmp( cmd, "for" ) == 0 || /* sqsh-2.3 - Improvement suggested by Niki Hansche */
+ strcmp( cmd, "func" ) == 0 ||
+ strcmp( cmd, "while" ) == 0)
{
/*
** If we hit another \do statement, then we want to
@@ -674,7 +719,7 @@ static void cmd_do_sigint_cancel( sig, user_data )
{
if (user_data != NULL)
{
- ct_cancel( (CS_CONNECTION*)user_data, (CS_COMMAND*)NULL,
+ ct_cancel( (CS_CONNECTION*)user_data, (CS_COMMAND*)NULL,
CS_CANCEL_ATTN );
}
sg_canceled = True;
diff --git a/src/cmd_exit.c b/src/cmd_exit.c
index 8010ca4..8e5d04e 100644
--- a/src/cmd_exit.c
+++ b/src/cmd_exit.c
@@ -30,7 +30,7 @@
/*-- Current Version --*/
#if !defined(lint) && !defined(__LINT__)
-static char RCS_Id[] = "$Id: cmd_exit.c,v 1.3 2010/01/26 15:03:50 mwesdorp Exp $" ;
+static char RCS_Id[] = "$Id: cmd_exit.c,v 1.4 2012/03/14 09:17:51 mwesdorp Exp $" ;
USE(RCS_Id)
#endif /* !defined(lint) */
@@ -43,6 +43,8 @@ int cmd_exit( argc, argv )
int argc ;
char *argv[] ;
{
+ int i;
+
/*
* sqsh-2.1.7 - Feature to provide for an exit code.
*
@@ -65,6 +67,17 @@ int cmd_exit( argc, argv )
}
}
+ /*
+ * sqsh-2.1.8 - Check if jobs are running that would otherwise be killed.
+ * If that is the case, show a message and continue the shell.
+ */
+ for( i = 0; i < g_jobset->js_hsize; i++ ) {
+ if (g_jobset->js_jobs[i] != NULL) {
+ fprintf( stderr, "You have running jobs or pending job output\n" ) ;
+ return CMD_FAIL ;
+ }
+ }
+
return CMD_EXIT ;
}
diff --git a/src/cmd_for.c b/src/cmd_for.c
index 915b400..a07504e 100644
--- a/src/cmd_for.c
+++ b/src/cmd_for.c
@@ -50,7 +50,6 @@ int cmd_for( argc, argv )
{
varbuf_t *for_buf;
int ret;
- int exit_status;
char *var_name;
int i;
diff --git a/src/cmd_func.c b/src/cmd_func.c
index 1dcb4f4..5f52dfd 100644
--- a/src/cmd_func.c
+++ b/src/cmd_func.c
@@ -70,13 +70,12 @@ int cmd_func( argc, argv )
do_export = True;
break;
default :
- fprintf( stderr, "\\func: -%c: Invalid option\n",
- (int)ch );
+ fprintf( stderr, "\\func: %s\n", sqsh_get_errstr());
have_error = True;
}
}
- if ((argc - sqsh_optind) != 1)
+ if ( have_error || (argc - sqsh_optind) != 1)
{
fprintf( stderr, "Use: \\func [-x] <name>\n" );
fprintf( stderr, " <body>\n" );
@@ -181,8 +180,7 @@ int cmd_call( argc, argv )
if (f == NULL)
{
- fprintf( stderr, "\\call: Error calling %s: %s\n",
- func_name ? (char*)func_name : "NULL", sqsh_get_errstr() );
+ fprintf( stderr, "\\call: Error calling %s: %s\n", func_name ? (char*)func_name : "NULL", sqsh_get_errstr() );
return(CMD_FAIL);
}
diff --git a/src/cmd_go.c b/src/cmd_go.c
index b68556f..84ce504 100644
--- a/src/cmd_go.c
+++ b/src/cmd_go.c
@@ -41,7 +41,7 @@
/*-- Current Version --*/
#if !defined(lint) && !defined(__LINT__)
-static char RCS_Id[] = "$Id: cmd_go.c,v 1.4 2010/02/25 10:50:47 mwesdorp Exp $";
+static char RCS_Id[] = "$Id: cmd_go.c,v 1.7 2014/03/11 21:49:04 mwesdorp Exp $";
USE(RCS_Id)
#endif /* !defined(lint) */
@@ -78,6 +78,7 @@ int cmd_go( argc, argv )
char *repeat_batch; /* Dito. */
char *filter; /* Dito. */
char *filter_prog; /* Dito. */
+ char *nosepline; /* Dito. */
char *sql;
int sql_len;
char pause_buf[5]; /* Buffer for "hit enter" */
@@ -121,7 +122,7 @@ int cmd_go( argc, argv )
fprintf( stderr, "\\go: Unbalanced comment tokens encountered\n" );
have_error = True;
}
- else while ((ch = sqsh_getopt( argc, argv, "nfhps:m:x;w:d:t;T:" )) != EOF)
+ else while ((ch = sqsh_getopt( argc, argv, "nfhps:m:x;w:d:t;T:el" )) != EOF)
{
switch (ch)
{
@@ -159,6 +160,14 @@ int cmd_go( argc, argv )
}
break;
+ case 'e' :
+ if (env_put( g_env, "echo", "1", ENV_F_TRAN ) == False)
+ {
+ fprintf( stderr, "\\go: -e: %s\n", sqsh_get_errstr() );
+ have_error = True;
+ }
+ break;
+
case 'x' :
dsp_flags |= DSP_F_X;
@@ -174,6 +183,9 @@ int cmd_go( argc, argv )
case 'f' :
dsp_flags |= DSP_F_NOFOOTERS;
break;
+ case 'l' :
+ dsp_flags |= DSP_F_NOSEPLINE;
+ break;
case 'm' :
dsp_name = sqsh_optarg;
break;
@@ -218,11 +230,13 @@ int cmd_go( argc, argv )
if( (argc - sqsh_optind) > 1 || have_error)
{
fprintf( stderr,
- "Use: \\go [-d display] [-h] [-f] [-n] [-p] [-m mode] [-s sec]\n"
+ "Use: \\go [-d display] [-e] [-h] [-f] [-l] [-n] [-p] [-m mode] [-s sec]\n"
" [-t [filter]] [-w width] [-x [xgeom]] [-T title] [xacts]\n"
" -d display When used with -x, send result to named display\n"
+ " -e Echo SQL buffer to output\n"
" -h Suppress headers\n"
" -f Suppress footers\n"
+ " -l Suppress line separators with pretty style output mode\n"
" -n Do not expand variables\n"
" -p Report runtime statistics\n"
" -m mode Switch display mode for result set\n"
@@ -306,14 +320,15 @@ int cmd_go( argc, argv )
* Retrieve any variables that may affect the way in which
* we process or display data.
*/
- env_get( g_env, "headers", &headers );
- env_get( g_env, "footers", &footers );
- env_get( g_env, "echo", &echo );
- env_get( g_env, "expand", &expand );
- env_get( g_env, "statistics", &statistics );
- env_get( g_env, "clear_on_fail", &clear_on_fail );
- env_get( g_env, "batch_pause", &batch_pause );
- env_get( g_env, "filter", &filter );
+ env_get( g_env, "batch_pause", &batch_pause );
+ env_get( g_env, "clear_on_fail", &clear_on_fail );
+ env_get( g_env, "echo", &echo );
+ env_get( g_env, "expand", &expand );
+ env_get( g_env, "filter", &filter );
+ env_get( g_env, "footers", &footers );
+ env_get( g_env, "headers", &headers );
+ env_get( g_env, "nosepline", &nosepline );
+ env_get( g_env, "statistics", &statistics );
/*
* If the user didn't request for statistics via the flag, but
@@ -322,10 +337,12 @@ int cmd_go( argc, argv )
if( show_stats == False && (statistics != NULL && *statistics == '1') )
show_stats = True;
- if( !(dsp_flags & DSP_F_NOHEADERS) && headers != NULL && *headers == '0' )
+ if( !(dsp_flags & DSP_F_NOHEADERS) && headers != NULL && *headers == '0' )
dsp_flags |= DSP_F_NOHEADERS;
- if( !(dsp_flags & DSP_F_NOFOOTERS) && footers != NULL && *footers == '0' )
+ if( !(dsp_flags & DSP_F_NOFOOTERS) && footers != NULL && *footers == '0' )
dsp_flags |= DSP_F_NOFOOTERS;
+ if( !(dsp_flags & DSP_F_NOSEPLINE) && nosepline != NULL && *nosepline == '1' )
+ dsp_flags |= DSP_F_NOSEPLINE;
/*
diff --git a/src/cmd_history.c b/src/cmd_history.c
index 0a3bd91..42d5579 100644
--- a/src/cmd_history.c
+++ b/src/cmd_history.c
@@ -35,7 +35,7 @@
/*-- Current Version --*/
#if !defined(lint) && !defined(__LINT__)
-static char RCS_Id[] = "$Id: cmd_history.c,v 1.5 2010/02/25 10:50:47 mwesdorp Exp $" ;
+static char RCS_Id[] = "$Id: cmd_history.c,v 1.9 2013/12/03 09:22:23 mwesdorp Exp $" ;
USE(RCS_Id)
#endif /* !defined(lint) */
@@ -64,12 +64,14 @@ int cmd_history( argc, argv )
char dttm[32];
char hdrinfo[64];
char *datetime = NULL;
+ char *cp;
+ char fmt[64];
/*
- * Initialize number of history buffers to show to the total number of
- * available buffers.
- */
+ * Initialize number of history buffers to show to the total number of
+ * available buffers.
+ */
shownum = g_history->h_nitems;
/*
@@ -81,10 +83,7 @@ int cmd_history( argc, argv )
{
case 'i' :
show_info = True;
- env_get( g_env, "datetime", &datetime);
- if (datetime == NULL || datetime[0] == '\0' || (strcmp(datetime,"default") == 0))
- datetime = "%Y%m%d %H:%M:%S";
- break;
+ break;
case 'x' :
if ((shownum = atoi(sqsh_optarg)) <= 0)
@@ -92,7 +91,7 @@ int cmd_history( argc, argv )
fprintf( stderr, "\\history: Invalid value for option -x (%s)\n", sqsh_optarg );
have_error = True;
}
- break;
+ break;
default :
fprintf( stderr, "\\history: %s\n", sqsh_get_errstr() );
@@ -115,6 +114,32 @@ int cmd_history( argc, argv )
}
/*
+ * sqsh-2.2.0 - Since the datetime format string may contain [] to filter out seconds for
+ * smalldatetime datatypes, we have to remove these brackets here. Also replace the %u format
+ * specifier with 000 when specified in the format string.
+ * sqsh-2.5: Strip of .%q and [] from the datetime format string.
+ */
+ if (show_info == True)
+ {
+ env_get( g_env, "datetime", &datetime);
+ if (datetime == NULL || *datetime == '\0' || (strcmp(datetime,"default") == 0))
+ strcpy (fmt, "%Y%m%d %H:%M:%S");
+ else
+ {
+ for (cp = fmt; *datetime != '\0'; datetime++)
+ {
+ if (*datetime == '.' && *(datetime+1) == '%' && *(datetime+2) == 'q')
+ {
+ datetime += 2;
+ }
+ else if (*datetime != '[' && *datetime != ']')
+ *cp++ = *datetime;
+ }
+ *cp = '\0';
+ }
+ }
+
+ /*
* Since we want to print our history from oldest to newest we
* will traverse the list backwards. Note, I don't like having
* cmd_history() play with the internals of the history structure,
@@ -130,19 +155,20 @@ int cmd_history( argc, argv )
line = hb->hb_buf ;
while( (nl = strchr( line, '\n' )) != NULL ) {
if( line == hb->hb_buf ) {
- if (show_info == True) {
- ts = localtime( &hb->hb_dttm );
- strftime( dttm, sizeof(dttm), datetime, ts );
- sprintf( hdrinfo, "(%2d - %2d/%s) ",
- hb->hb_nbr, hb->hb_count, dttm ) ;
+ if (show_info == True)
+ {
+ ts = localtime( &hb->hb_dttm );
+ strftime( dttm, sizeof(dttm), fmt, ts );
+ sprintf( hdrinfo, "(%2d - %2d/%s) ",
+ hb->hb_nbr, hb->hb_count, dttm ) ;
}
else
- sprintf( hdrinfo, "(%d) ", hb->hb_nbr ) ;
+ sprintf( hdrinfo, "(%d) ", hb->hb_nbr ) ;
- printf( "%s%*.*s\n", hdrinfo, nl - line, nl - line, line ) ;
+ printf( "%s%*.*s\n", hdrinfo, (int) (nl - line), (int) (nl - line), line ) ;
} else {
- printf( "%*s%*.*s\n", strlen(hdrinfo), " ", nl - line, nl - line, line ) ;
+ printf( "%*s%*.*s\n", (int) strlen(hdrinfo), " ", (int) (nl - line), (int) (nl - line), line ) ;
}
line = nl + 1 ;
@@ -152,7 +178,6 @@ int cmd_history( argc, argv )
printf( " %s\n", line ) ;
}
-
return CMD_LEAVEBUF ;
}
@@ -176,51 +201,46 @@ int cmd_hist_load( argc, argv )
* Only one argument allowed.
*/
if( argc > 2 ) {
- fprintf( stderr, "\\hist_load: Too many arguments; Use: \\hist_load [filename]\n" ) ;
+ fprintf( stderr, "\\hist-load: Too many arguments; Use: \\hist-load [filename]\n" ) ;
return CMD_FAIL ;
}
+ if (argc == 2)
+ history = argv[1];
+ else
+ env_get( g_env, "history", &history );
+
/*
- * Check if the history has been created.
+ * Check if the history has been created and a history file is provided.
*/
- if (g_history != NULL)
+ if ( g_history != NULL && history != NULL && *history != '\0' )
{
- if (argc == 2)
- history = argv[1];
- else
- env_get( g_env, "history", &history );
+ exp_buf = varbuf_create( 512 );
- if ( history != NULL )
+ if (exp_buf == NULL)
{
- exp_buf = varbuf_create( 512 );
-
- if (exp_buf == NULL)
+ fprintf( stderr, "\\hist-load: %s\n", sqsh_get_errstr() );
+ }
+ else
+ {
+ if (sqsh_expand( history, exp_buf, 0 ) == False)
{
- fprintf( stderr, "sqsh_exit: %s\n", sqsh_get_errstr() );
+ fprintf( stderr, "\\hist-load: Error expanding $history: %s\n",
+ sqsh_get_errstr() );
}
else
{
- if (sqsh_expand( history, exp_buf, 0 ) == False)
- {
- fprintf( stderr, "sqsh_exit: Error expanding $history: %s\n",
- sqsh_get_errstr() );
- }
+ if (history_load( g_history, varbuf_getstr(exp_buf) ) == True)
+ fprintf( stdout, "\\hist-load - History buffer loaded from %s\n",
+ varbuf_getstr(exp_buf) );
else
- {
- if (history_load( g_history, varbuf_getstr(exp_buf) ) == True)
- {
- fprintf( stdout, "History buffer loaded from %s\n",
- varbuf_getstr(exp_buf) );
- sprintf( str, "%d", history_get_nbr(g_history) );
- env_set( g_env, "histnum", str );
- }
- else
- fprintf( stdout, "Failed to load history from %s\n",
- varbuf_getstr(exp_buf) );
+ fprintf( stderr, "\\hist-load - Error: Failed to load history from %s\n",
+ varbuf_getstr(exp_buf) );
- }
- varbuf_destroy( exp_buf );
+ sprintf( str, "%d", history_get_nbr(g_history) );
+ env_set( g_env, "histnum", str );
}
+ varbuf_destroy( exp_buf );
}
}
return CMD_LEAVEBUF ;
@@ -237,6 +257,7 @@ int cmd_hist_save( argc, argv )
int argc ;
char *argv[] ;
{
+ char str[16];
char *history;
varbuf_t *exp_buf;
@@ -245,45 +266,47 @@ int cmd_hist_save( argc, argv )
* Only one argument allowed.
*/
if( argc > 2 ) {
- fprintf( stderr, "\\hist_save: Too many arguments; Use: \\hist_save [filename]\n" ) ;
+ fprintf( stderr, "\\hist-save: Too many arguments; Use: \\hist-save [filename]\n" ) ;
return CMD_FAIL ;
}
+ if (argc == 2)
+ history = argv[1];
+ else
+ env_get( g_env, "history", &history );
+
/*
- * If the history has been created, and it contains items,
- * then we write the history out to a file.
+ * If the history has been created, and it contains items, and a history file is provided
+ * then we write the history out to this file.
*/
- if (g_history != NULL)
+ if ( g_history != NULL && history != NULL && *history != '\0' && history_get_nitems( g_history ) > 0 )
{
- if (argc == 2)
- history = argv[1];
- else
- env_get( g_env, "history", &history );
+ exp_buf = varbuf_create( 512 );
- if (history != NULL && history_get_nitems( g_history ) > 0)
+ if (exp_buf == NULL)
{
- exp_buf = varbuf_create( 512 );
-
- if (exp_buf == NULL)
+ fprintf( stderr, "\\hist-save: %s\n", sqsh_get_errstr() );
+ }
+ else
+ {
+ if (sqsh_expand( history, exp_buf, 0 ) == False)
{
- fprintf( stderr, "sqsh_exit: %s\n", sqsh_get_errstr() );
+ fprintf( stderr, "\\hist-save: Error expanding $history: %s\n",
+ sqsh_get_errstr() );
}
else
{
- if (sqsh_expand( history, exp_buf, 0 ) == False)
- {
- fprintf( stderr, "sqsh_exit: Error expanding $history: %s\n",
- sqsh_get_errstr() );
- }
+ if (history_save( g_history, varbuf_getstr(exp_buf) ) == True)
+ fprintf( stdout, "\\hist-save - History buffer saved to %s\n",
+ varbuf_getstr(exp_buf) );
else
- {
- if (history_save( g_history, varbuf_getstr(exp_buf) ) == True)
- fprintf( stdout, "History buffer saved to %s\n",
- varbuf_getstr(exp_buf) );
+ fprintf( stderr, "\\hist-save - Error: Failed to write history to %s\n",
+ varbuf_getstr(exp_buf) );
- }
- varbuf_destroy( exp_buf );
+ sprintf( str, "%d", history_get_nbr(g_history) );
+ env_set( g_env, "histnum", str );
}
+ varbuf_destroy( exp_buf );
}
}
return CMD_LEAVEBUF ;
diff --git a/src/cmd_if.c b/src/cmd_if.c
index 59ba367..38579ca 100644
--- a/src/cmd_if.c
+++ b/src/cmd_if.c
@@ -180,7 +180,6 @@ int cmd_if_exec( argc, argv, exit_status )
pid_t ret_pid;
int status;
char nbr[16];
- int ret;
func_t *f;
char *return_str;
@@ -233,7 +232,7 @@ int cmd_if_exec( argc, argv, exit_status )
case -1:
fprintf( stderr, "\\if: fork() call failed: %s\n",
strerror(errno) );
- env_set( g_internal_env, "$?", "-1" );
+ env_set( g_internal_env, "?", "-1" );
sig_restore();
return(CMD_FAIL);
@@ -264,7 +263,7 @@ int cmd_if_exec( argc, argv, exit_status )
fprintf( stderr, "\\if: Error from waitpid(): %s\n",
strerror(errno) );
- env_set( g_internal_env, "$?", "-1" );
+ env_set( g_internal_env, "?", "-1" );
sig_restore();
return(CMD_FAIL);
}
@@ -279,7 +278,7 @@ int cmd_if_exec( argc, argv, exit_status )
}
sprintf( nbr, "%d", *exit_status );
- env_set( g_internal_env, "$?", nbr );
+ env_set( g_internal_env, "?", nbr );
break;
}
@@ -468,6 +467,15 @@ int cmd_if_input( if_buf, else_buf )
}
prompt_indent[i] = '\0';
env_put( g_env, "prompt_indent", prompt_indent, ENV_F_TRAN );
+
+ /*
+ ** Bugfix sqsh-2.1.8
+ ** Copy the nested new 'if' into the current buffer.
+ */
+ if (parse_state == STATE_IF)
+ varbuf_strcat( if_buf, str );
+ else
+ varbuf_strcat( else_buf, str );
}
else if (strcmp( cmd, "elif" ) == 0 &&
nesting_level == 1)
diff --git a/src/cmd_input.c b/src/cmd_input.c
index 6fc34ce..60bf67c 100644
--- a/src/cmd_input.c
+++ b/src/cmd_input.c
@@ -52,7 +52,7 @@
/*-- Current Version --*/
#if !defined(lint) && !defined(__LINT__)
-static char RCS_Id[] = "$Id: cmd_input.c,v 1.5 2010/01/28 15:30:37 mwesdorp Exp $";
+static char RCS_Id[] = "$Id: cmd_input.c,v 1.9 2013/07/20 16:18:35 mwesdorp Exp $";
USE(RCS_Id)
#endif /* !defined(lint) */
@@ -60,6 +60,11 @@ USE(RCS_Id)
static void input_sigint_jmp _ANSI_ARGS(( int, void* ));
static char* input_strchr _ANSI_ARGS(( varbuf_t*, char*, int ));
static int input_read _ANSI_ARGS(( varbuf_t*, int ));
+#if defined(USE_READLINE)
+static int DynKeywordLoad _ANSI_ARGS(( void )); /* sqsh-2.1.8 - Feature dynamic keyword load */
+#endif
+/* sqsh-2.3 - Check if we currently are in a C style comment in the SQL buffer */
+static int csc_buffer _ANSI_ARGS(( varbuf_t* ));
/*
* The following macro is used to determine if a line of input is
@@ -71,8 +76,8 @@ static int input_read _ANSI_ARGS(( varbuf_t*, int ));
/*
- * sg_jmp_buf: The following buffer is used to contain the location
- * to which this module will return upon receipt of a
+ * sg_jmp_buf: The following buffer is used to contain the location
+ * to which this module will return upon receipt of a
* SIGINT. It is only used while waiting on input from the
* user.
*/
@@ -110,12 +115,15 @@ int cmd_input()
char *newline_go ; /* Value of $newline_go */
char *history_shorthand ; /* Value of $history_shorthand */
char *lineno ; /* Value of $lineno */
+#if defined(USE_READLINE)
+ char *keyword_dynamic ; /* Value of $keyword_dynamic */
+ char *keyword_refresh ; /* Value of $keyword_refresh */
+#endif
/*-- Misc --*/
int exit_status ; /* Exit status of sub-command */
JMP_BUF old_jmp_buf ; /* Store the previous jmp_buf */
int is_cmd ; /* True if the current line is cmd */
- int no_hist ; /* True if hist should not be updt. */
job_id_t job_id ; /* Id of job launched or completed */
char *defer_file ; /* Name of file holding user output */
struct stat stat_buf ; /* Check for defer file's existence */
@@ -127,6 +135,11 @@ int cmd_input()
int cur_lineno;
int interactive;
+ /*
+ * sqsh-2.2.0 - Extension on semicolon_hack
+ */
+ char *semicolon_hack2 ; /* Value of $semicolon_hack2 */
+ char *str_remainder = NULL; /* Remainder of input string after ; */
/*
* Variables that need to be restored before turning to the
@@ -229,37 +242,68 @@ int cmd_input()
*/
for (;;)
{
- no_hist = False; /* Save history for this buffer */
-
+#if defined(USE_READLINE)
/*
- * Clear out the buffer that will be used to place input read
- * from the user.
+ * sqsh-2.1.8 - Feature dynamic keyword load
+ * If we are in interactive mode and we have keyword_dynamic enabled
+ * then we want to do a refresh of the keyword list when the database
+ * context is changed, i.e. a "use <database>" command was executed.
*/
- varbuf_clear( read_buf );
+ env_get( g_env, "keyword_dynamic", &keyword_dynamic );
+ env_get( g_internal_env, "keyword_refresh", &keyword_refresh );
+ if (interactive &&
+ keyword_refresh != NULL && *keyword_refresh != '0' &&
+ keyword_dynamic != NULL && *keyword_dynamic != '0')
+ {
+ (void) DynKeywordLoad();
+ env_set( g_internal_env, "keyword_refresh", "0" );
+ }
+#endif
/*
- * If an input_file was supplied, or no input string was supplied
- * then call input_read. By default, if input_read gets a NULL
- * input_file, stdin is used.
+ * sqsh-2.2.0 - Semicolon_hack2. If str_remainder is not NULL
+ * then we have a leftover from the previous loop were a ;
+ * has been processed. So this part of the input should be
+ * processed next. The else branch executes the pre-sqsh-2.2.0
+ * code path.
*/
- ret = input_read( read_buf, interactive );
-
- if (ret <= 0)
+ if (str_remainder != NULL)
{
- if (ret == 0)
+ str = str_remainder;
+ str_remainder = NULL;
+ }
+ else
+ {
+ /*
+ * Clear out the buffer that will be used to place input read
+ * from the user.
+ */
+ varbuf_clear( read_buf );
+
+ /*
+ * If an input_file was supplied, or no input string was supplied
+ * then call input_read. By default, if input_read gets a NULL
+ * input_file, stdin is used.
+ */
+ ret = input_read( read_buf, interactive );
+
+ if (ret <= 0)
{
- goto loop_leave;
+ if (ret == 0)
+ {
+ goto loop_leave;
+ }
+ fprintf( stderr, "input: %s\n", sqsh_get_errstr() );
+ goto loop_abort;
}
- fprintf( stderr, "input: %s\n", sqsh_get_errstr() );
- goto loop_abort;
+
+ /*
+ * Pull contents of read_buf out.
+ */
+ str = varbuf_getstr( read_buf );
}
/*
- * Pull contents of read_buf out.
- */
- str = varbuf_getstr( read_buf );
-
- /*
* The first thing we need to determine is if the current
* line contains a sqsh command. This information will be
* used in several places.
@@ -276,7 +320,7 @@ int cmd_input()
* then we pretend it is a buffer recall. So, we turn
* it into a logical call to \buf-append.
*/
- if (is_cmd == False && interactive && *str == '!' &&
+ if (is_cmd == False && interactive && *str == '!' &&
!isspace((int)*(str+1)))
{
@@ -316,50 +360,93 @@ int cmd_input()
* input_strchr(), returns the first ';' in str that will not
* be contained in double quotes when str is appended to
* g_sqlbuf.
+ * sqsh-2.2.0 - If semicolon_hack2 is set, it doesn't matter
+ * if the input line is a command or not. We still want to
+ * process possible semicolons. So that makes the if statement
+ * a bit more complex.
*/
- env_get( g_env, "semicolon_hack", &semicolon_hack );
- if (semicolon_hack != NULL && *semicolon_hack == '1' && !is_cmd &&
- strchr( str, ';') != NULL &&
- (ch = input_strchr( g_sqlbuf, str, ';' )) != NULL)
+ env_get( g_env, "semicolon_hack", &semicolon_hack );
+ env_get( g_env, "semicolon_hack2", &semicolon_hack2 );
+ if ( (strchr( str, ';') != NULL && (ch = input_strchr( g_sqlbuf, str, ';' )) != NULL) &&
+ ((semicolon_hack != NULL && *semicolon_hack == '1' && !is_cmd) ||
+ (semicolon_hack2 != NULL && *semicolon_hack2 == '1'))
+ )
{
/*
- * Copy everything up to the ';' into the current work buffer.
- */
- if (ch - str != 0)
- {
- varbuf_strncat( g_sqlbuf, str, ch - str );
- varbuf_charcat( g_sqlbuf, '\n' );
-
- /*
- * We now have an extra line.
- */
- env_set( g_env, "lineno", "+1" );
- }
-
- /*
* Look up the name of the command that the user wishes
* to use when a semicolon is encountered.
*/
env_get( g_env, "semicolon_cmd", &semicolon_cmd );
-
if (semicolon_cmd == NULL || *semicolon_cmd == '\0')
- {
varbuf_strcpy( sg_buf, "\\go " );
- }
else
- {
varbuf_strcpy( sg_buf, semicolon_cmd );
- varbuf_charcat( sg_buf, ' ' );
- }
/*
- * Now, stick the semicolon command in the front of everything
- * following the semicolon. and turn that into the command
- * line.
+ * sqsh-2.2.0 - The hack is going to be even worse and worse.
+ * If semicolon_hack2 is set, then we treat a ; as a
+ * command or batch separator, execute the portion before
+ * the ; as a SQL buffer, or as a sqsh command. The remainder
+ * of the string after the ; is saved for later use.
*/
- varbuf_strcat( sg_buf, ch + 1 );
+ if (semicolon_hack2 != NULL && *semicolon_hack2 == '1')
+ {
+ /*
+ * replace the ; with end of line
+ */
+ *ch = '\0';
+ /*
+ * save the remainder of the string in str_remainder
+ * or set it to NULL if there is really nothing left
+ */
+ str_remainder = ch + 1;
+ if (*str_remainder == '\n' || *str_remainder == '\0')
+ str_remainder = NULL;
+ /*
+ * Check if we have to deal with a sqsh command or
+ * a SQL statement, at least the last part of it.
+ */
+ if (!is_cmd && jobset_is_cmd( g_jobset, str ) == False)
+ {
+ if (ch - str != 0)
+ {
+ varbuf_strncat( g_sqlbuf, str, ch - str );
+ varbuf_charcat( g_sqlbuf, '\n' );
+ env_set( g_env, "lineno", "+1" );
+ }
+ str = varbuf_getstr( sg_buf );
+ }
+ /* else the current str is a sqsh command */
+ }
+ else
+ {
+ /*
+ * Original pre-sqsh-2.2.0 code path with only
+ * semicolon_hack set to true.
+ */
+ /*
+ * Copy everything up to the ';' into the current work buffer.
+ */
+ if (ch - str != 0)
+ {
+ varbuf_strncat( g_sqlbuf, str, ch - str );
+ varbuf_charcat( g_sqlbuf, '\n' );
- str = varbuf_getstr( sg_buf );
+ /*
+ * We now have an extra line.
+ */
+ env_set( g_env, "lineno", "+1" );
+ }
+
+ /*
+ * Now, stick the semicolon command in the front of everything
+ * following the semicolon. and turn that into the command
+ * line.
+ */
+ varbuf_charcat( sg_buf, ' ' );
+ varbuf_strcat( sg_buf, ch + 1 );
+ str = varbuf_getstr( sg_buf );
+ }
is_cmd = True;
}
@@ -449,7 +536,7 @@ int cmd_input()
* if $interactive is set to 0, then this entry will
* automatically be thrown away.
*/
- if (!no_hist && interactive)
+ if (interactive)
{
history_append( g_history, varbuf_getstr(g_sqlbuf) );
@@ -463,8 +550,8 @@ int cmd_input()
case CMD_CLEARBUF:
/*
- * sqsh-2.1.7 - The same as CMD_RESETBUF but without
- * saving the buffer to the history.
+ * sqsh-2.1.7 - The same as CMD_RESETBUF but without
+ * saving the buffer to the history.
*/
varbuf_clear( g_sqlbuf );
env_set( g_env, "lineno", "=1" ) ; /* Set to 1 */
@@ -505,7 +592,6 @@ int cmd_input()
case CMD_ABORT :
goto loop_abort;
break;
-
default :
sprintf( number, "=%d", cur_lineno );
@@ -521,7 +607,7 @@ int cmd_input()
* jobset_run() returned a non-negative value, so it launched
* a background process. The only thing we need to do it
* let the user know it was launched.
- * sqsh-2.1.7 - Also save and clear the command buffer.
+ * sqsh-2.1.7 - Also save and clear the command buffer.
*/
default :
if (interactive)
@@ -529,14 +615,11 @@ int cmd_input()
job_pid = jobset_get_pid( g_jobset, job_id );
fprintf( stdout, "Job #%d running [%d]\n", (int)job_id,
(int)job_pid );
- if (!no_hist)
- {
- history_append( g_history, varbuf_getstr(g_sqlbuf) );
+ history_append( g_history, varbuf_getstr(g_sqlbuf) );
- /*-- Set histnum to be current history number --*/
- sprintf( number, "%d", history_get_nbr(g_history) );
- env_set( g_env, "histnum", number );
- }
+ /*-- Set histnum to be current history number --*/
+ sprintf( number, "%d", history_get_nbr(g_history) );
+ env_set( g_env, "histnum", number );
varbuf_clear( g_sqlbuf );
env_set( g_env, "lineno", "=1" ) ; /* Set to 1 */
}
@@ -551,7 +634,7 @@ int cmd_input()
* than each time the user hits return.
*/
job_id = 0;
- while(interactive &&
+ while(interactive &&
(job_id = jobset_wait(g_jobset, -1, &exit_status, JOB_NONBLOCK)) > 0)
{
/*
@@ -649,7 +732,7 @@ loop_done :
if (read_buf != NULL)
varbuf_destroy( read_buf );
-
+
/*
* Restore the line number to its previous value.
*/
@@ -667,7 +750,7 @@ loop_done :
varbuf_destroy( g_sqlbuf );
g_sqlbuf = (varbuf_t*)orig_sqlbuf;
}
-
+
/*
* Restore the original signal context, and, just in case
* cmd_loop() has been recursively called, restore the original
@@ -700,7 +783,7 @@ static int input_read( output_buf, interactive )
char *exp_prompt = NULL;
/*
- * If we are in interactive mode then we need to display a
+ * If we are in interactive mode then we need to display a
* prompt to the user.
*/
if (interactive)
@@ -708,7 +791,7 @@ static int input_read( output_buf, interactive )
/*
* If we haven't already allocated a buffer in which to
* expand the prompt then we should do so.
- * sqsh-2.1.6 - expand buffer from 32 to 64 bytes.
+ * sqsh-2.1.6 - expand buffer from 32 to 64 bytes.
*/
if (sg_prompt_buf == NULL)
{
@@ -736,13 +819,13 @@ static int input_read( output_buf, interactive )
if (!is_continued)
{
env_get( g_env, "prompt", &prompt );
- if( prompt == NULL || *prompt == '\0' )
+ if( prompt == NULL || *prompt == '\0' )
prompt = "${lineno}> ";
}
else
{
env_get( g_env, "prompt2", &prompt );
- if( prompt == NULL || *prompt == '\0' )
+ if( prompt == NULL || *prompt == '\0' )
prompt = "--> ";
}
@@ -755,7 +838,7 @@ static int input_read( output_buf, interactive )
fprintf( stderr, "prompt: %s\n", sqsh_get_errstr() );
varbuf_strcpy( sg_prompt_buf, "?> " );
}
-
+
exp_prompt = varbuf_getstr(sg_prompt_buf);
}
else
@@ -790,8 +873,12 @@ static int input_read( output_buf, interactive )
* table name, [_0-9A-Za-z]. If we hit a comment, then we
* simply ignore this line, without even incrementing the
* line number.
+ * sqsh-2.3 - Only ignore sqsh # comments if the current
+ * SQL buffer did not start a C style comment construct,
+ * that is not closed so far, and if we are not inside a
+ * single or double quotes string.
*/
- if (IS_COMMENT(str))
+ if (IS_COMMENT(str) && csc_buffer( g_sqlbuf ) == 0)
{
if (is_continued)
{
@@ -873,13 +960,13 @@ static char* input_strchr( varbuf, str, c )
case QUOTE_NONE:
switch (*cptr)
{
- case '\'':
+ case '\'':
quote_type = QUOTE_SINGLE;
break;
- case '\"':
+ case '\"':
quote_type = QUOTE_DOUBLE;
break;
- case '/' :
+ case '/' :
if (*(cptr + 1) == '*')
quote_type = QUOTE_COMMENT;
break;
@@ -897,28 +984,28 @@ static char* input_strchr( varbuf, str, c )
break;
}
break;
-
+
case QUOTE_COMMENT:
if (*cptr == '*' && *(cptr + 1) == '/')
{
quote_type = QUOTE_NONE;
}
break;
-
+
case QUOTE_SINGLE:
if (*cptr == '\'')
{
quote_type = QUOTE_NONE;
}
break;
-
+
case QUOTE_DOUBLE:
if (*cptr == '\"')
{
quote_type = QUOTE_NONE;
}
break;
-
+
default:
break;
}
@@ -935,13 +1022,13 @@ static char* input_strchr( varbuf, str, c )
case QUOTE_NONE:
switch (*cptr)
{
- case '\'':
+ case '\'':
quote_type = QUOTE_SINGLE;
break;
- case '\"':
+ case '\"':
quote_type = QUOTE_DOUBLE;
break;
- case '/' :
+ case '/' :
if (*(cptr + 1) == '*')
quote_type = QUOTE_COMMENT;
break;
@@ -959,28 +1046,28 @@ static char* input_strchr( varbuf, str, c )
break;
}
break;
-
+
case QUOTE_COMMENT:
if (*cptr == '*' && *(cptr + 1) == '/')
{
quote_type = QUOTE_NONE;
}
break;
-
+
case QUOTE_SINGLE:
if (*cptr == '\'')
{
quote_type = QUOTE_NONE;
}
break;
-
+
case QUOTE_DOUBLE:
if (*cptr == '\"')
{
quote_type = QUOTE_NONE;
}
break;
-
+
default:
break;
}
@@ -992,6 +1079,120 @@ static char* input_strchr( varbuf, str, c )
}
/*
+ * csc_buffer():
+ *
+ * sqsh-2.3 - Blast through the SQL buffer that is created up
+ * till now and see if we are in a quoted or double
+ * quoted string or in a C style comment.
+ * Return the value of the quote_type that reflects the
+ * current situation. (0 means not in quotes or comments)
+ */
+static int csc_buffer( varbuf )
+ varbuf_t *varbuf;
+{
+#define QUOTE_NONE 0
+#define QUOTE_SINGLE 1
+#define QUOTE_DOUBLE 2
+#define QUOTE_COMMENT 3
+
+ char *cptr;
+ int quote_type = QUOTE_NONE;
+ int csclevel = 0;
+
+
+ if ( (cptr = varbuf_getstr(varbuf)) == NULL )
+ return QUOTE_NONE;
+
+ /*-- Blast through varbuf --*/
+ for (; *cptr != '\0'; ++cptr)
+ {
+ /*
+ * First step over any escape characters and the character
+ * that is escaped by \\ itself, but still do a sanity
+ * check on end of string altogether.
+ */
+ if (*cptr == '\\' && *(cptr + 1) == '\\')
+ {
+ cptr += 3;
+ if (*cptr == '\0' || *(cptr - 1) == '\0')
+ break;
+ }
+
+ switch (quote_type)
+ {
+ case QUOTE_NONE:
+ switch (*cptr)
+ {
+ case '\'':
+ quote_type = QUOTE_SINGLE;
+ break;
+ case '\"':
+ quote_type = QUOTE_DOUBLE;
+ break;
+ case '/' :
+ if (*(cptr + 1) == '*')
+ {
+ quote_type = QUOTE_COMMENT;
+ ++csclevel;
+ ++cptr;
+ }
+ break;
+ case '-': /* -- comment till end of end line */
+ if (*(cptr + 1) == '-')
+ {
+ while (*cptr != '\n' && *cptr != '\0')
+ ++cptr;
+
+ if (*cptr == '\0')
+ --cptr;
+ }
+ break;
+ default:
+ break;
+ }
+ break;
+
+ case QUOTE_COMMENT:
+ /*
+ * C style comments in SQL may be nested, but do not
+ * take quoting or -- comments in account anymore.
+ * This is according to isql behavior.
+ */
+ if (*cptr == '/' && *(cptr + 1) == '*')
+ {
+ ++cptr;
+ ++csclevel;
+ }
+ else if (*cptr == '*' && *(cptr + 1) == '/')
+ {
+ ++cptr;
+ if (--csclevel == 0)
+ quote_type = QUOTE_NONE;
+ }
+ break;
+
+ case QUOTE_SINGLE:
+ if (*cptr == '\'')
+ {
+ quote_type = QUOTE_NONE;
+ }
+ break;
+
+ case QUOTE_DOUBLE:
+ if (*cptr == '\"')
+ {
+ quote_type = QUOTE_NONE;
+ }
+ break;
+
+ default:
+ break;
+ }
+ }
+ return quote_type;
+}
+
+/*
* input_sigint_jmp():
*
* Used to catch ^C's from the user. If there is currently a database
@@ -1003,3 +1204,140 @@ static void input_sigint_jmp( sig, user_data )
{
LONGJMP( sg_jmp_buf, 1 );
}
+
+#if defined(USE_READLINE)
+/*
+ * Function: DynKeywordLoad()
+ *
+ * sqsh-2.1.8 - Dynamically execute a query provided by the variable keyword_query
+ * and load the result set into the readline autocompletion list.
+ * By default the query is "select name from sysobjects order by name"
+ * But of course you can change this to anything you like as long as the result set
+ * contains a first column with character data. The variable keyword_query can be
+ * defined in your .sqshrc file for example or in a sqsh_session file.
+ *
+ */
+static int DynKeywordLoad ()
+{
+ CS_COMMAND *cmd;
+ CS_CHAR *keyword_query;
+ CS_DATAFMT columns[1];
+ CS_RETCODE ret;
+ CS_RETCODE results_ret;
+ CS_INT result_type;
+ CS_INT count;
+ CS_INT idx;
+ CS_INT datalength[1];
+ CS_SMALLINT indicator [1];
+ CS_CHAR name [256];
+
+
+ env_get( g_env, "keyword_query", &keyword_query );
+ if ( keyword_query == NULL || *keyword_query == '\0' ) {
+ DBG(sqsh_debug(DEBUG_ERROR, "DynKeywordLoad: Variable keyword_query is empty.\n"));
+ return (CS_FAIL);
+ }
+ if ( g_connection == NULL )
+ {
+ DBG(sqsh_debug(DEBUG_ERROR, "DynKeywordLoad: g_connection is not initialized.\n"));
+ return (CS_FAIL);
+ }
+ if (ct_cmd_alloc( g_connection, &cmd ) != CS_SUCCEED)
+ {
+ DBG(sqsh_debug(DEBUG_ERROR, "DynKeywordLoad: Call to ct_cmd_alloc failed.\n"));
+ return (CS_FAIL);
+ }
+ if (ct_command( cmd, /* Command Structure */
+ CS_LANG_CMD, /* Command Type */
+ keyword_query, /* Buffer */
+ CS_NULLTERM, /* Buffer Length */
+ CS_UNUSED /* Options */
+ ) != CS_SUCCEED)
+ {
+ ct_cmd_drop( cmd );
+ DBG(sqsh_debug(DEBUG_ERROR, "DynKeywordLoad: Call to ct_command failed.\n"));
+ return (CS_FAIL);
+ }
+ if (ct_send( cmd ) != CS_SUCCEED)
+ {
+ ct_cmd_drop( cmd );
+ DBG(sqsh_debug(DEBUG_ERROR, "DynKeywordLoad: Call to ct_send failed.\n"));
+ return (CS_FAIL);
+ }
+
+ (void) sqsh_readline_clear(); /* Empty the current keyword list */
+ (void) sqsh_readline_load (); /* Reload keywords from $keyword_file */
+
+ while ((results_ret = ct_results(cmd, &result_type)) == CS_SUCCEED)
+ {
+ switch ((int) result_type)
+ {
+ case CS_ROW_RESULT:
+ columns[0].datatype = CS_CHAR_TYPE;
+ columns[0].format = CS_FMT_NULLTERM;
+ columns[0].maxlength = 255;
+ columns[0].count = 1;
+ columns[0].locale = NULL;
+ ct_bind(cmd, 1, &columns[0], name, &datalength[0], &indicator[0]);
+
+ while ( ct_fetch (cmd, CS_UNUSED, CS_UNUSED, CS_UNUSED, &count) == CS_SUCCEED )
+ {
+ /* Remove trailing blanks, tabs and newlines, just in case */
+ for ( idx = strlen(name) - 1;
+ idx >= 0 && (name[idx] == ' ' || name[idx] == '\t' || name[idx] == '\n');
+ name[idx--] = '\0');
+ sqsh_readline_add (name); /* Add name to readline linked list of keywords */
+ }
+ break;
+
+ case CS_COMPUTE_RESULT:
+ case CS_CURSOR_RESULT:
+ case CS_MSG_RESULT:
+ case CS_PARAM_RESULT:
+ case CS_STATUS_RESULT:
+ /*
+ * Just ignore these kind of results.
+ */
+ while ( ct_fetch (cmd, CS_UNUSED, CS_UNUSED, CS_UNUSED, &count) == CS_SUCCEED );
+ break;
+
+ case CS_CMD_SUCCEED:
+ DBG(sqsh_debug(DEBUG_ERROR, "DynKeywordLoad: No rows returned from query.\n"));
+ ret = CS_FAIL;
+ break;
+
+ case CS_CMD_FAIL:
+ DBG(sqsh_debug(DEBUG_ERROR, "DynKeywordLoad: Error encountered during query processing.\n"));
+ ret = CS_FAIL;
+ break;
+
+ case CS_CMD_DONE:
+ break;
+
+ default:
+ DBG(sqsh_debug(DEBUG_ERROR, "DynKeywordLoad: Unexpected error encountered. (1)\n"));
+ ret = CS_FAIL;
+ break;
+ }
+ }
+
+ switch ((int) results_ret)
+ {
+ case CS_END_RESULTS:
+ ret = CS_SUCCEED;
+ break;
+
+ case CS_FAIL:
+ DBG(sqsh_debug(DEBUG_ERROR, "DynKeywordLoad: Unexpected error encountered. (2)\n"));
+ ret = CS_FAIL;
+ break;
+
+ default:
+ DBG(sqsh_debug(DEBUG_ERROR, "DynKeywordLoad: Unexpected error encountered. (3)\n"));
+ ret = CS_FAIL;
+ break;
+ }
+ ct_cmd_drop( cmd );
+ return ( ret );
+}
+#endif
diff --git a/src/cmd_jobs.c b/src/cmd_jobs.c
index 7a62a64..a9a2cc9 100644
--- a/src/cmd_jobs.c
+++ b/src/cmd_jobs.c
@@ -31,7 +31,7 @@
/*-- Current Version --*/
#if !defined(lint) && !defined(__LINT__)
-static char RCS_Id[] = "$Id: cmd_jobs.c,v 1.2 2010/01/26 15:03:50 mwesdorp Exp $" ;
+static char RCS_Id[] = "$Id: cmd_jobs.c,v 1.3 2013/04/04 10:52:35 mwesdorp Exp $" ;
USE(RCS_Id)
#endif /* !defined(lint) */
@@ -82,7 +82,7 @@ int cmd_jobs( argc, argv )
printf( "\tFlags : %d\n", j->job_flags ) ;
printf( "\tOutput : %s\n", j->job_output ) ;
printf( "\tStatus : %d\n", j->job_status ) ;
- printf( "\tChild pid: %d\n", j->job_pid ) ;
+ printf( "\tChild pid: %d\n", (int) j->job_pid ) ;
}
}
}
diff --git a/src/cmd_lock.c b/src/cmd_lock.c
index ad9ea3c..3c8edca 100644
--- a/src/cmd_lock.c
+++ b/src/cmd_lock.c
@@ -40,7 +40,7 @@
/*-- Current Version --*/
#if !defined(lint) && !defined(__LINT__)
-static char RCS_Id[] = "$Id: cmd_lock.c,v 1.1.1.1 2004/04/07 12:35:03 chunkm0nkey Exp $";
+static char RCS_Id[] = "$Id: cmd_lock.c,v 1.2 2013/04/04 10:52:35 mwesdorp Exp $";
USE(RCS_Id)
#endif /* !defined(lint) */
@@ -48,13 +48,14 @@ int cmd_lock( argc, argv )
int argc ;
char *argv[] ;
{
+#if defined(HAVE_CRYPT)
#if defined(HAVE_SHADOW_H)
- struct spwd *spwd;
+ struct spwd *spwd;
+#endif
+ char *crypt_pass;
#endif
struct passwd *passwd;
- char salt[2];
char pass[25];
- char *crypt_pass;
char *real_pass = NULL;
int len;
@@ -85,7 +86,7 @@ int cmd_lock( argc, argv )
#if defined(HAVE_SHADOW_H)
/*
* If the passwd->pw_passwd entry is undefined or contains an invalid
- * password (e.g. "x"), the we are probably using shadow passwords,
+ * password (e.g. "x"), then we are probably using shadow passwords,
* so lets give that a try.
*/
if (real_pass == NULL || strlen(real_pass) < 2) {
@@ -145,10 +146,7 @@ int cmd_lock( argc, argv )
return CMD_LEAVEBUF;
#if defined(HAVE_CRYPT)
- salt[0] = real_pass[0];
- salt[1] = real_pass[1];
-
- crypt_pass = (char*)crypt( pass, salt );
+ crypt_pass = (char*)crypt( pass, real_pass );
if (strcmp( real_pass, crypt_pass ) != 0) {
fprintf( stderr, "sqsh: Invalid password.\n" );
diff --git a/src/cmd_loop.c b/src/cmd_loop.c
index 17ecc76..68c4c0d 100644
--- a/src/cmd_loop.c
+++ b/src/cmd_loop.c
@@ -39,7 +39,7 @@
/*-- Current Version --*/
#if !defined(lint) && !defined(__LINT__)
-static char RCS_Id[] = "$Id: cmd_loop.c,v 1.1.1.1 2004/04/07 12:35:03 chunkm0nkey Exp $";
+static char RCS_Id[] = "$Id: cmd_loop.c,v 1.2 2013/04/18 11:54:43 mwesdorp Exp $";
USE(RCS_Id)
#endif /* !defined(lint) */
@@ -50,7 +50,7 @@ int cmd_loop( argc, argv )
int argc;
char *argv[];
{
- FILE *input_file ; /* Where input is coming from */
+ FILE *input_file = NULL; /* Where input is coming from */
int ret;
int exit_status;
@@ -195,7 +195,7 @@ int cmd_loop( argc, argv )
* If we opened a file to read, then close it. There is a brief period
* here where an interrupt could trash us, but lets hope for the best.
*/
- if (file_name != NULL)
+ if (input_file != NULL)
{
/*
* Let the stdin be what it used to be.
diff --git a/src/cmd_misc.c b/src/cmd_misc.c
index bd0ead5..6af2760 100644
--- a/src/cmd_misc.c
+++ b/src/cmd_misc.c
@@ -35,7 +35,7 @@
/*-- Current Version --*/
#if !defined(lint) && !defined(__LINT__)
-static char RCS_Id[] = "$Id: cmd_misc.c,v 1.2 2009/04/14 10:02:54 mwesdorp Exp $" ;
+static char RCS_Id[] = "$Id: cmd_misc.c,v 1.3 2013/04/04 10:52:35 mwesdorp Exp $" ;
USE(RCS_Id)
#endif /* !defined(lint) */
@@ -89,8 +89,8 @@ int cmd_display( sqlbuf )
/*-- Print the line of text --*/
fprintf( stdout, "%s%*.*s\n",
s, /* Prompt */
- end - buf, /* Length of line */
- end - buf, /* Length of line */
+ (int) (end - buf), /* Length of line */
+ (int) (end - buf), /* Length of line */
buf ) ; /* Line itself */
fflush( stdout ) ;
diff --git a/src/cmd_read.c b/src/cmd_read.c
index e9b8de2..61889a5 100644
--- a/src/cmd_read.c
+++ b/src/cmd_read.c
@@ -35,7 +35,7 @@
/*-- Current Version --*/
#if !defined(lint) && !defined(__LINT__)
-static char RCS_Id[] = "$Id: cmd_read.c,v 1.4 2004/11/05 13:01:14 mpeppler Exp $";
+static char RCS_Id[] = "$Id: cmd_read.c,v 1.5 2013/04/29 15:48:33 mwesdorp Exp $";
USE(RCS_Id)
#endif /* !defined(lint) */
@@ -82,7 +82,7 @@ int cmd_read( argc, argv )
}
/*
- * There should only be on more argument left on the command line,
+ * There should only be one more argument left on the command line,
* so if there are more, or if an error was found above, then
* print out a usage message.
*/
@@ -93,7 +93,7 @@ int cmd_read( argc, argv )
var_name = argv[sqsh_optind];
- if (hide_output == True)
+ if ( hide_output == True && isatty(fileno(stdin)) )
{
r = sqsh_getinput( "", input, sizeof(input), 0 );
if (r < 0)
@@ -107,46 +107,10 @@ int cmd_read( argc, argv )
}
else
{
- /* If stdin is a tty then simply read from stdin.
- If stdin is NOT a tty (e.g. redirected via < )
- then open the tty for reading, and then close it again.
- */
- if(sqsh_stdin_isatty()) {
- if (fgets( input, sizeof(input), stdin ) == NULL)
- {
- fprintf( stderr, "\\read: %s\n", strerror(errno) );
- return CMD_FAIL;
- }
- } else {
- char *tty_name;
- FILE *fin;
-
- tty_name = ctermid(NULL);
- if (tty_name == NULL) {
- sqsh_set_error( SQSH_E_EXIST,
- "cmd_read: Unable to determine controlling tty" );
- return CMD_FAIL;
- }
-
- fin = fopen("/dev/tty", "r");
- if (!fin) {
- fprintf( stderr, "\\read: %s\n", strerror(errno) );
- return CMD_FAIL;
- }
- if (fgets( input, sizeof(input), fin ) == NULL)
- {
- fprintf( stderr, "\\read: %s\n", strerror(errno) );
- fclose(fin);
- return CMD_FAIL;
- }
- fclose(fin);
- }
-
- str = strchr( input, '\n' );
-
- if (str != NULL)
+ if (fgets( input, sizeof(input), stdin ) == NULL)
{
- str = '\0';
+ fprintf( stderr, "\\read: %s\n", strerror(errno) );
+ return CMD_FAIL;
}
}
diff --git a/src/cmd_reconnect.c b/src/cmd_reconnect.c
index c5d2990..7eb4818 100644
--- a/src/cmd_reconnect.c
+++ b/src/cmd_reconnect.c
@@ -30,7 +30,7 @@
/*-- Current Version --*/
#if !defined(lint) && !defined(__LINT__)
-static char RCS_Id[] = "$Id: cmd_reconnect.c,v 1.1.1.1 2004/04/07 12:35:02 chunkm0nkey Exp $" ;
+static char RCS_Id[] = "$Id: cmd_reconnect.c,v 1.3 2013/04/25 14:09:47 mwesdorp Exp $" ;
USE(RCS_Id)
#endif /* !defined(lint) */
@@ -39,24 +39,37 @@ USE(RCS_Id)
*
* Re-establishes a connection the database, closing the prior
* connection. This allows, essentially, an 'su' for databases.
+ *
+ * sqsh-2.2.0 - Also save the current context and let ct_connect setup
+ * a new context. In case of success we can drop the original context,
+ * otherwise restore the original context.
*/
int cmd_reconnect( argc, argv )
int argc ;
char *argv[] ;
{
CS_CONNECTION *old_connection;
+ CS_CONTEXT *old_context;
old_connection = g_connection;
+ old_context = g_context;
g_connection = NULL;
+ g_context = NULL;
if( cmd_connect( argc, argv ) == CMD_FAIL )
{
g_connection = old_connection ;
+ g_context = old_context ;
return CMD_FAIL ;
}
- ct_close( old_connection, CS_FORCE_CLOSE );
+ if (ct_close( old_connection, CS_UNUSED ) != CS_SUCCEED)
+ ct_close( old_connection, CS_FORCE_CLOSE );
ct_con_drop( old_connection );
+ if (ct_exit( old_context, CS_UNUSED ) != CS_SUCCEED)
+ ct_exit( old_context, CS_FORCE_EXIT );
+ cs_ctx_drop( old_context );
+
return CMD_LEAVEBUF ;
}
diff --git a/src/cmd_reset.c b/src/cmd_reset.c
index 703f748..45ac4b2 100644
--- a/src/cmd_reset.c
+++ b/src/cmd_reset.c
@@ -28,13 +28,17 @@
#include "sqsh_env.h"
#include "sqsh_cmd.h"
#include "cmd.h"
+#if defined(USE_READLINE)
+#include "sqsh_readline.h"
+#endif
/*-- Current Version --*/
#if !defined(lint) && !defined(__LINT__)
-static char RCS_Id[] = "$Id: cmd_reset.c,v 1.2 2010/01/26 15:03:50 mwesdorp Exp $" ;
+static char RCS_Id[] = "$Id: cmd_reset.c,v 1.3 2013/04/04 10:52:35 mwesdorp Exp $" ;
USE(RCS_Id)
#endif /* !defined(lint) */
+
/*
* cmd_clear:
*
@@ -50,8 +54,9 @@ int cmd_clear( argc, argv )
return CMD_FAIL ;
}
#if defined(USE_READLINE)
- if (g_interactive)
- _rl_clear_screen();
+ if (g_interactive) {
+ _rl_clear_screen ();
+ }
#endif
return CMD_CLEARBUF ;
}
diff --git a/src/cmd_run.c b/src/cmd_run.c
new file mode 100644
index 0000000..94186ce
--- /dev/null
+++ b/src/cmd_run.c
@@ -0,0 +1,230 @@
+/*
+ * cmd_run.c - Execute a batch file from the prompt
+ *
+ * Copyright (C) 2014 by Martin Wesdorp.
+ *
+ * This program 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 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program 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 this program. If not, write to the Free Software
+ * Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ */
+#include <stdio.h>
+#include "sqsh_config.h"
+#include "sqsh_global.h"
+#include "sqsh_varbuf.h"
+#include "sqsh_env.h"
+#include "sqsh_error.h"
+#include "sqsh_cmd.h"
+#include "sqsh_job.h"
+#include "sqsh_getopt.h"
+#include "sqsh_readline.h"
+#include "sqsh_stdin.h"
+#include "cmd.h"
+#include "cmd_misc.h"
+#include "cmd_input.h"
+
+/*-- Current Version --*/
+#if !defined(lint) && !defined(__LINT__)
+static char RCS_Id[] = "$Id: cmd_run.c,v 1.5 2014/03/11 21:49:04 mwesdorp Exp $";
+USE(RCS_Id)
+#endif /* !defined(lint) */
+
+/*
+ * cmd_run():
+ */
+int cmd_run( argc, argv )
+ int argc;
+ char *argv[];
+{
+ FILE *input_file = NULL; /* Where input is coming from */
+ int fn_optind; /* argv index of filename argument */
+ char *swap_ptr; /* Used for swapping strings */
+ int exit_status;
+
+ /*-- Variables settable by command line options --*/
+ char *file_name = NULL;
+ int have_error = False;
+
+ /*-- Variables required by sqsh_getopt --*/
+ int c;
+ extern int sqsh_optind;
+ extern char *sqsh_optarg;
+
+
+ /*
+ * Open global environment transaction
+ */
+ env_tran( g_env );
+
+ /*
+ * Parse the command line options.
+ */
+ while ((c = sqsh_getopt( argc, argv, "efhlnpm:i:" )) != EOF)
+ {
+ switch (c)
+ {
+ case 'e' :
+ if (env_put( g_env, "echo", "1", ENV_F_TRAN ) == False)
+ {
+ fprintf( stderr, "\\run: -e: %s\n", sqsh_get_errstr() );
+ have_error = True;
+ }
+ break;
+
+ case 'f' :
+ if (env_put( g_env, "footers", "0", ENV_F_TRAN ) == False)
+ {
+ fprintf( stderr, "\\run: -f: %s\n", sqsh_get_errstr() );
+ have_error = True;
+ }
+ break;
+
+ case 'h' :
+ if (env_put( g_env, "headers", "0", ENV_F_TRAN ) == False)
+ {
+ fprintf( stderr, "\\run: -h: %s\n", sqsh_get_errstr() );
+ have_error = True;
+ }
+ break;
+
+ case 'l' :
+ if (env_put( g_env, "nosepline", "1", ENV_F_TRAN ) == False)
+ {
+ fprintf( stderr, "\\run: -l: %s\n", sqsh_get_errstr() );
+ have_error = True;
+ }
+ break;
+
+ case 'n' :
+ if (env_put( g_env, "expand", "0", ENV_F_TRAN ) == False)
+ {
+ fprintf( stderr, "\\run: -n: %s\n", sqsh_get_errstr() );
+ have_error = True;
+ }
+ break;
+
+ case 'p' :
+ if (env_put( g_env, "statistics", "1", ENV_F_TRAN ) == False)
+ {
+ fprintf( stderr, "\\run: -p: %s\n", sqsh_get_errstr() );
+ have_error = True;
+ }
+ break;
+
+ case 'm' :
+ if (env_put( g_env, "style", sqsh_optarg, ENV_F_TRAN ) == False)
+ {
+ fprintf( stderr, "\\run: -m: %s\n", sqsh_get_errstr() );
+ have_error = True;
+ }
+ break;
+
+ case 'i' :
+ file_name = sqsh_optarg;
+ break;
+
+ default :
+ fprintf(stderr, "\\run: %s\n", sqsh_get_errstr() );
+ have_error = True;
+ }
+ }
+
+ /*
+ * Check that a file is provided.
+ */
+ if( file_name == NULL || have_error )
+ {
+ fprintf( stderr, "Use: \\run [-e] [-f] [-h] [-n] [-p] [-m style] -i filename [optional script parameters ...]\n" );
+ fprintf( stderr, " -e Run the script file with echo on\n" );
+ fprintf( stderr, " -f Suppress footers\n" );
+ fprintf( stderr, " -h Suppress headers\n" );
+ fprintf( stderr, " -l Suppress separator lines with pretty output\n" );
+ fprintf( stderr, " -n Disable SQL buffer variable expansion\n" );
+ fprintf( stderr, " -p Report runtime statistics\n" );
+ fprintf( stderr, " -m style Specify output style {bcp|csv|horiz|html|meta|none|pretty|vert}\n" );
+ fprintf( stderr, " -i filename SQL file to run\n" );
+ env_rollback( g_env );
+ return CMD_FAIL;
+ }
+
+ /*
+ * If there are any arguments left on the command line, they need to be put on the
+ * argument stack. Make sure that the new argv[0] on the stack points to the filename.
+ */
+ for ( fn_optind = 0; fn_optind < argc && argv[fn_optind] != file_name; fn_optind++ );
+ if (sqsh_optind-1 != fn_optind)
+ {
+ swap_ptr = argv[sqsh_optind-1];
+ argv[sqsh_optind-1] = file_name;
+ argv[fn_optind] = swap_ptr;
+ }
+ g_func_args[g_func_nargs].argc = argc - sqsh_optind + 1;
+ g_func_args[g_func_nargs].argv = &(argv[sqsh_optind-1]);
+ g_func_nargs++;
+
+ /*
+ * Open the file for input and make it stdin.
+ */
+ if ((input_file = fopen( (char*) file_name, "r" )) == NULL)
+ {
+ fprintf( stderr, "\\run: %s: %s\n", (char*) file_name, strerror( errno ) );
+ g_func_nargs--;
+ env_rollback( g_env );
+ return CMD_FAIL;
+ }
+ env_put ( g_env, "script", file_name, ENV_F_TRAN);
+ sqsh_stdin_file( input_file );
+
+ /*
+ * Make sure we have a valid connection.
+ */
+ if ((jobset_run( g_jobset, "\\connect", &exit_status )) == -1 || exit_status == CMD_FAIL)
+ {
+ fprintf( stderr, "\\run: Unable to (re)connect\n" );
+ sqsh_stdin_pop();
+ fclose( input_file );
+ g_func_nargs--;
+ env_rollback( g_env );
+ return CMD_FAIL;
+ }
+
+ /*
+ * Start processing the batch file. Ignore the return value.
+ */
+ (void) cmd_input();
+
+ /*
+ * Pop the argument stack.
+ * Reset stdin to what it used to be.
+ * Close the open batch file.
+ * Rollback the global environment to its original state.
+ */
+ sqsh_stdin_pop();
+ fclose( input_file );
+ g_func_nargs--;
+ env_rollback( g_env );
+
+ /*
+ * Set appropriate return and exit values.
+ * If script used \exit, then $exit_value may be set and we need to assign this value to $?.
+ * If \return was used, then "$?" may already be set and we can leave it that way.
+ */
+ env_get ( g_env, "exit_value", &swap_ptr );
+ if (*swap_ptr != '0' )
+ {
+ env_set ( g_internal_env, "?", swap_ptr );
+ env_set ( g_env, "exit_value", "0" );
+ }
+
+ return CMD_LEAVEBUF;
+}
diff --git a/src/cmd_shell.c b/src/cmd_shell.c
index f5c3c51..1c94c99 100644
--- a/src/cmd_shell.c
+++ b/src/cmd_shell.c
@@ -32,7 +32,7 @@
/*-- Current Version --*/
#if !defined(lint) && !defined(__LINT__)
-static char RCS_Id[] = "$Id: cmd_shell.c,v 1.1.1.1 2004/04/07 12:35:05 chunkm0nkey Exp $";
+static char RCS_Id[] = "$Id: cmd_shell.c,v 1.3 2014/03/11 21:49:04 mwesdorp Exp $";
USE(RCS_Id)
#endif /* !defined(lint) */
@@ -110,3 +110,87 @@ int cmd_shell( argc, argv )
return CMD_LEAVEBUF;
}
+
+/*
+ * cmd_lcd: Change local working directory.
+ * sqsh-2.5 - New feature.
+ */
+int cmd_lcd( argc, argv )
+ int argc;
+ char *argv[];
+{
+ int ret; /* Return value */
+ char tmp[512] = ""; /* Tmp storage area */
+ static char owd[512] = ""; /* Old working directory (previous) */
+ char *sp; /* String pointer */
+
+
+ if (argc != 2)
+ {
+ fprintf( stderr, "Use: \\lcd dir_name\n" );
+ env_set ( g_internal_env, "?", "1" );
+ return CMD_FAIL;
+ }
+
+ sp = getcwd ( tmp, sizeof(tmp) );
+ sp = ( strcmp ( argv[1], "-" ) == 0 && owd[0] != '\0' ) ? owd : argv[1];
+ ret = chdir ( sp );
+ if (ret != 0)
+ {
+ fprintf( stderr, "\\lcd: %s: %s\n", (char*) sp, strerror( errno ) );
+ env_set ( g_internal_env, "?", "1" );
+ return CMD_FAIL;
+ }
+ else
+ fprintf( stdout, "\\lcd: local directory changed to: %s\n", sp );
+
+ strcpy (owd, tmp);
+ env_set ( g_internal_env, "?", "0" );
+ return CMD_LEAVEBUF;
+}
+
+/*
+ * cmd_pwd: Print current working directory.
+ * sqsh-2.5 - New feature.
+ */
+int cmd_pwd( argc, argv )
+ int argc;
+ char *argv[];
+{
+ char pwd[512];
+
+ if (argc != 1)
+ {
+ fprintf( stderr, "Use: \\pwd\n" );
+ env_set ( g_internal_env, "?", "1" );
+ return CMD_FAIL;
+ }
+
+ fprintf( stdout, "%s\n", getcwd( pwd, sizeof(pwd) ) );
+ env_set ( g_internal_env, "?", "0" );
+ return CMD_LEAVEBUF;
+}
+
+/*
+ * cmd_ls: Show files in current directory.
+ * sqsh-2.5 - New feature.
+ */
+int cmd_ls( argc, argv )
+ int argc;
+ char *argv[];
+{
+ char return_value[10];
+ int exit_status;
+
+ if (argc != 1)
+ {
+ fprintf( stderr, "Use: \\ls\n" );
+ env_set ( g_internal_env, "?", "1" );
+ return CMD_FAIL;
+ }
+
+ exit_status = system ( "ls" );
+ sprintf (return_value, "%d", exit_status);
+ env_set ( g_internal_env, "?", return_value );
+ return CMD_LEAVEBUF;
+}
diff --git a/src/config.h b/src/config.h
deleted file mode 100644
index 2932b93..0000000
--- a/src/config.h
+++ /dev/null
@@ -1,85 +0,0 @@
-/* src/config.h. Generated by configure. */
-#ifndef config_h_included
-#define config_h_included
-
-/*
- * Define the following if you compiler is an ANSI compiler and supports
- * prototypes, etl a.
- */
-#define STDC_HEADERS 1
-
-/*
- * The include file sys/wait.h is required by sqsh_sigcld.c in order
- * to call wait_pid(). Define this if the header file is available.
- */
-#define HAVE_SYS_WAIT_H 1
-
-/*
- * Common header files.
- */
-#define HAVE_STDLIB_H 1
-#define HAVE_SYS_TYPES_H 1
-#define HAVE_STRING_H 1
-#define HAVE_FCNTL_H 1
-#define HAVE_UNISTD_H 1
-#define HAVE_MEMORY_H 1
-#define HAVE_ERRNO_H 1
-#define HAVE_SYS_TIME_H 1
-#define HAVE_TIME_H 1
-#define HAVE_SYS_PARAM_H 1
-#define HAVE_LIMITS_H 1
-#define HAVE_CRYPT_H 1
-#define HAVE_SHADOW_H 1
-#define HAVE_STROPTS_H 1
-
-/*
- * If you compiler doesn't fully support the keyword 'const'
- * then define const to be empty.
- */
-/* #undef const */
-
-/*
- * If the following types are not defined in stdlib.h and sys/types.h
- * then guess the closest possible data type.
- */
-/* #undef mode_t */
-/* #undef pid_t */
-/* #undef uid_t */
-
-/*
- * The following is the return type of a signal handler. On most
- * systems this is void.
- */
-#define RETSIGTYPE void
-
-/*
- * The following functions are frequently unavailable on certain
- * systems.
- */
-#define HAVE_STRCASECMP 1
-#define HAVE_STRERROR 1
-/* #undef HAVE_CFTIME */
-#define HAVE_STRFTIME 1
-#define HAVE_MEMCPY 1
-#define HAVE_MEMMOVE 1
-#define HAVE_LOCALTIME 1
-#define HAVE_TIMELOCAL 1
-#define HAVE_STRCHR 1
-#define HAVE_SIGSETJMP 1
-#define HAVE_GETTIMEOFDAY 1
-/* #undef HAVE_GET_PROCESS_STATS */
-#define HAVE_SIGACTION 1
-/* #undef HAVE_CRYPT */
-#define HAVE_POLL 1
-
-/*
- * Define if your compiler supports the volatile keyword.
- */
-#define HAVE_VOLATILE 1
-
-/*
- * Signal behaviour
- */
-/* #undef SYSV_SIGNALS */
-
-#endif
diff --git a/src/config.h.in b/src/config.h.in
index 87cab22..aa2abc0 100644
--- a/src/config.h.in
+++ b/src/config.h.in
@@ -1,154 +1,91 @@
-/* src/config.h.in. Generated from configure.in by autoheader. */
+#ifndef config_h_included
+#define config_h_included
-/* Define to 1 if you have the `cftime' function. */
-#undef HAVE_CFTIME
-
-/* Define to 1 if you have the `crypt' function. */
-#undef HAVE_CRYPT
-
-/* Define to 1 if you have the <crypt.h> header file. */
-#undef HAVE_CRYPT_H
+/*
+ * Define the following if you compiler is an ANSI compiler and supports
+ * prototypes, etl a.
+ */
+#undef STDC_HEADERS
-/* Define to 1 if you have the <errno.h> header file. */
-#undef HAVE_ERRNO_H
+/*
+ * The include file sys/wait.h is required by sqsh_sigcld.c in order
+ * to call wait_pid(). Define this if the header file is available.
+ */
+#undef HAVE_SYS_WAIT_H
-/* Define to 1 if you have the <fcntl.h> header file. */
+/*
+ * Common header files.
+ */
+#undef HAVE_STDLIB_H
+#undef HAVE_SYS_TYPES_H
+#undef HAVE_STRING_H
#undef HAVE_FCNTL_H
-
-/* Define to 1 if you have the `gettimeofday' function. */
-#undef HAVE_GETTIMEOFDAY
-
-/* Define to 1 if you have the `get_process_stats' function. */
-#undef HAVE_GET_PROCESS_STATS
-
-/* Define to 1 if you have the <inttypes.h> header file. */
-#undef HAVE_INTTYPES_H
-
-/* Define to 1 if you have the <limits.h> header file. */
-#undef HAVE_LIMITS_H
-
-/* Define to 1 if you have the <locale.h> header file. */
-#undef HAVE_LOCALE_H
-
-/* Define to 1 if you have the `localtime' function. */
-#undef HAVE_LOCALTIME
-
-/* Define to 1 if you have the `memcpy' function. */
-#undef HAVE_MEMCPY
-
-/* Define to 1 if you have the `memmove' function. */
-#undef HAVE_MEMMOVE
-
-/* Define to 1 if you have the <memory.h> header file. */
+#undef HAVE_UNISTD_H
#undef HAVE_MEMORY_H
-
-/* Define to 1 if you have the `poll' function. */
-#undef HAVE_POLL
-
-/* Define to 1 if you have the `setlocale' function. */
-#undef HAVE_SETLOCALE
-
-/* Define to 1 if you have the <shadow.h> header file. */
+#undef HAVE_ERRNO_H
+#undef HAVE_SYS_TIME_H
+#undef HAVE_TIME_H
+#undef HAVE_SYS_PARAM_H
+#undef HAVE_LIMITS_H
+#undef HAVE_CRYPT_H
#undef HAVE_SHADOW_H
+#undef HAVE_STROPTS_H
-/* Define to 1 if you have the `sigaction' function. */
-#undef HAVE_SIGACTION
-
-/* Define to 1 if your environment provides sigsetjpm() */
-#undef HAVE_SIGSETJMP
+/*
+ * If you compiler doesn't fully support the keyword 'const'
+ * then define const to be empty.
+ */
+#undef const
-/* Define to 1 if you have the <stdint.h> header file. */
-#undef HAVE_STDINT_H
+/*
+ * If the following types are not defined in stdlib.h and sys/types.h
+ * then guess the closest possible data type.
+ */
+#undef mode_t
+#undef pid_t
+#undef uid_t
-/* Define to 1 if you have the <stdlib.h> header file. */
-#undef HAVE_STDLIB_H
+/*
+ * The following is the return type of a signal handler. On most
+ * systems this is void.
+ */
+#undef RETSIGTYPE
-/* Define to 1 if you have the `strcasecmp' function. */
+/*
+ * The following functions are frequently unavailable on certain
+ * systems.
+ */
#undef HAVE_STRCASECMP
-
-/* Define to 1 if you have the `strchr' function. */
-#undef HAVE_STRCHR
-
-/* Define to 1 if you have the `strerror' function. */
#undef HAVE_STRERROR
-
-/* Define to 1 if you have the `strftime' function. */
+#undef HAVE_CFTIME
#undef HAVE_STRFTIME
-
-/* Define to 1 if you have the <strings.h> header file. */
-#undef HAVE_STRINGS_H
-
-/* Define to 1 if you have the <string.h> header file. */
-#undef HAVE_STRING_H
-
-/* Define to 1 if you have the <stropts.h> header file. */
-#undef HAVE_STROPTS_H
-
-/* Define to 1 if you have the <sys/param.h> header file. */
-#undef HAVE_SYS_PARAM_H
-
-/* Define to 1 if you have the <sys/stat.h> header file. */
-#undef HAVE_SYS_STAT_H
-
-/* Define to 1 if you have the <sys/time.h> header file. */
-#undef HAVE_SYS_TIME_H
-
-/* Define to 1 if you have the <sys/types.h> header file. */
-#undef HAVE_SYS_TYPES_H
-
-/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
-#undef HAVE_SYS_WAIT_H
-
-/* Define to 1 if you have the `timelocal' function. */
+#undef HAVE_MEMCPY
+#undef HAVE_MEMMOVE
+#undef HAVE_LOCALTIME
#undef HAVE_TIMELOCAL
+#undef HAVE_STRCHR
+#undef HAVE_SIGSETJMP
+#undef HAVE_GETTIMEOFDAY
+#undef HAVE_GET_PROCESS_STATS
+#undef HAVE_SIGACTION
+#undef HAVE_CRYPT
+#undef HAVE_POLL
-/* Define to 1 if you have the <time.h> header file. */
-#undef HAVE_TIME_H
-
-/* Define to 1 if you have the <unistd.h> header file. */
-#undef HAVE_UNISTD_H
-
-/* Define to 1 if your compiler supports the volatile keyword */
+/*
+ * Define if your compiler supports the volatile keyword.
+ */
#undef HAVE_VOLATILE
-/* Define to the address where bug reports for this package should be sent. */
-#undef PACKAGE_BUGREPORT
-
-/* Define to the full name of this package. */
-#undef PACKAGE_NAME
-
-/* Define to the full name and version of this package. */
-#undef PACKAGE_STRING
-
-/* Define to the one symbol short name of this package. */
-#undef PACKAGE_TARNAME
-
-/* Define to the home page for this package. */
-#undef PACKAGE_URL
-
-/* Define to the version of this package. */
-#undef PACKAGE_VERSION
-
-/* Define as the return type of signal handlers (`int' or `void'). */
-#undef RETSIGTYPE
-
-/* Define to 1 if you have the ANSI C header files. */
-#undef STDC_HEADERS
-
-/* Define to 1 if your environment supports SysV signals */
+/*
+ * Signal behaviour
+ */
#undef SYSV_SIGNALS
-/* Define to empty if `const' does not conform to ANSI C. */
-#undef const
-
-/* Define to `int' if <sys/types.h> doesn't define. */
-#undef gid_t
-
-/* Define to `int' if <sys/types.h> does not define. */
-#undef mode_t
-
-/* Define to `int' if <sys/types.h> does not define. */
-#undef pid_t
+/*
+ * sqsh-2.3 : Test availability of locale
+ */
+#undef HAVE_LOCALE_H
+#undef HAVE_LOCALECONV
+#undef HAVE_SETLOCALE
-/* Define to `int' if <sys/types.h> doesn't define. */
-#undef uid_t
+#endif
diff --git a/src/config.h.nt b/src/config.h.nt
deleted file mode 100644
index 47971d3..0000000
--- a/src/config.h.nt
+++ /dev/null
@@ -1,85 +0,0 @@
-/* config.h. Generated automatically by configure. */
-#ifndef config_h_included
-#define config_h_included
-
-/*
- * Define the following if you compiler is an ANSI compiler and supports
- * prototypes, etl a.
- */
-#define STDC_HEADERS 1
-
-/*
- * The include file sys/wait.h is required by sqsh_sigcld.c in order
- * to call wait_pid(). Define this if the header file is available.
- */
-#define HAVE_SYS_WAIT_H 1
-
-/*
- * Common header files.
- */
-#define HAVE_STDLIB_H 1 /* #include <stdlib.h> */
-#define HAVE_SYS_TYPES_H 1 /* #include <sys/types.h> */
-#define HAVE_STRING_H 1 /* #include <string.h> */
-#define HAVE_FCNTL_H 1 /* #include <fcntl.h> */
-#define HAVE_UNISTD_H 1 /* #include <unistd.h> */
-#define HAVE_MEMORY_H 1 /* #include <memory.h> */
-#define HAVE_ERRNO_H 1 /* #include <errno.h> */
-#define HAVE_SYS_TIME_H 1 /* #include <sys/time.h> */
-#define HAVE_TIME_H 1 /* #include <time.h> */
-#define HAVE_SYS_PARAM_H 1 /* #include <sys/param.h> */
-#define HAVE_LIMITS_H 1 /* #include <limits.h> */
-/* #undef HAVE_CRYPT_H */ /* #include <crypt.h> */
-/* #undef HAVE_SHADOW_H */ /* #include <shadow.h> */
-/* #undef HAVE_STROPTS_H 1 */ /* #include <stropts.h> */
-
-/*
- * If you compiler doesn't fully support the keyword 'const'
- * then define const to be empty.
- */
-/* #undef const */
-
-/*
- * If the following types are not defined in stdlib.h and sys/types.h
- * then guess the closest possible data type.
- */
-/* #undef mode_t */
-/* #undef pid_t */
-/* #undef uid_t */
-
-/*
- * The following is the return type of a signal handler. On most
- * systems this is void.
- */
-#define RETSIGTYPE void
-
-/*
- * The following functions are frequently unavailable on certain
- * systems.
- */
-#define HAVE_STRCASECMP 1
-#define HAVE_STRERROR 1
-/* #undef HAVE_CFTIME */
-#define HAVE_STRFTIME 1
-#define HAVE_MEMCPY 1
-#define HAVE_MEMMOVE 1
-#define HAVE_LOCALTIME 1
-#define HAVE_TIMELOCAL 1
-#define HAVE_STRCHR 1
-#define HAVE_SIGSETJMP 1
-#define HAVE_GETTIMEOFDAY 1
-/* #undef HAVE_GET_PROCESS_STATS */
-#define HAVE_POSIX_SIGNALS 1
-/* #undef HAVE_CRYPT */
-/* #define HAVE_POLL 1 */
-
-/*
- * Define if your compiler supports the volatile keyword.
- */
-#define HAVE_VOLATILE 1
-
-/*
- * Signal behaviour
- */
-/* #undef SYSV_SIGNALS */
-
-#endif
diff --git a/src/dsp.c b/src/dsp.c
index 0373538..b44c390 100644
--- a/src/dsp.c
+++ b/src/dsp.c
@@ -31,7 +31,7 @@
/*-- Current Version --*/
#if !defined(lint) && !defined(__LINT__)
-static char RCS_Id[] = "$Id: dsp.c,v 1.3 2008/05/21 17:51:24 mpeppler Exp $";
+static char RCS_Id[] = "$Id: dsp.c,v 1.6 2014/01/18 18:36:34 mwesdorp Exp $";
USE(RCS_Id)
#endif /* !defined(lint) */
@@ -50,7 +50,7 @@ int g_dsp_interrupted = False;
static CS_COMMAND *sg_cmd = NULL;
/*
- * g_dsp_props: This data structure contains the current set of
+ * g_dsp_props: This data structure contains the current set of
* properties defined for the display sub-system. Be careful
* when editing this data strcuture.
*/
@@ -178,6 +178,9 @@ int dsp_cmd( output, cmd, sql, flags )
sig_install( SIGINT, dsp_signal, (void*)NULL, 0 );
sig_install( SIGPIPE, dsp_signal, (void*)NULL, 0 );
+ /* sqsh-2.5 - Feature p2f, reset g_p2fc before a new batch is started */
+ g_p2fc = 0;
+
if (ct_send( cmd ) != CS_SUCCEED)
ret = DSP_FAIL;
@@ -188,7 +191,7 @@ int dsp_cmd( output, cmd, sql, flags )
* All that is left is to process the results of the current
* query, reinstall the old signal handlers, and return!
*/
- if (ret == DSP_SUCCEED)
+ if (ret == DSP_SUCCEED)
{
if ((flags & DSP_F_NOTHING) != 0)
{
@@ -305,12 +308,26 @@ static int dsp_prop_set( prop, ptr, len )
{
switch (prop)
{
+ /*
+ * sqsh-2.1.9 - Introduced and remapped property types DSP_DATETIMEFMT, DSP_DATEFMT
+ * and DSP_TIMEFMT to implement date and time datatype conversions with strftime as
+ * already existed for the datetime and smalldatetime datatypes.
+ * This feature request was filed as bugreport 3603409 on Sourceforge.
+ */
+ case DSP_DATETIMEFMT:
+ return dsp_datetimefmt_set( (char*)ptr );
+ break;
+
case DSP_DATEFMT:
return dsp_datefmt_set( (char*)ptr );
break;
+ case DSP_TIMEFMT:
+ return dsp_timefmt_set( (char*)ptr );
+ break;
+
case DSP_COLWIDTH:
- DBG(sqsh_debug(DEBUG_DISPLAY,
+ DBG(sqsh_debug(DEBUG_DISPLAY,
"dsp_prop: dsp_prop(DSP_SET, DSP_COLWDTH, %d)\n", *((int*)ptr));)
if (*((int*)ptr) < 1)
@@ -323,7 +340,7 @@ static int dsp_prop_set( prop, ptr, len )
break;
case DSP_FLOAT_PREC:
- DBG(sqsh_debug(DEBUG_DISPLAY,
+ DBG(sqsh_debug(DEBUG_DISPLAY,
"dsp_prop: dsp_prop(DSP_SET, DSP_FLOAT_PREC, %d)\n", *((int*)ptr));)
if (*((int*)ptr) < 0 || *((int*)ptr) < g_dsp_props.p_flt_scale)
@@ -336,7 +353,7 @@ static int dsp_prop_set( prop, ptr, len )
break;
case DSP_FLOAT_SCALE:
- DBG(sqsh_debug(DEBUG_DISPLAY,
+ DBG(sqsh_debug(DEBUG_DISPLAY,
"dsp_prop: dsp_prop(DSP_SET, DSP_FLOAT_SCALE, %d)\n",
*((int*)ptr));)
@@ -350,7 +367,7 @@ static int dsp_prop_set( prop, ptr, len )
break;
case DSP_REAL_PREC:
- DBG(sqsh_debug(DEBUG_DISPLAY,
+ DBG(sqsh_debug(DEBUG_DISPLAY,
"dsp_prop: dsp_prop(DSP_SET, DSP_REAL_PREC, %d)\n", *((int*)ptr));)
if (*((int*)ptr) < 0 || *((int*)ptr) < g_dsp_props.p_real_scale)
@@ -363,7 +380,7 @@ static int dsp_prop_set( prop, ptr, len )
break;
case DSP_REAL_SCALE:
- DBG(sqsh_debug(DEBUG_DISPLAY,
+ DBG(sqsh_debug(DEBUG_DISPLAY,
"dsp_prop: dsp_prop(DSP_SET, DSP_REAL_SCALE, %d)\n",
*((int*)ptr));)
@@ -377,7 +394,7 @@ static int dsp_prop_set( prop, ptr, len )
break;
case DSP_STYLE:
- DBG(sqsh_debug(DEBUG_DISPLAY,
+ DBG(sqsh_debug(DEBUG_DISPLAY,
"dsp_prop: dsp_prop(DSP_SET, DSP_STYLE, %d)\n", *((int*)ptr));)
if (!(DSP_VALID_STYLE( *((int*)ptr) )))
@@ -389,8 +406,8 @@ static int dsp_prop_set( prop, ptr, len )
g_dsp_props.p_style = *((int*)ptr);
break;
- case DSP_WIDTH:
- DBG(sqsh_debug(DEBUG_DISPLAY,
+ case DSP_WIDTH:
+ DBG(sqsh_debug(DEBUG_DISPLAY,
"dsp_prop: dsp_prop(DSP_SET, DSP_WIDTH, %d)\n", *((int*)ptr));)
if (*((int*)ptr) >= 30)
@@ -404,8 +421,8 @@ static int dsp_prop_set( prop, ptr, len )
}
break;
- case DSP_OUTPUTPARMS:
- DBG(sqsh_debug(DEBUG_DISPLAY,
+ case DSP_OUTPUTPARMS:
+ DBG(sqsh_debug(DEBUG_DISPLAY,
"dsp_prop: dsp_prop(DSP_SET, DSP_OUTPUTPARMS, %d)\n",
*((int*)ptr));)
@@ -421,10 +438,13 @@ static int dsp_prop_set( prop, ptr, len )
break;
case DSP_COLSEP:
- DBG(sqsh_debug(DEBUG_DISPLAY,
- "dsp_prop: dsp_prop(DSP_SET, DSP_COLSEP, '%s')\n",
+ DBG(sqsh_debug(DEBUG_DISPLAY,
+ "dsp_prop: dsp_prop(DSP_SET, DSP_COLSEP, '%s')\n",
(ptr == NULL)?"NULL":((char*)ptr));)
+ if (ptr == NULL || strcasecmp (ptr, "default") == 0)
+ ptr = " "; /* sqsh-2.5 - Set to default when ptr is NULL */
+
if (len == DSP_NULLTERM)
{
len = strlen( (char*)ptr );
@@ -432,7 +452,7 @@ static int dsp_prop_set( prop, ptr, len )
if (len > MAX_SEPLEN || len < 0)
{
- sqsh_set_error( SQSH_E_INVAL,
+ sqsh_set_error( SQSH_E_INVAL,
"Invalid length of column separator (between 0 and %d allowed)",
MAX_SEPLEN );
return DSP_FAIL;
@@ -446,10 +466,13 @@ static int dsp_prop_set( prop, ptr, len )
break;
case DSP_BCP_COLSEP:
- DBG(sqsh_debug(DEBUG_DISPLAY,
- "dsp_prop: dsp_prop(DSP_SET, DSP_BCP_COLSEP, '%s')\n",
+ DBG(sqsh_debug(DEBUG_DISPLAY,
+ "dsp_prop: dsp_prop(DSP_SET, DSP_BCP_COLSEP, '%s')\n",
(ptr == NULL)?"NULL":((char*)ptr));)
+ if (ptr == NULL || strcasecmp (ptr, "default") == 0)
+ ptr = "|"; /* sqsh-2.5 - Set to default when ptr is NULL */
+
if (len == DSP_NULLTERM)
{
len = strlen( (char*)ptr );
@@ -457,7 +480,7 @@ static int dsp_prop_set( prop, ptr, len )
if (len > MAX_SEPLEN || len < 0)
{
- sqsh_set_error( SQSH_E_INVAL,
+ sqsh_set_error( SQSH_E_INVAL,
"Invalid length of bcp col separator (between 0 and %d allowed)",
MAX_SEPLEN );
return DSP_FAIL;
@@ -471,10 +494,13 @@ static int dsp_prop_set( prop, ptr, len )
break;
case DSP_BCP_ROWSEP:
- DBG(sqsh_debug(DEBUG_DISPLAY,
- "dsp_prop: dsp_prop(DSP_SET, DSP_BCP_ROWSEP, '%s')\n",
+ DBG(sqsh_debug(DEBUG_DISPLAY,
+ "dsp_prop: dsp_prop(DSP_SET, DSP_BCP_ROWSEP, '%s')\n",
(ptr == NULL)?"NULL":((char*)ptr));)
+ if (ptr == NULL || strcasecmp (ptr, "default") == 0)
+ ptr = "|"; /* sqsh-2.5 - Set to default when ptr is NULL */
+
if (len == DSP_NULLTERM)
{
len = strlen( (char*)ptr );
@@ -482,7 +508,7 @@ static int dsp_prop_set( prop, ptr, len )
if (len > MAX_SEPLEN || len < 0)
{
- sqsh_set_error( SQSH_E_INVAL,
+ sqsh_set_error( SQSH_E_INVAL,
"Invalid length of bcp row separator (between 0 and %d allowed)",
MAX_SEPLEN );
return DSP_FAIL;
@@ -496,8 +522,8 @@ static int dsp_prop_set( prop, ptr, len )
break;
case DSP_BCP_TRIM:
- DBG(sqsh_debug(DEBUG_DISPLAY,
- "dsp_prop: dsp_prop(DSP_SET, DSP_BCP_TRIM, '%d')\n",
+ DBG(sqsh_debug(DEBUG_DISPLAY,
+ "dsp_prop: dsp_prop(DSP_SET, DSP_BCP_TRIM, '%d')\n",
(ptr == NULL)?-1:*((int*)ptr));)
if (*((int*)ptr) == 0)
@@ -511,10 +537,13 @@ static int dsp_prop_set( prop, ptr, len )
break;
case DSP_LINESEP:
- DBG(sqsh_debug(DEBUG_DISPLAY,
- "dsp_prop: dsp_prop(DSP_SET, DSP_LINESEP, '%s')\n",
+ DBG(sqsh_debug(DEBUG_DISPLAY,
+ "dsp_prop: dsp_prop(DSP_SET, DSP_LINESEP, '%s')\n",
(ptr == NULL)?"NULL":((char*)ptr));)
+ if (ptr == NULL || strcasecmp (ptr, "default") == 0)
+ ptr = "\n\t"; /* sqsh-2.5 - Set to default when ptr is NULL */
+
if (len == DSP_NULLTERM)
{
len = strlen( (char*)ptr );
@@ -522,7 +551,7 @@ static int dsp_prop_set( prop, ptr, len )
if (len > MAX_SEPLEN || len < 0)
{
- sqsh_set_error( SQSH_E_INVAL,
+ sqsh_set_error( SQSH_E_INVAL,
"Invalid length of line separator (between 0 and %d allowed)",
MAX_SEPLEN );
return DSP_FAIL;
@@ -535,8 +564,8 @@ static int dsp_prop_set( prop, ptr, len )
break;
case DSP_XGEOM:
- DBG(sqsh_debug(DEBUG_DISPLAY,
- "dsp_prop: dsp_prop(DSP_SET, DSP_XGEOM, '%s')\n",
+ DBG(sqsh_debug(DEBUG_DISPLAY,
+ "dsp_prop: dsp_prop(DSP_SET, DSP_XGEOM, '%s')\n",
(ptr == NULL)?"NULL":((char*)ptr));)
if (len == DSP_NULLTERM)
@@ -546,7 +575,7 @@ static int dsp_prop_set( prop, ptr, len )
if (len > MAX_XGEOM || len < 0)
{
- sqsh_set_error( SQSH_E_INVAL,
+ sqsh_set_error( SQSH_E_INVAL,
"Invalid length of X geometry (between 0 and %d allowed)",
MAX_XGEOM );
return DSP_FAIL;
@@ -557,7 +586,7 @@ static int dsp_prop_set( prop, ptr, len )
break;
case DSP_MAXLEN:
- DBG(sqsh_debug(DEBUG_DISPLAY,
+ DBG(sqsh_debug(DEBUG_DISPLAY,
"dsp_prop: dsp_prop(DSP_SET, DSP_MAXLEN, %d)\n", *((int*)ptr));)
if (*((int*)ptr) < 0)
@@ -591,49 +620,69 @@ static int dsp_prop_get( prop, ptr, len )
{
switch (prop)
{
+ /*
+ * sqsh-2.1.9 - Introduced and remapped property types DSP_DATETIMEFMT, DSP_DATEFMT
+ * and DSP_TIMEFMT to implement date and time datatype conversions with strftime as
+ * already existed for the datetime and smalldatetime datatypes.
+ * This feature request was filed as bugreport 3603409 on Sourceforge.
+ */
case DSP_COLWIDTH:
- DBG(sqsh_debug(DEBUG_DISPLAY,
- "dsp_prop: dsp_prop(DSP_GET, DSP_COLWIDTH) = %d\n",
+ DBG(sqsh_debug(DEBUG_DISPLAY,
+ "dsp_prop: dsp_prop(DSP_GET, DSP_COLWIDTH) = %d\n",
g_dsp_props.p_colwidth);)
*((int*)ptr) = g_dsp_props.p_colwidth;
break;
case DSP_FLOAT_PREC:
- DBG(sqsh_debug(DEBUG_DISPLAY,
- "dsp_prop: dsp_prop(DSP_GET, DSP_FLOAT_PREC) = %d\n",
+ DBG(sqsh_debug(DEBUG_DISPLAY,
+ "dsp_prop: dsp_prop(DSP_GET, DSP_FLOAT_PREC) = %d\n",
g_dsp_props.p_flt_prec);)
*((int*)ptr) = g_dsp_props.p_flt_prec;
break;
case DSP_FLOAT_SCALE:
- DBG(sqsh_debug(DEBUG_DISPLAY,
- "dsp_prop: dsp_prop(DSP_GET, DSP_FLOAT_SCALE) = %d\n",
+ DBG(sqsh_debug(DEBUG_DISPLAY,
+ "dsp_prop: dsp_prop(DSP_GET, DSP_FLOAT_SCALE) = %d\n",
g_dsp_props.p_flt_scale);)
*((int*)ptr) = g_dsp_props.p_flt_scale;
break;
case DSP_REAL_PREC:
- DBG(sqsh_debug(DEBUG_DISPLAY,
- "dsp_prop: dsp_prop(DSP_GET, DSP_REAL_PREC) = %d\n",
+ DBG(sqsh_debug(DEBUG_DISPLAY,
+ "dsp_prop: dsp_prop(DSP_GET, DSP_REAL_PREC) = %d\n",
g_dsp_props.p_real_prec);)
*((int*)ptr) = g_dsp_props.p_real_prec;
break;
case DSP_REAL_SCALE:
- DBG(sqsh_debug(DEBUG_DISPLAY,
- "dsp_prop: dsp_prop(DSP_GET, DSP_REAL_SCALE) = %d\n",
+ DBG(sqsh_debug(DEBUG_DISPLAY,
+ "dsp_prop: dsp_prop(DSP_GET, DSP_REAL_SCALE) = %d\n",
g_dsp_props.p_real_scale);)
*((int*)ptr) = g_dsp_props.p_real_scale;
break;
+ case DSP_DATETIMEFMT:
+ DBG(sqsh_debug(DEBUG_DISPLAY,
+ "dsp_prop: dsp_prop(DSP_GET, DSP_DATETIMEFMT) = %s\n",
+ dsp_datetimefmt_get());)
+
+ if (len <= 0)
+ {
+ sqsh_set_error( SQSH_E_INVAL, "length must be greater than 0" );
+ return DSP_FAIL;
+ }
+
+ strncpy( (char*)ptr, dsp_datetimefmt_get(), len );
+ break;
+
case DSP_DATEFMT:
- DBG(sqsh_debug(DEBUG_DISPLAY,
- "dsp_prop: dsp_prop(DSP_GET, DSP_DATEFMT) = %s\n",
+ DBG(sqsh_debug(DEBUG_DISPLAY,
+ "dsp_prop: dsp_prop(DSP_GET, DSP_DATEFMT) = %s\n",
dsp_datefmt_get());)
if (len <= 0)
@@ -644,74 +693,88 @@ static int dsp_prop_get( prop, ptr, len )
strncpy( (char*)ptr, dsp_datefmt_get(), len );
break;
+
+ case DSP_TIMEFMT:
+ DBG(sqsh_debug(DEBUG_DISPLAY,
+ "dsp_prop: dsp_prop(DSP_GET, DSP_TIMEFMT) = %s\n",
+ dsp_timefmt_get());)
+
+ if (len <= 0)
+ {
+ sqsh_set_error( SQSH_E_INVAL, "length must be greater than 0" );
+ return DSP_FAIL;
+ }
+
+ strncpy( (char*)ptr, dsp_timefmt_get(), len );
+ break;
case DSP_STYLE:
- DBG(sqsh_debug(DEBUG_DISPLAY,
- "dsp_prop: dsp_prop(DSP_GET, DSP_STYLE) = %d\n",
+ DBG(sqsh_debug(DEBUG_DISPLAY,
+ "dsp_prop: dsp_prop(DSP_GET, DSP_STYLE) = %d\n",
g_dsp_props.p_style);)
*((int*)ptr) = g_dsp_props.p_style;
break;
- case DSP_WIDTH:
- DBG(sqsh_debug(DEBUG_DISPLAY,
- "dsp_prop: dsp_prop(DSP_GET, DSP_WIDTH) = %d\n",
+ case DSP_WIDTH:
+ DBG(sqsh_debug(DEBUG_DISPLAY,
+ "dsp_prop: dsp_prop(DSP_GET, DSP_WIDTH) = %d\n",
g_dsp_props.p_width);)
*((int*)ptr) = g_dsp_props.p_width;
break;
- case DSP_OUTPUTPARMS:
- DBG(sqsh_debug(DEBUG_DISPLAY,
- "dsp_prop: dsp_prop(DSP_GET, DSP_OUTPUTPARMS) = %d\n",
+ case DSP_OUTPUTPARMS:
+ DBG(sqsh_debug(DEBUG_DISPLAY,
+ "dsp_prop: dsp_prop(DSP_GET, DSP_OUTPUTPARMS) = %d\n",
g_dsp_props.p_outputparms);)
*((int*)ptr) = g_dsp_props.p_outputparms;
break;
case DSP_COLSEP:
- DBG(sqsh_debug(DEBUG_DISPLAY,
- "dsp_prop: dsp_prop(DSP_GET, DSP_COLSEP) = %s\n",
+ DBG(sqsh_debug(DEBUG_DISPLAY,
+ "dsp_prop: dsp_prop(DSP_GET, DSP_COLSEP) = %s\n",
g_dsp_props.p_colsep);)
strncpy( (char*)ptr, g_dsp_props.p_colsep, len );
break;
case DSP_BCP_COLSEP:
- DBG(sqsh_debug(DEBUG_DISPLAY,
- "dsp_prop: dsp_prop(DSP_GET, DSP_BCP_COLSEP) = %s\n",
+ DBG(sqsh_debug(DEBUG_DISPLAY,
+ "dsp_prop: dsp_prop(DSP_GET, DSP_BCP_COLSEP) = %s\n",
g_dsp_props.p_bcp_colsep);)
strncpy( (char*)ptr, g_dsp_props.p_bcp_colsep, len );
break;
case DSP_BCP_ROWSEP:
- DBG(sqsh_debug(DEBUG_DISPLAY,
- "dsp_prop: dsp_prop(DSP_GET, DSP_BCP_ROWSEP) = %s\n",
+ DBG(sqsh_debug(DEBUG_DISPLAY,
+ "dsp_prop: dsp_prop(DSP_GET, DSP_BCP_ROWSEP) = %s\n",
g_dsp_props.p_bcp_rowsep);)
strncpy( (char*)ptr, g_dsp_props.p_bcp_rowsep, len );
break;
case DSP_BCP_TRIM:
- DBG(sqsh_debug(DEBUG_DISPLAY,
- "dsp_prop: dsp_prop(DSP_GET, DSP_BCP_TRIM) = %d\n",
+ DBG(sqsh_debug(DEBUG_DISPLAY,
+ "dsp_prop: dsp_prop(DSP_GET, DSP_BCP_TRIM) = %d\n",
g_dsp_props.p_bcp_trim);)
*((int*)ptr) = g_dsp_props.p_bcp_trim;
break;
case DSP_LINESEP:
- DBG(sqsh_debug(DEBUG_DISPLAY,
- "dsp_prop: dsp_prop(DSP_GET, DSP_LINESEP) = %s\n",
+ DBG(sqsh_debug(DEBUG_DISPLAY,
+ "dsp_prop: dsp_prop(DSP_GET, DSP_LINESEP) = %s\n",
g_dsp_props.p_linesep);)
strncpy( (char*)ptr, g_dsp_props.p_linesep, len );
break;
case DSP_XGEOM:
- DBG(sqsh_debug(DEBUG_DISPLAY,
- "dsp_prop: dsp_prop(DSP_GET, DSP_XGEOM) = %s\n",
+ DBG(sqsh_debug(DEBUG_DISPLAY,
+ "dsp_prop: dsp_prop(DSP_GET, DSP_XGEOM) = %s\n",
g_dsp_props.p_xgeom);)
if (len <= 0)
@@ -724,8 +787,8 @@ static int dsp_prop_get( prop, ptr, len )
break;
case DSP_MAXLEN:
- DBG(sqsh_debug(DEBUG_DISPLAY,
- "dsp_prop: dsp_prop(DSP_GET, DSP_MAXLEN) = %d\n",
+ DBG(sqsh_debug(DEBUG_DISPLAY,
+ "dsp_prop: dsp_prop(DSP_GET, DSP_MAXLEN) = %d\n",
g_dsp_props.p_maxlen);)
*((int*)ptr) = g_dsp_props.p_maxlen;
diff --git a/src/dsp.h b/src/dsp.h
index a4171a9..68ebafd 100644
--- a/src/dsp.h
+++ b/src/dsp.h
@@ -107,6 +107,7 @@ typedef struct _dsp_desc_t {
*/
#define DSP_F_NOHEADERS (1<<0) /* Suppress headers */
#define DSP_F_NOFOOTERS (1<<1) /* Suppress footers */
+#define DSP_F_NOSEPLINE (1<<2) /* Suppress seperator lines */
#define DSP_F_NOTHING (1<<3) /* Everything */
#define DSP_F_X (1<<4) /* Send output to X Window */
@@ -122,13 +123,17 @@ extern int g_dsp_interrupted;
#define DSP_GET 1
#define DSP_SET 2
+/*
+ * sqsh-2.1.9 - Introduced or changed property types DSP_DATETIMEFMT, DSP_DATEFMT and DSP_TIMEFMT
+ */
+
/*-- Types of properties for dsp_prop() --*/
#define DSP_WIDTH 1
#define DSP_COLSEP 2
#define DSP_LINESEP 3
#define DSP_XGEOM 4
#define DSP_STYLE 5
-#define DSP_DATEFMT 6
+#define DSP_DATETIMEFMT 6
#define DSP_FLOAT_SCALE 7
#define DSP_FLOAT_PREC 8
#define DSP_REAL_SCALE 9
@@ -141,7 +146,9 @@ extern int g_dsp_interrupted;
#define DSP_MAXLEN 16
#define DSP_CSV_COLSEP 17
#define DSP_CSV_ROWSEP 18
-#define DSP_VALID_PROP(p) ((p) >= DSP_WIDTH && (p) <= DSP_CSV_ROWSEP)
+#define DSP_DATEFMT 19
+#define DSP_TIMEFMT 20
+#define DSP_VALID_PROP(p) ((p) >= DSP_WIDTH && (p) <= DSP_TIMEFMT)
/*-- Length for dsp_prop() --*/
@@ -226,34 +233,44 @@ typedef struct dsp_prop_st {
* (or as defaulted).
*/
extern dsp_prop_t g_dsp_props;
-
+
+/*
+ * sqsh-2.1.9 - To implement the date and time datatypes conversion feature,
+ * the following prototypes have been added or modified: dsp_datetimefmt_set,
+ * dsp_datetimefmt_get, dsp_datefmt_set, dsp_datefmt_get, dsp_timefmt_set,
+ * dsp_timefmt_get and dsp_datetime_conv.
+*/
+
/*-- Internal Prototypes --*/
-dsp_out_t* dsp_fopen _ANSI_ARGS(( FILE* ));
-int dsp_fputc _ANSI_ARGS(( int, dsp_out_t* ));
-int dsp_fputs _ANSI_ARGS(( char*, dsp_out_t* ));
-int dsp_fflush _ANSI_ARGS(( dsp_out_t* ));
-int dsp_fprintf _ANSI_ARGS(( dsp_out_t*, char*, ... ));
-int dsp_fclose _ANSI_ARGS(( dsp_out_t* ));
-int dsp_horiz _ANSI_ARGS(( dsp_out_t*, CS_COMMAND*, int ));
-int dsp_meta _ANSI_ARGS(( dsp_out_t*, CS_COMMAND*, int ));
-int dsp_vert _ANSI_ARGS(( dsp_out_t*, CS_COMMAND*, int ));
-int dsp_bcp _ANSI_ARGS(( dsp_out_t*, CS_COMMAND*, int ));
-int dsp_csv _ANSI_ARGS(( dsp_out_t*, CS_COMMAND*, int ));
-int dsp_html _ANSI_ARGS(( dsp_out_t*, CS_COMMAND*, int ));
-int dsp_none _ANSI_ARGS(( dsp_out_t*, CS_COMMAND*, int ));
-int dsp_pretty _ANSI_ARGS(( dsp_out_t*, CS_COMMAND*, int ));
-int dsp_x _ANSI_ARGS(( dsp_out_t*, CS_COMMAND*, int, dsp_t* ));
-int dsp_datefmt_set _ANSI_ARGS(( char* ));
-char* dsp_datefmt_get _ANSI_ARGS(( void ));
-dsp_desc_t* dsp_desc_bind _ANSI_ARGS(( CS_COMMAND*, CS_INT ));
-CS_INT dsp_desc_fetch _ANSI_ARGS(( CS_COMMAND*, dsp_desc_t* ));
-void dsp_desc_destroy _ANSI_ARGS(( dsp_desc_t* ));
-CS_INT dsp_datetime_len _ANSI_ARGS(( CS_CONTEXT*, CS_INT ));
-CS_INT dsp_datetime4_len _ANSI_ARGS(( CS_CONTEXT* ));
-CS_INT dsp_money_len _ANSI_ARGS(( CS_CONTEXT* ));
-CS_INT dsp_money4_len _ANSI_ARGS(( CS_CONTEXT* ));
-CS_RETCODE dsp_datetime_conv _ANSI_ARGS(( CS_CONTEXT*, CS_DATAFMT*, CS_VOID*,
- CS_CHAR*, CS_INT ));
+dsp_out_t* dsp_fopen _ANSI_ARGS(( FILE* ));
+int dsp_fputc _ANSI_ARGS(( int, dsp_out_t* ));
+int dsp_fputs _ANSI_ARGS(( char*, dsp_out_t* ));
+int dsp_fflush _ANSI_ARGS(( dsp_out_t* ));
+int dsp_fprintf _ANSI_ARGS(( dsp_out_t*, char*, ... ));
+int dsp_fclose _ANSI_ARGS(( dsp_out_t* ));
+int dsp_horiz _ANSI_ARGS(( dsp_out_t*, CS_COMMAND*, int ));
+int dsp_meta _ANSI_ARGS(( dsp_out_t*, CS_COMMAND*, int ));
+int dsp_vert _ANSI_ARGS(( dsp_out_t*, CS_COMMAND*, int ));
+int dsp_bcp _ANSI_ARGS(( dsp_out_t*, CS_COMMAND*, int ));
+int dsp_csv _ANSI_ARGS(( dsp_out_t*, CS_COMMAND*, int ));
+int dsp_html _ANSI_ARGS(( dsp_out_t*, CS_COMMAND*, int ));
+int dsp_none _ANSI_ARGS(( dsp_out_t*, CS_COMMAND*, int ));
+int dsp_pretty _ANSI_ARGS(( dsp_out_t*, CS_COMMAND*, int ));
+int dsp_x _ANSI_ARGS(( dsp_out_t*, CS_COMMAND*, int, dsp_t* ));
+int dsp_datetimefmt_set _ANSI_ARGS(( char* ));
+char* dsp_datetimefmt_get _ANSI_ARGS(( void ));
+int dsp_datefmt_set _ANSI_ARGS(( char* ));
+char* dsp_datefmt_get _ANSI_ARGS(( void ));
+int dsp_timefmt_set _ANSI_ARGS(( char* ));
+char* dsp_timefmt_get _ANSI_ARGS(( void ));
+dsp_desc_t* dsp_desc_bind _ANSI_ARGS(( CS_COMMAND*, CS_INT ));
+CS_INT dsp_desc_fetch _ANSI_ARGS(( CS_COMMAND*, dsp_desc_t* ));
+void dsp_desc_destroy _ANSI_ARGS(( dsp_desc_t* ));
+CS_INT dsp_datetime_len _ANSI_ARGS(( CS_CONTEXT*, CS_INT ));
+CS_INT dsp_datetime4_len _ANSI_ARGS(( CS_CONTEXT* ));
+CS_INT dsp_money_len _ANSI_ARGS(( CS_CONTEXT* ));
+CS_INT dsp_money4_len _ANSI_ARGS(( CS_CONTEXT* ));
+CS_RETCODE dsp_datetime_conv _ANSI_ARGS(( CS_CONTEXT*, CS_DATAFMT*, CS_VOID*, CS_CHAR*, CS_INT, CS_INT ));
#if defined(DEBUG)
char* dsp_result_name _ANSI_ARGS(( CS_INT ));
diff --git a/src/dsp_conv.c b/src/dsp_conv.c
index 78e1027..6c6878c 100644
--- a/src/dsp_conv.c
+++ b/src/dsp_conv.c
@@ -28,34 +28,59 @@
#include "sqsh_error.h"
#include "sqsh_compat.h"
#include "dsp.h"
+#include "config.h"
+
+#if defined(HAVE_LOCALE_H)
+#include <locale.h>
+#endif
/*-- Current Version --*/
#if !defined(lint) && !defined(__LINT__)
-static char RCS_Id[] = "$Id: dsp_conv.c,v 1.2 2004/04/10 00:10:30 mpeppler Exp $";
+static char RCS_Id[] = "$Id: dsp_conv.c,v 1.7 2013/07/23 20:57:28 mwesdorp Exp $";
USE(RCS_Id)
#endif /* !defined(lint) */
+/*
+ * sqsh-2.1.9 - Introduced and remapped global variables sg_datetime_fmt, sg_date_fmt
+ * and sg_time_fmt as well as the functions dsp_datetimefmt_set, dsp_datetimefmt_get,
+ * dsp_datefmt_set, dsp_datefmt_get, dsp_timefmt_set and dsp_timefmt_get to implement
+ * date and time datatype conversions with strftime as already existed for the datetime
+ * and smalldatetime datatypes.
+ * This feature request was filed as bugreport 3603409 on Sourceforge.
+ */
+
/*-- Local Globals --*/
static char sg_datetime_fmt[64] = "\0";
+static char sg_date_fmt[64] = "\0";
+static char sg_time_fmt[64] = "\0";
static int sg_datetime_len = -1;
static int sg_datetime4_len = -1;
static int sg_date_len = -1;
static int sg_time_len = -1;
+static int sg_bigdatetime_len = -1;
+static int sg_bigtime_len = -1;
+#if defined(HAVE_SETLOCALE)
+static char *sg_locale = NULL;
+#endif
+#if defined(CS_BIGDATETIME_TYPE) && defined(CS_BIGTIME_TYPE)
+static char sg_datetime_def[64] = "%b %d %Y %l:%M:%S.%q%p";
+static char sg_time_def[64] = "%l:%M:%S.%q%p";
+#endif
/*-- Prototypes --*/
-static CS_INT dsp_type_len _ANSI_ARGS(( CS_CONTEXT*, CS_CHAR*,
+static CS_INT dsp_type_len _ANSI_ARGS(( CS_CONTEXT*, CS_CHAR*,
CS_DATAFMT*, CS_VOID* ));
static char* dsp_datetime_strip _ANSI_ARGS(( CS_INT, char*, int ));
/*
- * dsp_datefmt_set():
+ * dsp_datetimefmt_set():
*
* Set the conversion format to be used by the display routine when
* converting dates. A format string of NULL or "default" indicates
* that the default CT-Lib conversion method should be used. Otherwise
* a string suitable for use by strftime() should be supplied.
*/
-int dsp_datefmt_set( fmt )
+int dsp_datetimefmt_set( fmt )
char *fmt;
{
/*
@@ -64,8 +89,9 @@ int dsp_datefmt_set( fmt )
* we are now changing the format from what it was, these
* variables should be reset.
*/
- sg_datetime_len = -1;
- sg_datetime4_len = -1;
+ sg_datetime_len = -1;
+ sg_datetime4_len = -1;
+ sg_bigdatetime_len = -1;
/*
* If the format is NULL or "default", then we simply store
@@ -82,18 +108,19 @@ int dsp_datefmt_set( fmt )
* longer than the size of sg_datetime_fmt, then we quietly
* trim it to the appropriate length.
*/
- strncpy( sg_datetime_fmt, fmt, sizeof(sg_datetime_fmt) );
+ strncpy( sg_datetime_fmt, fmt, sizeof(sg_datetime_fmt)-1 );
+ sg_datetime_fmt[sizeof(sg_datetime_fmt)-1] = '\0';
return DSP_SUCCEED;
}
/*
- * dsp_datefmt_get():
+ * dsp_datetimefmt_get():
*
* Retrieve the conversion format to be used by the display routine when
* converting dates. A format string of NULL or "default" indicates
* that the default CT-Lib conversion method should be used.
*/
-char* dsp_datefmt_get()
+char* dsp_datetimefmt_get()
{
if (*sg_datetime_fmt == '\0')
{
@@ -103,14 +130,139 @@ char* dsp_datefmt_get()
return sg_datetime_fmt;
}
+
+/*
+ * dsp_datefmt_set():
+ *
+ * sqsh-2.1.9 - Date and time datatype conversion feature.
+ *
+ * Set the conversion format to be used by the display routine when
+ * converting dates. A format string of NULL or "default" indicates
+ * that the default CT-Lib conversion method should be used. Otherwise
+ * a string suitable for use by strftime() should be supplied.
+ */
+int dsp_datefmt_set( fmt )
+ char *fmt;
+{
+ /*
+ * The dsp_datetime_len() function uses these global variables
+ * to store the results of the last time it was called. Since
+ * we are now changing the format from what it was, these
+ * variables should be reset.
+ */
+ sg_date_len = -1;
+
+ /*
+ * If the format is NULL or "default", then we simply store
+ * away the format to be used as an empty string.
+ */
+ if (fmt == NULL || strcmp( fmt, "default" ) == 0)
+ {
+ sg_date_fmt[0] = '\0';
+ return DSP_SUCCEED;
+ }
+
+ /*
+ * This is a little cheesy. If the user passes us a string
+ * longer than the size of sg_date_fmt, then we quietly
+ * trim it to the appropriate length.
+ */
+ strncpy( sg_date_fmt, fmt, sizeof(sg_date_fmt)-1 );
+ sg_date_fmt[sizeof(sg_date_fmt)-1] = '\0';
+ return DSP_SUCCEED;
+}
+
+/*
+ * dsp_datefmt_get():
+ *
+ * sqsh-2.1.9 - Date and time datatype conversion feature.
+ *
+ * Retrieve the conversion format to be used by the display routine when
+ * converting dates. A format string of NULL or "default" indicates
+ * that the default CT-Lib conversion method should be used.
+ */
+char* dsp_datefmt_get()
+{
+ if (*sg_date_fmt == '\0')
+ {
+ return "default";
+ }
+
+ return sg_date_fmt;
+}
+
+/*
+ * dsp_timefmt_set():
+ *
+ * sqsh-2.1.9 - Date and time datatype conversion feature.
+ *
+ * Set the conversion format to be used by the display routine when
+ * converting times. A format string of NULL or "default" indicates
+ * that the default CT-Lib conversion method should be used. Otherwise
+ * a string suitable for use by strftime() should be supplied.
+ */
+int dsp_timefmt_set( fmt )
+ char *fmt;
+{
+ /*
+ * The dsp_time_len() function uses these global variables
+ * to store the results of the last time it was called. Since
+ * we are now changing the format from what it was, these
+ * variables should be reset.
+ */
+ sg_time_len = -1;
+ sg_bigtime_len = -1;
+
+ /*
+ * If the format is NULL or "default", then we simply store
+ * away the format to be used as an empty string.
+ */
+ if (fmt == NULL || strcmp( fmt, "default" ) == 0)
+ {
+ sg_time_fmt[0] = '\0';
+ return DSP_SUCCEED;
+ }
+
+ /*
+ * This is a little cheesy. If the user passes us a string
+ * longer than the size of sg_time_fmt, then we quietly
+ * trim it to the appropriate length.
+ */
+ strncpy( sg_time_fmt, fmt, sizeof(sg_time_fmt)-1 );
+ sg_time_fmt[sizeof(sg_time_fmt)-1] = '\0';
+ return DSP_SUCCEED;
+}
+
+/*
+ * dsp_timefmt_get():
+ *
+ * sqsh-2.1.9 - Date and time datatype conversion feature.
+ *
+ * Retrieve the conversion format to be used by the display routine when
+ * converting dates. A format string of NULL or "default" indicates
+ * that the default CT-Lib conversion method should be used.
+ */
+char* dsp_timefmt_get()
+{
+ if (*sg_time_fmt == '\0')
+ {
+ return "default";
+ }
+
+ return sg_time_fmt;
+}
+
/*
* dsp_datetime_len():
*
* Calculates the maximum number of characters required to store
* a date in a string format of the current locale. This function
- * is similar to dsp_money_len() except that every month is
+ * is similar to dsp_money_len() except that every month is
* converted to verify if particular month names are longer than
* others.
+ *
+ * sqsh-2.1.9 - Also implement date and time datatype conversions.
+ * sqsh-2.3 - Improve handling of bigdatetime and bigtime data types.
*/
CS_INT dsp_datetime_len( ctxt, type )
CS_CONTEXT *ctxt;
@@ -125,6 +277,30 @@ CS_INT dsp_datetime_len( ctxt, type )
int max_len;
int len;
char *fmt;
+#if defined(CS_BIGDATETIME_TYPE) && defined(CS_BIGTIME_TYPE)
+ char *conv_fmt;
+#endif
+#if defined(HAVE_LOCALE_H) && defined(HAVE_SETLOCALE)
+ char *locale;
+
+ /*
+ * sqsh-2.3 : If the locale was changed recently, we have to reset
+ * the cached type len values.
+ */
+ locale = setlocale (LC_ALL, NULL);
+ if ( sg_locale != locale )
+ {
+ DBG(sqsh_debug(DEBUG_DISPLAY, "locale changed to %s\n", locale);)
+
+ sg_locale = locale;
+ sg_datetime_len = -1;
+ sg_datetime4_len = -1;
+ sg_date_len = -1;
+ sg_time_len = -1;
+ sg_bigdatetime_len = -1;
+ sg_bigtime_len = -1;
+ }
+#endif
/*
* Check to see if we have cached the value from the last time
@@ -155,6 +331,20 @@ CS_INT dsp_datetime_len( ctxt, type )
}
#endif
+#if defined(CS_BIGDATETIME_TYPE)
+ if (type == CS_BIGDATETIME_TYPE && sg_bigdatetime_len != -1)
+ {
+ return sg_bigdatetime_len;
+ }
+#endif
+
+#if defined(CS_BIGTIME_TYPE)
+ if (type == CS_BIGTIME_TYPE && sg_bigtime_len != -1)
+ {
+ return sg_bigtime_len;
+ }
+#endif
+
/*
* If the user is using the default CT-Lib conversion format then
* we try a brute force test of all of the months in the year,
@@ -162,15 +352,12 @@ CS_INT dsp_datetime_len( ctxt, type )
*/
max_len = 0;
- /* The user defined conversion with strftime, etc. is not implemented
- for the CS_DATE_TYPE and CS_TIME_TYPE datatypes */
- if (*sg_datetime_fmt == '\0' ||
+ if ((type == CS_DATETIME_TYPE && *sg_datetime_fmt == '\0')
+ || (type == CS_DATETIME4_TYPE && *sg_datetime_fmt == '\0')
#if defined(CS_DATE_TYPE)
- (type == CS_DATE_TYPE || type == CS_TIME_TYPE)
-#else
- 0
+ || (type == CS_DATE_TYPE && *sg_date_fmt == '\0')
#endif
- )
+ )
{
dt_fmt.datatype = type;
dt_fmt.maxlength = sizeof(CS_DATETIME);
@@ -189,21 +376,52 @@ CS_INT dsp_datetime_len( ctxt, type )
for (i = 1; i <= 12; i++)
{
/*-- Build a made-up day of the month --*/
- sprintf( dt_buf, "%d/12/1997 11:59:53:123PM", i );
+ switch (type)
+ {
+ case CS_DATETIME_TYPE:
+ sprintf( dt_buf, "%d/12/1997 11:59:53.123PM", i );
+ break;
+ case CS_DATETIME4_TYPE:
+ sprintf( dt_buf, "%d/12/1997 11:59PM", i );
+ break;
+#if defined(CS_DATE_TYPE)
+ case CS_DATE_TYPE:
+ sprintf( dt_buf, "%d/12/1997", i );
+ break;
+#endif
+ default:
+ sprintf( dt_buf, "%d/12/1997 11:59:53PM", i );
+ break;
+ }
len = dsp_type_len( ctxt, (CS_CHAR*)dt_buf, &dt_fmt, &dt );
/*-- Keep track of the longest date encountered --*/
max_len = max(len, max_len);
}
}
+#if defined(CS_TIME_TYPE)
+ else if (type == CS_TIME_TYPE && *sg_time_fmt == '\0')
+ {
+ dt_fmt.datatype = type;
+ dt_fmt.maxlength = sizeof(CS_DATETIME);
+ dt_fmt.locale = NULL;
+ dt_fmt.format = CS_FMT_UNUSED;
+ dt_fmt.scale = 0;
+ dt_fmt.precision = 0;
+ sprintf( dt_buf, "11:59:53.123PM" );
+ max_len = dsp_type_len( ctxt, (CS_CHAR*)dt_buf, &dt_fmt, &dt );
+ }
+#endif
else
{
/*
* If the user has supplied a display format to be used in
* place of the CT-Lib format, then we have a lot of work
- * to do; beginning wth building a reasonable UNIX time
+ * to do; beginning with building a reasonable UNIX time
* structure.
+ * sqsh-2.3 : Note that CS_BIGDATETIME_TYPE and CS_BIGTIME_TYPE
+ * will use a default format here, if one is not supplied.
*/
tm.tm_sec = 59;
tm.tm_min = 59;
@@ -216,10 +434,37 @@ CS_INT dsp_datetime_len( ctxt, type )
/*
* Strip down the format string as defined by the CS_DATETIME
- * datatype, and replace the ms (%u) with the longest possible
+ * datatype, and replace the ms (%q) with the longest possible
* number.
*/
- fmt = dsp_datetime_strip( type, sg_datetime_fmt, 999 );
+ switch (type)
+ {
+#if defined(CS_DATE_TYPE)
+ case CS_DATE_TYPE:
+ fmt = dsp_datetime_strip( type, sg_date_fmt, 999 );
+ break;
+#endif
+#if defined(CS_TIME_TYPE)
+ case CS_TIME_TYPE:
+ fmt = dsp_datetime_strip( type, sg_time_fmt, 999 );
+ break;
+#endif
+#if defined(CS_BIGDATETIME_TYPE)
+ case CS_BIGDATETIME_TYPE:
+ conv_fmt = sg_datetime_fmt[0] == '\0' ? sg_datetime_def : sg_datetime_fmt;
+ fmt = dsp_datetime_strip( type, conv_fmt, 999999 );
+ break;
+#endif
+#if defined(CS_BIGTIME_TYPE)
+ case CS_BIGTIME_TYPE:
+ conv_fmt = sg_time_fmt[0] == '\0' ? sg_time_def : sg_time_fmt;
+ fmt = dsp_datetime_strip( type, conv_fmt, 999999 );
+ break;
+#endif
+ default:
+ fmt = dsp_datetime_strip( type, sg_datetime_fmt, 999 );
+ break;
+ }
max_len = 0;
max_month = 0;
@@ -270,31 +515,42 @@ CS_INT dsp_datetime_len( ctxt, type )
}
}
- DBG(sqsh_debug(DEBUG_DISPLAY,
- "dsp_datetime_len: %s = %d chars\n",
- (type == CS_DATETIME_TYPE)?"CS_DATETIME":"CS_SMALLDATETIME",
- max_len);)
-
- switch(type) {
- case CS_DATETIME_TYPE:
- sg_datetime_len = max_len;
- break;
- case CS_DATETIME4_TYPE:
- sg_datetime4_len = max_len;
- break;
+ DBG(sqsh_debug(DEBUG_DISPLAY,
+ "dsp_datetime_len: %s (type %d) = %d chars\n",
+ (type == CS_DATETIME_TYPE)?"CS_DATETIME":"Other DATE/TIME type",
+ type, max_len);)
+
+ switch (type) {
+ case CS_DATETIME_TYPE:
+ sg_datetime_len = max_len;
+ break;
+
+ case CS_DATETIME4_TYPE:
+ sg_datetime4_len = max_len;
+ break;
#if defined(CS_DATE_TYPE)
- case CS_DATE_TYPE:
- sg_date_len = max_len;
- break;
+ case CS_DATE_TYPE:
+ sg_date_len = max_len;
+ break;
#endif
#if defined(CS_TIME_TYPE)
- case CS_TIME_TYPE:
- sg_time_len = max_len;
- break;
+ case CS_TIME_TYPE:
+ sg_time_len = max_len;
+ break;
+#endif
+#if defined(CS_BIGDATETIME_TYPE)
+ case CS_BIGDATETIME_TYPE:
+ sg_bigdatetime_len = max_len;
+ break;
+#endif
+#if defined(CS_BIGTIME_TYPE)
+ case CS_BIGTIME_TYPE:
+ sg_bigtime_len = max_len;
+ break;
#endif
}
-/* fprintf(stderr, "type = %d, len = %d\n", type, max_len); */
+/* fprintf(stderr, "type = %d, len = %d\n", type, max_len); */
return (CS_INT)max_len;
}
@@ -306,30 +562,56 @@ CS_INT dsp_datetime_len( ctxt, type )
* of length, len according to the conversion style as defined in
* dsp_datetime_fmt(). This function returns CS_SUCCEED up success or
* CS_FAIL upon failure (duh!).
+ *
+ * sqsh-2.1.9 - Also implement the date and time datatype conversions.
*/
-CS_RETCODE dsp_datetime_conv( ctx, dt_fmt, dt, buf, len )
+CS_RETCODE dsp_datetime_conv( ctx, dt_fmt, dt, buf, len, type )
CS_CONTEXT *ctx; /* Context */
CS_DATAFMT *dt_fmt; /* Date format */
CS_VOID *dt; /* Pointer to date */
CS_CHAR *buf; /* Buffer */
CS_INT len; /* Length */
+ CS_INT type; /* CS_TYPE */
{
struct tm tm;
char *fmt;
CS_DATEREC dr;
CS_DATAFMT cs_fmt;
+ char *conv_fmt;
+
+
+ switch (type)
+ {
+#if defined(CS_DATE_TYPE)
+ case CS_DATE_TYPE:
+ conv_fmt = sg_date_fmt;
+ break;
+#endif
+#if defined(CS_TIME_TYPE)
+ case CS_TIME_TYPE:
+ conv_fmt = sg_time_fmt;
+ break;
+#endif
+#if defined(CS_BIGDATETIME_TYPE)
+ case CS_BIGDATETIME_TYPE:
+ conv_fmt = sg_datetime_fmt[0] == '\0' ? sg_datetime_def : sg_datetime_fmt;
+ break;
+#endif
+#if defined(CS_BIGTIME_TYPE)
+ case CS_BIGTIME_TYPE:
+ conv_fmt = sg_time_fmt[0] == '\0' ? sg_time_def : sg_time_fmt;
+ break;
+#endif
+ default:
+ conv_fmt = sg_datetime_fmt;
+ break;
+ }
/*
* If the user has not specified a format, then we let ct-lib
* do its thing. This seems to be OK for most platforms.
*/
- if (*sg_datetime_fmt == '\0' ||
-#if defined(CS_DATE_TYPE)
- (dt_fmt->datatype == CS_DATE_TYPE || dt_fmt->datatype == CS_TIME_TYPE)
-#else
- 0
-#endif
- )
+ if (*conv_fmt == '\0')
{
cs_fmt.datatype = CS_CHAR_TYPE;
cs_fmt.locale = NULL;
@@ -345,8 +627,7 @@ CS_RETCODE dsp_datetime_conv( ctx, dt_fmt, dt, buf, len )
(CS_VOID*)buf, /* String */
(CS_INT*)NULL ) != CS_SUCCEED)
{
- fprintf( stderr,
- "dsp_datetime_conv: cs_convert(DATETIME->CHAR) failed\n" );
+ fprintf( stderr, "dsp_datetime_conv: cs_convert(DATETIME->CHAR) failed\n" );
return CS_FAIL;
}
@@ -379,8 +660,12 @@ CS_RETCODE dsp_datetime_conv( ctx, dt_fmt, dt, buf, len )
* type of date that we are processing and replace the ms
* field if it exists.
*/
- fmt = dsp_datetime_strip( dt_fmt->datatype, sg_datetime_fmt,
- (int)dr.datemsecond );
+#if defined(CS_BIGDATETIME_TYPE) && defined(CS_BIGTIME_TYPE)
+ if (dt_fmt->datatype == CS_BIGDATETIME_TYPE || dt_fmt->datatype == CS_BIGTIME_TYPE)
+ fmt = dsp_datetime_strip( dt_fmt->datatype, conv_fmt, (int) dr.datesecfrac );
+ else
+#endif
+ fmt = dsp_datetime_strip( dt_fmt->datatype, conv_fmt, (int) dr.datemsecond );
/*
* According to the strftime(3C) documentation, there is no real
@@ -426,12 +711,12 @@ CS_INT dsp_money_len( ctxt )
*/
len = dsp_type_len( ctxt, (CS_CHAR*)"-922337203685477.5808",
&mon_fmt, (CS_VOID*)&mon );
-
+
if (len < 19)
{
len = 19;
}
-
+
DBG(sqsh_debug(DEBUG_DISPLAY, "dsp_money_len: CS_MONEY = %d chars\n",
len);)
@@ -550,7 +835,7 @@ static char* dsp_datetime_strip( type, fmt, ms )
/*
* Now, we want to keep date format that the caller specified,
- * but we want to strip out the milisecond (%u) and the
+ * but we want to strip out the millisecond (%q) and the
* delimeter for small and regular datetimes ([]).
*/
for (cp = new_fmt; *fmt != '\0'; ++fmt)
@@ -558,11 +843,21 @@ static char* dsp_datetime_strip( type, fmt, ms )
switch (*fmt)
{
case '%':
- if (*(fmt + 1) == 'u')
+ if (*(fmt + 1) == 'q')
{
- fmt += 2;
- sprintf( cp, "%03d", ms );
- cp += 3;
+ fmt += 1;
+#if defined(CS_BIGDATETIME_TYPE) && defined(CS_BIGTIME_TYPE)
+ if (type == CS_BIGDATETIME_TYPE || type == CS_BIGTIME_TYPE)
+ {
+ sprintf( cp, "%06d", ms );
+ cp += 6;
+ }
+ else
+#endif
+ {
+ sprintf( cp, "%03d", ms );
+ cp += 3;
+ }
}
else
{
@@ -583,7 +878,7 @@ static char* dsp_datetime_strip( type, fmt, ms )
case ']':
break;
-
+
default:
*cp++ = *fmt;
}
diff --git a/src/dsp_csv.c b/src/dsp_csv.c
index 75f889e..32b1c58 100644
--- a/src/dsp_csv.c
+++ b/src/dsp_csv.c
@@ -34,7 +34,7 @@ extern int errno;
/*-- Current Version --*/
#if !defined(lint) && !defined(__LINT__)
-static char RCS_Id[] = "$Id: dsp_csv.c,v 1.1 2005/07/24 11:41:19 mpeppler Exp $";
+static char RCS_Id[] = "$Id: dsp_csv.c,v 1.2 2013/02/19 18:06:42 mwesdorp Exp $";
USE(RCS_Id)
#endif /* !defined(lint) */
@@ -206,7 +206,12 @@ static void dsp_col( output, col_value, col_width )
if (end > col_value || (end == col_value && !isspace((int)*end))) {
dsp_fputc('"', output);
for (; col_value <= end; ++col_value)
+ {
+ /* sqsh-2.1.9 - Bug fix 3525302 */
+ if (*col_value == '"')
+ dsp_fputc('"', output);
dsp_fputc( *col_value, output );
+ }
dsp_fputc('"', output);
}
}
diff --git a/src/dsp_desc.c b/src/dsp_desc.c
index 3bb968f..f2bbd54 100644
--- a/src/dsp_desc.c
+++ b/src/dsp_desc.c
@@ -32,10 +32,19 @@
/*-- Current Version --*/
#if !defined(lint) && !defined(__LINT__)
-static char RCS_Id[] = "$Id: dsp_desc.c,v 1.6 2010/05/03 19:52:09 mpeppler Exp $";
+static char RCS_Id[] = "$Id: dsp_desc.c,v 1.13 2013/12/03 09:22:23 mwesdorp Exp $";
USE(RCS_Id)
#endif /* !defined(lint) */
+/*
+ * sqsh-2.5 : FreeTDS defines a datatype CS_UNIQUE_TYPE for the MSSQL uniqueidentifier.
+ * In order to compile correctly and make coding somewhat easier we define the type here,
+ * in case it was not defined already.
+*/
+#if !defined(CS_UNIQUE_TYPE)
+#define CS_UNIQUE_TYPE 40
+#endif
+
/*-- Local Prototypes --*/
static CS_INT dsp_dlen _ANSI_ARGS(( CS_DATAFMT* ));
static CS_INT dsp_just _ANSI_ARGS(( CS_INT ));
@@ -48,21 +57,56 @@ static void dsp_display_fmt _ANSI_ARGS(( CS_CHAR*, CS_DATAFMT* ));
* it is OK for CT-Lib to do the work. This macro allows us to test
* a given type as to whether or not we are going to let CT-Lib
* do the dirty work.
+ * sqsh-2.1.8: Add CS_BINARY_TYPE and CS_IMAGE_TYPE to the list.
+ * Fix bugreport 3079678.
+ * sqsh-2.3 : Added missing data types to the list (CS_UNITEXT_TYPE,
+ * CS_BIGINT_TYPE,CS_USMALLINT_TYPE,CS_UINT_TYPE,CS_UBIGINT_TYPE)
*/
-#define LET_CTLIB_CONV(t) \
- (((t) == CS_CHAR_TYPE) || \
- ((t) == CS_TEXT_TYPE) || \
- ((t) == CS_TINYINT_TYPE) || \
- ((t) == CS_SMALLINT_TYPE) || \
- ((t) == CS_INT_TYPE) || \
- ((t) == CS_BIT_TYPE) || \
- ((t) == CS_NUMERIC_TYPE) || \
- ((t) == CS_DECIMAL_TYPE) || \
- ((t) == CS_VARCHAR_TYPE) || \
- ((t) == CS_LONGCHAR_TYPE) || \
- ((t) == CS_LONGBINARY_TYPE)|| \
- ((t) == CS_VARBINARY_TYPE) || \
- ((t) == CS_UNICHAR_TYPE))
+#if defined(CS_UNITEXT_TYPE) && defined(CS_BIGINT_TYPE) && defined(CS_USMALLINT_TYPE) && defined(CS_UINT_TYPE) && defined(CS_UBIGINT_TYPE)
+#define LET_CTLIB_CONV(t) ( \
+ ((t) == CS_CHAR_TYPE) \
+ || ((t) == CS_BINARY_TYPE) \
+ || ((t) == CS_LONGCHAR_TYPE) \
+ || ((t) == CS_LONGBINARY_TYPE) \
+ || ((t) == CS_TEXT_TYPE) \
+ || ((t) == CS_IMAGE_TYPE) \
+ || ((t) == CS_TINYINT_TYPE) \
+ || ((t) == CS_SMALLINT_TYPE) \
+ || ((t) == CS_INT_TYPE) \
+ || ((t) == CS_BIT_TYPE) \
+ || ((t) == CS_NUMERIC_TYPE) \
+ || ((t) == CS_DECIMAL_TYPE) \
+ || ((t) == CS_VARCHAR_TYPE) \
+ || ((t) == CS_VARBINARY_TYPE) \
+ || ((t) == CS_UNICHAR_TYPE) \
+ || ((t) == CS_UNITEXT_TYPE) \
+ || ((t) == CS_BIGINT_TYPE) \
+ || ((t) == CS_USMALLINT_TYPE) \
+ || ((t) == CS_UINT_TYPE) \
+ || ((t) == CS_UBIGINT_TYPE) \
+ || ((t) == CS_UNIQUE_TYPE) \
+ )
+#else
+#define LET_CTLIB_CONV(t) ( \
+ ((t) == CS_CHAR_TYPE) \
+ || ((t) == CS_BINARY_TYPE) \
+ || ((t) == CS_LONGCHAR_TYPE) \
+ || ((t) == CS_LONGBINARY_TYPE) \
+ || ((t) == CS_TEXT_TYPE) \
+ || ((t) == CS_IMAGE_TYPE) \
+ || ((t) == CS_TINYINT_TYPE) \
+ || ((t) == CS_SMALLINT_TYPE) \
+ || ((t) == CS_INT_TYPE) \
+ || ((t) == CS_BIT_TYPE) \
+ || ((t) == CS_NUMERIC_TYPE) \
+ || ((t) == CS_DECIMAL_TYPE) \
+ || ((t) == CS_VARCHAR_TYPE) \
+ || ((t) == CS_VARBINARY_TYPE) \
+ || ((t) == CS_UNICHAR_TYPE) \
+ || ((t) == CS_UNIQUE_TYPE) \
+ )
+#endif
+
/*
* dsp_desc_bind():
@@ -89,15 +133,14 @@ dsp_desc_t* dsp_desc_bind( cmd, result_type )
CS_UNUSED, /* Buffer Length */
(CS_INT*)NULL) != CS_SUCCEED)
{
- fprintf( stderr,
- "dsp_desc_bind: Unable to retrieve column count (CS_NUMDATA)\n" );
+ fprintf( stderr, "dsp_desc_bind: Unable to retrieve column count (CS_NUMDATA)\n" );
return NULL;
}
d = (dsp_desc_t*)malloc( sizeof( dsp_desc_t ) );
c = (dsp_col_t*)malloc( sizeof( dsp_col_t ) * ncols );
- if (d == NULL || c == NULL)
+ if (d == NULL || c == NULL)
{
fprintf( stderr, "dsp_desc_bind: Memory allocation failure.\n" );
if (d != NULL)
@@ -113,7 +156,7 @@ dsp_desc_t* dsp_desc_bind( cmd, result_type )
d->d_bylist_size = 0;
d->d_bylist = NULL;
- for (i = 0; i < ncols; i++)
+ for (i = 0; i < ncols; i++)
{
d->d_cols[i].c_data = NULL;
@@ -130,7 +173,7 @@ dsp_desc_t* dsp_desc_bind( cmd, result_type )
d->d_cols[i].c_format.usertype = 0;
d->d_cols[i].c_format.locale = NULL;
}
-
+
if (result_type == CS_COMPUTE_RESULT)
{
if (ct_compute_info( cmd, /* Command */
@@ -141,22 +184,19 @@ dsp_desc_t* dsp_desc_bind( cmd, result_type )
(CS_INT*)NULL ) != CS_SUCCEED)
{
dsp_desc_destroy( d );
- fprintf( stderr,
- "dsp_desc_bind: Unable to fetch by-list len of compute results\n" );
+ fprintf( stderr, "dsp_desc_bind: Unable to fetch by-list len of compute results\n" );
return NULL;
}
if (d->d_bylist_size > 0)
{
- d->d_bylist = (CS_SMALLINT*)malloc( sizeof(CS_SMALLINT) *
- d->d_bylist_size );
-
+ d->d_bylist = (CS_SMALLINT*)malloc( sizeof(CS_SMALLINT) *d->d_bylist_size );
+
if (d->d_bylist == NULL)
{
dsp_desc_destroy( d );
- fprintf( stderr,
- "dsp_desc_bind: Memory failure for by-list size array\n" );
+ fprintf( stderr, "dsp_desc_bind: Memory failure for by-list size array\n" );
return NULL;
}
@@ -168,26 +208,24 @@ dsp_desc_t* dsp_desc_bind( cmd, result_type )
(CS_INT*)NULL) != CS_SUCCEED)
{
dsp_desc_destroy( d );
- fprintf( stderr,
- "dsp_desc_bind: Memory allocation failure for by-list array\n" );
+ fprintf( stderr, "dsp_desc_bind: Memory allocation failure for by-list array\n" );
return NULL;
}
}
}
-
+
/*
* Blast through the set of columns, binding the output to a
* friendly chunk of memory.
*/
- for (i = 0; i < ncols; i++)
+ for (i = 0; i < ncols; i++)
{
/*-- Get description for column --*/
- if (ct_describe( cmd, i+1, &d->d_cols[i].c_format ) != CS_SUCCEED)
+ if (ct_describe( cmd, i+1, &d->d_cols[i].c_format ) != CS_SUCCEED)
{
dsp_desc_destroy( d );
- fprintf( stderr,
- "dsp_desc_bind: Unable to fetch description of column #%d\n",
+ fprintf( stderr, "dsp_desc_bind: Unable to fetch description of column #%d\n",
(int)i+1 );
return NULL;
}
@@ -200,9 +238,9 @@ dsp_desc_t* dsp_desc_bind( cmd, result_type )
d->d_cols[i].c_data = NULL;
#if 0
- /* This code has been commented out as it generates the dreaded
- "bind resulted in truncation" error. */
- if (g_dsp_props.p_maxlen > 0 &&
+ /* This code has been commented out as it generates the dreaded
+ "bind resulted in truncation" error. */
+ if (g_dsp_props.p_maxlen > 0 &&
d->d_cols[i].c_maxlength > g_dsp_props.p_maxlen)
{
d->d_cols[i].c_maxlength = g_dsp_props.p_maxlen;
@@ -219,9 +257,9 @@ dsp_desc_t* dsp_desc_bind( cmd, result_type )
* request), I am forcing these data types to malloc a tad
* more memory then they may need.
*/
- /* The amount of memory alloced used to be 64 bytes. Pushed
- to 256 following discovery of buffer overflow problems by
- Mike Tibbetts */
+ /* The amount of memory alloced used to be 64 bytes. Pushed
+ to 256 following discovery of buffer overflow problems by
+ Mike Tibbetts */
if (d->d_cols[i].c_format.datatype == CS_FLOAT_TYPE ||
d->d_cols[i].c_format.datatype == CS_REAL_TYPE)
{
@@ -271,22 +309,22 @@ dsp_desc_t* dsp_desc_bind( cmd, result_type )
DBG(sqsh_debug(DEBUG_DISPLAY,
"dsp_desc_bind: ct_bind(\n"
- " cmd = 0x%p,\n"
+ " cmd = %p,\n"
" item = %d,\n"
" fmt = [datatype = CS_CHAR_TYPE,\n"
" format = CS_FMT_NULLTERM,\n"
" maxlength = %d,\n"
" count = 1,\n"
" locale = NULL],\n"
- " buf = 0x%p,\n"
+ " buf = %p,\n"
" bytes= NULL,\n"
- " ind = 0x%p)\n",
- (void*)cmd,
- i + 1,
- (int)str_fmt.maxlength,
+ " ind = %p)\n",
+ (void*)cmd,
+ i + 1,
+ (int)str_fmt.maxlength,
(void*)d->d_cols[i].c_data,
(void*)&d->d_cols[i].c_nullind);)
-
+
/*
* Now, bind the incoming row to the native data type. That
@@ -316,9 +354,8 @@ dsp_desc_t* dsp_desc_bind( cmd, result_type )
* data prior to doing the conversion.
*/
d->d_cols[i].c_is_native = CS_TRUE;
- d->d_cols[i].c_native =
- (CS_VOID*)malloc(d->d_cols[i].c_format.maxlength);
-
+ d->d_cols[i].c_native = (CS_VOID*)malloc(d->d_cols[i].c_format.maxlength);
+
if (d->d_cols[i].c_native == NULL)
{
fprintf( stderr,
@@ -336,7 +373,7 @@ dsp_desc_t* dsp_desc_bind( cmd, result_type )
DBG(sqsh_debug(DEBUG_DISPLAY,
"dsp_desc_bind: ct_bind(\n"
- " cmd = 0x%p,\n"
+ " cmd = %p,\n"
" item = %d,\n"
" fmt = [datatype = %d,\n"
" format = %d,\n"
@@ -344,12 +381,12 @@ dsp_desc_t* dsp_desc_bind( cmd, result_type )
" scale = %d,\n"
" precision = %d,\n"
" count = %d,\n"
- " locale = 0x%p],\n"
- " buf = 0x%p,\n"
- " bytes= 0x%p,\n"
- " ind = 0x%p)\n",
- (void*)cmd,
- i + 1,
+ " locale = %p],\n"
+ " buf = %p,\n"
+ " bytes= %p,\n"
+ " ind = %p)\n",
+ (void*)cmd,
+ i + 1,
(int)d->d_cols[i].c_format.datatype,
(int)d->d_cols[i].c_format.format,
(int)d->d_cols[i].c_format.maxlength,
@@ -422,6 +459,7 @@ dsp_desc_t* dsp_desc_bind( cmd, result_type )
return d;
}
+
CS_INT dsp_desc_fetch( cmd, d )
CS_COMMAND *cmd;
dsp_desc_t *d;
@@ -429,7 +467,12 @@ CS_INT dsp_desc_fetch( cmd, d )
CS_RETCODE r;
CS_INT nrows;
CS_INT i;
+ CS_INT j;
+ CS_INT p;
CS_DATAFMT str_fmt;
+#if defined(HAVE_LOCALE_H)
+ CS_CHAR *radix;
+#endif
if ((r = ct_fetch( cmd, /* Command */
CS_UNUSED, /* Type */
@@ -440,11 +483,11 @@ CS_INT dsp_desc_fetch( cmd, d )
return CS_END_DATA;
}
- /* mpeppler - 4/9/2004
- allow CS_ROW_FAIL results to go through and not abort the entire
- query. CS_ROW_FAIL usually means a conversion or truncation error
- which shouldn't be fatal to the entire query, although a warning
- should be printed. */
+ /* mpeppler - 4/9/2004
+ allow CS_ROW_FAIL results to go through and not abort the entire
+ query. CS_ROW_FAIL usually means a conversion or truncation error
+ which shouldn't be fatal to the entire query, although a warning
+ should be printed. */
if (r != CS_SUCCEED && r != CS_ROW_FAIL)
{
return r;
@@ -480,20 +523,63 @@ CS_INT dsp_desc_fetch( cmd, d )
* If the is_native flag is FALSE then the data was already
* converted into a string for us by CT-Lib, so there is
* nothing left to be done.
+ * sqsh-2.1.8: Except when the source datatype was binary, then
+ * we have to prepend the result string with characters '0x'.
+ * 20110107: Prepend 0x0 in case of odd number of chars in string.
*/
if (d->d_cols[i].c_is_native == CS_FALSE)
{
+ if (d->d_cols[i].c_format.datatype == CS_BINARY_TYPE ||
+ d->d_cols[i].c_format.datatype == CS_LONGBINARY_TYPE ||
+ d->d_cols[i].c_format.datatype == CS_VARBINARY_TYPE ||
+ d->d_cols[i].c_format.datatype == CS_IMAGE_TYPE)
+ {
+ p = strlen (d->d_cols[i].c_data);
+ j = (p % 2 == 0 ? 2 : 3);
+ for (; p >= 0; p--)
+ d->d_cols[i].c_data[p+j] = d->d_cols[i].c_data[p];
+ d->d_cols[i].c_data[0] = '0';
+ d->d_cols[i].c_data[1] = 'x';
+ if (j==3) d->d_cols[i].c_data[2] = '0';
+ }
+#if defined(HAVE_LOCALE_H)
+ else if (d->d_cols[i].c_format.datatype == CS_NUMERIC_TYPE ||
+ d->d_cols[i].c_format.datatype == CS_DECIMAL_TYPE)
+ {
+ /*
+ * sqsh-2.3: Convert the decimal separator in numeric/decimal datatypes
+ * to the character according to the locale definition of the client.
+ * By courtesy of Niki Hansche.
+ */
+ if (g_lconv != NULL && (radix = (CS_CHAR *) strrchr((CS_CHAR*) (d->d_cols[i].c_data), '.')) != NULL)
+ {
+ *radix = (CS_CHAR) *g_lconv->decimal_point;
+ }
+ }
+#endif
continue;
}
+ /*
+ * The datatype is declared native, so we have to convert it to displayable character data here.
+ * The case for CS_BINARY_TYPE, CS_LONGBINARY_TYPE. CS_VARBINARY_TYPE, CS_IMAGE_TYPE,
+ * CS_NUMERIC_TYPE and CS_DECIMAL_TYPE will only be executed if one or more of these datatypes
+ * are removed from the LET_CTLIB_CONV macro coded above. Otherwise these types are already
+ * decoded by CT-LIB. Note that freetds might have problems converting NUMERIC and DECIMAL
+ * types with cs_convert.
+ */
str_fmt.maxlength = d->d_cols[i].c_maxlength + 1;
+ str_fmt.precision = d->d_cols[i].c_format.precision;
+ str_fmt.scale = d->d_cols[i].c_format.scale;
+ d->d_cols[i].c_format.maxlength = d->d_cols[i].c_native_len;
switch (d->d_cols[i].c_format.datatype)
{
case CS_BINARY_TYPE:
+ case CS_LONGBINARY_TYPE:
+ case CS_VARBINARY_TYPE:
case CS_IMAGE_TYPE:
strcpy( d->d_cols[i].c_data, "0x" );
- d->d_cols[i].c_format.maxlength = d->d_cols[i].c_native_len;
if (cs_convert( g_context, /* Context */
&d->d_cols[i].c_format, /* Source Format */
@@ -502,54 +588,112 @@ CS_INT dsp_desc_fetch( cmd, d )
(CS_VOID*)(d->d_cols[i].c_data+2),/* Dest Data */
(CS_INT*)NULL ) == CS_FAIL)
{
- fprintf( stderr,
- "dsp_desc_fetch: cs_convert(BIN->CHAR) column %d failed\n",
- (int)i+1 );
+ fprintf( stderr, "dsp_desc_fetch: cs_convert(BIN->CHAR) column %d failed\n", (int) i+1 );
+ dsp_display_fmt( "src_fmt", &d->d_cols[i].c_format );
+ dsp_display_fmt( "dst_fmt", &str_fmt );
+ return CS_FAIL;
+ }
+ break;
+
+ case CS_NUMERIC_TYPE:
+ case CS_DECIMAL_TYPE:
+ if (cs_convert( g_context, /* Context */
+ &d->d_cols[i].c_format, /* Source Format */
+ d->d_cols[i].c_native, /* Source Data */
+ &str_fmt, /* Dest Format */
+ (CS_VOID*)(d->d_cols[i].c_data),/* Dest Data */
+ (CS_INT*)NULL ) == CS_FAIL)
+ {
+ fprintf( stderr, "dsp_desc_fetch: cs_convert(NUMERIC->CHAR) column %d failed\n", (int) i+1 );
+ dsp_display_fmt( "src_fmt", &d->d_cols[i].c_format );
+ dsp_display_fmt( "dst_fmt", &str_fmt );
+ return CS_FAIL;
+ }
+
+#if defined(HAVE_LOCALE_H)
+ /*
+ * sqsh-2.3: Convert the decimal separator in numeric/decimal datatypes
+ * to the character according to the locale definition of the client.
+ * By courtesy of Niki Hansche.
+ */
+ if (g_lconv != NULL && (radix = (CS_CHAR *) strrchr((CS_CHAR*) (d->d_cols[i].c_data), '.')) != NULL)
+ {
+ *radix = (CS_CHAR) *g_lconv->decimal_point;
+ }
+#endif
+ break;
+
+ case CS_MONEY_TYPE:
+ case CS_MONEY4_TYPE:
+ if (cs_convert( g_context, /* Context */
+ &d->d_cols[i].c_format, /* Source Format */
+ d->d_cols[i].c_native, /* Source Data */
+ &str_fmt, /* Dest Format */
+ (CS_VOID*)(d->d_cols[i].c_data),/* Dest Data */
+ (CS_INT*)NULL ) == CS_FAIL)
+ {
+ fprintf( stderr, "dsp_desc_fetch: cs_convert(MONEY->CHAR) column %d failed\n", (int) i+1 );
dsp_display_fmt( "src_fmt", &d->d_cols[i].c_format );
dsp_display_fmt( "dst_fmt", &str_fmt );
return CS_FAIL;
}
+
+#if defined(HAVE_LOCALE_H)
+ /*
+ * sqsh-2.3: Convert the decimal separator in money datatypes
+ * to the character according to the locale definition of the client.
+ * By courtesy of Niki Hansche.
+ */
+ if (g_lconv != NULL && (radix = (CS_CHAR *) strrchr((CS_CHAR*) (d->d_cols[i].c_data), '.')) != NULL)
+ {
+ *radix = (CS_CHAR) *g_lconv->mon_decimal_point;
+ }
+#endif
break;
case CS_REAL_TYPE:
- sprintf( (char*)d->d_cols[i].c_data, "%*.*f",
+ sprintf( (char*)d->d_cols[i].c_data, "%*.*f",
g_dsp_props.p_real_prec + 2,
g_dsp_props.p_real_scale,
(double)(*((CS_REAL*)d->d_cols[i].c_native)) );
break;
case CS_FLOAT_TYPE:
- sprintf( (char*)d->d_cols[i].c_data, "%*.*f",
+ sprintf( (char*)d->d_cols[i].c_data, "%*.*f",
g_dsp_props.p_flt_prec + 2,
g_dsp_props.p_flt_scale,
(double)(*((CS_FLOAT*)d->d_cols[i].c_native)) );
break;
+ /*
+ * sqsh-2.1.9 - Also take date and time datatypes into consideration
+ */
case CS_DATETIME_TYPE:
case CS_DATETIME4_TYPE:
#if defined(CS_DATE_TYPE)
- case CS_DATE_TYPE:
+ case CS_DATE_TYPE:
#endif
#if defined(CS_TIME_TYPE)
- case CS_TIME_TYPE:
+ case CS_TIME_TYPE:
+#endif
+#if defined(CS_BIGDATETIME_TYPE)
+ case CS_BIGDATETIME_TYPE:
#endif
-#if defined(CS_BIGDATETIME)
- case CS_BIGDATETIME_TYPE:
- case CS_BIGTIME_TYPE:
+#if defined(CS_BIGTIME_TYPE)
+ case CS_BIGTIME_TYPE:
#endif
if (dsp_datetime_conv( g_context, /* Context */
- &d->d_cols[i].c_format, /* Data format */
+ &d->d_cols[i].c_format, /* Data format */
d->d_cols[i].c_native, /* Data */
d->d_cols[i].c_data, /* Destination */
- d->d_cols[i].c_maxlength+1 ) != CS_SUCCEED)
+ d->d_cols[i].c_maxlength+1,
+ d->d_cols[i].c_format.datatype ) != CS_SUCCEED)
{
return CS_FAIL;
}
break;
-
- default:
- d->d_cols[i].c_format.maxlength = d->d_cols[i].c_native_len;
+ default:
if (cs_convert( g_context, /* Context */
&d->d_cols[i].c_format, /* Source Format */
d->d_cols[i].c_native, /* Source Data */
@@ -557,9 +701,10 @@ CS_INT dsp_desc_fetch( cmd, d )
(CS_VOID*)d->d_cols[i].c_data, /* Dest Data */
(CS_INT*)NULL ) != CS_SUCCEED)
{
- fprintf( stderr,
- "dsp_desc_fetch: cs_convert(%d->CHAR) column %d failed\n",
- (int)d->d_cols[i].c_format.datatype, (int)i+1 );
+ fprintf( stderr, "dsp_desc_fetch: cs_convert(%d->CHAR) column %d failed\n",
+ (int) d->d_cols[i].c_format.datatype, (int) i+1 );
+ dsp_display_fmt( "src_fmt", &d->d_cols[i].c_format );
+ dsp_display_fmt( "dst_fmt", &str_fmt );
return CS_FAIL;
}
break;
@@ -580,11 +725,11 @@ void dsp_desc_destroy( d )
{
CS_INT i;
- if (d != NULL)
+ if (d != NULL)
{
- if (d->d_cols != NULL)
+ if (d->d_cols != NULL)
{
- for (i = 0; i < d->d_ncols; i++)
+ for (i = 0; i < d->d_ncols; i++)
{
if (d->d_cols[i].c_native != NULL)
{
@@ -607,6 +752,7 @@ void dsp_desc_destroy( d )
}
}
+
static void dsp_display_fmt( nm, f )
CS_CHAR *nm;
CS_DATAFMT *f;
@@ -614,35 +760,25 @@ static void dsp_display_fmt( nm, f )
if (f->namelen > 0 && f->namelen < CS_MAX_NAME)
{
fprintf( stderr, "%s->name = %*.*s\n",
- (char*)nm, (int)f->namelen, (int)f->namelen, (char*)f->name );
+ (char*) nm, (int) f->namelen, (int) f->namelen, (char*) f->name );
}
else
{
- fprintf( stderr, "%s->name = <empty>\n",
- (char*)nm );
+ fprintf( stderr, "%s->name = <empty>\n", (char*)nm );
}
- fprintf( stderr, "%s->namelen = %d\n",
- (char*)nm, (int)f->namelen );
- fprintf( stderr, "%s->datatype = %d\n",
- (char*)nm, (int)f->datatype );
- fprintf( stderr, "%s->format = %d\n",
- (char*)nm, (int)f->format );
- fprintf( stderr, "%s->maxlength = %d\n",
- (char*)nm, (int)f->maxlength );
- fprintf( stderr, "%s->scale = %d\n",
- (char*)nm, (int)f->scale );
- fprintf( stderr, "%s->precision = %d\n",
- (char*)nm, (int)f->precision );
- fprintf( stderr, "%s->status = %d\n",
- (char*)nm, (int)f->status );
- fprintf( stderr, "%s->count = %d\n",
- (char*)nm, (int)f->count );
- fprintf( stderr, "%s->usertype = %d\n",
- (char*)nm, (int)f->usertype );
- fprintf( stderr, "%s->locale = 0x%p\n",
- (char*)nm, (void*)f->locale );
+ fprintf( stderr, "%s->namelen = %d\n", (char*) nm, (int) f->namelen );
+ fprintf( stderr, "%s->datatype = %d\n", (char*) nm, (int) f->datatype );
+ fprintf( stderr, "%s->format = %d\n", (char*) nm, (int) f->format );
+ fprintf( stderr, "%s->maxlength = %d\n", (char*) nm, (int) f->maxlength);
+ fprintf( stderr, "%s->scale = %d\n", (char*) nm, (int) f->scale );
+ fprintf( stderr, "%s->precision = %d\n", (char*) nm, (int) f->precision);
+ fprintf( stderr, "%s->status = %d\n", (char*) nm, (int) f->status );
+ fprintf( stderr, "%s->count = %d\n", (char*) nm, (int) f->count );
+ fprintf( stderr, "%s->usertype = %d\n", (char*) nm, (int) f->usertype );
+ fprintf( stderr, "%s->locale = %p\n", (char*) nm, (void*) f->locale );
}
+
/*
* dsp_just():
*
@@ -651,21 +787,44 @@ static void dsp_display_fmt( nm, f )
static CS_INT dsp_just( type )
CS_INT type;
{
- switch (type)
+ switch (type)
{
- case CS_BIT_TYPE:
case CS_TINYINT_TYPE:
case CS_SMALLINT_TYPE:
case CS_INT_TYPE:
case CS_REAL_TYPE:
case CS_FLOAT_TYPE:
+ case CS_BIT_TYPE:
+ case CS_DATETIME_TYPE:
+ case CS_DATETIME4_TYPE:
case CS_MONEY_TYPE:
case CS_MONEY4_TYPE:
case CS_NUMERIC_TYPE:
case CS_DECIMAL_TYPE:
- case CS_DATETIME_TYPE:
- case CS_DATETIME4_TYPE:
- case CS_BINARY_TYPE:
+#if defined(CS_DATE_TYPE)
+ case CS_DATE_TYPE:
+#endif
+#if defined(CS_TIME_TYPE)
+ case CS_TIME_TYPE:
+#endif
+#if defined(CS_BIGINT_TYPE)
+ case CS_BIGINT_TYPE:
+#endif
+#if defined(CS_USMALLINT_TYPE)
+ case CS_USMALLINT_TYPE:
+#endif
+#if defined(CS_UINT_TYPE)
+ case CS_UINT_TYPE:
+#endif
+#if defined(CS_UBIGINT_TYPE)
+ case CS_UBIGINT_TYPE:
+#endif
+#if defined(CS_BIGDATETIME_TYPE)
+ case CS_BIGDATETIME_TYPE:
+#endif
+#if defined(CS_BIGTIME_TYPE)
+ case CS_BIGTIME_TYPE:
+#endif
return DSP_JUST_RIGHT;
default:
break;
@@ -684,21 +843,27 @@ static CS_INT dsp_just( type )
static CS_INT dsp_dlen( fmt )
CS_DATAFMT *fmt;
{
- switch (fmt->datatype)
+ switch (fmt->datatype)
{
case CS_CHAR_TYPE:
case CS_LONGCHAR_TYPE:
case CS_TEXT_TYPE:
case CS_VARCHAR_TYPE:
+ case CS_UNICHAR_TYPE:
+#if defined(CS_UNITEXT_TYPE)
+ case CS_UNITEXT_TYPE:
+#endif
+#if defined(CS_XML_TYPE)
+ case CS_XML_TYPE:
+#endif
return fmt->maxlength;
- case CS_IMAGE_TYPE:
+
case CS_BINARY_TYPE:
case CS_LONGBINARY_TYPE:
+ case CS_IMAGE_TYPE:
case CS_VARBINARY_TYPE:
- case CS_UNICHAR_TYPE:
- return (2 * fmt->maxlength) + 4;
- case CS_BIT_TYPE:
- return 1;
+ return (2 * fmt->maxlength) + 2; /* sqsh-2.1.8 fix */
+
case CS_TINYINT_TYPE:
return 3;
case CS_SMALLINT_TYPE:
@@ -711,22 +876,51 @@ static CS_INT dsp_dlen( fmt )
case CS_FLOAT_TYPE:
/*-- Sign + Decimal + Precision --*/
return 2 + g_dsp_props.p_flt_prec;
+ case CS_BIT_TYPE:
+ return 1;
+
case CS_MONEY4_TYPE:
return dsp_money4_len( g_context );
case CS_MONEY_TYPE:
return dsp_money_len( g_context );
+ case CS_NUMERIC_TYPE:
+ case CS_DECIMAL_TYPE:
+ return (fmt->precision + 3);
+
case CS_DATETIME_TYPE:
case CS_DATETIME4_TYPE:
#if defined(CS_DATE_TYPE)
- case CS_DATE_TYPE:
+ case CS_DATE_TYPE:
#endif
#if defined(CS_TIME_TYPE)
- case CS_TIME_TYPE:
+ case CS_TIME_TYPE:
+#endif
+#if defined(CS_BIGDATETIME_TYPE)
+ case CS_BIGDATETIME_TYPE:
+#endif
+#if defined(CS_BIGTIME_TYPE)
+ case CS_BIGTIME_TYPE:
#endif
return dsp_datetime_len( g_context, fmt->datatype);
- case CS_NUMERIC_TYPE:
- case CS_DECIMAL_TYPE:
- return (fmt->precision + 3);
+
+#if defined(CS_BIGINT_TYPE)
+ case CS_BIGINT_TYPE:
+ return 20;
+#endif
+#if defined(CS_USMALLINT_TYPE)
+ case CS_USMALLINT_TYPE:
+ return 5;
+#endif
+#if defined(CS_UINT_TYPE)
+ case CS_UINT_TYPE:
+ return 10;
+#endif
+#if defined(CS_UBIGINT_TYPE)
+ case CS_UBIGINT_TYPE:
+ return 20;
+#endif
+ case CS_UNIQUE_TYPE:
+ return 36;
default:
break;
}
diff --git a/src/dsp_html.c b/src/dsp_html.c
index a227869..1a051fb 100644
--- a/src/dsp_html.c
+++ b/src/dsp_html.c
@@ -34,7 +34,7 @@ extern int errno;
/*-- Current Version --*/
#if !defined(lint) && !defined(__LINT__)
-static char RCS_Id[] = "$Id: dsp_html.c,v 1.2 2004/04/11 15:14:32 mpeppler Exp $";
+static char RCS_Id[] = "$Id: dsp_html.c,v 1.4 2013/08/21 11:16:39 mwesdorp Exp $";
USE(RCS_Id)
#endif /* !defined(lint) */
@@ -125,7 +125,7 @@ int dsp_html( output, cmd, flags )
case CS_STATUS_RESULT:
if (in_table == CS_TRUE)
{
- dsp_fputs( "</table>\n", output );
+ dsp_fputs( "</tbody>\n</table>\n", output );
in_table = CS_FALSE;
}
@@ -197,7 +197,7 @@ int dsp_html( output, cmd, flags )
if (in_table == CS_TRUE)
{
- dsp_fputs( "</table>\n", output );
+ dsp_fputs( "</tbody>\n</table>\n", output );
}
if (rows_affected != CS_NO_COUNT && !(flags & DSP_F_NOFOOTERS))
@@ -230,7 +230,7 @@ int dsp_html( output, cmd, flags )
if (select_desc == NULL)
goto dsp_fail;
- dsp_fputs( "\n<table border>\n", output );
+ dsp_fputs( "\n<table class=\"sqshtable\" border=\"1\">\n", output );
in_table = CS_TRUE;
/*
@@ -241,7 +241,7 @@ int dsp_html( output, cmd, flags )
if (g_dsp_interrupted)
goto dsp_interrupted;
- dsp_fputs( "<tr>\n", output );
+ dsp_fputs( "<thead>\n<tr>\n", output );
for (i = 0; i < select_desc->d_ncols; i++)
{
col = &select_desc->d_cols[i];
@@ -257,7 +257,7 @@ int dsp_html( output, cmd, flags )
}
dsp_fputs( "</th>\n", output );
}
- dsp_fputs( "</tr>\n", output );
+ dsp_fputs( "</tr>\n</thead><tbody>\n", output );
}
if (g_dsp_interrupted)
@@ -279,11 +279,11 @@ int dsp_html( output, cmd, flags )
if (col->c_justification == DSP_JUST_RIGHT)
{
- dsp_fputs( " <td align=right>", output );
+ dsp_fputs( " <td style=\"text-align: right;\">", output );
}
else
{
- dsp_fputs( " <td align=left>", output );
+ dsp_fputs( " <td style=\"text-align: left;\">", output );
}
if (col->c_nullind == -1)
@@ -358,7 +358,7 @@ int dsp_html( output, cmd, flags )
if (in_table == CS_TRUE)
{
- dsp_fputs( "</table>\n", output );
+ dsp_fputs( "</tbody></table>\n", output );
}
if (last_row_result != CS_STATUS_RESULT && rows_affected != CS_NO_COUNT &&
@@ -434,7 +434,7 @@ static CS_INT dsp_comp_prrow_one( output, sel_desc, com_desc )
dsp_col_t *sel_col;
dsp_col_t *com_col;
- dsp_fputs( "<tr>\n", output );
+ dsp_fputs( "<thead>\n<tr>\n", output );
for (i = 0; i < sel_desc->d_ncols; i++)
{
dsp_fputs( " <th>", output );
@@ -462,9 +462,9 @@ static CS_INT dsp_comp_prrow_one( output, sel_desc, com_desc )
dsp_fputs( "</th>", output );
}
- dsp_fputs( "</tr>\n", output );
+ dsp_fputs( "</tr>\n</thead><tbody>\n", output );
- dsp_fputs( "<tr>\n", output );
+ dsp_fputs( "<tbody>\n<tr>\n", output );
for (i = 0; i < sel_desc->d_ncols; i++)
{
/*-- Handy Pointer --*/
@@ -472,11 +472,11 @@ static CS_INT dsp_comp_prrow_one( output, sel_desc, com_desc )
if (sel_col->c_justification == DSP_JUST_RIGHT)
{
- dsp_fputs( " <td align=right>", output );
+ dsp_fputs( " <td style=\"text-align: right;\">", output );
}
else
{
- dsp_fputs( " <td align=left>", output );
+ dsp_fputs( " <td style=\"text-align: left;\">", output );
}
/*
@@ -503,7 +503,7 @@ static CS_INT dsp_comp_prrow_one( output, sel_desc, com_desc )
dsp_fputs( "<br>", output );
}
}
- dsp_fputs( "</tr>\n", output );
+ dsp_fputs( "</tr>\n</tbody>\n", output );
return count;
}
diff --git a/src/dsp_meta.c b/src/dsp_meta.c
index 9beb88c..8759806 100644
--- a/src/dsp_meta.c
+++ b/src/dsp_meta.c
@@ -32,7 +32,7 @@
/*-- Current Version --*/
#if !defined(lint) && !defined(__LINT__)
-static char RCS_Id[] = "$Id: dsp_meta.c,v 1.3 2004/04/11 15:14:32 mpeppler Exp $";
+static char RCS_Id[] = "$Id: dsp_meta.c,v 1.5 2013/12/03 09:22:23 mwesdorp Exp $";
USE(RCS_Id)
#endif /* !defined(lint) */
@@ -370,6 +370,18 @@ static CS_CHAR* dsp_meta_status( s, fmt )
strcat( fmt, "CS_RETURN" );
}
+#if defined(CS_RETURN_CANBENULL)
+ if (s & CS_RETURN_CANBENULL)
+ {
+ if (need_comma)
+ {
+ strcat(fmt, "," );
+ }
+ need_comma = CS_TRUE;
+
+ strcat( fmt, "CS_RETURN_CANBENULL" );
+ }
+#endif
if (s & CS_TIMESTAMP)
{
if (need_comma)
@@ -532,14 +544,6 @@ static CS_CHAR* dsp_meta_datatype( t )
return "CS_DATETIME_TYPE";
case CS_DATETIME4_TYPE:
return "CS_DATETIME4_TYPE";
-#if defined(CS_DATE_TYPE)
- case CS_DATE_TYPE:
- return "CS_DATE_TYPE";
-#endif
-#if defined(CS_TIME_TYPE)
- case CS_TIME_TYPE:
- return "CS_TIME_TYPE";
-#endif
case CS_MONEY_TYPE:
return "CS_MONEY_TYPE";
case CS_MONEY4_TYPE:
@@ -562,6 +566,58 @@ static CS_CHAR* dsp_meta_datatype( t )
return "CS_VOID_TYPE";
case CS_USHORT_TYPE:
return "CS_USHORT_TYPE";
+#if defined(CS_UNICHAR_TYPE)
+ case CS_UNICHAR_TYPE:
+ return "CS_UNICHAR_TYPE";
+#endif
+#if defined(CS_BLOB_TYPE)
+ case CS_BLOB_TYPE:
+ return "CS_BLOB_TYPE";
+#endif
+#if defined(CS_DATE_TYPE)
+ case CS_DATE_TYPE:
+ return "CS_DATE_TYPE";
+#endif
+#if defined(CS_TIME_TYPE)
+ case CS_TIME_TYPE:
+ return "CS_TIME_TYPE";
+#endif
+#if defined(CS_UNITEXT_TYPE)
+ case CS_UNITEXT_TYPE:
+ return "CS_UNITEXT_TYPE";
+#endif
+#if defined(CS_BIGINT_TYPE)
+ case CS_BIGINT_TYPE:
+ return "CS_BIGINT_TYPE";
+#endif
+#if defined(CS_USMALLINT_TYPE)
+ case CS_USMALLINT_TYPE:
+ return "CS_USMALLINT_TYPE";
+#endif
+#if defined(CS_UINT_TYPE)
+ case CS_UINT_TYPE:
+ return "CS_UINT_TYPE";
+#endif
+#if defined(CS_UBIGINT_TYPE)
+ case CS_UBIGINT_TYPE:
+ return "CS_UBIGINT_TYPE";
+#endif
+#if defined(CS_XML_TYPE)
+ case CS_XML_TYPE:
+ return "CS_XML_TYPE";
+#endif
+#if defined(CS_BIGDATETIME_TYPE)
+ case CS_BIGDATETIME_TYPE:
+ return "CS_BIGDATETIME_TYPE";
+#endif
+#if defined(CS_BIGTIME_TYPE)
+ case CS_BIGTIME_TYPE:
+ return "CS_BIGTIME_TYPE";
+#endif
+#if defined(CS_UNIQUE_TYPE)
+ case CS_UNIQUE_TYPE:
+ return "CS_UNIQUE_TYPE";
+#endif
default:
break;
}
diff --git a/src/dsp_pretty.c b/src/dsp_pretty.c
index 06cb9bd..e274b41 100644
--- a/src/dsp_pretty.c
+++ b/src/dsp_pretty.c
@@ -34,7 +34,7 @@ extern int errno;
/*-- Current Version --*/
#if !defined(lint) && !defined(__LINT__)
-static char RCS_Id[] = "$Id: dsp_pretty.c,v 1.3 2005/11/19 16:51:11 mpeppler Exp $";
+static char RCS_Id[] = "$Id: dsp_pretty.c,v 1.4 2014/01/18 18:36:34 mwesdorp Exp $";
USE(RCS_Id)
#endif /* !defined(lint) */
@@ -279,6 +279,8 @@ int dsp_pretty( o, cmd, flags )
/*
* Then, while there is data to fetch, display the
* data for each row as it comes back.
+ * sqsh-2.5: Suppress printing of a separator line when the flag
+ * DSP_F_NOSEPLINE is enabled using the -l option with \go -mpretty.
*/
while ((ret = dsp_desc_fetch( cmd, select_desc )) == CS_SUCCEED)
{
@@ -286,10 +288,14 @@ int dsp_pretty( o, cmd, flags )
goto dsp_interrupted;
dsp_prrow( o, select_desc );
+ if (!(flags & DSP_F_NOSEPLINE))
+ dsp_prsep( o, select_desc, (int)'-' );
if (g_dsp_interrupted)
goto dsp_interrupted;
}
+ if ((flags & DSP_F_NOSEPLINE) && !(flags & DSP_F_NOFOOTERS))
+ dsp_prsep( o, select_desc, (int)'-' );
if (ret != CS_END_DATA)
{
@@ -621,8 +627,6 @@ static void dsp_prrow( output, desc )
}
while (done == False);
- dsp_prsep( output, desc, (int)'-' );
-
return;
}
diff --git a/src/dsp_x.c b/src/dsp_x.c
index 121b4a0..c1b2228 100644
--- a/src/dsp_x.c
+++ b/src/dsp_x.c
@@ -29,14 +29,16 @@
#include <stdio.h>
#include <ctype.h>
#include "sqsh_config.h"
+#include "sqsh_debug.h"
#include "sqsh_error.h"
+#include "sqsh_expand.h"
#include "sqsh_global.h"
-#include "sqsh_debug.h"
+#include "sqsh_init.h"
#include "dsp.h"
/*-- Current Version --*/
#if !defined(lint) && !defined(__LINT__)
-static char RCS_Id[] = "$Id: dsp_x.c,v 1.6 2010/02/08 13:25:48 mwesdorp Exp $";
+static char RCS_Id[] = "$Id: dsp_x.c,v 1.8 2013/05/07 21:18:02 mwesdorp Exp $";
USE(RCS_Id)
#endif /* !defined(lint) */
@@ -114,7 +116,7 @@ int dsp_x( output, cmd, flags, dsp_func )
else
{
i = 0;
- for (cp = g_dsp_props.p_xgeom; *cp != '\0' && isdigit(*cp); ++cp)
+ for (cp = g_dsp_props.p_xgeom; *cp != '\0' && isdigit( (int) *cp); ++cp)
{
number[i++] = *cp;
}
@@ -251,7 +253,6 @@ static int dsp_x_init( fd, width, height )
int width;
int height;
{
- int i;
int nlines;
/*-- Widgets that make up our window --*/
@@ -265,17 +266,14 @@ static int dsp_x_init( fd, width, height )
Widget w_btn_form;
Widget w_btn_ok;
XmString s_ok;
- XmString s_cancel;
cb_data_t cd; /* Data for callbacks */
XtInputId id; /* Id of input source */
Dimension dim;
- int text_width;
- int orig_width;
int argc;
char *argv[1];
char *cp;
char *xwin_title = NULL;
- varbuf_t *exp_buf;
+ varbuf_t *exp_buf = NULL;
/*
* At this point we are in the child process, the rest is pretty
@@ -419,7 +417,8 @@ static int dsp_x_init( fd, width, height )
NULL);
XtMainLoop();
- varbuf_destroy( exp_buf );
+ if (exp_buf != NULL)
+ varbuf_destroy( exp_buf );
exit(0);
}
@@ -435,12 +434,9 @@ static void dsp_x_input_cb (client_data, fd, id)
int *fd;
XtInputId *id;
{
- static int len = 0; /* Total Length of text in widget */
char buffer[2048]; /* Read up to 2K of input */
int n;
cb_data_t *cd;
- char *cp;
- char number[20];
cd = (cb_data_t*)client_data;
@@ -524,7 +520,7 @@ static int dsp_x_init( fd, width, height )
int argc;
char *argv[1];
char *xwin_title = NULL;
- varbuf_t *exp_buf;
+ varbuf_t *exp_buf = NULL;
XFontStruct *font = NULL; /* Font for text widget */
@@ -640,7 +636,8 @@ static int dsp_x_init( fd, width, height )
XtRealizeWidget( w_top );
XtMainLoop();
- varbuf_destroy( exp_buf );
+ if (exp_buf != NULL)
+ varbuf_destroy( exp_buf );
exit(0);
}
diff --git a/src/sqsh b/src/sqsh
deleted file mode 100755
index 7dbc9d0..0000000
--- a/src/sqsh
+++ /dev/null
Binary files differ
diff --git a/src/sqsh_buf.c b/src/sqsh_buf.c
index 0562ba1..1667b27 100644
--- a/src/sqsh_buf.c
+++ b/src/sqsh_buf.c
@@ -29,18 +29,14 @@
#include "sqsh_error.h"
#include "sqsh_stdin.h"
#include "sqsh_buf.h"
+#include "sqsh_readline.h"
/*-- Current Version --*/
#if !defined(lint) && !defined(__LINT__)
-static char RCS_Id[] = "$Id: sqsh_buf.c,v 1.3 2010/01/26 15:03:50 mwesdorp Exp $" ;
+static char RCS_Id[] = "$Id: sqsh_buf.c,v 1.4 2012/03/14 09:17:51 mwesdorp Exp $" ;
USE(RCS_Id)
#endif /* !defined(lint) */
-#if defined(USE_READLINE)
-#include <readline/readline.h>
-extern void add_history();
-#endif /* USE_READLINE */
-
/*
* Note: This whole module is quite a bit different from all other
* sqsh_*.c modules, in that it provides no real data for itself.
diff --git a/src/sqsh_config.h b/src/sqsh_config.h
index 1f22fe1..f7e2bf0 100644
--- a/src/sqsh_config.h
+++ b/src/sqsh_config.h
@@ -34,9 +34,10 @@
* The maximum length of a password. I just pulled this one out of
* the air.
* sqsh-2.1.6 - Increased value from 12 to 30
+ * sqsh-2.4 - Increased value from 30 to 64
*/
#ifndef SQSH_PASSLEN
-#define SQSH_PASSLEN 30
+#define SQSH_PASSLEN 64
#endif
/*
@@ -128,6 +129,19 @@
#define SQSH_MAXFD 256
#endif
+#if defined(USE_READLINE)
+/*
+ * sqsh-2.1.8 - Define the default query that will be executed in
+ * case keyword_dynamic is enabled and an interactive connection is setup
+ * to a Sybase ASE or Microsoft MSSQL database server, or the database
+ * context is changed due to a "use" command.
+ *
+ */
+# ifndef SQSH_KEYQUERY
+# define SQSH_KEYQUERY "select name from sysobjects order by name"
+# endif
+#endif
+
/*
* End user configuration section
*/
@@ -135,7 +149,7 @@
/*
* Current version number.
*/
-#define SQSH_VERSION "sqsh-2.1.7"
+#define SQSH_VERSION "sqsh-2.5.16.1"
#if !defined(__ansi__)
# if defined(__STDC__) || defined(STDC_HEADERS) || defined(PROTOTYPES)
diff --git a/src/sqsh_ctx.c b/src/sqsh_ctx.c
deleted file mode 100644
index 0149e9e..0000000
--- a/src/sqsh_ctx.c
+++ /dev/null
@@ -1,334 +0,0 @@
-/*
-** sqsh_ctx.c - Manipulate a context of execution.
-**
-** Copyright (C) 1995, 1996 by Scott C. Gray
-**
-** This program 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 2 of the License, or
-** (at your option) any later version.
-**
-** This program 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 this program. If not, write to the Free Software
-** Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
-**
-** You may contact the author :
-** e-mail: gray@voicenet.com
-** grays@xtend-tech.com
-** gray@xenotropic.com
-*/
-#include <stdio.h>
-#include "sqsh_config.h"
-#include "sqsh_error.h"
-#include "sqsh_ctx.h"
-
-/*
-** sqsh_ctx_t: This data structure is used to hold the context of
-** a sqsh block.
-*/
-typedef struct sqsh_ctx_st
-{
- int ctx_argc; /* Argument count to current context */
- char **ctx_argv; /* Array of arguments */
- CS_CONNECTION *ctx_conn; /* Connection to the database */
- dsp_desc_t *ctx_cols; /* Columns referenced from \do loop */
- varbuf_t *ctx_sqlbuf; /* Current SQL command */
- struct sqsh_ctx_st *ctx_prev; /* Previous context */
-}
-sqsh_ctx_t;
-
-/*
-** sg_cur_ctx: Pointer to the current execution context.
-*/
-static sqsh_ctx_t *sg_cur_ctx;
-
-/*
-** sqsh_ctx_push():
-**
-** Allocates a new execution context.
-*/
-int sqsh_ctx_push()
-{
- sqsh_ctx_t *ctx;
-
- ctx = (sqsh_ctx_t*)malloc(sizeof(sqsh_ctx_t));
-
- if (ctx == NULL)
- {
- sqsh_set_error( SQSH_E_NOMEM,
- "sqsh_ctx_push: Memory allocation failure\n" );
- return(False);
- }
-
- ctx->ctx_argc = -1;
- ctx->ctx_argv = NULL;
- ctx->ctx_conn = NULL;
- ctx->ctx_cols = NULL;
- ctx->ctx_sqlbuf = NULL;
- ctx->ctx_prev = sg_cur_ctx;
-
- sg_cur_ctx = ctx;
- return(True);
-}
-
-/*
-** sqsh_ctx_pop():
-**
-** Discard the current context and return to the previous one.
-** This will automatically close any connection and the
-** current column descriptions and sqlbuffer for the
-** context.
-*/
-int sqsh_ctx_pop()
-{
- sqsh_ctx_t *ctx;
- CS_INT conn_status;
-
- if (sg_cur_ctx == NULL)
- {
- fprintf( stderr,
- "sqsh_ctx_pop: No more contexts left!\n" );
- return(False);
- }
-
- ctx = sg_cur_ctx;
- sg_cur_ctx = sg_cur_ctx->ctx_prev;
-
- if (ctx->ctx_conn != NULL)
- {
- if (ct_con_props( ctx->ctx_conn, CS_GET, CS_CON_STATUS,
- (CS_VOID*)&conn_status, CS_UNUSED, (CS_INT*)NULL ) != CS_SUCCEED)
- {
- conn_status = CS_CONSTAT_CONNECTED;
- }
-
- if ((conn_status & CS_CONSTAT_CONNECTED)
- == CS_CONSTAT_CONNECTED)
- {
- ct_close( ctx->ctx_conn, CS_FORCE_CLOSE );
- }
-
- ct_con_drop( ctx->ctx_conn );
- }
-
- if (ctx->ctx_cols != NULL)
- {
- dsp_desc_destroy( ctx->ctx_cols );
- }
-
- if (ctx->ctx_sqlbuf != NULL)
- {
- varbuf_destroy( ctx->ctx_sqlbuf );
- }
-
- free( ctx );
- return(True);
-}
-
-/*
-** sqsh_ctx_set_args():
-**
-** Set an argument set for the current context. Note that
-** the argv[] array will not be freed when the context
-** returns. This is the duty of the function that allocated
-** the context.
-*/
-int sqsh_ctx_set_args (argc, argv)
- int argc;
- char *argv[];
-{
- if (sg_cur_ctx == NULL)
- {
- fprintf( stderr,
- "sqsh_ctx_set_args: There is no available execution context!\n" );
- return(False);
- }
-
- sg_cur_ctx->ctx_argc = argc;
- sg_cur_ctx->ctx_argv = argv;
- return(True);
-}
-
-/*
-** sqsh_ctx_get_args():
-**
-** Fetch the current argument list.
-*/
-int sqsh_ctx_get_args (argc, argv)
- int *argc;
- char ***argv;
-{
- sqsh_ctx_t *ctx;
-
- for (ctx = sg_cur_ctx; ctx != NULL; ctx = ctx->ctx_prev)
- {
- if (ctx->ctx_argv != NULL && ctx->ctx_argc >= 0)
- {
- *argc = ctx->ctx_argc;
- *argv = ctx->ctx_argv;
- return(True);
- }
- }
-
- *argc = -1;
- *argv = NULL;
- return(False);
-}
-
-/*
-** sqsh_ctx_set_conn():
-**
-** Attaches a connection to the current context. This connection
-** will automatically be closed and destroyed when the current
-** context is dropped.
-*/
-int sqsh_ctx_set_conn (conn)
- CS_CONNECTION *conn;
-{
- if (sg_cur_ctx == NULL)
- {
- fprintf( stderr,
- "sqsh_ctx_set_conn: There is no available execution context!\n" );
- return(False);
- }
-
- if (sg_cur_ctx->ctx_conn != NULL)
- {
- fprintf( stderr,
- "sqsh_ctx_set_conn: There is already an attached connectioN!\n" );
- return(False);
- }
-
- sg_cur_ctx->ctx_conn = conn;
- return(True);
-}
-
-/*
-** sqsh_ctx_get_conn():
-**
-** Fetch the current connection.
-*/
-int sqsh_ctx_get_conn (conn)
- CS_CONNECTION **conn;
-{
- sqsh_ctx_t *ctx;
-
- for (ctx = sg_cur_ctx; ctx != NULL; ctx = ctx->ctx_prev)
- {
- if (ctx->ctx_conn != NULL)
- {
- *conn = ctx->ctx_conn;
- return(True);
- }
- }
-
- *conn = NULL;
- return(False);
-}
-
-/*
-** sqsh_ctx_set_cols():
-**
-** Attaches a description of the a result set to the current context.
-** This is only utilized by the \do loop right now.
-*/
-int sqsh_ctx_set_cols (desc)
- dsp_desc_t *desc;
-{
- if (sg_cur_ctx == NULL)
- {
- fprintf( stderr,
- "sqsh_ctx_set_cols: There is no available execution context!\n" );
- return(False);
- }
-
- if (sg_cur_ctx->ctx_cols != NULL)
- {
- fprintf( stderr,
- "sqsh_ctx_set_cols: There is already a column description in the "
- "current exuection context!\n" );
- return(False);
- }
-
- sg_cur_ctx->ctx_cols = desc;
- return(True);
-}
-
-/*
-** sqsh_ctx_get_cols():
-**
-** Fetch the current column set..
-*/
-int sqsh_ctx_get_cols (desc)
- dsp_desc_t **desc;
-{
- sqsh_ctx_t *ctx;
-
- for (ctx = sg_cur_ctx; ctx != NULL; ctx = ctx->ctx_prev)
- {
- if (ctx->ctx_cols != NULL)
- {
- *desc = ctx->ctx_cols;
- return(True);
- }
- }
-
- *desc = NULL;
- return(False);
-}
-
-/*
-** sqsh_ctx_set_sqlbuf():
-**
-** Attach a new SQL buffer to the current context.
-*/
-int sqsh_ctx_set_sqlbuf (sqlbuf)
- varbuf_t *sqlbuf;
-{
- if (sg_cur_ctx == NULL)
- {
- fprintf( stderr,
- "sqsh_ctx_set_sqlbuf: There is no available execution context!\n" );
- return(False);
- }
-
- if (sg_cur_ctx->ctx_sqlbuf != NULL)
- {
- fprintf( stderr,
- "sqsh_ctx_set_cols: There is already a sql buffer in the "
- "current exuection context!\n" );
- return(False);
- }
-
- sg_cur_ctx->ctx_sqlbuf = sqlbuf;
- return(True);
-}
-
-/*
-** sqsh_ctx_get_sqlbuf():
-**
-** Get the current sql buffer.
-*/
-int sqsh_ctx_get_sqlbuf (sqlbuf)
- varbuf_t **sqlbuf;
-{
- sqsh_ctx_t *ctx;
-
- for (ctx = sg_cur_ctx; ctx != NULL; ctx = ctx->ctx_prev)
- {
- if (ctx->ctx_sqlbuf != NULL)
- {
- *sqlbuf = ctx->ctx_sqlbuf;
- return(True);
- }
- }
-
- *sqlbuf = NULL;
- return(False);
-
-}
diff --git a/src/sqsh_ctx.h b/src/sqsh_ctx.h
deleted file mode 100644
index 9b4bed5..0000000
--- a/src/sqsh_ctx.h
+++ /dev/null
@@ -1,21 +0,0 @@
-#ifndef sqsh_ctx_h_included
-#define sqsh_ctx_h_included
-#include <ctpublic.h>
-#include "sqsh_varbuf.h"
-#include "dsp.h"
-
-/*
-** Prototypes for manipulating the context.
-*/
-int sqsh_ctx_push _ANSI_ARGS(( void ));
-int sqsh_ctx_set_args _ANSI_ARGS(( int, char** ));
-int sqsh_ctx_get_args _ANSI_ARGS(( int*, char*** ));
-int sqsh_ctx_set_conn _ANSI_ARGS(( CS_CONNECTION* ));
-int sqsh_ctx_get_conn _ANSI_ARGS(( CS_CONNECTION** ));
-int sqsh_ctx_set_cols _ANSI_ARGS(( dsp_desc_t* ));
-int sqsh_ctx_get_cols _ANSI_ARGS(( dsp_desc_t** ));
-int sqsh_ctx_set_sqlbuf _ANSI_ARGS(( varbuf_t* ));
-int sqsh_ctx_get_sqlbuf _ANSI_ARGS(( varbuf_t** ));
-int sqsh_ctx_pop _ANSI_ARGS(( void ));
-
-#endif /* sqsh_ctx_h_included */
diff --git a/src/sqsh_debug.c b/src/sqsh_debug.c
index b5c9d51..a91ebbc 100644
--- a/src/sqsh_debug.c
+++ b/src/sqsh_debug.c
@@ -34,7 +34,7 @@
#endif
#if !defined(lint) && !defined(__LINT__)
-static char RCS_Id[] = "$Id: sqsh_debug.c,v 1.1.1.1 2004/04/07 12:35:05 chunkm0nkey Exp $" ;
+static char RCS_Id[] = "$Id: sqsh_debug.c,v 1.3 2013/05/05 19:50:43 mwesdorp Exp $" ;
USE(RCS_Id)
#endif
@@ -92,3 +92,20 @@ void sqsh_debug( debug_mask, fmt, va_alist )
return ;
}
+#if defined(__ansi__)
+int sqsh_debug_show( int debug_mask )
+#else
+int sqsh_debug_show( debug_mask )
+ int debug_mask ;
+#endif
+{
+#if defined(DEBUG)
+ if( debug_mask == DEBUG_ALL || (debug_mask & sg_debug_level) )
+ return True;
+ else
+ return False;
+#else
+ return False;
+#endif /* DEBUG */
+}
+
diff --git a/src/sqsh_debug.h b/src/sqsh_debug.h
index 315ea5e..be06006 100644
--- a/src/sqsh_debug.h
+++ b/src/sqsh_debug.h
@@ -39,6 +39,8 @@
#define DEBUG_RPC (1<<11) /* Debug the rpc command */
#define DEBUG_ERROR (1<<12) /* Debug error handlers */
#define DEBUG_SIG (1<<13) /* Debug signal handlers */
+#define DEBUG_HISTORY (1<<14) /* Debug history processing */
+#define DEBUG_TDS (1<<15) /* Debug TDS protocol CS communications */
#define DEBUG_ALL ~(0) /* Turn on all debugging */
#if defined(DEBUG)
@@ -48,6 +50,7 @@
#endif
int sqsh_debug_level _ANSI_ARGS(( int )) ;
+int sqsh_debug_show _ANSI_ARGS(( int )) ;
void sqsh_debug _ANSI_ARGS(( int, char*, ... )) ;
#endif /* sqsh_debug_h_included */
diff --git a/src/sqsh_env.c b/src/sqsh_env.c
index dee4940..33cc8fa 100644
--- a/src/sqsh_env.c
+++ b/src/sqsh_env.c
@@ -29,7 +29,7 @@
/*-- Current Version --*/
#if !defined(lint) && !defined(__LINT__)
-static char RCS_Id[] = "$Id: sqsh_env.c,v 1.1.1.1 2004/04/07 12:35:05 chunkm0nkey Exp $";
+static char RCS_Id[] = "$Id: sqsh_env.c,v 1.2 2013/04/25 14:09:47 mwesdorp Exp $";
USE(RCS_Id)
#endif /* !defined(lint) */
@@ -57,14 +57,14 @@ env_t* env_create( hsize )
if (hsize < 1)
{
sqsh_set_error( SQSH_E_BADPARAM, NULL );
- return False;
+ return NULL;
}
/*-- Attempt to allocate an environment --*/
if ((e = (env_t*)malloc(sizeof(env_t))) == NULL)
{
sqsh_set_error( SQSH_E_NOMEM, NULL );
- return False;
+ return NULL;
}
/*-- Create the hash table --*/
@@ -72,7 +72,7 @@ env_t* env_create( hsize )
{
free( e );
sqsh_set_error( SQSH_E_NOMEM, NULL );
- return False;
+ return NULL;
}
for (i = 0; i < hsize; i++)
@@ -196,12 +196,16 @@ int env_remove( e, var_name, flags )
*/
if (e->env_save != NULL && (flags & ENV_F_TRAN) != 0)
{
+ DBG(sqsh_debug( DEBUG_ENV, "env_remove: Variable '%s' with value '%s' deleted in TRAN\n",
+ v->var_name , v->var_value);)
v->var_sptype = ENV_SP_REMOVE;
v->var_nxt = e->env_save;
e->env_save = v;
}
else
{
+ DBG(sqsh_debug( DEBUG_ENV, "env_remove: Variable '%s' with value '%s' deleted\n",
+ v->var_name , v->var_value);)
var_destroy( v );
}
@@ -297,10 +301,11 @@ int env_put( e, var_name, value, flags )
return False;
}
-
new_v->var_sptype = ENV_SP_CHANGE;
new_v->var_nxt = e->env_save;
e->env_save = new_v;
+ DBG(sqsh_debug( DEBUG_ENV, "env_put: Variable '%s' changed from '%s' to '%s' in TRAN\n",
+ v->var_name , v->var_value, value );)
}
/*
@@ -316,6 +321,22 @@ int env_put( e, var_name, value, flags )
}
else
{
+ if (e->env_save != NULL && (flags & ENV_F_TRAN) != 0)
+ {
+ new_v = var_create( var_name, value );
+
+ if (new_v == NULL)
+ {
+ return False;
+ }
+
+ new_v->var_sptype = ENV_SP_NEW;
+ new_v->var_nxt = e->env_save;
+ e->env_save = new_v;
+ DBG(sqsh_debug( DEBUG_ENV, "env_put: Variable '%s' with value '%s' added in TRAN\n",
+ var_name , value );)
+ }
+
/*
* The variable doesn't exist, so create it and stick it
* into the hash table.
@@ -345,7 +366,7 @@ int env_put( e, var_name, value, flags )
* if a 'get' validation function exists for the variable, then it is called.
* Upon success, 1 is returned with value containing the value of var_name,
* otherwise 0 is returned if the variable doesn't exist, or a -1
- * is retuend if the validation function failed, or some other error condition
+ * is returned if the validation function failed, or some other error condition
* ocurred.
*/
int env_nget( e, var_name, value, n )
@@ -357,6 +378,9 @@ int env_nget( e, var_name, value, n )
var_t *v;
int hval;
char *cptr;
+#if defined(DEBUG)
+ char *dbg_var_name;
+#endif
/*-- Always check your arguments --*/
if (e == NULL || var_name == NULL)
@@ -390,15 +414,19 @@ int env_nget( e, var_name, value, n )
}
#if defined(DEBUG)
+ dbg_var_name = sqsh_strdup (var_name);
+ if (n >= 0)
+ dbg_var_name[n] = '\0';
if (v == NULL)
{
- sqsh_debug( DEBUG_ENV, "env_nget: Miss on %s, checking environment.\n",
- var_name );
+ sqsh_debug( DEBUG_ENV, "env_nget: Miss on variable '%s', checking OS environment\n",
+ dbg_var_name );
}
else
{
- sqsh_debug( DEBUG_ENV, "env_nget: Hit on %s.\n", var_name );
+ sqsh_debug( DEBUG_ENV, "env_nget: Hit on variable '%s'\n", dbg_var_name );
}
+ free (dbg_var_name);
#endif /* DEBUG */
/*
@@ -421,7 +449,7 @@ int env_nget( e, var_name, value, n )
/*
* If we are only interested in part of a string, then
- * we need to need to create a temporary buffer in which
+ * we need to create a temporary buffer in which
* to place the partial string to pass it to getenv.
*/
if (n >= 0)
@@ -505,37 +533,12 @@ int env_nget( e, var_name, value, n )
return 1;
}
-int env_print( e )
- env_t *e;
-{
- int i;
- var_t *v;
-
- if (e == NULL)
- {
- sqsh_set_error( SQSH_E_BADPARAM, NULL );
- return False;
- }
-
- for (i = 0; i < e->env_hsize; i++)
- {
- for (v = e->env_htable[i]; v != NULL; v = v->var_nxt)
- {
- printf("%s = %s\n",
- v->var_name != NULL ? v->var_name : "NULL",
- v->var_value != NULL ? v->var_value : "NULL" );
- }
- }
-
- sqsh_set_error( SQSH_E_NONE, NULL );
- return True;
-}
/*
* env_tran():
*
* Create a transaction "save-point" in the environment. After
- * calling env_tran(), subsequnt calls to env_put() or env_remove()
+ * calling env_tran(), subsequent calls to env_put() or env_remove()
* with a flag of ENV_F_TRAN will cause the resulting change to
* be logged. A call to env_rollback() will restore all logged
* changes to be reversed, and a call to env_commit() ends the
@@ -576,33 +579,34 @@ int env_rollback( e )
var_t *v;
/*
- * Now, blast through our save stack, reseting each variable
+ * Now, blast through our save stack, resetting each variable
* to its original state.
*/
while (e->env_save != NULL &&
e->env_save->var_sptype != ENV_SP_START)
{
v = e->env_save;
- e->env_save = e->env_save->var_nxt;
+ e->env_save = v->var_nxt;
switch (v->var_sptype)
{
case ENV_SP_NEW:
DBG(sqsh_debug( DEBUG_ENV,
- "env_rollback: Removing '%s'\n", v->var_name );)
+ "env_rollback: Removing variable '%s'\n", v->var_name );)
env_remove( e, v->var_name, 0 );
break;
case ENV_SP_CHANGE:
DBG(sqsh_debug( DEBUG_ENV,
- "env_rollback: Restoring '%s' to '%s'\n",
+ "env_rollback: Restoring variable '%s' to '%s'\n",
v->var_name, v->var_value );)
env_put( e, v->var_name, v->var_value, 0 );
break;
case ENV_SP_REMOVE:
DBG(sqsh_debug( DEBUG_ENV,
- "env_rollback: Adding '%s'\n", v->var_name );)
+ "env_rollback: Adding variable '%s' with value '%s'\n",
+ v->var_name, v->var_value );)
env_set_valid( e, v->var_name, v->var_value,
v->var_setf, v->var_getf );
@@ -619,10 +623,10 @@ int env_rollback( e )
if (e->env_save != NULL)
{
v = e->env_save;
- e->env_save = e->env_save->var_nxt;
+ e->env_save = v->var_nxt;
var_destroy( v );
}
- DBG(sqsh_debug( DEBUG_ENV, "env_save: Save-point restored\n" );)
+ DBG(sqsh_debug( DEBUG_ENV, "env_rollback: Save-point rolled-back\n" );)
return True;
}
@@ -646,11 +650,7 @@ int env_commit( e )
e->env_save = v->var_nxt;
var_destroy( v );
}
- else
- {
- e->env_save = NULL;
- }
- DBG(sqsh_debug( DEBUG_ENV, "env_commit: Save-point restored\n" );)
+ DBG(sqsh_debug( DEBUG_ENV, "env_commit: Save-point committed\n" );)
return True;
}
@@ -803,6 +803,7 @@ static var_t* var_create( var_name, value )
v->var_sptype = ENV_SP_NONE;
v->var_setf = NULL;
v->var_getf = NULL;
+ v->var_nxt = NULL;
return v;
}
diff --git a/src/sqsh_env.h b/src/sqsh_env.h
index 8c5e529..d7d934b 100644
--- a/src/sqsh_env.h
+++ b/src/sqsh_env.h
@@ -59,13 +59,12 @@ int env_set_valid _ANSI_ARGS(( env_t*, char*, char*, env_f*, env_f* ));
int env_set _ANSI_ARGS(( env_t*, char*, char* ));
int env_put _ANSI_ARGS(( env_t*, char*, char*, int ));
int env_remove _ANSI_ARGS(( env_t*, char*, int ));
-int env_del _ANSI_ARGS(( env_t*, char* ));
-int env_get _ANSI_ARGS(( env_t*, char*, char** ));
int env_nget _ANSI_ARGS(( env_t*, char*, char**, int ));
int env_tran _ANSI_ARGS(( env_t* ));
int env_commit _ANSI_ARGS(( env_t* ));
int env_rollback _ANSI_ARGS(( env_t* ));
int env_destroy _ANSI_ARGS(( env_t* ));
+/* int env_get _ANSI_ARGS(( env_t*, char*, char** )); */
#define env_get(e,k,v) env_nget(e,k,v,-1)
diff --git a/src/sqsh_expand.c b/src/sqsh_expand.c
index 06d0a35..d2150de 100644
--- a/src/sqsh_expand.c
+++ b/src/sqsh_expand.c
@@ -33,10 +33,11 @@
#include "sqsh_expand.h"
#include "sqsh_strchr.h"
#include "sqsh_sig.h"
+#include "sqsh_readline.h"
/*-- Current Version --*/
#if !defined(lint) && !defined(__LINT__)
-static char RCS_Id[] = "$Id: sqsh_expand.c,v 1.5 2010/01/26 15:03:50 mwesdorp Exp $";
+static char RCS_Id[] = "$Id: sqsh_expand.c,v 1.9 2014/03/16 13:19:17 mwesdorp Exp $";
USE(RCS_Id)
#endif /* !defined(lint) */
@@ -53,6 +54,9 @@ static int expand_command _ANSI_ARGS(( char**, char*, varbuf_t*, int ));
static int expand_skip_eol _ANSI_ARGS(( char**, char*, varbuf_t*, int ));
static int expand_skip_comment _ANSI_ARGS(( char**, char*, varbuf_t*, int ));
static void expand_sighandler _ANSI_ARGS(( int, void* ));
+#if defined (USE_READLINE)
+static int expand_tilde _ANSI_ARGS(( char**, char*, char*, varbuf_t*, int ));
+#endif
int sqsh_expand( str, buf, flags )
char *str;
@@ -70,7 +74,7 @@ int sqsh_expand( str, buf, flags )
* final results in buf. It attempts to follow some of the basic rules
* of shells. If a variable is contained within double quotes it is still
* expanded (although, unlike a shell it doesn't strip the quotes), if a
- * variable is contained in double quotes it is not expanded. sqsh_expand()
+ * variable is contained in single quotes it is not expanded. sqsh_expand()
* returns True upon success, and False if there is some sort of error.
*/
int sqsh_nexpand( str, buf, flags, n )
@@ -79,13 +83,15 @@ int sqsh_nexpand( str, buf, flags, n )
int flags;
int n;
{
- int quote_type = QUOTE_NONE ; /* Which quotes are we in? */
- int r ; /* Results of varbuf_() functions */
+ int quote_type = QUOTE_NONE ; /* Which type of quotes are we in? */
+ int r ; /* Results of varbuf_() functions */
+ char *str_start; /* Keep pointer to start of string */
char *str_end;
int leading_whitespace = True;
DBG(char *instr;)
DBG(instr = str;)
+ str_start = str;
/*-- Clear out the expansion buffer --*/
varbuf_clear( buf );
@@ -140,8 +146,7 @@ int sqsh_nexpand( str, buf, flags, n )
}
else
{
- r = varbuf_charcat( buf, *str );
- ++str;
+ r = varbuf_charcat( buf, *str++ );
}
break;
@@ -153,8 +158,7 @@ int sqsh_nexpand( str, buf, flags, n )
}
else
{
- r = varbuf_charcat( buf, *str );
- ++str;
+ r = varbuf_charcat( buf, *str++ );
}
break;
@@ -173,7 +177,7 @@ int sqsh_nexpand( str, buf, flags, n )
/*
* Determine if we are contained within single quotes. If we
- * are then paramters no longer get expanded.
+ * are then parameters no longer get expanded.
*/
case '\'':
/*
@@ -183,23 +187,24 @@ int sqsh_nexpand( str, buf, flags, n )
if (quote_type == QUOTE_DOUBLE)
{
r = varbuf_charcat( buf, *str++ );
- break;
}
-
- /*
- * Unless requested to do otherwise, go ahead and stick
- * the quote in the destination buffer.
- */
- if (!(flags & EXP_STRIPQUOTE))
- r = varbuf_charcat( buf, *str );
-
- /*
- * If we are in already in single quotes, then mark outselves
- * as no longer being in them. Otherwise, we are currently
- * in single quotes.
- */
- quote_type = (quote_type==QUOTE_SINGLE)?QUOTE_NONE:QUOTE_SINGLE;
- ++str;
+ else
+ {
+ /*
+ * Unless requested to do otherwise, go ahead and stick
+ * the quote in the destination buffer.
+ */
+ if (!(flags & EXP_STRIPQUOTE))
+ r = varbuf_charcat( buf, *str );
+
+ /*
+ * If we are already in single quotes, then mark ourselves
+ * as no longer being in them. Otherwise, we are currently
+ * in single quotes.
+ */
+ quote_type = (quote_type==QUOTE_SINGLE)?QUOTE_NONE:QUOTE_SINGLE;
+ ++str;
+ }
break;
/*
@@ -214,25 +219,26 @@ int sqsh_nexpand( str, buf, flags, n )
if (quote_type == QUOTE_SINGLE)
{
r = varbuf_charcat( buf, *str++ );
- break;
}
-
- /*
- * Unless requested to do otherwise, go ahead and stick
- * the quote in the destination buffer.
- */
- if (!(flags & EXP_STRIPQUOTE))
- r = varbuf_charcat( buf, *str );
-
- /*
- * If we are in already in double quotes, then mark outselves
- * as no longer being in them. Otherwise, we are currently
- * in double quotes.
- */
- quote_type = (quote_type==QUOTE_DOUBLE)?QUOTE_NONE:QUOTE_DOUBLE;
- ++str;
+ else
+ {
+ /*
+ * Unless requested to do otherwise, go ahead and stick
+ * the quote in the destination buffer.
+ */
+ if (!(flags & EXP_STRIPQUOTE))
+ r = varbuf_charcat( buf, *str );
+
+ /*
+ * If we are already in double quotes, then mark ourselves
+ * as no longer being in them. Otherwise, we are currently
+ * in double quotes.
+ */
+ quote_type = (quote_type==QUOTE_DOUBLE)?QUOTE_NONE:QUOTE_DOUBLE;
+ ++str;
+ }
break;
-
+
/*
* Look for the command substitution character.
*/
@@ -246,11 +252,12 @@ int sqsh_nexpand( str, buf, flags, n )
if (quote_type == QUOTE_SINGLE || flags & EXP_IGNORECMD)
{
r = varbuf_charcat( buf, *str++ );
- break;
}
-
- if (expand_command( &str, str_end, buf, flags ) == False)
- return False;
+ else
+ {
+ if (expand_command( &str, str_end, buf, flags ) == False)
+ return False;
+ }
break;
/*
@@ -266,11 +273,12 @@ int sqsh_nexpand( str, buf, flags, n )
if (quote_type == QUOTE_SINGLE)
{
r = varbuf_charcat( buf, *str++ );
- break;
}
-
- if (expand_escape( &str, str_end, buf, flags ) == False)
- return False;
+ else
+ {
+ if (expand_escape( &str, str_end, buf, flags ) == False)
+ return False;
+ }
break;
/*
@@ -286,11 +294,12 @@ int sqsh_nexpand( str, buf, flags, n )
if (quote_type == QUOTE_SINGLE)
{
r = varbuf_charcat( buf, *str++ );
- break;
}
-
- if (expand_variable( &str, str_end, buf, flags ) == False)
- return False;
+ else
+ {
+ if (expand_variable( &str, str_end, buf, flags ) == False)
+ return False;
+ }
break;
case '#':
@@ -301,28 +310,45 @@ int sqsh_nexpand( str, buf, flags, n )
if (quote_type == QUOTE_SINGLE)
{
r = varbuf_charcat( buf, *str++ );
- break;
}
+ else
+ {
+ /*
+ ** Only expand columns when there are actually
+ ** columns available to be expanded (this may
+ ** protect us against expanding weird temp-table
+ ** names.
+ */
+ if ((flags & EXP_COLUMNS) != 0 && g_do_ncols > 0)
+ {
+ r = 0;
+ if (expand_column( &str, str_end, buf, flags ) == False)
+ return False;
+ }
+ else
+ {
+ r = varbuf_charcat( buf, *str++ );
+ }
+ }
+ break;
+#if defined (USE_READLINE)
/*
- ** Only expand columns when there are actually
- ** columns available to be expanded (this may
- ** protect us against expanding weird temp-table
- ** names.
+ ** sqsh-2.5: Expand a tilde on the command line to the
+ ** corresponding home directory of the specified unix/linux login.
*/
- if ((flags & EXP_COLUMNS) != 0 && g_do_ncols > 0)
+ case '~':
+ if (quote_type == QUOTE_SINGLE || (flags & EXP_TILDE) == 0)
{
- r = 0;
- if (expand_column( &str, str_end, buf, flags ) == False)
- return False;
+ r = varbuf_charcat( buf, *str++ );
}
else
{
- r = varbuf_charcat( buf, *str++ );
+ if (expand_tilde( &str, str_start, str_end, buf, flags ) == False)
+ return False;
}
break;
-
-
+#endif
default:
r = varbuf_charcat( buf, *str++ );
}
@@ -350,7 +376,7 @@ int sqsh_nexpand( str, buf, flags, n )
/*
* expand_skip_eol():
*
- * Copy everything up to the current end of line into the
+ * Copy everything up to the current end of line into the
* expand buffer.
*/
static int expand_skip_eol( cpp, str_end, buf, flags )
@@ -400,7 +426,7 @@ static int expand_skip_comment( cpp, str_end, buf, flags )
/*
* Track down the end of comment.
*/
- while (*str && (str_end == NULL || str != (str_end-1)) &&
+ while (*str && (str_end == NULL || str != (str_end-1)) &&
(*str != '*' || *(str+1) != '/'))
{
++str;
@@ -408,18 +434,18 @@ static int expand_skip_comment( cpp, str_end, buf, flags )
/* if we're not at the end of the string (CR 1046570)*/
if(*str) {
- /*
- * If we failed to find a closing comment, then
- * we stopped at the end of line.
- */
- if (*str != '*' || *(str+1) != '/')
- {
- ++str;
- }
- else
- {
- str += 2;
- }
+ /*
+ * If we failed to find a closing comment, then
+ * we stopped at the end of line.
+ */
+ if (*str != '*' || *(str+1) != '/')
+ {
+ ++str;
+ }
+ else
+ {
+ str += 2;
+ }
}
varbuf_strncat( buf, *cpp, str - (*cpp) );
@@ -436,7 +462,7 @@ static int expand_skip_comment( cpp, str_end, buf, flags )
* buffer (str_end), which may be NULL if the string is NULL terminated,
* a desination buffer (buf), and the current set of parsing flags. cpp
* should be pointing a ` character.
- *
+ *
*/
static int expand_command( cpp, str_end, buf, flags )
char **cpp;
@@ -480,7 +506,7 @@ static int expand_command( cpp, str_end, buf, flags )
sqsh_set_error( SQSH_E_BADQUOTE, "Unbounded ` character" );
return False;
}
-
+
/*
* Create a buffer to hold the soon-to-be-expanded
* command string.
@@ -498,7 +524,7 @@ static int expand_command( cpp, str_end, buf, flags )
* may encounter along the way as well as any escape sequences
* (so they may be interpreted by the underlying shell).
*/
- if (sqsh_nexpand( cmd_start, cmd, flags|EXP_STRIPNL|EXP_STRIPESC,
+ if (sqsh_nexpand( cmd_start, cmd, flags|EXP_STRIPNL|EXP_STRIPESC,
(str - cmd_start) ) == False)
{
varbuf_destroy( cmd );
@@ -543,7 +569,7 @@ static int expand_command( cpp, str_end, buf, flags )
env_get( g_env, "ifs", &ifs );
if( ifs == NULL || *ifs == '\0' )
ifs = "\f\n\r\t\v";
-
+
/*
* Because this expansion could theoretically take a while
* we want to protect ourselves agains recieving an interrupt
@@ -584,7 +610,7 @@ static int expand_command( cpp, str_end, buf, flags )
if( got_signal == 0 && ch != EOF )
varbuf_charcat( buf, ' ' );
}
-
+
/*
* While we haven't reached EOF, and we haven't hit an IFS
* character start copying character into the buffer.
@@ -677,7 +703,7 @@ static int expand_variable( cpp, str_end, buf, flags )
* the variable. We are still in part of the name if we
* see the characters [?a-zA-Z0-9_] and special character # and *.
*/
- while (!(str_end == NULL && str == str_end) && *str != '\0' &&
+ while (!(str_end == NULL && str == str_end) && *str != '\0' &&
(isalnum((int)*str) || strchr("#*?_$", *str) ))
{
if (!isdigit((int)*str))
@@ -689,7 +715,7 @@ static int expand_variable( cpp, str_end, buf, flags )
/*
* Keep track of where the variable ends, this may not be
- * equal to the value of str if the next character is a
+ * equal to the value of str if the next character is a
* close brace.
*/
var_name_end = str;
@@ -717,15 +743,41 @@ static int expand_variable( cpp, str_end, buf, flags )
if( var_name_start == var_name_end )
{
- if (varbuf_charcat( buf, *str++ ) == -1)
- return False;
- *cpp = str;
- return True;
+ if (varbuf_charcat( buf, *str++ ) == -1)
+ return False;
+ *cpp = str;
+ return True;
}
+
/*
- * Check for special case. First, $# is the number of arguments.
+ * Check for special cases.
+ * sqsh-2.2.0 - First, $? is the result of last action.
*/
- if (*var_name_start == '#' &&
+ if (*var_name_start == '?' &&
+ (var_name_end - var_name_start) == 1)
+ {
+ env_get( g_internal_env, "?", &var_value );
+ varbuf_strcat( buf, var_value );
+ *cpp = str;
+ return(True);
+ }
+
+ /*
+ * Next, $$ is the current processid.
+ */
+ if (*var_name_start == '$' &&
+ (var_name_end - var_name_start) == 1)
+ {
+ sprintf(nbr, "%d", (int) getpid() );
+ varbuf_strcat( buf, nbr );
+ *cpp = str;
+ return(True);
+ }
+
+ /*
+ * Next, $# is the number of arguments.
+ */
+ if (*var_name_start == '#' &&
(var_name_end - var_name_start) == 1)
{
/*
@@ -745,23 +797,10 @@ static int expand_variable( cpp, str_end, buf, flags )
return(True);
}
-
- /*
- * Next, $$ is the current processid.
- */
- if (*var_name_start == '$' &&
- (var_name_end - var_name_start) == 1)
- {
- sprintf(nbr, "%d", getpid() );
- varbuf_strcat( buf, nbr );
- *cpp = str;
- return(True);
- }
-
/*
* Next, $* is the complete list of arguments.
*/
- if (*var_name_start == '*' &&
+ if (*var_name_start == '*' &&
(var_name_end - var_name_start) == 1)
{
if (g_func_nargs > 0)
@@ -780,7 +819,7 @@ static int expand_variable( cpp, str_end, buf, flags )
}
/*
- * Next special case. All digits point us to a function
+ * Next special case. All digits point us to a function
* argument.
*/
if (all_digits == True)
@@ -796,7 +835,7 @@ static int expand_variable( cpp, str_end, buf, flags )
/*
* If invalid argument number, then just leave blank.
*/
- if (g_func_nargs == 0 || arg_nbr < 0 ||
+ if (g_func_nargs == 0 || arg_nbr < 0 ||
arg_nbr > g_func_args[g_func_nargs-1].argc - 1)
{
*cpp = str;
@@ -812,7 +851,7 @@ static int expand_variable( cpp, str_end, buf, flags )
* First, check to see if the variable is available in our
* "external" environment.
*/
- r = env_nget( g_env, var_name_start, &var_value,
+ r = env_nget( g_env, var_name_start, &var_value,
var_name_end - var_name_start);
if (r == -1)
@@ -843,7 +882,7 @@ static int expand_variable( cpp, str_end, buf, flags )
if( varbuf_strcat( buf, var_value ) == -1 )
return False;
}
-
+
*cpp = str;
return True;
}
@@ -960,7 +999,7 @@ static int expand_escape( cpp, str_end, buf, flags )
if( varbuf_strncat( buf, str, 2 ) == -1 )
return False;
}
-
+
/*
* Skip straight to the escaped character.
*/
@@ -975,7 +1014,7 @@ static int expand_escape( cpp, str_end, buf, flags )
*str != '\0' && *str != '\n' ) {
if( varbuf_charcat( buf, *str ) == -1 )
return False;
- }
+ }
++str;
*cpp = str;
@@ -995,6 +1034,75 @@ static void expand_sighandler( sig, user_data )
*((int*)user_data) = sig;
}
+#if defined (USE_READLINE)
+/*
+ * expand_tilde():
+ *
+ * sqsh-2.5 : New function to expand a tilde expression to the
+ * corresponding unix/linux login home directory. Only available
+ * if Readline support is included.
+ */
+static int expand_tilde( cpp, str_start, str_end, buf, flags )
+ char **cpp;
+ char *str_start;
+ char *str_end;
+ varbuf_t *buf;
+ int flags;
+{
+ const char tilde_prefix[] = { ' ', '\"', '=', ':', '>', '<', '\t' };
+ const char tilde_suffix[] = { ' ', '/', '\"', '=', ':', '\n', '\t', '\0' };
+ char *str;
+ char *sqsh_tilde_expand;
+ char *tilde_name;
+ char *j;
+ int idx;
+ int found_prefix;
+ int found_suffix;
+
+ str = *cpp;
+
+ /*
+ * To be able to successfully expand a tilde directive like ~ or ~sybase,
+ * the tilde must be preceded with a character from the tilde_prefix list
+ * and the directive must be appended with a character from the tilde_suffix
+ * list. If all is well, we pass on the tilde directive to the Readline
+ * tilde_expand() function and store the result in the target buffer.
+ */
+ found_prefix = found_suffix = False;
+ if (str == str_start)
+ found_prefix = True; /* ~ is the very first character of the string */
+ else
+ {
+ for ( idx = 0; idx < sizeof(tilde_prefix) && !found_prefix; ++idx )
+ if (*(str-1) == tilde_prefix[idx])
+ found_prefix = True;
+ }
+ for ( j = str+1; isalnum((int) *j); j++ );
+ for ( idx = 0; idx < sizeof(tilde_suffix) && !found_suffix; ++idx)
+ if (*j == tilde_suffix[idx])
+ found_suffix = True;
+
+ if (found_prefix && found_suffix)
+ {
+ if ((tilde_name = malloc ( (int) (j - str + 1))) == NULL)
+ return False;
+ strncpy ( tilde_name, str, j - str );
+ tilde_name[j-str] = '\0';
+ sqsh_tilde_expand = tilde_expand ( tilde_name );
+ varbuf_strcat( buf, sqsh_tilde_expand );
+ free ( sqsh_tilde_expand );
+ free ( tilde_name );
+ str = j;
+ }
+ else
+ {
+ varbuf_charcat( buf, *str++ );
+ }
+
+ *cpp = str;
+ return True;
+}
+#endif
/*
* sqsh-2.1.6 feature - expand_color_prompt()
diff --git a/src/sqsh_expand.h b/src/sqsh_expand.h
index a566345..ceb908d 100644
--- a/src/sqsh_expand.h
+++ b/src/sqsh_expand.h
@@ -35,7 +35,8 @@
#define EXP_STRIPNL (1<<2) /* Strip out newlines */
#define EXP_IGNORECMD (1<<3) /* Ignore command substitution */
#define EXP_COMMENT (1<<4) /* Pay attention to comments */
-#define EXP_COLUMNS (1<<5) /* Pay attention to comments */
+#define EXP_COLUMNS (1<<5) /* Pay attention to columns */
+#define EXP_TILDE (1<<6) /* sqsh-2.5: Pay attention to tildes */
/*
* Passing a positive value into sqsh_nexpand() causes it to expand until
diff --git a/src/sqsh_getopt.c b/src/sqsh_getopt.c
index 6d93d5c..0b5afe9 100644
--- a/src/sqsh_getopt.c
+++ b/src/sqsh_getopt.c
@@ -33,7 +33,7 @@
/*-- Current Version --*/
#if !defined(lint) && !defined(__LINT__)
-static char RCS_Id[] = "$Id: sqsh_getopt.c,v 1.3 2008/04/06 10:03:08 mpeppler Exp $" ;
+static char RCS_Id[] = "$Id: sqsh_getopt.c,v 1.4 2013/02/24 22:21:10 mwesdorp Exp $" ;
USE(RCS_Id)
#endif /* !defined(lint) */
@@ -366,7 +366,8 @@ int sqsh_getopt_env( var_name, opt_flags )
/*-- Arguments must begin with a '-' --*/
if( *var_value != '-' ) {
- sqsh_set_error( SQSH_E_BADPARAM, "Options must begin with '-'" ) ;
+ sqsh_set_error( SQSH_E_BADPARAM, "Options must begin with '-' (found: %s)",
+ var_value ) ;
goto leave_err ;
}
@@ -394,8 +395,7 @@ int sqsh_getopt_env( var_name, opt_flags )
* Check to see if the next thing on the line is either EOF
* or another argument.
*/
- if( *var_value == '\0' || isspace((int)*var_value) ||
- is_flag(var_value) ) {
+ if( *var_value == '\0' || is_flag(var_value) ) {
/*
* If this option requires an argument and there isn't one
* available, then spew an error message.
@@ -431,7 +431,6 @@ int sqsh_getopt_env( var_name, opt_flags )
/*
* The option doesn't take an argument, so simply return.
*/
- ++var_value ;
sqsh_optarg = NULL ;
return flag ;
diff --git a/src/sqsh_global.c b/src/sqsh_global.c
index 5bfd1e3..3c6db63 100644
--- a/src/sqsh_global.c
+++ b/src/sqsh_global.c
@@ -28,7 +28,7 @@
/*-- Current Version --*/
#if !defined(lint) && !defined(__LINT__)
-static char RCS_Id[] = "$Id: sqsh_global.c,v 1.6 2010/01/26 15:03:50 mwesdorp Exp $" ;
+static char RCS_Id[] = "$Id: sqsh_global.c,v 1.11 2014/01/19 10:26:00 mwesdorp Exp $" ;
USE(RCS_Id)
#endif /* !defined(lint) */
@@ -50,10 +50,23 @@ alias_t *g_alias = NULL;
char *g_password = NULL;
int g_password_set = False;
char *g_lock = NULL;
-char *g_copyright = "Copyright (C) 1995-2001 Scott C. Gray\nPortions Copyright (C) 2004-2010 Michael Peppler";
+char *g_copyright = "Copyright (C) 1995-2001 Scott C. Gray\nPortions Copyright (C) 2004-2014 Michael Peppler and Martin Wesdorp";
char *g_version = SQSH_VERSION;
dsp_desc_t *g_do_cols[64];
int g_do_ncols = 0;
funcarg_t g_func_args[64];
-int g_func_nargs = 0;
-int g_interactive = False;
+int g_func_nargs = 0;
+int g_interactive = False;
+
+#if defined(HAVE_LOCALE_H)
+ struct lconv *g_lconv = NULL;
+#else
+ void *g_lconv = NULL;
+#endif
+
+/*
+ * sqsh-2.5 - Initialize variables for p2f feature.
+ */
+FILE *g_p2f_fp = NULL;
+int g_p2fc = 0;
+
diff --git a/src/sqsh_global.h b/src/sqsh_global.h
index 2dc101a..4d5b978 100644
--- a/src/sqsh_global.h
+++ b/src/sqsh_global.h
@@ -35,6 +35,12 @@
#include "dsp.h"
#include "sqsh_func.h"
+#include "config.h"
+
+#if defined(HAVE_LOCALE_H)
+ #include <locale.h>
+#endif
+
/* g_cs_ver: This is the value of CS_VERSION_xxx. Stored in a global
* because it is needed to figure out the correct BLK_VERSION_xxx
* value to use in cmd_blk.c
@@ -141,7 +147,7 @@ extern char *g_version ;
/*
* g_password & g_lock: Contains the current value of the regular database
- * password and the session lock password.
+ * password and the session lock password.
*/
extern int g_password_set;
extern char *g_password;
@@ -152,4 +158,20 @@ extern char *g_lock;
*/
extern int g_interactive;
+/*
+ * g_lconv: sqsh-2.3 - Do locale conversion of numeric/decimal/money datatypes.
+ */
+#if defined(HAVE_LOCALE_H)
+ extern struct lconv *g_lconv;
+#else
+ extern void *g_lconv;
+#endif
+
+/*
+ * sqsh-2.5 - New feature: Print to file from message handler after $p2faxm
+ * number of printed messages to screen.
+ */
+extern FILE *g_p2f_fp; /* Print to file filepointer */
+extern int g_p2fc; /* Print to file count */
+
#endif
diff --git a/src/sqsh_history.c b/src/sqsh_history.c
index 2998eb5..0a54c97 100644
--- a/src/sqsh_history.c
+++ b/src/sqsh_history.c
@@ -23,15 +23,17 @@
* gray@xenotropic.com
*/
#include <stdio.h>
+#include <sys/stat.h>
#include "sqsh_config.h"
#include "sqsh_error.h"
+#include "sqsh_expand.h"
+#include "sqsh_global.h"
#include "sqsh_history.h"
#include "sqsh_varbuf.h"
-#include "sqsh_global.h"
/*-- Current Version --*/
#if !defined(lint) && !defined(__LINT__)
-static char RCS_Id[] = "$Id: sqsh_history.c,v 1.6 2010/01/28 15:30:37 mwesdorp Exp $" ;
+static char RCS_Id[] = "$Id: sqsh_history.c,v 1.10 2013/05/03 11:19:38 mwesdorp Exp $" ;
USE(RCS_Id)
#endif /* !defined(lint) */
@@ -42,6 +44,7 @@ static int hisbuf_destroy _ANSI_ARGS(( hisbuf_t* )) ;
static unsigned long adler32 _ANSI_ARGS(( char*, int )) ; /* sqsh-2.1.6 feature */
static int chk_buf_ifs _ANSI_ARGS(( char*, int )) ; /* sqsh-2.1.7 feature */
static void hist_auto_save _ANSI_ARGS(( history_t* )) ; /* sqsh-2.1.7 feature */
+static int history_merge _ANSI_ARGS(( history_t*, history_t*)) ; /* sqsh-2.2.0 feature */
/*
@@ -216,7 +219,7 @@ int history_append( h, buf )
* order; else continue as usual.
*/
chksum = adler32 (buf, len);
- DBG(sqsh_debug(DEBUG_ERROR, "sqsh_history: checksum of buffer: %u\n", chksum);)
+ DBG(sqsh_debug(DEBUG_HISTORY, "sqsh_history: checksum of buffer: %u\n", chksum);)
env_get (g_env, "histunique", &histunique);
if (histunique != NULL && *histunique != '0')
{
@@ -411,6 +414,7 @@ int history_del( h, idx )
hb != NULL; hb->hb_nbr = i--, hb = hb->hb_nxt);
break;
}
+ h->h_change = HISTSAVE_FORCE;
hist_auto_save ( h );
return True ;
@@ -446,7 +450,7 @@ int history_range_del( h, idx_start, idx_end )
h->h_end = hb->hb_prv ;
hisbuf_destroy( hb ) ;
- h->h_nitems--;
+ h->h_nitems--;
}
/*
@@ -510,9 +514,12 @@ int history_save( h, save_file )
history_t *h ;
char *save_file ;
{
- hisbuf_t *hb ;
- FILE *fptr ;
- int saved_mask;
+ hisbuf_t *hb ;
+ FILE *fptr ;
+ mode_t saved_mask;
+ char *histmerge;
+ history_t *x;
+
/*-- Check the arguments --*/
if( h == NULL || save_file == NULL ) {
@@ -520,9 +527,25 @@ int history_save( h, save_file )
return False ;
}
- /*-- Open the file to be save to --*/
+ /*
+ * sqsh-2.2.0 - Merge the history file with the buffers in memory.
+ * If h_change is set to HISTSAVE_FORCE then we do not want to
+ * merge, because we may have just removed a bunch of buffers
+ * for example.
+ */
+ env_get (g_env, "histmerge", &histmerge);
+ if ( histmerge != NULL && *histmerge == '1' &&
+ h->h_change != HISTSAVE_FORCE)
+ {
+ x = history_create (history_get_size(h));
+ if (history_load (x, save_file) == True)
+ history_merge (h, x);
+ history_destroy (x);
+ }
+
+ /*-- Open the file to save to --*/
/* fix for 1105398 */
- saved_mask = umask(0066);
+ saved_mask = umask( (mode_t) 0066);
if( (fptr = fopen( save_file, "w" )) == NULL ) {
sqsh_set_error( errno, "%s: %s", save_file, strerror( errno ) ) ;
umask(saved_mask);
@@ -877,7 +900,7 @@ static void hist_auto_save ( h )
histsave == NULL || *histsave == '0')
return;
- if ( h->h_change != HISTSAVE_FORCE &&
+ if ( h->h_change != HISTSAVE_FORCE &&
++h->h_change < atoi(hist_auto_save) )
return;
@@ -891,7 +914,7 @@ static void hist_auto_save ( h )
if ( sqsh_expand( history, exp_buf, 0 ) == True )
{
history_save( h, varbuf_getstr(exp_buf) );
- DBG(sqsh_debug(DEBUG_ERROR, "sqsh_history: History automatically saved to %s\n",
+ DBG(sqsh_debug(DEBUG_HISTORY, "sqsh_history: History automatically saved to %s\n",
varbuf_getstr(exp_buf));)
}
varbuf_destroy( exp_buf );
@@ -900,3 +923,196 @@ static void hist_auto_save ( h )
return;
}
+
+/*
+ * history_merge():
+ *
+ * sqsh-2.2.0 - Merge the history list of x into the history list of h.
+ */
+static int history_merge (h, x)
+ history_t *h;
+ history_t *x;
+{
+ hisbuf_t *hbh;
+ hisbuf_t *hbx;
+ hisbuf_t *hbt;
+ int i;
+ char *histunique;
+#if defined (DEBUG)
+ char hdrinfo[64];
+ char *line, *nl;
+#endif
+
+
+ if (h == NULL || x == NULL)
+ {
+ sqsh_set_error( SQSH_E_BADPARAM, NULL ) ;
+ return False;
+ }
+
+ /*
+ * if histunique=On then remove the oldest double entries
+ * (based on hb_chksum) from h or x, otherwise only remove
+ * double entries from x, regardless the values of hb_dttm.
+ * Kind of nested loop join, h is outer table, x is inner table.
+ */
+ env_get (g_env, "histunique", &histunique);
+ hbh = h->h_start;
+ hbx = x->h_start;
+ while (hbh != NULL && hbx != NULL)
+ {
+ if (hbh->hb_chksum == hbx->hb_chksum)
+ {
+ if (hbx->hb_dttm > hbh->hb_dttm && *histunique == '1')
+ {
+ hbt = hbh->hb_nxt;
+ if (hbh->hb_prv != NULL)
+ hbh->hb_prv->hb_nxt = hbh->hb_nxt;
+ else
+ h->h_start = hbh->hb_nxt;
+ if (hbh->hb_nxt != NULL)
+ hbh->hb_nxt->hb_prv = hbh->hb_prv;
+ else
+ h->h_end = hbh->hb_prv;
+ hisbuf_destroy (hbh);
+ h->h_nitems--;
+ hbh = hbt;
+ hbx = x->h_start;
+ }
+ else
+ {
+ hbt = hbx->hb_nxt;
+ if (hbx->hb_prv != NULL)
+ hbx->hb_prv->hb_nxt = hbx->hb_nxt;
+ else
+ x->h_start = hbx->hb_nxt;
+ if (hbx->hb_nxt != NULL)
+ hbx->hb_nxt->hb_prv = hbx->hb_prv;
+ else
+ x->h_end = hbx->hb_prv;
+ hisbuf_destroy (hbx);
+ x->h_nitems--;
+ if ((hbx = hbt) == NULL)
+ {
+ hbh = hbh->hb_nxt;
+ hbx = x->h_start;
+ }
+ }
+ }
+ else
+ {
+ if ((hbx = hbx->hb_nxt) == NULL)
+ {
+ hbh = hbh->hb_nxt;
+ hbx = x->h_start;
+ }
+ }
+ }
+
+#if defined (DEBUG)
+ if ( sqsh_debug_show (DEBUG_HISTORY) )
+ {
+ fprintf (stdout, "history_merge: Available entries in original list %d\n", h->h_nitems);
+ fprintf (stdout, "history_merge: Available entries in merge list %d\n", x->h_nitems);
+ for (hbx = x->h_end; hbx != NULL; hbx = hbx->hb_prv)
+ {
+ line = hbx->hb_buf;
+ while ((nl = strchr (line, '\n' )) != NULL)
+ {
+ if (line == hbx->hb_buf) {
+ sprintf (hdrinfo, "(%d) ", hbx->hb_nbr);
+ fprintf (stdout, "%s%*.*s\n", hdrinfo, (int) (nl - line), (int) (nl - line), line);
+ } else {
+ fprintf (stdout, "%*s%*.*s\n", (int) strlen (hdrinfo), " ", (int) (nl - line), (int) (nl - line), line);
+ }
+ line = nl + 1;
+ }
+ if ( *line != '\0' )
+ fprintf (stdout, " %s\n", line);
+ }
+ }
+#endif
+
+ /*
+ * The remaining entries of x should be relinked into h
+ * order by hb_dttm.
+ */
+ for (hbx = x->h_start; hbx != NULL; hbx = x->h_start)
+ {
+ /*
+ * Unlink the first node from x.
+ */
+ x->h_start = hbx->hb_nxt;
+ if (hbx->hb_nxt != NULL)
+ hbx->hb_nxt->hb_prv = NULL;
+ else
+ x->h_end = NULL;
+ x->h_nitems--;
+
+ /*
+ * Link this node into h based on value of dttm in MRU-LRU order.
+ */
+ for (hbh = h->h_start; hbh != NULL && hbh->hb_dttm > hbx->hb_dttm; hbh = hbh->hb_nxt);
+
+ if (hbh != NULL)
+ {
+ if (hbh->hb_prv != NULL)
+ hbh->hb_prv->hb_nxt = hbx;
+ else
+ h->h_start = hbx;
+ hbx->hb_nxt = hbh;
+ hbx->hb_prv = hbh->hb_prv;
+ hbh->hb_prv = hbx;
+ }
+ else
+ {
+ if (h->h_end != NULL)
+ h->h_end->hb_nxt = hbx;
+ else
+ h->h_start = hbx;
+ hbx->hb_prv = h->h_end;
+ h->h_end = hbx;
+ hbx->hb_nxt = NULL;
+ }
+ ++h->h_nitems;
+ }
+
+ /*
+ * Renumber the list.
+ */
+ switch (h->h_nitems)
+ {
+ case 0 :
+ h->h_next_nbr = 1;
+ break;
+ case 1 :
+ h->h_start->hb_nbr = 1;
+ h->h_next_nbr = 2;
+ break;
+ default :
+ for (hbh = h->h_start, i = h->h_nitems, h->h_next_nbr = i + 1;
+ hbh != NULL; hbh->hb_nbr = i--, hbh = hbh->hb_nxt);
+ break;
+ }
+
+ /*
+ * If there are more entries than the allowed size of the list then
+ * unlink the oldest entries from the list and destroy them.
+ */
+ while (h->h_size < h->h_nitems)
+ {
+ hbh = h->h_end;
+ if (hbh->hb_prv != NULL)
+ {
+ h->h_end = hbh->hb_prv;
+ h->h_end->hb_nxt = NULL;
+ }
+ else
+ h->h_end = h->h_start = NULL;
+ hisbuf_destroy (hbh);
+ --h->h_nitems;
+ }
+
+ return True;
+}
+
diff --git a/src/sqsh_init.c b/src/sqsh_init.c
index 2619036..68613f7 100644
--- a/src/sqsh_init.c
+++ b/src/sqsh_init.c
@@ -32,6 +32,10 @@
#include "sqsh_readline.h"
#include "sqsh_stdin.h"
#include "sqsh_init.h"
+#include "config.h"
+#if defined(HAVE_LOCALE_H)
+#include <locale.h>
+#endif
/*
* The following defines the tables which are used to inialize the
* variable global variables.
@@ -44,7 +48,7 @@
/*-- Current Version --*/
#if !defined(lint) && !defined(__LINT__)
-static char RCS_Id[] = "$Id: sqsh_init.c,v 1.3 2010/02/17 11:35:06 mwesdorp Exp $" ;
+static char RCS_Id[] = "$Id: sqsh_init.c,v 1.9 2013/12/03 09:22:23 mwesdorp Exp $" ;
USE(RCS_Id)
#endif /* !defined(lint) */
@@ -64,8 +68,16 @@ int sqsh_init()
char *histsize ;
varbuf_t *expand_buf ;
+
+ /*
+ * sqsh-2.3 : Initialize locale to the default of C.
+ */
+#if defined(HAVE_LOCALE_H) && defined(HAVE_SETLOCALE)
+ setlocale ( LC_ALL, "" );
+#endif
+
/*
- * g_connection: This variable is initiazed to NULL. It is the responsibility
+ * g_connection: This variable is initiazed to NULL. It is the responsibility
* of a user function to actually perform the connection to
* set it. This allows sqsh to be started without actually
* connecting to the database.
@@ -79,7 +91,6 @@ int sqsh_init()
*/
if( (g_sqlbuf = varbuf_create( 1024 )) == NULL ) {
sqsh_set_error( sqsh_get_error(), "varbuf_create: %s", sqsh_get_errstr());
- varbuf_destroy( g_sqlbuf ) ;
return False ;
}
@@ -98,7 +109,7 @@ int sqsh_init()
*/
if ((g_funcset = funcset_create()) == NULL)
{
- sqsh_set_error( sqsh_get_error(),
+ sqsh_set_error( sqsh_get_error(),
"cmdset_create: %s", sqsh_get_errstr());
return False;
}
@@ -109,7 +120,7 @@ int sqsh_init()
*/
for( i = 0; i < (sizeof(sg_cmd_entry) / sizeof(cmd_entry_t)); i++ ) {
- if( cmdset_add( g_cmdset,
+ if( cmdset_add( g_cmdset,
sg_cmd_entry[i].ce_name,
sg_cmd_entry[i].ce_func ) == False ) {
sqsh_set_error( sqsh_get_error(), "cmdset_add: %s",
@@ -128,7 +139,7 @@ int sqsh_init()
}
for( i = 0; i < (sizeof(sg_alias_entry) / sizeof(alias_entry_t)); i++ ) {
- if( alias_add( g_alias,
+ if( alias_add( g_alias,
sg_alias_entry[i].ae_name,
sg_alias_entry[i].ae_body ) == False ) {
sqsh_set_error( sqsh_get_error(), "alias_add: %s: %s",
@@ -188,9 +199,9 @@ int sqsh_init()
* environment. This, more-or-less, emulates the behaviour as
* if you had typed it in from the command line.
*/
- if( sqsh_expand( sg_var_entry[i].ve_value, expand_buf,
+ if( sqsh_expand( sg_var_entry[i].ve_value, expand_buf,
EXP_STRIPESC ) == False ){
- sqsh_set_error( sqsh_get_error(), "%s: %s",
+ sqsh_set_error( sqsh_get_error(), "%s: %s",
sg_var_entry[i].ve_value, sqsh_get_errstr());
return False ;
}
@@ -201,7 +212,7 @@ int sqsh_init()
varbuf_getstr(expand_buf), /* Default value */
sg_var_entry[i].ve_set, /* Settor function */
sg_var_entry[i].ve_get ) == False ) {
- sqsh_set_error( sqsh_get_error(), "env_set_valid: %s",
+ sqsh_set_error( sqsh_get_error(), "env_set_valid: %s",
sqsh_get_errstr() ) ;
return False ;
}
@@ -212,7 +223,7 @@ int sqsh_init()
NULL, /* NULL value */
sg_var_entry[i].ve_set, /* Settor function */
sg_var_entry[i].ve_get ) == False ) {
- sqsh_set_error( sqsh_get_error(), "env_set_valid: %s",
+ sqsh_set_error( sqsh_get_error(), "env_set_valid: %s",
sqsh_get_errstr() ) ;
return False ;
}
@@ -223,10 +234,16 @@ int sqsh_init()
varbuf_destroy( expand_buf ) ;
/*
+ * sqsh-2.2.0 - Initialize variable keyword_refresh in the
+ * g_internal_env to prevent misses in subsequent variable lookups.
+ */
+ env_set( g_internal_env, "keyword_refresh", "0" );
+
+ /*
* Allocate our global set of sub-processes.
*/
if( (g_jobset = jobset_create( 47 )) == NULL ) {
- sqsh_set_error( sqsh_get_error(), "jobset_create: %s",
+ sqsh_set_error( sqsh_get_error(), "jobset_create: %s",
sqsh_get_errstr() ) ;
return False ;
}
@@ -241,7 +258,7 @@ int sqsh_init()
i = 10 ;
if( (g_history = history_create( i )) == NULL ) {
- sqsh_set_error( sqsh_get_error(), "history_create: %s",
+ sqsh_set_error( sqsh_get_error(), "history_create: %s",
sqsh_get_errstr() ) ;
return False ;
}
@@ -312,14 +329,16 @@ void sqsh_exit( exit_status )
if( g_connection != NULL )
{
- ct_close( g_connection, CS_FORCE_CLOSE );
+ if (ct_close( g_connection, CS_UNUSED) != CS_SUCCEED)
+ ct_close( g_connection, CS_FORCE_CLOSE );
ct_con_drop( g_connection );
g_connection = NULL;
}
if (g_context != NULL)
{
- ct_exit( g_context, CS_FORCE_EXIT );
+ if (ct_exit( g_context, CS_UNUSED ) != CS_SUCCEED)
+ ct_exit( g_context, CS_FORCE_EXIT );
/*
* If sqsh is aborting, maybe because of losing a database connection
@@ -333,7 +352,7 @@ void sqsh_exit( exit_status )
* This is due to the fact that the callback handler did not return
* to CS/CT-Library.
*/
- if (exit_status != 254)
+ if (exit_status != 254)
cs_ctx_drop( g_context );
g_context = NULL;
}
@@ -343,6 +362,11 @@ void sqsh_exit( exit_status )
g_buf = NULL;
}
+ if ( g_internal_env != NULL ) {
+ env_destroy( g_internal_env ) ;
+ g_internal_env = NULL;
+ }
+
/*
* sqsh-2.1.7 - Reset term_title.
*/
@@ -353,6 +377,14 @@ void sqsh_exit( exit_status )
fprintf (stdout, "%c]0;%c", '\033', '\007' );
}
+ /*
+ * sqsh-2.5 - Close file $p2fname
+ */
+ if (g_p2f_fp != NULL) {
+ fclose (g_p2f_fp);
+ g_p2f_fp = NULL;
+ }
+
if( g_env != NULL ) {
env_destroy( g_env ) ;
g_env = NULL;
diff --git a/src/sqsh_job.c b/src/sqsh_job.c
index a25c3d7..ee747d0 100644
--- a/src/sqsh_job.c
+++ b/src/sqsh_job.c
@@ -29,6 +29,7 @@
#include "sqsh_config.h"
#include "sqsh_error.h"
#include "sqsh_fd.h"
+#include "sqsh_init.h"
#include "sqsh_tok.h"
#include "sqsh_cmd.h"
#include "sqsh_global.h"
@@ -42,7 +43,7 @@
/*-- Current Version --*/
#if !defined(lint) && !defined(__LINT__)
-static char RCS_Id[] = "$Id: sqsh_job.c,v 1.4 2010/01/28 15:30:37 mwesdorp Exp $";
+static char RCS_Id[] = "$Id: sqsh_job.c,v 1.11 2014/03/14 17:24:53 mwesdorp Exp $";
USE(RCS_Id)
#endif /* !defined(lint) */
@@ -51,7 +52,7 @@ static job_t* job_alloc _ANSI_ARGS((jobset_t*));
static int job_free _ANSI_ARGS((job_t*));
static job_id_t jobset_wait_all _ANSI_ARGS((jobset_t*, int*, int));
static int jobset_parse _ANSI_ARGS((jobset_t*, job_t*, char*,
- varbuf_t*, int));
+ varbuf_t*, int));
static job_t* jobset_get _ANSI_ARGS((jobset_t*, job_id_t));
static void jobset_run_sigint _ANSI_ARGS((int, void*));
static int jobset_get_cmd _ANSI_ARGS((jobset_t*, char*, cmd_t**));
@@ -118,9 +119,8 @@ jobset_t* jobset_create( hsize )
if( (js->js_sigcld = sigcld_create()) == NULL ) {
free( js->js_jobs );
free( js );
- sqsh_set_error( sqsh_get_error(), "sigcld_create: %s",
- sqsh_get_errstr() );
- return NULL;
+ sqsh_set_error( sqsh_get_error(), "sigcld_create: %s", sqsh_get_errstr() );
+ return NULL;
}
/*-- Initialize our command structure --*/
@@ -183,14 +183,14 @@ static int jobset_get_cmd( js, cmd_line, cmd )
return 0;
DBG(sqsh_debug( DEBUG_JOB, "jobset_get_cmd: Testing '%s'\n",
- varbuf_getstr(sg_cmd_buf) );)
+ varbuf_getstr(sg_cmd_buf) );)
/*
* Try to grab the first token from the command line. If there
* is any error while tokenizing, then we will assume that this
* isn't a command.
*/
- if( sqsh_tok( varbuf_getstr( sg_cmd_buf ), &tok, 0 ) == False )
+ if( sqsh_tok( varbuf_getstr( sg_cmd_buf ), &tok, 0 ) == False )
return 0;
/*
@@ -200,7 +200,7 @@ static int jobset_get_cmd( js, cmd_line, cmd )
* command.
*/
if( tok->tok_type != SQSH_T_WORD ||
- (*cmd = cmdset_get(g_cmdset, sqsh_tok_value(tok))) == NULL )
+ (*cmd = cmdset_get(g_cmdset, sqsh_tok_value(tok))) == NULL )
return 0;
return 1;
@@ -310,11 +310,11 @@ job_id_t jobset_run( js, cmd_line, exit_status )
* Expand the command line of any tokens, keeping quotes and stripping
* escape characters (i.e. removing them as part of the expansion
* process).
+ * sqsh-2.5 : Implemented tilde expansion in sqsh_expand().
*/
- if (sqsh_expand( cmd_line, sg_cmd_buf, EXP_COLUMNS ) == False)
+ if (sqsh_expand( cmd_line, sg_cmd_buf, EXP_COLUMNS | EXP_TILDE ) == False)
{
- sqsh_set_error( sqsh_get_error(), "sqsh_expand: %s",
- sqsh_get_errstr() );
+ sqsh_set_error( sqsh_get_error(), "sqsh_expand: %s", sqsh_get_errstr() );
return -1;
}
@@ -366,7 +366,7 @@ job_id_t jobset_run( js, cmd_line, exit_status )
/*
* If this was a \while statement, then the sole argument to the
- * function will be the unexpanted command line stripped of
+ * function will be the unexpanded command line stripped of
* all redirection crap.
*/
if (while_buf != NULL)
@@ -374,8 +374,7 @@ job_id_t jobset_run( js, cmd_line, exit_status )
if (args_add(job->job_args, "\\while" ) == False ||
args_add(job->job_args, varbuf_getstr(while_buf)) == False)
{
- sqsh_set_error( sqsh_get_error(), "args_add: %s",
- sqsh_get_errstr() );
+ sqsh_set_error( sqsh_get_error(), "args_add: %s", sqsh_get_errstr() );
goto jobset_abort;
}
}
@@ -414,6 +413,7 @@ job_id_t jobset_run( js, cmd_line, exit_status )
*/
while (sig_restore() >= 0);
sig_install ( SIGINT, SIG_H_IGN, NULL, 0 );
+ sqsh_getopt_reset();
ret = cmd->cmd_ptr( args_argc(job->job_args),
args_argv(job->job_args) );
sqsh_exit(0);
@@ -449,9 +449,9 @@ job_id_t jobset_run( js, cmd_line, exit_status )
/*
* Link the new job into our hash table.
*/
- hval = job->job_id % js->js_hsize;
- job->job_nxt = js->js_jobs[hval];
- js->js_jobs[hval] = job;
+ hval = job->job_id % js->js_hsize;
+ job->job_nxt = js->js_jobs[hval];
+ js->js_jobs[hval] = job;
/*-- And return it --*/
return job->job_id;
@@ -484,14 +484,12 @@ job_id_t jobset_run( js, cmd_line, exit_status )
{
sig_install( SIGPIPE, SIG_H_POLL, (void*)NULL, 0 );
- *exit_status = cmd->cmd_ptr( args_argc(job->job_args),
- args_argv(job->job_args) );
+ *exit_status = cmd->cmd_ptr( args_argc(job->job_args), args_argv(job->job_args) );
}
else
{
- *exit_status = cmd->cmd_ptr( args_argc(job->job_args),
- args_argv(job->job_args) );
+ *exit_status = cmd->cmd_ptr( args_argc(job->job_args), args_argv(job->job_args) );
}
}
@@ -520,14 +518,14 @@ job_id_t jobset_run( js, cmd_line, exit_status )
* Lastly, destroy the job structure that we allocated. It almost
* makes you wonder why it was created at all.
*/
- job_free( job );
+ job_free( job );
/*
* Note, reguardless of the exit status of the command, we return 0
* (i.e. the command was called succesfully reguarldess of whether
* or not the job performed its task.
*/
- sqsh_set_error( SQSH_E_NONE, NULL );
+ sqsh_set_error( SQSH_E_NONE, NULL );
return 0;
jobset_abort:
@@ -589,9 +587,7 @@ job_id_t jobset_wait( js, job_id, exit_status, block_type )
pid_t pid;
/*-- Always check your parameters --*/
- if( js == NULL || exit_status == NULL ||
- (block_type != JOB_BLOCK && block_type != JOB_NONBLOCK) ) {
-
+ if( js == NULL || exit_status == NULL || (block_type != JOB_BLOCK && block_type != JOB_NONBLOCK) ) {
sqsh_set_error( SQSH_E_BADPARAM, NULL );
return -1;
}
@@ -602,7 +598,7 @@ job_id_t jobset_wait( js, job_id, exit_status, block_type )
/*-- Find out if the job exists --*/
/* (sqsh-2.1.7 - Bug fix for bucket calculation) --*/
for( j = js->js_jobs[job_id % js->js_hsize];
- j != NULL && j->job_id != job_id ; j = j->job_nxt );
+ j != NULL && j->job_id != job_id ; j = j->job_nxt );
/*-- If we can't, error --*/
if( j == NULL ) {
@@ -643,9 +639,9 @@ job_id_t jobset_wait( js, job_id, exit_status, block_type )
* If we have reached this point, then the job has completed so
* it is just a matter of recording the exit status and returning.
*/
- j->job_flags |= JOB_DONE;
+ j->job_flags |= JOB_DONE;
j->job_end = time(NULL);
- j->job_status = *exit_status;
+ j->job_status = *exit_status;
/*
* Propagate any errors back to the caller.
@@ -659,10 +655,10 @@ job_id_t jobset_wait( js, job_id, exit_status, block_type )
sqsh_set_error( sqsh_get_error(), "sigcld_wait: %s", sqsh_get_errstr() );
}
else {
- sqsh_set_error( SQSH_E_NONE, NULL );
+ sqsh_set_error( SQSH_E_NONE, NULL );
}
- return j->job_id;
+ return j->job_id;
}
int jobset_end( js, job_id )
@@ -685,8 +681,8 @@ int jobset_end( js, job_id )
/*-- Search for the job --*/
j_prv = NULL;
for( j = js->js_jobs[hval]; j != NULL && j->job_id != job_id;
- j = j->job_nxt )
- j_prv = j;
+ j = j->job_nxt )
+ j_prv = j;
if( j == NULL ) {
sqsh_set_error( SQSH_E_EXIST, "Invalid job_id %d", job_id );
@@ -701,31 +697,28 @@ int jobset_end( js, job_id )
/*-- Kill the job --*/
if( kill( j->job_pid, SIGTERM ) == -1 ) {
- sqsh_set_error( errno, "Unable to SIGTERM pid %d: %s", j->job_pid,
- strerror( errno ) );
- return False;
+ sqsh_set_error( errno, "Unable to SIGTERM pid %d: %s", j->job_pid, strerror( errno ) );
+ return False;
}
/*-- Wait for it to die. --*/
- if( sigcld_wait( js->js_sigcld, j->job_pid, &exit_status,
- SIGCLD_BLOCK ) == -1 ) {
- sqsh_set_error( sqsh_get_error(), "sigcld_wait: %s",
- sqsh_get_errstr() );
- return False;
+ if( sigcld_wait( js->js_sigcld, j->job_pid, &exit_status, SIGCLD_BLOCK ) == -1 ) {
+ sqsh_set_error( sqsh_get_error(), "sigcld_wait: %s", sqsh_get_errstr() );
+ return False;
}
}
/*
* Finally unlink it from the list of jobs that are running.
*/
- if( j_prv != NULL )
- j_prv->job_nxt = j->job_nxt;
+ if( j_prv != NULL )
+ j_prv->job_nxt = j->job_nxt;
else
js->js_jobs[hval] = j->job_nxt;
- job_free( j );
- sqsh_set_error( SQSH_E_NONE, NULL );
- return True;
+ job_free( j );
+ sqsh_set_error( SQSH_E_NONE, NULL );
+ return True;
}
@@ -866,8 +859,7 @@ int jobset_destroy( js )
* child process is going down.
*/
kill( j->job_pid, SIGTERM );
- sigcld_wait( js->js_sigcld, j->job_pid, &exit_status,
- SIGCLD_BLOCK );
+ sigcld_wait( js->js_sigcld, j->job_pid, &exit_status, SIGCLD_BLOCK );
}
job_free( j );
@@ -928,7 +920,7 @@ static job_id_t jobset_wait_all( js, exit_status, block_type )
* then return 0.
*/
if( pid == 0 ) {
- sqsh_set_error( SQSH_E_NONE, NULL );
+ sqsh_set_error( SQSH_E_NONE, NULL );
return 0;
}
@@ -939,9 +931,9 @@ static job_id_t jobset_wait_all( js, exit_status, block_type )
for( i = 0; i < js->js_hsize; i++ ) {
for( j = js->js_jobs[i]; j != NULL && j->job_pid != pid;
- j = j->job_nxt );
+ j = j->job_nxt );
- if( j != NULL ) {
+ if( j != NULL ) {
/*
* If we have reached this point, then the job has completed so
@@ -961,8 +953,8 @@ static job_id_t jobset_wait_all( js, exit_status, block_type )
* for a pid that we don't have registered as belonging to a job.
* Hmmm...what to do?
*/
- sqsh_set_error( SQSH_E_EXIST, "Received SIGCHLD for unknown pid!" );
- return -1;
+ sqsh_set_error( SQSH_E_EXIST, "Received SIGCHLD for unknown pid!" );
+ return -1;
}
/*
@@ -994,7 +986,7 @@ static int jobset_parse( js, job, cmd_line, while_buf, tok_flags )
char *pipe_ptr = NULL ; /* Location of | */
char *cp;
/* sqsh-2.1.6 - New variables */
- varbuf_t *exp_buf;
+ varbuf_t *exp_buf = NULL ;
/*
@@ -1011,7 +1003,7 @@ static int jobset_parse( js, job, cmd_line, while_buf, tok_flags )
*/
cp = cmd_line;
while( (bg_ptr = sqsh_strchr( cp, '&' )) != NULL &&
- bg_ptr != cmd_line && *(bg_ptr - 1) == '>' )
+ bg_ptr != cmd_line && *(bg_ptr - 1) == '>' )
cp = bg_ptr + 1;
/*
@@ -1053,11 +1045,10 @@ static int jobset_parse( js, job, cmd_line, while_buf, tok_flags )
if( tmp_dir == NULL || *tmp_dir == '\0' )
tmp_dir = SQSH_TMP;
else /* sqsh-2.1.6 feature - Expand tmp_dir variable */
- {
+ {
if ((exp_buf = varbuf_create( 512 )) == NULL)
{
- sqsh_set_error( sqsh_get_error(),"varbuf: %s",
- sqsh_get_errstr() );
+ sqsh_set_error( sqsh_get_error(), "varbuf: %s", sqsh_get_errstr() );
return False;
}
if (sqsh_expand( tmp_dir, exp_buf, 0 ) == False)
@@ -1067,10 +1058,9 @@ static int jobset_parse( js, job, cmd_line, while_buf, tok_flags )
}
/*-- Create the defer file --*/
- sprintf( defer_path, "%s/sqsh-dfr.%d-%d",
- tmp_dir, (int) getpid(), job->job_id );
-
- varbuf_destroy( exp_buf ); /* sqsh-2.1.6 feature */
+ sprintf( defer_path, "%s/sqsh-dfr.%d-%d", tmp_dir, (int) getpid(), job->job_id );
+ if ( exp_buf != NULL )
+ varbuf_destroy( exp_buf ); /* sqsh-2.1.6 feature */
/*-- Let the job structure know where it is --*/
if( (job->job_output = sqsh_strdup( defer_path )) == NULL ) {
@@ -1080,8 +1070,7 @@ static int jobset_parse( js, job, cmd_line, while_buf, tok_flags )
/*-- Now, open the file --*/
if( (defer_fd = sqsh_open(defer_path,O_CREAT|O_WRONLY|O_TRUNC,0600)) == -1 ) {
- sqsh_set_error( sqsh_get_error(), "Unable to open %s: %s",
- defer_path, sqsh_get_errstr() );
+ sqsh_set_error( sqsh_get_error(), "Unable to open %s: %s", defer_path, sqsh_get_errstr() );
return False;
}
@@ -1090,9 +1079,8 @@ static int jobset_parse( js, job, cmd_line, while_buf, tok_flags )
* stdout and stderr.
*/
if( sqsh_dup2( defer_fd, fileno(stdout) ) == -1 ||
- sqsh_dup2( defer_fd, fileno(stderr) ) == -1 ) {
- sqsh_set_error( sqsh_get_error(), "sqsh_dup2: %s",
- sqsh_get_errstr() );
+ sqsh_dup2( defer_fd, fileno(stderr) ) == -1 ) {
+ sqsh_set_error( sqsh_get_error(), "sqsh_dup2: %s", sqsh_get_errstr() );
sqsh_close( defer_fd );
return False;
}
@@ -1140,8 +1128,7 @@ static int jobset_parse( js, job, cmd_line, while_buf, tok_flags )
if( (fd = sqsh_popen( pipe_ptr+1, "w", NULL, NULL )) == -1 )
{
env_set( g_internal_env, "?", "-255" );
- sqsh_set_error(sqsh_get_error(), "sqsh_popen: %s",
- sqsh_get_errstr());
+ sqsh_set_error( sqsh_get_error(), "sqsh_popen: %s", sqsh_get_errstr());
return False;
}
@@ -1150,8 +1137,7 @@ static int jobset_parse( js, job, cmd_line, while_buf, tok_flags )
* created to our stdout.
*/
if( sqsh_dup2( fd, fileno(stdout) ) == -1 ) {
- sqsh_set_error( sqsh_get_error(), "sqsh_dup2: %s",
- sqsh_get_errstr() );
+ sqsh_set_error( sqsh_get_error(), "sqsh_dup2: %s", sqsh_get_errstr() );
sqsh_close( fd );
return False;
}
@@ -1195,8 +1181,7 @@ static int jobset_parse( js, job, cmd_line, while_buf, tok_flags )
* the file descriptor to.
*/
if( sqsh_tok( NULL, &tok, tok_flags ) == False ) {
- sqsh_set_error( sqsh_get_error(), "sqsh_tok: %s",
- sqsh_get_errstr() );
+ sqsh_set_error( sqsh_get_error(), "sqsh_tok: %s", sqsh_get_errstr() );
return False;
}
@@ -1219,9 +1204,9 @@ static int jobset_parse( js, job, cmd_line, while_buf, tok_flags )
flag = O_WRONLY | O_CREAT | O_TRUNC;
/*-- Now, open the file --*/
- if( (fd = sqsh_open( sqsh_tok_value(tok), flag, 0 )) == -1 ) {
- sqsh_set_error( sqsh_get_error(), "Unable to open %s: %s",
- sqsh_tok_value(tok), sqsh_get_errstr() );
+ cp = sqsh_tok_value(tok);
+ if( (fd = sqsh_open( cp, flag, 0 )) == -1 ) {
+ sqsh_set_error( sqsh_get_error(), "Unable to open %s: %s", cp, sqsh_get_errstr() );
return False;
}
@@ -1230,8 +1215,7 @@ static int jobset_parse( js, job, cmd_line, while_buf, tok_flags )
* to the newly opened file and close the file.
*/
if( sqsh_dup2( fd, tok->tok_fd_left ) == -1 ) {
- sqsh_set_error( sqsh_get_error(), "sqsh_dup2: %s",
- sqsh_get_errstr() );
+ sqsh_set_error( sqsh_get_error(), "sqsh_dup2: %s", sqsh_get_errstr() );
return False;
}
sqsh_close( fd );
@@ -1244,8 +1228,7 @@ static int jobset_parse( js, job, cmd_line, while_buf, tok_flags )
* in from.
*/
if( sqsh_tok( NULL, &tok, tok_flags ) == False ) {
- sqsh_set_error( sqsh_get_error(), "sqsh_tok: %s",
- sqsh_get_errstr() );
+ sqsh_set_error( sqsh_get_error(), "sqsh_tok: %s", sqsh_get_errstr() );
return False;
}
@@ -1259,15 +1242,14 @@ static int jobset_parse( js, job, cmd_line, while_buf, tok_flags )
}
/*-- Now, open the file --*/
- if( (fd = sqsh_open( sqsh_tok_value(tok), O_RDONLY, 0 )) == -1 ) {
- sqsh_set_error( sqsh_get_error(), "%s: %s", sqsh_tok_value(tok),
- sqsh_get_errstr() );
+ cp = sqsh_tok_value(tok);
+ if( (fd = sqsh_open( cp, O_RDONLY, 0 )) == -1 ) {
+ sqsh_set_error( sqsh_get_error(), "%s: %s", cp, sqsh_get_errstr() );
return False;
}
if( (sqsh_dup2( fd, fileno(stdin) )) == -1 ) {
- sqsh_set_error( sqsh_get_error(), "%s: %s", sqsh_tok_value(tok),
- sqsh_get_errstr() );
+ sqsh_set_error( sqsh_get_error(), "%s: %s", cp, sqsh_get_errstr() );
return False;
}
sqsh_close( fd );
@@ -1279,8 +1261,7 @@ static int jobset_parse( js, job, cmd_line, while_buf, tok_flags )
* dirty work.
*/
if( sqsh_dup2( tok->tok_fd_right, tok->tok_fd_left ) == -1 ) {
- sqsh_set_error( sqsh_get_error(), "sqsh_dup2: %s",
- sqsh_get_errstr() );
+ sqsh_set_error( sqsh_get_error(), "sqsh_dup2: %s", sqsh_get_errstr() );
return False;
}
@@ -1310,8 +1291,7 @@ static int jobset_parse( js, job, cmd_line, while_buf, tok_flags )
{
if (args_add(job->job_args, sqsh_tok_value( tok )) == False)
{
- sqsh_set_error( sqsh_get_error(), "args_add: %s",
- sqsh_get_errstr() );
+ sqsh_set_error( sqsh_get_error(), "args_add: %s", sqsh_get_errstr() );
return False;
}
}
@@ -1353,13 +1333,13 @@ static job_t* jobset_get( js, job_id )
hval = job_id % js->js_hsize;
/*-- Search for the job --*/
- for( j = js->js_jobs[job_id % js->js_hsize];
- j != NULL && j->job_id != job_id; j = j->job_nxt );
+ for( j = js->js_jobs[hval];
+ j != NULL && j->job_id != job_id; j = j->job_nxt );
/*-- ESTUPID --*/
- if( j == NULL ) {
- sqsh_set_error( SQSH_E_EXIST, NULL );
- return NULL;
+ if( j == NULL ) {
+ sqsh_set_error( SQSH_E_EXIST, NULL );
+ return NULL;
}
return j;
@@ -1460,14 +1440,14 @@ static int jobset_global_init()
*/
if( sg_cmd_buf == NULL ) {
if( (sg_cmd_buf = varbuf_create( 128 )) == NULL ) {
- sqsh_set_error( sqsh_get_error(),"varbuf: %s",sqsh_get_errstr() );
+ sqsh_set_error( sqsh_get_error(), "varbuf: %s", sqsh_get_errstr() );
return False;
}
}
if( sg_alias_buf == NULL ) {
if( (sg_alias_buf = varbuf_create( 128 )) == NULL ) {
- sqsh_set_error( sqsh_get_error(),"varbuf: %s",sqsh_get_errstr() );
+ sqsh_set_error( sqsh_get_error(), "varbuf: %s", sqsh_get_errstr() );
return False;
}
}
@@ -1476,7 +1456,7 @@ static int jobset_global_init()
{
if ((sg_while_buf = varbuf_create( 128 )) == NULL)
{
- sqsh_set_error( sqsh_get_error(),"varbuf: %s",sqsh_get_errstr() );
+ sqsh_set_error( sqsh_get_error(), "varbuf: %s", sqsh_get_errstr() );
return False;
}
}
diff --git a/src/sqsh_main.c b/src/sqsh_main.c
index 098dcb1..29601b7 100644
--- a/src/sqsh_main.c
+++ b/src/sqsh_main.c
@@ -27,9 +27,6 @@
#include <termios.h>
#include <pwd.h>
#include "sqsh_config.h"
-#ifdef HAVE_LOCALE_H
-#include <locale.h>
-#endif
#include "sqsh_job.h"
#include "sqsh_error.h"
#include "sqsh_global.h"
@@ -45,7 +42,7 @@
/*-- Current Version --*/
#if !defined(lint) && !defined(__LINT__)
-static char RCS_Id[] = "$Id: sqsh_main.c,v 1.17 2010/02/17 11:35:06 mwesdorp Exp $";
+static char RCS_Id[] = "$Id: sqsh_main.c,v 1.23 2013/04/25 14:09:47 mwesdorp Exp $";
USE(RCS_Id)
#endif /* !defined(lint) */
@@ -148,7 +145,6 @@ main( argc, argv )
char *batch_failcount;
char *exit_failcount;
char *exit_value;
- char *keyword_file;
char *term_title;
char str[512];
int ch;
@@ -166,6 +162,15 @@ main( argc, argv )
varbuf_t *exp_buf;
/*
+ * sqsh-2.2.0 - Variables used by password handling option
+ * moved here.
+ */
+ char buf[MAXPWD];
+ char *p;
+ int fdin, fdout;
+
+
+ /*
* If termios.h defines TIOCGWINSZ, then we need to declare a
* structure in which to retrieve the current window size.
*/
@@ -199,15 +204,6 @@ main( argc, argv )
}
/*
- * Now initialize our system locale, to get a sane default
- * character set for the current environment
- * This may still be overridden by the -J option
- */
-#ifdef HAVE_SETLOCALE
- setlocale(LC_ALL, "");
-#endif
-
- /*
* If the first argument on the command line is -r, then we want
* to process it before we attempt to read the .sqshrc file (since
* -r allows the user to specify another .sqshrc file.
@@ -228,6 +224,8 @@ main( argc, argv )
else
{
rcfile = NULL;
+ /* sqsh-2.1.9 - Set rcfile environment variable also to NULL */
+ env_set( g_env, "rcfile", rcfile );
}
}
else
@@ -279,7 +277,7 @@ main( argc, argv )
if (access( cptr, R_OK ) != -1)
{
env_set( g_env, "cur_rcfile", cptr );
- if((jobset_run( g_jobset, "\\loop -n $cur_rcfile", &exit_status))
+ if((jobset_run( g_jobset, "\\loop -n $cur_rcfile", &exit_status))
== -1 )
{
fprintf( stderr, "\\loop: %s\n", sqsh_get_errstr() );
@@ -295,6 +293,8 @@ main( argc, argv )
cptr = strtok( NULL, ":\n\t\r" );
}
+ /* sqsh-2.1.9 - Remove temporary environment variable cur_rcfile */
+ env_remove( g_env, "cur_rcfile", 0);
varbuf_destroy(exp_buf);
}
@@ -309,7 +309,7 @@ main( argc, argv )
"a:A:bBc;C:d:D:eE:f:G:hH:i:I:J:k:K:l:L:m:n:N:o:pP;Q:r;R:s:S:t;T:U:vV;w:Xy:z:Z;\250:" )) != EOF)
{
ret = 0;
- switch (ch)
+ switch (ch)
{
case 'a' :
ret = env_set( g_env, "thresh_exit", sqsh_optarg );
@@ -377,7 +377,6 @@ main( argc, argv )
read_file = True;
show_banner = False;
ret = env_set( g_env, "script", sqsh_optarg );
- ret = env_set( g_internal_env, "0", sqsh_optarg );
break;
case 'I' :
ret = env_set( g_env, "interfaces", sqsh_optarg );
@@ -448,19 +447,19 @@ main( argc, argv )
while( *sqsh_optarg != '\0' )
*sqsh_optarg++ = ' ';
}
-
+
break;
case 'Q' : /* sqsh-2.1.6 */
ret = env_set( g_env, "query_timeout", sqsh_optarg );
break;
case 'r' :
- /*
- * The alternative sqshrc file should already have been
- * processed above. Note that the -r option should be the
- * first option on the command line, otherwise the option
- * is ignored, also the option and the filename should be
- * separated by at leat a blank space.
- */
+ /*
+ * The alternative sqshrc file should already have been
+ * processed above. Note that the -r option should be the
+ * first option on the command line, otherwise the option
+ * is ignored, also the option and the filename should be
+ * separated by at leat a blank space.
+ */
ret = True;
break;
case 'R' : /* sqsh-2.1.6 */
@@ -520,19 +519,15 @@ main( argc, argv )
case '\250' :
#if defined(SQSH_HIDEPWD)
{
- /*
- * sqsh-2.1.7 - Incorporated patch by David Wood
- * to solve a problem with pipes already in use. (Patch-id 2607434)
- * The actual pipe file descriptors will now be passed on with the \250 option.
- */
- char buf[MAXPWD];
- char *p;
- int fdin, fdout;
-
+ /*
+ * sqsh-2.1.7 - Incorporated patch by David Wood
+ * to solve a problem with pipes already in use. (Patch-id 2607434)
+ * The actual pipe file descriptors will now be passed on with the \250 option.
+ */
memset(buf, 0, MAXPWD);
if (sqsh_optarg != NULL)
strcpy (buf, sqsh_optarg);
- if (p = strchr(buf, '/')) {
+ if ((p = strchr(buf, '/')) != NULL) {
*p = '\0';
fdin = atoi(buf);
fdout = atoi(p+1);
@@ -568,7 +563,7 @@ main( argc, argv )
* Check the results from whichever variable we attempted
* to set.
*/
- if (ret == False)
+ if (ret == False)
{
fprintf( stderr, "sqsh: -%c: %s\n", ch, sqsh_get_errstr() );
sqsh_exit( 255 );
@@ -594,7 +589,7 @@ main( argc, argv )
{
if (sqsh_optind > 1)
{
- argv[sqsh_optind-1] = argv[0];
+ env_get (g_env, "script", &(argv[sqsh_optind-1])) ;
}
g_func_args[g_func_nargs].argc = argc - sqsh_optind + 1;
g_func_args[g_func_nargs].argv = &(argv[sqsh_optind-1]);
@@ -622,7 +617,7 @@ main( argc, argv )
sqsh_exit( 255 );
}
if (stdin_tty && stdout_tty)
- g_interactive = True;
+ g_interactive = True;
#if defined(TIOCGWINSZ)
/*
@@ -632,24 +627,25 @@ main( argc, argv )
*/
if (set_width == False && stdout_tty)
{
- /* Check to see if the width has been set via the sqshrc file.
- To do this we get the current setting - if it is != 80 then
- the sqshrc file had a \set width directive, which we don't want
- to override here. */
- char *w;
- env_get( g_env, "width", &w);
- if(!w || atoi(w) == 80) {
- if (ioctl(fileno(stdout), TIOCGWINSZ, &ws ) != -1) {
- sprintf( str, "%d", ws.ws_col );
- env_set( g_env, "width", str );
-
- DBG(sqsh_debug(DEBUG_SCREEN,"sqsh_main: Screen width = %d\n",
- ws.ws_col);)
- } else {
+ /* Check to see if the width has been set via the sqshrc file.
+ * To do this we get the current setting - if it is != 80 then
+ * the sqshrc file had a \set width directive, which we don't want
+ * to override here.
+ */
+ char *w;
+ env_get( g_env, "width", &w);
+ if(!w || atoi(w) == 80) {
+ if (ioctl(fileno(stdout), TIOCGWINSZ, &ws ) != -1) {
+ sprintf( str, "%d", ws.ws_col );
+ env_set( g_env, "width", str );
+
+ DBG(sqsh_debug(DEBUG_SCREEN,"sqsh_main: Screen width = %d\n",
+ ws.ws_col);)
+ } else {
DBG(sqsh_debug(DEBUG_SCREEN,"sqsh_main: ioctl(%d,TIOCGWINSZ): %s\n",
(int)fileno(stdout), strerror(errno));)
- }
- }
+ }
+ }
#if defined(SIGWINCH)
if (stdout_tty)
@@ -703,7 +699,7 @@ main( argc, argv )
* banner.
*/
env_get( g_env, "banner", &banner );
- if (show_banner && (banner == NULL || *banner == '1') &&
+ if (show_banner && (banner == NULL || *banner == '1') &&
g_interactive)
{
printf( "%s ", g_version );
@@ -750,7 +746,7 @@ main( argc, argv )
env_get( g_env, "history", &history );
/*
- * If a history file has been defined, then we want to
+ * If a history file has been defined, then we want to
* expand its contents. This will allow folks to have
* a different history file for each server.
*/
@@ -781,31 +777,9 @@ main( argc, argv )
}
/*
- * If the user has requested some form of keyword completion
- * then attempt to read the contents of the keywords file.
- * sqsh-2.1.6 feature - Expand keyword_file variable
- */
- env_get( g_env, "keyword_file", &keyword_file );
- if ( keyword_file != NULL && *keyword_file != '\0')
- {
- exp_buf = varbuf_create( 512 );
- if (exp_buf == NULL)
- {
- fprintf( stderr, "sqsh: %s\n", sqsh_get_errstr() );
- sqsh_exit( 255 );
- }
- if (sqsh_expand( keyword_file, exp_buf, 0 ) != False)
- sqsh_readline_read( varbuf_getstr( exp_buf) );
- else
- fprintf( stderr, "sqsh: Error expanding $keyword_file: %s\n",
- sqsh_get_errstr() );
- varbuf_destroy( exp_buf );
- }
-
- /*
* Initialize the readline "sub-system". This basically consists
* of installing handlers for readline keyword completion and
- * sucking in the readline history file.
+ * sucking in the completion keyword list and the readline history file.
*/
sqsh_readline_init();
}
@@ -894,6 +868,7 @@ main( argc, argv )
*/
sqsh_exit( 0 );
/* NOTREACHED */
+ return (0);
}
#if defined(TIOCGWINSZ) && defined(SIGWINCH)
@@ -903,7 +878,7 @@ main( argc, argv )
*
* This function is called whenever a SIGWINCH (window size change)
* signal is recieved during the life of sqsh. Unfortunately, this
- * function calls quite a few functions that are known not to be
+ * function calls quite a few functions that are known not to be
* signal safe, but I am willing to accept the risk. Thanks
* to David Whitemarsh <djw@accessio.demon.co.uk> for supplying
* this code.
@@ -926,7 +901,7 @@ static void sigwinch_handler( sig, user_data )
if (isatty( fileno(stdout) ))
ctty_fd = fileno(stdout);
else {
-
+
/*
* Attempt to grab the path to our controlling tty. If we can't
* find it, then we have to give up.
@@ -999,7 +974,7 @@ static void print_usage()
sprintf( str, " [%s]", sg_flags[i].flag );
else
sprintf( str, " [%s %s]", sg_flags[i].flag, sg_flags[i].arg );
-
+
len = strlen( str );
if( (line_len + len) > 68 ) {
@@ -1037,60 +1012,117 @@ static void print_usage()
* sqsh-2.1.7 - Incorporated patch by David Wood
* to solve a problem with pipes already in use. (Patch-id 2607434)
* The actual pipe file descriptors will now be passed on with the \250 option.
+ * sqsh-2.2.0 - Function reworked.
*/
static void hide_password (argc, argv)
int argc;
char *argv[];
{
- int i, j;
- int filedes[2];
- char buf[32];
- char nullpwd[2];
- char *pwd = NULL;
-
- for (i = 1; i < argc; ++i) {
- if (*(argv[i]) == '-' && *(argv[i] + 1) == 'P') {
- if (*(argv[i]+2)) {
- pwd = (argv[i]+2); /* Password passed on as: "sqsh -SSYBASE -Usa -Pxxxxxx" */
- } else if (i + 1 < argc && *(argv[i + 1]) != '-') {
- pwd = argv[i + 1]; /* Password passed on as: "sqsh -SSYBASE -Usa -P xxxxxx" */
- /* Reshuffle the argv list to remove the password string */
- for (j = i + 1; j < argc - 1; j++)
- argv[j] = argv[j + 1];
- argv[j] = NULL;
- argc--;
+ int i, j;
+ char buf[32];
+ int filedes[2];
+ char nullpwd[2];
+ pid_t pid;
+ char *pwd = NULL;
+ int status;
+
+
+ nullpwd[0] = '\n';
+ nullpwd[1] = '\0';
+
+ /*
+ * Loop through the list of arguments only once and skip all intermediate -P
+ * entries, but remember the last password specified.
+ */
+ for (i = 0, j = 0; argv[i] != NULL; ++i)
+ {
+ if (*(argv[i]) == '-' && *(argv[i]+1) == 'P')
+ {
+ /*
+ * New password parameter encounterd.
+ */
+ pwd = NULL;
+ if (*(argv[i]+2) != '\0')
+ {
+ /*
+ * Password passed on as: "sqsh -SSYBASE -Usa -Pxxxxxx" , or as -P-
+ */
+ pwd = (argv[i]+2);
+ }
+ else if ((i+1 < argc) && (*(argv[i+1]) != '-' || (*(argv[i+1]) == '-' && *(argv[i+1]+1) == '\0')))
+ {
+ /*
+ * Password passed on as: "sqsh -SSYBASE -Usa -P xxxxxx" , or as -P -
+ */
+ pwd = argv[++i];
}
if (pwd == NULL || (pwd != NULL && strlen(pwd) == 0))
{
- nullpwd[0] = '\n';
- nullpwd[1] = '\0';
- pwd = nullpwd; /* Empty (NULL) password passed on as:
- * "sqsh -SSYBASE -Usa -P " or "sqsh -SSYBASE -Usa -P '' " */
+ /*
+ * Empty (NULL) password passed on as:
+ * "sqsh -SSYBASE -Usa -P " or "sqsh -SSYBASE -Usa -P '' "
+ */
+ pwd = nullpwd;
}
+ }
+ else
+ argv[j++] = argv[i];
+ }
- /* Create the pipe... */
- if (pipe(filedes) == -1) {
- perror("sqsh: Error: Can't pipe()");
- return;
- }
- sprintf(buf, "-%c%d/%d", '\250', filedes[0], filedes[1]);
- argv[i] = buf;
-
- if (fork()) {
- /* Re-execute ourselves, with the modified argv[] */
- execvp(argv[0], argv);
- /* Not reached */
- } else {
- /* ... and write the password to the pipe */
- if (write(filedes[1], pwd, strlen(pwd)) != strlen(pwd)) {
- fprintf(stderr, "sqsh: Error: Failed to write password to pipe (filedes=%d)\n", filedes[1]);
- sqsh_exit(255);
- }
- close(filedes[0]);
- close(filedes[1]);
- sqsh_exit(0);
- }
+ /*
+ * If pwd == NULL then no -P was specified as argument and we do not
+ * have to hide anything from the argument list.
+ */
+ if (pwd == NULL)
+ {
+ return;
+ }
+
+ /*
+ * Create the pipe.
+ */
+ if (pipe (filedes) == -1)
+ {
+ perror ("sqsh: Error: Can't pipe()");
+ return;
+ }
+ sprintf (buf, "-%c%d/%d", '\250', filedes[0], filedes[1]);
+ argv[j++] = buf;
+ argv[j] = NULL;
+
+ if ((pid = fork()) != 0)
+ {
+ /*
+ * sqsh-2.2.0 - This code is executed by the parent process.
+ * Wait for the child process to finish execution before we continue.
+ */
+ (void) waitpid (pid, &status, 0);
+ /*
+ * Re-execute ourselves in the parent process, with the modified argv[] list.
+ */
+ if (WIFEXITED(status) != 0 && WEXITSTATUS(status) == 0)
+ (void) execvp (argv[0], argv);
+ /* Not reached */
+ else
+ {
+ fprintf (stderr, "sqsh: Error: Processing of function hide_password failed unexpectedly\n");
+ sqsh_exit (255);
+ }
+ }
+ else
+ {
+ /*
+ * The child process writes the password to the pipe, closes the pipe
+ * and exits.
+ */
+ if ((int) write (filedes[1], pwd, strlen(pwd)) != (int) strlen(pwd))
+ {
+ fprintf (stderr, "sqsh: Error: Failed to write password to pipe (filedes=%d)\n", filedes[1]);
+ sqsh_exit (255);
}
+ (void) close (filedes[0]);
+ (void) close (filedes[1]);
+ sqsh_exit (0);
}
}
diff --git a/src/sqsh_parser/Makefile.in b/src/sqsh_parser/Makefile.in
new file mode 100644
index 0000000..ef22495
--- /dev/null
+++ b/src/sqsh_parser/Makefile.in
@@ -0,0 +1,31 @@
+CC = @CC@
+CFLAGS = -c @CFLAGS@
+CPPFLAGS = @CPPFLAGS@
+OBJMODE = @OBJMODE@
+LEX = flex -Cm
+LEMON = lemon -q
+
+libsqsh: sqsh_parser.o tsql.o tsql.yy.o
+ ar -rcsv ${OBJMODE} sqsh_parser.a sqsh_parser.o tsql.o tsql.yy.o
+
+sqsh_parser.o: sqsh_parser.c sqsh_parser.h
+ ${CC} $(CFLAGS) -o $@ sqsh_parser.c
+
+tsql.o: tsql.c sqsh_parser.h
+ ${CC} $(CFLAGS) -o $@ tsql.c
+
+tsql.yy.o: tsql.yy.c tsql.h
+ ${CC} $(CFLAGS) -o $@ tsql.yy.c
+
+tsql.c: tsql.y
+ ${LEMON} -s -q tsql.y
+
+tsql.yy.c: tsql.l
+ ${LEX} -o tsql.yy.c tsql.l
+
+clean:
+ rm -f sqsh_parser.o tsql.o tsql.yy.o sqsh_parser.a
+
+distclean:
+ rm -f Makefile sqsh_parser.o tsql.o tsql.yy.o sqsh_parser.a
+# rm -f Makefile sqsh_parser.o tsql.o tsql.yy.o tsql.c tsql.yy.c tsql.h sqsh_parser.a
diff --git a/src/sqsh_parser/sqsh_parser.c b/src/sqsh_parser/sqsh_parser.c
new file mode 100644
index 0000000..c3014df
--- /dev/null
+++ b/src/sqsh_parser/sqsh_parser.c
@@ -0,0 +1,129 @@
+/*
+ * File: main.c
+ * Author: K.-M. Hansche
+ *
+ * Created on 19. Juli 2013, 07:41
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <search.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "sqsh_parser.h"
+
+void* def_root = NULL;
+aliascallback callback = NULL;
+long callbacklparam = 0;
+
+static void* xmalloc(size_t size) {
+ void* m = malloc(size);
+ if (m == NULL) {
+ exit(0);
+ }
+ memset(m, 0, size);
+ return m;
+}
+
+static void free_node(void *nodep) {
+ t_tdef* datap;
+ datap = (t_tdef*) nodep;
+
+ free(datap->alias);
+ free(datap->table);
+ free(datap);
+
+}
+
+static int def_compare(const void *pa, const void *pb) {
+ return strcmp(((t_tdef*) pa)->alias, ((t_tdef*) pb)->alias);
+}
+
+void* addTableDefNode(char* table, char* alias) {
+ if (table == NULL) return NULL;
+ if (alias == NULL || strcmp(alias, "") == 0) alias = table;
+
+ t_tdef* tdef = (t_tdef*) xmalloc(sizeof (t_tdef));
+ tdef->table = (char(*)) xmalloc((strlen(table) + 1) * sizeof (char));
+ tdef->alias = (char(*)) xmalloc((strlen(alias) + 1) * sizeof (char));
+
+ strcpy(tdef->table, table);
+ strcpy(tdef->alias, alias);
+
+ void* p = tsearch(tdef, &def_root, def_compare);
+ if (tdef != *(t_tdef **) p) {
+ free_node(tdef);
+ }
+
+ return p;
+}
+
+static void callback_walker(const void *nodep, const VISIT which, const int depth) {
+ t_tdef* datap;
+
+ datap = *(t_tdef**) nodep;
+
+ switch (which) {
+ case preorder:
+ case endorder:
+ break;
+ case postorder:
+ case leaf:
+ callback(datap->table, datap->alias, callbacklparam);
+ break;
+ }
+}
+
+static void print_walker(const void *nodep, const VISIT which, const int depth) {
+ t_tdef* datap;
+
+ datap = *(t_tdef**) nodep;
+
+ switch (which) {
+ case preorder:
+ break;
+ case postorder:
+ printf("Table: %s\t alias: %s\t depth: %i\n", datap->table, datap->alias, depth);
+ break;
+ case endorder:
+ break;
+ case leaf:
+ printf("Table: %s\t alias: %s\t depth: %i\tLeaf\n", datap->table, datap->alias, depth);
+ break;
+ }
+}
+
+void delTableDefs(void) {
+#if !defined(_GNU_SOURCE)
+ t_tdef* datap;
+
+ while (def_root != NULL) {
+ datap = *(t_tdef**)def_root;
+ tdelete((void *)datap, &def_root, def_compare);
+ free_node(datap);
+ }
+#else
+ tdestroy(def_root, free_node);
+ def_root = NULL;
+#endif
+}
+
+char* getTableForAlias(char* alias) {
+ t_tdef tdef;
+ t_tdef** res;
+
+ if (alias == NULL) return NULL;
+
+ tdef.alias = alias;
+ res = tfind(&tdef, &def_root, def_compare);
+
+ return res != NULL ? (*res)->table : NULL;
+}
+
+void getTablesAndAliases(aliascallback cb, long lparam){
+ callback=cb;
+ callbacklparam=lparam;
+ twalk(def_root, callback_walker);
+}
+
diff --git a/src/sqsh_parser/sqsh_parser.h b/src/sqsh_parser/sqsh_parser.h
new file mode 100644
index 0000000..b8659bf
--- /dev/null
+++ b/src/sqsh_parser/sqsh_parser.h
@@ -0,0 +1,65 @@
+/*
+ * File: sqsh_parser.h
+ * Author: K.-M. Hansche
+ *
+ * Created on 22. Juli 2013, 17:37
+ */
+
+#ifndef SQSH_PARSER_H
+#define SQSH_PARSER_H
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+ typedef void (* aliascallback)(char* table, char* alias, long lparam);
+
+ /**
+ * Extract table/alias combos from an arbitrary sql-statement.
+ * Please call delTabledefs after you are done.
+ *
+ * @param sql A complete or incomplete sql-statement.
+ */
+ extern void parseSql(char* sql);
+
+ /**
+ *
+ * @param alias The alias (or tablename, for simplicity) you want to get the
+ * tablename for.
+ * @return The tablename or NULL. The string will be freed on delTableDefs.
+ */
+ extern char* getTableForAlias(char* alias);
+
+ /**
+ * Free all resources, including strings from getTableForAlias.
+ */
+ extern void delTableDefs(void);
+
+ /**
+ * Insert a tabledefinition into the global tree.
+ * The strings are duplicated internally and freed on delTabledefs.
+ *
+ * @param table A tablename
+ * @param alias The used alias for that name. May be NULL.
+ * @return
+ */
+ extern void* addTableDefNode(char* table, char* alias);
+
+ /**
+ * Iterate over all data. Calls cb for every table/alias-pair.
+ * @param cb A callback defined as typedef void (* aliascallback)(char* table, char* alias, long lparam);
+ * @param lparam The user-defined lparam for cb;
+ */
+ extern void getTablesAndAliases(aliascallback cb, long lparam);
+
+ typedef struct {
+ char* table;
+ char* alias;
+ } t_tdef;
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* SQSH_PARSER_H */
+
diff --git a/src/sqsh_parser/tsql.c b/src/sqsh_parser/tsql.c
new file mode 100644
index 0000000..dc19062
--- /dev/null
+++ b/src/sqsh_parser/tsql.c
@@ -0,0 +1,970 @@
+/* Driver template for the LEMON parser generator.
+** The author disclaims copyright to this source code.
+*/
+/* First off, code is included that follows the "include" declaration
+** in the input grammar file. */
+#include <stdio.h>
+#line 1 "tsql.y"
+
+ #include <string.h>
+ #include <assert.h>
+ #include <stdlib.h>
+
+ #include "sqsh_parser.h"
+#line 15 "tsql.c"
+/* Next is all token values, in a form suitable for use by makeheaders.
+** This section will be null unless lemon is run with the -m switch.
+*/
+/*
+** These constants (all generated automatically by the parser generator)
+** specify the various kinds of tokens (terminals) that the parser
+** understands.
+**
+** Each symbol here is a terminal symbol in the grammar.
+*/
+/* Make sure the INTERFACE macro is defined.
+*/
+#ifndef INTERFACE
+# define INTERFACE 1
+#endif
+/* The next thing included is series of defines which control
+** various aspects of the generated parser.
+** YYCODETYPE is the data type used for storing terminal
+** and nonterminal numbers. "unsigned char" is
+** used if there are fewer than 250 terminals
+** and nonterminals. "int" is used otherwise.
+** YYNOCODE is a number of type YYCODETYPE which corresponds
+** to no legal terminal or nonterminal number. This
+** number is used to fill in empty slots of the hash
+** table.
+** YYFALLBACK If defined, this indicates that one or more tokens
+** have fall-back values which should be used if the
+** original value of the token will not parse.
+** YYACTIONTYPE is the data type used for storing terminal
+** and nonterminal numbers. "unsigned char" is
+** used if there are fewer than 250 rules and
+** states combined. "int" is used otherwise.
+** ParseTOKENTYPE is the data type used for minor tokens given
+** directly to the parser from the tokenizer.
+** YYMINORTYPE is the data type used for all minor tokens.
+** This is typically a union of many types, one of
+** which is ParseTOKENTYPE. The entry in the union
+** for base tokens is called "yy0".
+** YYSTACKDEPTH is the maximum depth of the parser's stack. If
+** zero the stack is dynamically sized using realloc()
+** ParseARG_SDECL A static variable declaration for the %extra_argument
+** ParseARG_PDECL A parameter declaration for the %extra_argument
+** ParseARG_STORE Code to store %extra_argument into yypParser
+** ParseARG_FETCH Code to extract %extra_argument from yypParser
+** YYNSTATE the combined number of states.
+** YYNRULE the number of rules in the grammar
+** YYERRORSYMBOL is the code number of the error symbol. If not
+** defined, then do no error processing.
+*/
+#define YYCODETYPE unsigned char
+#define YYNOCODE 13
+#define YYACTIONTYPE unsigned char
+#define ParseTOKENTYPE char*
+typedef union {
+ int yyinit;
+ ParseTOKENTYPE yy0;
+} YYMINORTYPE;
+#ifndef YYSTACKDEPTH
+#define YYSTACKDEPTH 100
+#endif
+#define ParseARG_SDECL
+#define ParseARG_PDECL
+#define ParseARG_FETCH
+#define ParseARG_STORE
+#define YYNSTATE 15
+#define YYNRULE 10
+#define YY_NO_ACTION (YYNSTATE+YYNRULE+2)
+#define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1)
+#define YY_ERROR_ACTION (YYNSTATE+YYNRULE)
+
+/* The yyzerominor constant is used to initialize instances of
+** YYMINORTYPE objects to zero. */
+static const YYMINORTYPE yyzerominor = { 0 };
+
+/* Define the yytestcase() macro to be a no-op if is not already defined
+** otherwise.
+**
+** Applications can choose to define yytestcase() in the %include section
+** to a macro that can assist in verifying code coverage. For production
+** code the yytestcase() macro should be turned off. But it is useful
+** for testing.
+*/
+#ifndef yytestcase
+# define yytestcase(X)
+#endif
+
+
+/* Next are the tables used to determine what action to take based on the
+** current state and lookahead token. These tables are used to implement
+** functions that take a state number and lookahead value and return an
+** action integer.
+**
+** Suppose the action integer is N. Then the action is determined as
+** follows
+**
+** 0 <= N < YYNSTATE Shift N. That is, push the lookahead
+** token onto the stack and goto state N.
+**
+** YYNSTATE <= N < YYNSTATE+YYNRULE Reduce by rule N-YYNSTATE.
+**
+** N == YYNSTATE+YYNRULE A syntax error has occurred.
+**
+** N == YYNSTATE+YYNRULE+1 The parser accepts its input.
+**
+** N == YYNSTATE+YYNRULE+2 No such action. Denotes unused
+** slots in the yy_action[] table.
+**
+** The action table is constructed as a single large table named yy_action[].
+** Given state S and lookahead X, the action is computed as
+**
+** yy_action[ yy_shift_ofst[S] + X ]
+**
+** If the index value yy_shift_ofst[S]+X is out of range or if the value
+** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X or if yy_shift_ofst[S]
+** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table
+** and that yy_default[S] should be used instead.
+**
+** The formula above is for computing the action when the lookahead is
+** a terminal symbol. If the lookahead is a non-terminal (as occurs after
+** a reduce action) then the yy_reduce_ofst[] array is used in place of
+** the yy_shift_ofst[] array and YY_REDUCE_USE_DFLT is used in place of
+** YY_SHIFT_USE_DFLT.
+**
+** The following are the tables generated in this section:
+**
+** yy_action[] A single table containing all actions.
+** yy_lookahead[] A table containing the lookahead for each entry in
+** yy_action. Used to detect hash collisions.
+** yy_shift_ofst[] For each state, the offset into yy_action for
+** shifting terminals.
+** yy_reduce_ofst[] For each state, the offset into yy_action for
+** shifting non-terminals after a reduce.
+** yy_default[] Default action for each state.
+*/
+#define YY_ACTTAB_COUNT (18)
+static const YYACTIONTYPE yy_action[] = {
+ /* 0 */ 15, 7, 12, 1, 26, 2, 8, 4, 3, 5,
+ /* 10 */ 9, 7, 10, 1, 13, 11, 6, 14,
+};
+static const YYCODETYPE yy_lookahead[] = {
+ /* 0 */ 0, 1, 11, 3, 7, 8, 9, 4, 5, 10,
+ /* 10 */ 11, 1, 11, 3, 2, 2, 2, 9,
+};
+#define YY_SHIFT_USE_DFLT (-1)
+#define YY_SHIFT_COUNT (7)
+#define YY_SHIFT_MIN (0)
+#define YY_SHIFT_MAX (14)
+static const signed char yy_shift_ofst[] = {
+ /* 0 */ 10, 14, 0, 14, 14, 3, 13, 12,
+};
+#define YY_REDUCE_USE_DFLT (-10)
+#define YY_REDUCE_COUNT (4)
+#define YY_REDUCE_MIN (-9)
+#define YY_REDUCE_MAX (8)
+static const signed char yy_reduce_ofst[] = {
+ /* 0 */ -3, -1, 8, 1, -9,
+};
+static const YYACTIONTYPE yy_default[] = {
+ /* 0 */ 25, 25, 25, 25, 25, 19, 23, 25, 17, 20,
+ /* 10 */ 22, 24, 21, 18, 16,
+};
+
+/* The next table maps tokens into fallback tokens. If a construct
+** like the following:
+**
+** %fallback ID X Y Z.
+**
+** appears in the grammar, then ID becomes a fallback token for X, Y,
+** and Z. Whenever one of the tokens X, Y, or Z is input to the parser
+** but it does not parse, the type of the token is changed to ID and
+** the parse is retried before an error is thrown.
+*/
+#ifdef YYFALLBACK
+static const YYCODETYPE yyFallback[] = {
+};
+#endif /* YYFALLBACK */
+
+/* The following structure represents a single element of the
+** parser's stack. Information stored includes:
+**
+** + The state number for the parser at this level of the stack.
+**
+** + The value of the token stored at this level of the stack.
+** (In other words, the "major" token.)
+**
+** + The semantic value stored at this level of the stack. This is
+** the information used by the action routines in the grammar.
+** It is sometimes called the "minor" token.
+*/
+struct yyStackEntry {
+ YYACTIONTYPE stateno; /* The state-number */
+ YYCODETYPE major; /* The major token value. This is the code
+ ** number for the token at this stack level */
+ YYMINORTYPE minor; /* The user-supplied minor token value. This
+ ** is the value of the token */
+};
+typedef struct yyStackEntry yyStackEntry;
+
+/* The state of the parser is completely contained in an instance of
+** the following structure */
+struct yyParser {
+ int yyidx; /* Index of top element in stack */
+#ifdef YYTRACKMAXSTACKDEPTH
+ int yyidxMax; /* Maximum value of yyidx */
+#endif
+ int yyerrcnt; /* Shifts left before out of the error */
+ ParseARG_SDECL /* A place to hold %extra_argument */
+#if YYSTACKDEPTH<=0
+ int yystksz; /* Current side of the stack */
+ yyStackEntry *yystack; /* The parser's stack */
+#else
+ yyStackEntry yystack[YYSTACKDEPTH]; /* The parser's stack */
+#endif
+};
+typedef struct yyParser yyParser;
+
+#ifndef NDEBUG
+#include <stdio.h>
+static FILE *yyTraceFILE = 0;
+static char *yyTracePrompt = 0;
+#endif /* NDEBUG */
+
+#ifndef NDEBUG
+/*
+** Turn parser tracing on by giving a stream to which to write the trace
+** and a prompt to preface each trace message. Tracing is turned off
+** by making either argument NULL
+**
+** Inputs:
+** <ul>
+** <li> A FILE* to which trace output should be written.
+** If NULL, then tracing is turned off.
+** <li> A prefix string written at the beginning of every
+** line of trace output. If NULL, then tracing is
+** turned off.
+** </ul>
+**
+** Outputs:
+** None.
+*/
+void ParseTrace(FILE *TraceFILE, char *zTracePrompt){
+ yyTraceFILE = TraceFILE;
+ yyTracePrompt = zTracePrompt;
+ if( yyTraceFILE==0 ) yyTracePrompt = 0;
+ else if( yyTracePrompt==0 ) yyTraceFILE = 0;
+}
+#endif /* NDEBUG */
+
+#ifndef NDEBUG
+/* For tracing shifts, the names of all terminals and nonterminals
+** are required. The following table supplies these names */
+static const char *const yyTokenName[] = {
+ "$", "INSUP", "TOKEN", "FROM",
+ "COMMA", "JOIN", "error", "prog",
+ "statements", "statement", "tabledefs", "tabledef",
+};
+#endif /* NDEBUG */
+
+#ifndef NDEBUG
+/* For tracing reduce actions, the names of all rules are required.
+*/
+static const char *const yyRuleName[] = {
+ /* 0 */ "prog ::= statements",
+ /* 1 */ "statements ::= statements statement",
+ /* 2 */ "statements ::= statement",
+ /* 3 */ "statement ::= INSUP TOKEN",
+ /* 4 */ "statement ::= FROM tabledefs",
+ /* 5 */ "tabledefs ::= tabledef",
+ /* 6 */ "tabledefs ::= tabledefs COMMA tabledef",
+ /* 7 */ "tabledefs ::= tabledefs JOIN tabledef",
+ /* 8 */ "tabledef ::= TOKEN",
+ /* 9 */ "tabledef ::= TOKEN TOKEN",
+};
+#endif /* NDEBUG */
+
+
+#if YYSTACKDEPTH<=0
+/*
+** Try to increase the size of the parser stack.
+*/
+static void yyGrowStack(yyParser *p){
+ int newSize;
+ yyStackEntry *pNew;
+
+ newSize = p->yystksz*2 + 100;
+ pNew = realloc(p->yystack, newSize*sizeof(pNew[0]));
+ if( pNew ){
+ p->yystack = pNew;
+ p->yystksz = newSize;
+#ifndef NDEBUG
+ if( yyTraceFILE ){
+ fprintf(yyTraceFILE,"%sStack grows to %d entries!\n",
+ yyTracePrompt, p->yystksz);
+ }
+#endif
+ }
+}
+#endif
+
+/*
+** This function allocates a new parser.
+** The only argument is a pointer to a function which works like
+** malloc.
+**
+** Inputs:
+** A pointer to the function used to allocate memory.
+**
+** Outputs:
+** A pointer to a parser. This pointer is used in subsequent calls
+** to Parse and ParseFree.
+*/
+void *ParseAlloc(void *(*mallocProc)(size_t)){
+ yyParser *pParser;
+ pParser = (yyParser*)(*mallocProc)( (size_t)sizeof(yyParser) );
+ if( pParser ){
+ pParser->yyidx = -1;
+#ifdef YYTRACKMAXSTACKDEPTH
+ pParser->yyidxMax = 0;
+#endif
+#if YYSTACKDEPTH<=0
+ pParser->yystack = NULL;
+ pParser->yystksz = 0;
+ yyGrowStack(pParser);
+#endif
+ }
+ return pParser;
+}
+
+/* The following function deletes the value associated with a
+** symbol. The symbol can be either a terminal or nonterminal.
+** "yymajor" is the symbol code, and "yypminor" is a pointer to
+** the value.
+*/
+static void yy_destructor(
+ yyParser *yypParser, /* The parser */
+ YYCODETYPE yymajor, /* Type code for object to destroy */
+ YYMINORTYPE *yypminor /* The object to be destroyed */
+){
+ ParseARG_FETCH;
+ switch( yymajor ){
+ /* Here is inserted the actions which take place when a
+ ** terminal or non-terminal is destroyed. This can happen
+ ** when the symbol is popped from the stack during a
+ ** reduce or during error processing or when a parser is
+ ** being destroyed before it is finished parsing.
+ **
+ ** Note: during a reduce, the only symbols destroyed are those
+ ** which appear on the RHS of the rule, but which are not used
+ ** inside the C code.
+ */
+ /* TERMINAL Destructor */
+ case 1: /* INSUP */
+ case 2: /* TOKEN */
+ case 3: /* FROM */
+ case 4: /* COMMA */
+ case 5: /* JOIN */
+{
+#line 14 "tsql.y"
+free((yypminor->yy0));
+#line 375 "tsql.c"
+}
+ break;
+ default: break; /* If no destructor action specified: do nothing */
+ }
+}
+
+/*
+** Pop the parser's stack once.
+**
+** If there is a destructor routine associated with the token which
+** is popped from the stack, then call it.
+**
+** Return the major token number for the symbol popped.
+*/
+static int yy_pop_parser_stack(yyParser *pParser){
+ YYCODETYPE yymajor;
+ yyStackEntry *yytos = &pParser->yystack[pParser->yyidx];
+
+ if( pParser->yyidx<0 ) return 0;
+#ifndef NDEBUG
+ if( yyTraceFILE && pParser->yyidx>=0 ){
+ fprintf(yyTraceFILE,"%sPopping %s\n",
+ yyTracePrompt,
+ yyTokenName[yytos->major]);
+ }
+#endif
+ yymajor = yytos->major;
+ yy_destructor(pParser, yymajor, &yytos->minor);
+ pParser->yyidx--;
+ return yymajor;
+}
+
+/*
+** Deallocate and destroy a parser. Destructors are all called for
+** all stack elements before shutting the parser down.
+**
+** Inputs:
+** <ul>
+** <li> A pointer to the parser. This should be a pointer
+** obtained from ParseAlloc.
+** <li> A pointer to a function used to reclaim memory obtained
+** from malloc.
+** </ul>
+*/
+void ParseFree(
+ void *p, /* The parser to be deleted */
+ void (*freeProc)(void*) /* Function used to reclaim memory */
+){
+ yyParser *pParser = (yyParser*)p;
+ if( pParser==0 ) return;
+ while( pParser->yyidx>=0 ) yy_pop_parser_stack(pParser);
+#if YYSTACKDEPTH<=0
+ free(pParser->yystack);
+#endif
+ (*freeProc)((void*)pParser);
+}
+
+/*
+** Return the peak depth of the stack for a parser.
+*/
+#ifdef YYTRACKMAXSTACKDEPTH
+int ParseStackPeak(void *p){
+ yyParser *pParser = (yyParser*)p;
+ return pParser->yyidxMax;
+}
+#endif
+
+/*
+** Find the appropriate action for a parser given the terminal
+** look-ahead token iLookAhead.
+**
+** If the look-ahead token is YYNOCODE, then check to see if the action is
+** independent of the look-ahead. If it is, return the action, otherwise
+** return YY_NO_ACTION.
+*/
+static int yy_find_shift_action(
+ yyParser *pParser, /* The parser */
+ YYCODETYPE iLookAhead /* The look-ahead token */
+){
+ int i;
+ int stateno = pParser->yystack[pParser->yyidx].stateno;
+
+ if( stateno>YY_SHIFT_COUNT
+ || (i = yy_shift_ofst[stateno])==YY_SHIFT_USE_DFLT ){
+ return yy_default[stateno];
+ }
+ assert( iLookAhead!=YYNOCODE );
+ i += iLookAhead;
+ if( i<0 || i>=YY_ACTTAB_COUNT || yy_lookahead[i]!=iLookAhead ){
+ if( iLookAhead>0 ){
+#ifdef YYFALLBACK
+ YYCODETYPE iFallback; /* Fallback token */
+ if( iLookAhead<sizeof(yyFallback)/sizeof(yyFallback[0])
+ && (iFallback = yyFallback[iLookAhead])!=0 ){
+#ifndef NDEBUG
+ if( yyTraceFILE ){
+ fprintf(yyTraceFILE, "%sFALLBACK %s => %s\n",
+ yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]);
+ }
+#endif
+ return yy_find_shift_action(pParser, iFallback);
+ }
+#endif
+#ifdef YYWILDCARD
+ {
+ int j = i - iLookAhead + YYWILDCARD;
+ if(
+#if YY_SHIFT_MIN+YYWILDCARD<0
+ j>=0 &&
+#endif
+#if YY_SHIFT_MAX+YYWILDCARD>=YY_ACTTAB_COUNT
+ j<YY_ACTTAB_COUNT &&
+#endif
+ yy_lookahead[j]==YYWILDCARD
+ ){
+#ifndef NDEBUG
+ if( yyTraceFILE ){
+ fprintf(yyTraceFILE, "%sWILDCARD %s => %s\n",
+ yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[YYWILDCARD]);
+ }
+#endif /* NDEBUG */
+ return yy_action[j];
+ }
+ }
+#endif /* YYWILDCARD */
+ }
+ return yy_default[stateno];
+ }else{
+ return yy_action[i];
+ }
+}
+
+/*
+** Find the appropriate action for a parser given the non-terminal
+** look-ahead token iLookAhead.
+**
+** If the look-ahead token is YYNOCODE, then check to see if the action is
+** independent of the look-ahead. If it is, return the action, otherwise
+** return YY_NO_ACTION.
+*/
+static int yy_find_reduce_action(
+ int stateno, /* Current state number */
+ YYCODETYPE iLookAhead /* The look-ahead token */
+){
+ int i;
+#ifdef YYERRORSYMBOL
+ if( stateno>YY_REDUCE_COUNT ){
+ return yy_default[stateno];
+ }
+#else
+ assert( stateno<=YY_REDUCE_COUNT );
+#endif
+ i = yy_reduce_ofst[stateno];
+ assert( i!=YY_REDUCE_USE_DFLT );
+ assert( iLookAhead!=YYNOCODE );
+ i += iLookAhead;
+#ifdef YYERRORSYMBOL
+ if( i<0 || i>=YY_ACTTAB_COUNT || yy_lookahead[i]!=iLookAhead ){
+ return yy_default[stateno];
+ }
+#else
+ assert( i>=0 && i<YY_ACTTAB_COUNT );
+ assert( yy_lookahead[i]==iLookAhead );
+#endif
+ return yy_action[i];
+}
+
+/*
+** The following routine is called if the stack overflows.
+*/
+static void yyStackOverflow(yyParser *yypParser, YYMINORTYPE *yypMinor){
+ ParseARG_FETCH;
+ yypParser->yyidx--;
+#ifndef NDEBUG
+ if( yyTraceFILE ){
+ fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt);
+ }
+#endif
+ while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
+ /* Here code is inserted which will execute if the parser
+ ** stack every overflows */
+ ParseARG_STORE; /* Suppress warning about unused %extra_argument var */
+}
+
+/*
+** Perform a shift action.
+*/
+static void yy_shift(
+ yyParser *yypParser, /* The parser to be shifted */
+ int yyNewState, /* The new state to shift in */
+ int yyMajor, /* The major token to shift in */
+ YYMINORTYPE *yypMinor /* Pointer to the minor token to shift in */
+){
+ yyStackEntry *yytos;
+ yypParser->yyidx++;
+#ifdef YYTRACKMAXSTACKDEPTH
+ if( yypParser->yyidx>yypParser->yyidxMax ){
+ yypParser->yyidxMax = yypParser->yyidx;
+ }
+#endif
+#if YYSTACKDEPTH>0
+ if( yypParser->yyidx>=YYSTACKDEPTH ){
+ yyStackOverflow(yypParser, yypMinor);
+ return;
+ }
+#else
+ if( yypParser->yyidx>=yypParser->yystksz ){
+ yyGrowStack(yypParser);
+ if( yypParser->yyidx>=yypParser->yystksz ){
+ yyStackOverflow(yypParser, yypMinor);
+ return;
+ }
+ }
+#endif
+ yytos = &yypParser->yystack[yypParser->yyidx];
+ yytos->stateno = (YYACTIONTYPE)yyNewState;
+ yytos->major = (YYCODETYPE)yyMajor;
+ yytos->minor = *yypMinor;
+#ifndef NDEBUG
+ if( yyTraceFILE && yypParser->yyidx>0 ){
+ int i;
+ fprintf(yyTraceFILE,"%sShift %d\n",yyTracePrompt,yyNewState);
+ fprintf(yyTraceFILE,"%sStack:",yyTracePrompt);
+ for(i=1; i<=yypParser->yyidx; i++)
+ fprintf(yyTraceFILE," %s",yyTokenName[yypParser->yystack[i].major]);
+ fprintf(yyTraceFILE,"\n");
+ }
+#endif
+}
+
+/* The following table contains information about every rule that
+** is used during the reduce.
+*/
+static const struct {
+ YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */
+ unsigned char nrhs; /* Number of right-hand side symbols in the rule */
+} yyRuleInfo[] = {
+ { 7, 1 },
+ { 8, 2 },
+ { 8, 1 },
+ { 9, 2 },
+ { 9, 2 },
+ { 10, 1 },
+ { 10, 3 },
+ { 10, 3 },
+ { 11, 1 },
+ { 11, 2 },
+};
+
+static void yy_accept(yyParser*); /* Forward Declaration */
+
+/*
+** Perform a reduce action and the shift that must immediately
+** follow the reduce.
+*/
+static void yy_reduce(
+ yyParser *yypParser, /* The parser */
+ int yyruleno /* Number of the rule by which to reduce */
+){
+ int yygoto; /* The next state */
+ int yyact; /* The next action */
+ YYMINORTYPE yygotominor; /* The LHS of the rule reduced */
+ yyStackEntry *yymsp; /* The top of the parser's stack */
+ int yysize; /* Amount to pop the stack */
+ ParseARG_FETCH;
+ yymsp = &yypParser->yystack[yypParser->yyidx];
+#ifndef NDEBUG
+ if( yyTraceFILE && yyruleno>=0
+ && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){
+ fprintf(yyTraceFILE, "%sReduce [%s].\n", yyTracePrompt,
+ yyRuleName[yyruleno]);
+ }
+#endif /* NDEBUG */
+
+ /* Silence complaints from purify about yygotominor being uninitialized
+ ** in some cases when it is copied into the stack after the following
+ ** switch. yygotominor is uninitialized when a rule reduces that does
+ ** not set the value of its left-hand side nonterminal. Leaving the
+ ** value of the nonterminal uninitialized is utterly harmless as long
+ ** as the value is never used. So really the only thing this code
+ ** accomplishes is to quieten purify.
+ **
+ ** 2007-01-16: The wireshark project (www.wireshark.org) reports that
+ ** without this code, their parser segfaults. I'm not sure what there
+ ** parser is doing to make this happen. This is the second bug report
+ ** from wireshark this week. Clearly they are stressing Lemon in ways
+ ** that it has not been previously stressed... (SQLite ticket #2172)
+ */
+ /*memset(&yygotominor, 0, sizeof(yygotominor));*/
+ yygotominor = yyzerominor;
+
+
+ switch( yyruleno ){
+ /* Beginning here are the reduction cases. A typical example
+ ** follows:
+ ** case 0:
+ ** #line <lineno> <grammarfile>
+ ** { ... } // User supplied code
+ ** #line <lineno> <thisfile>
+ ** break;
+ */
+ case 3: /* statement ::= INSUP TOKEN */
+#line 19 "tsql.y"
+{addTableDefNode(yymsp[0].minor.yy0, yymsp[0].minor.yy0);free(yymsp[0].minor.yy0); yy_destructor(yypParser,1,&yymsp[-1].minor);
+}
+#line 681 "tsql.c"
+ break;
+ case 4: /* statement ::= FROM tabledefs */
+#line 20 "tsql.y"
+{
+ yy_destructor(yypParser,3,&yymsp[-1].minor);
+}
+#line 688 "tsql.c"
+ break;
+ case 6: /* tabledefs ::= tabledefs COMMA tabledef */
+#line 22 "tsql.y"
+{
+ yy_destructor(yypParser,4,&yymsp[-1].minor);
+}
+#line 695 "tsql.c"
+ break;
+ case 7: /* tabledefs ::= tabledefs JOIN tabledef */
+#line 23 "tsql.y"
+{
+ yy_destructor(yypParser,5,&yymsp[-1].minor);
+}
+#line 702 "tsql.c"
+ break;
+ case 8: /* tabledef ::= TOKEN */
+#line 24 "tsql.y"
+{addTableDefNode(yymsp[0].minor.yy0, yymsp[0].minor.yy0); free(yymsp[0].minor.yy0);}
+#line 707 "tsql.c"
+ break;
+ case 9: /* tabledef ::= TOKEN TOKEN */
+#line 25 "tsql.y"
+{addTableDefNode(yymsp[-1].minor.yy0, yymsp[0].minor.yy0); free(yymsp[-1].minor.yy0); free(yymsp[0].minor.yy0);}
+#line 712 "tsql.c"
+ break;
+ default:
+ /* (0) prog ::= statements */ yytestcase(yyruleno==0);
+ /* (1) statements ::= statements statement */ yytestcase(yyruleno==1);
+ /* (2) statements ::= statement */ yytestcase(yyruleno==2);
+ /* (5) tabledefs ::= tabledef */ yytestcase(yyruleno==5);
+ break;
+ };
+ yygoto = yyRuleInfo[yyruleno].lhs;
+ yysize = yyRuleInfo[yyruleno].nrhs;
+ yypParser->yyidx -= yysize;
+ yyact = yy_find_reduce_action(yymsp[-yysize].stateno,(YYCODETYPE)yygoto);
+ if( yyact < YYNSTATE ){
+#ifdef NDEBUG
+ /* If we are not debugging and the reduce action popped at least
+ ** one element off the stack, then we can push the new element back
+ ** onto the stack here, and skip the stack overflow test in yy_shift().
+ ** That gives a significant speed improvement. */
+ if( yysize ){
+ yypParser->yyidx++;
+ yymsp -= yysize-1;
+ yymsp->stateno = (YYACTIONTYPE)yyact;
+ yymsp->major = (YYCODETYPE)yygoto;
+ yymsp->minor = yygotominor;
+ }else
+#endif
+ {
+ yy_shift(yypParser,yyact,yygoto,&yygotominor);
+ }
+ }else{
+ assert( yyact == YYNSTATE + YYNRULE + 1 );
+ yy_accept(yypParser);
+ }
+}
+
+/*
+** The following code executes when the parse fails
+*/
+#ifndef YYNOERRORRECOVERY
+static void yy_parse_failed(
+ yyParser *yypParser /* The parser */
+){
+ ParseARG_FETCH;
+#ifndef NDEBUG
+ if( yyTraceFILE ){
+ fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt);
+ }
+#endif
+ while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
+ /* Here code is inserted which will be executed whenever the
+ ** parser fails */
+#line 9 "tsql.y"
+
+ //Actually we don't expect everything to parse.
+#line 767 "tsql.c"
+ ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */
+}
+#endif /* YYNOERRORRECOVERY */
+
+/*
+** The following code executes when a syntax error first occurs.
+*/
+static void yy_syntax_error(
+ yyParser *yypParser, /* The parser */
+ int yymajor, /* The major type of the error token */
+ YYMINORTYPE yyminor /* The minor type of the error token */
+){
+ ParseARG_FETCH;
+#define TOKEN (yyminor.yy0)
+ ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */
+}
+
+/*
+** The following is executed when the parser accepts
+*/
+static void yy_accept(
+ yyParser *yypParser /* The parser */
+){
+ ParseARG_FETCH;
+#ifndef NDEBUG
+ if( yyTraceFILE ){
+ fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt);
+ }
+#endif
+ while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser);
+ /* Here code is inserted which will be executed whenever the
+ ** parser accepts */
+ ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */
+}
+
+/* The main parser program.
+** The first argument is a pointer to a structure obtained from
+** "ParseAlloc" which describes the current state of the parser.
+** The second argument is the major token number. The third is
+** the minor token. The fourth optional argument is whatever the
+** user wants (and specified in the grammar) and is available for
+** use by the action routines.
+**
+** Inputs:
+** <ul>
+** <li> A pointer to the parser (an opaque structure.)
+** <li> The major token number.
+** <li> The minor token number.
+** <li> An option argument of a grammar-specified type.
+** </ul>
+**
+** Outputs:
+** None.
+*/
+void Parse(
+ void *yyp, /* The parser */
+ int yymajor, /* The major token code number */
+ ParseTOKENTYPE yyminor /* The value for the token */
+ ParseARG_PDECL /* Optional %extra_argument parameter */
+){
+ YYMINORTYPE yyminorunion;
+ int yyact; /* The parser action. */
+ int yyendofinput; /* True if we are at the end of input */
+#ifdef YYERRORSYMBOL
+ int yyerrorhit = 0; /* True if yymajor has invoked an error */
+#endif
+ yyParser *yypParser; /* The parser */
+
+ /* (re)initialize the parser, if necessary */
+ yypParser = (yyParser*)yyp;
+ if( yypParser->yyidx<0 ){
+#if YYSTACKDEPTH<=0
+ if( yypParser->yystksz <=0 ){
+ /*memset(&yyminorunion, 0, sizeof(yyminorunion));*/
+ yyminorunion = yyzerominor;
+ yyStackOverflow(yypParser, &yyminorunion);
+ return;
+ }
+#endif
+ yypParser->yyidx = 0;
+ yypParser->yyerrcnt = -1;
+ yypParser->yystack[0].stateno = 0;
+ yypParser->yystack[0].major = 0;
+ }
+ yyminorunion.yy0 = yyminor;
+ yyendofinput = (yymajor==0);
+ ParseARG_STORE;
+
+#ifndef NDEBUG
+ if( yyTraceFILE ){
+ fprintf(yyTraceFILE,"%sInput %s\n",yyTracePrompt,yyTokenName[yymajor]);
+ }
+#endif
+
+ do{
+ yyact = yy_find_shift_action(yypParser,(YYCODETYPE)yymajor);
+ if( yyact<YYNSTATE ){
+ assert( !yyendofinput ); /* Impossible to shift the $ token */
+ yy_shift(yypParser,yyact,yymajor,&yyminorunion);
+ yypParser->yyerrcnt--;
+ yymajor = YYNOCODE;
+ }else if( yyact < YYNSTATE + YYNRULE ){
+ yy_reduce(yypParser,yyact-YYNSTATE);
+ }else{
+ assert( yyact == YY_ERROR_ACTION );
+#ifdef YYERRORSYMBOL
+ int yymx;
+#endif
+#ifndef NDEBUG
+ if( yyTraceFILE ){
+ fprintf(yyTraceFILE,"%sSyntax Error!\n",yyTracePrompt);
+ }
+#endif
+#ifdef YYERRORSYMBOL
+ /* A syntax error has occurred.
+ ** The response to an error depends upon whether or not the
+ ** grammar defines an error token "ERROR".
+ **
+ ** This is what we do if the grammar does define ERROR:
+ **
+ ** * Call the %syntax_error function.
+ **
+ ** * Begin popping the stack until we enter a state where
+ ** it is legal to shift the error symbol, then shift
+ ** the error symbol.
+ **
+ ** * Set the error count to three.
+ **
+ ** * Begin accepting and shifting new tokens. No new error
+ ** processing will occur until three tokens have been
+ ** shifted successfully.
+ **
+ */
+ if( yypParser->yyerrcnt<0 ){
+ yy_syntax_error(yypParser,yymajor,yyminorunion);
+ }
+ yymx = yypParser->yystack[yypParser->yyidx].major;
+ if( yymx==YYERRORSYMBOL || yyerrorhit ){
+#ifndef NDEBUG
+ if( yyTraceFILE ){
+ fprintf(yyTraceFILE,"%sDiscard input token %s\n",
+ yyTracePrompt,yyTokenName[yymajor]);
+ }
+#endif
+ yy_destructor(yypParser, (YYCODETYPE)yymajor,&yyminorunion);
+ yymajor = YYNOCODE;
+ }else{
+ while(
+ yypParser->yyidx >= 0 &&
+ yymx != YYERRORSYMBOL &&
+ (yyact = yy_find_reduce_action(
+ yypParser->yystack[yypParser->yyidx].stateno,
+ YYERRORSYMBOL)) >= YYNSTATE
+ ){
+ yy_pop_parser_stack(yypParser);
+ }
+ if( yypParser->yyidx < 0 || yymajor==0 ){
+ yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
+ yy_parse_failed(yypParser);
+ yymajor = YYNOCODE;
+ }else if( yymx!=YYERRORSYMBOL ){
+ YYMINORTYPE u2;
+ u2.YYERRSYMDT = 0;
+ yy_shift(yypParser,yyact,YYERRORSYMBOL,&u2);
+ }
+ }
+ yypParser->yyerrcnt = 3;
+ yyerrorhit = 1;
+#elif defined(YYNOERRORRECOVERY)
+ /* If the YYNOERRORRECOVERY macro is defined, then do not attempt to
+ ** do any kind of error recovery. Instead, simply invoke the syntax
+ ** error routine and continue going as if nothing had happened.
+ **
+ ** Applications can set this macro (for example inside %include) if
+ ** they intend to abandon the parse upon the first syntax error seen.
+ */
+ yy_syntax_error(yypParser,yymajor,yyminorunion);
+ yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
+ yymajor = YYNOCODE;
+
+#else /* YYERRORSYMBOL is not defined */
+ /* This is what we do if the grammar does not define ERROR:
+ **
+ ** * Report an error message, and throw away the input token.
+ **
+ ** * If the input token is $, then fail the parse.
+ **
+ ** As before, subsequent error messages are suppressed until
+ ** three input tokens have been successfully shifted.
+ */
+ if( yypParser->yyerrcnt<=0 ){
+ yy_syntax_error(yypParser,yymajor,yyminorunion);
+ }
+ yypParser->yyerrcnt = 3;
+ yy_destructor(yypParser,(YYCODETYPE)yymajor,&yyminorunion);
+ if( yyendofinput ){
+ yy_parse_failed(yypParser);
+ }
+ yymajor = YYNOCODE;
+#endif
+ }
+ }while( yymajor!=YYNOCODE && yypParser->yyidx>=0 );
+ return;
+}
diff --git a/src/sqsh_parser/tsql.h b/src/sqsh_parser/tsql.h
new file mode 100644
index 0000000..690892d
--- /dev/null
+++ b/src/sqsh_parser/tsql.h
@@ -0,0 +1,5 @@
+#define INSUP 1
+#define TOKEN 2
+#define FROM 3
+#define COMMA 4
+#define JOIN 5
diff --git a/src/sqsh_parser/tsql.l b/src/sqsh_parser/tsql.l
new file mode 100644
index 0000000..911a3e7
--- /dev/null
+++ b/src/sqsh_parser/tsql.l
@@ -0,0 +1,69 @@
+%{
+#include "tsql.h"
+
+#define KW(w) {return w;}
+
+%}
+
+%option noyywrap
+%option warn
+%option 8bit
+%s INFROM
+%s INDML
+
+
+alpha [A-Za-zäöüß_]
+anum [A-Za-z0-9_äöüß_\.\-]
+anumsp [A-Za-z0-9_äöüß_ \.\-]
+ws [ \t\r\n]
+
+%%
+
+<INITIAL>from/{ws}+ {BEGIN INFROM; KW(FROM);}
+<INITIAL>(?i:insert|update|delete)/{ws}+ {BEGIN INDML; KW(INSUP);}
+<INITIAL>(?i:insert{ws}+into)/{ws}+ {BEGIN INDML; KW(INSUP);}
+<INITIAL,INFROM>(?i:join)/{ws}+ {BEGIN INFROM; KW(JOIN);}
+<INFROM>(?i:inner|left|right|outer)/{ws}+ {BEGIN INITIAL;}
+<INFROM>(?i:where|on)/{ws}+ {BEGIN INITIAL;}
+<INFROM>{alpha}{anum}* {KW(TOKEN);}
+<INFROM>\"{alpha}{anumsp}*\" {KW(TOKEN);}
+<INFROM>\[{alpha}{anumsp}*\] {KW(TOKEN);}
+<INDML>{alpha}{anum}* {BEGIN INITIAL; KW(TOKEN);}
+<INDML>\"{alpha}{anumsp}*\" {BEGIN INITIAL; KW(TOKEN);}
+<INDML>\[{alpha}{anumsp}*\] {BEGIN INITIAL; KW(TOKEN);}
+<INFROM>, {KW(COMMA);}
+<INFROM>"(" {BEGIN INITIAL;}
+. ;
+[\n] ;
+
+
+%%
+
+int testlex(char *buffer)
+{
+ yy_scan_string(buffer);
+ int rl;
+
+ while ((rl=yylex())!=0){
+ printf("Token: %i yytext: %s\n", rl, yytext);
+ }
+ yylex_destroy();
+ return 0;
+}
+
+extern void *ParseAlloc(void *(*mallocProc)(size_t));
+extern void ParseFree(void *p, void (*freeProc)(void*));
+extern void Parse(void *yyp, int yymajor, void* yyminor);
+void parseSql(char* sql) {
+ int lr;
+ void* pParser = ParseAlloc(malloc);
+
+ yy_scan_string(sql);
+
+ while ((lr=yylex())!=0){
+ Parse(pParser, lr, strdup(yytext));
+ }
+ Parse(pParser, 0, NULL);
+ ParseFree(pParser, free);
+ yylex_destroy();
+}
diff --git a/src/sqsh_parser/tsql.y b/src/sqsh_parser/tsql.y
new file mode 100644
index 0000000..55e345b
--- /dev/null
+++ b/src/sqsh_parser/tsql.y
@@ -0,0 +1,25 @@
+%include {
+ #include <string.h>
+ #include <assert.h>
+ #include <stdlib.h>
+
+ #include "sqsh_parser.h"
+}
+
+%parse_failure {
+ //Actually we don't expect everything to parse.
+}
+
+%token_type {char*}
+%token_destructor {free($$);}
+
+prog ::= statements.
+statements ::= statements statement.
+statements ::= statement.
+statement ::= INSUP TOKEN(B). {addTableDefNode(B, B);free(B);}
+statement ::= FROM tabledefs.
+tabledefs ::= tabledef.
+tabledefs ::= tabledefs COMMA tabledef.
+tabledefs ::= tabledefs JOIN tabledef. // Right, "on"-clauses are filtered by the lexer.
+tabledef ::= TOKEN(B). {addTableDefNode(B, B); free(B);}
+tabledef ::= TOKEN(B) TOKEN(C). {addTableDefNode(B, C); free(B); free(C);}
diff --git a/src/sqsh_parser/tsql.yy.c b/src/sqsh_parser/tsql.yy.c
new file mode 100644
index 0000000..0c30655
--- /dev/null
+++ b/src/sqsh_parser/tsql.yy.c
@@ -0,0 +1,2097 @@
+#line 2 "tsql.yy.c"
+
+#line 4 "tsql.yy.c"
+
+#define YY_INT_ALIGNED short int
+
+/* A lexical scanner generated by flex */
+
+#define FLEX_SCANNER
+#define YY_FLEX_MAJOR_VERSION 2
+#define YY_FLEX_MINOR_VERSION 5
+#define YY_FLEX_SUBMINOR_VERSION 35
+#if YY_FLEX_SUBMINOR_VERSION > 0
+#define FLEX_BETA
+#endif
+
+/* First, we deal with platform-specific or compiler-specific issues. */
+
+/* begin standard C headers. */
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <stdlib.h>
+
+/* end standard C headers. */
+
+/* flex integer type definitions */
+
+#ifndef FLEXINT_H
+#define FLEXINT_H
+
+/* C99 systems have <inttypes.h>. Non-C99 systems may or may not. */
+
+#if defined (__STDC_VERSION__) && __STDC_VERSION__ >= 199901L
+
+/* C99 says to define __STDC_LIMIT_MACROS before including stdint.h,
+ * if you want the limit (max/min) macros for int types.
+ */
+#ifndef __STDC_LIMIT_MACROS
+#define __STDC_LIMIT_MACROS 1
+#endif
+
+#include <inttypes.h>
+typedef int8_t flex_int8_t;
+typedef uint8_t flex_uint8_t;
+typedef int16_t flex_int16_t;
+typedef uint16_t flex_uint16_t;
+typedef int32_t flex_int32_t;
+typedef uint32_t flex_uint32_t;
+#else
+typedef signed char flex_int8_t;
+typedef short int flex_int16_t;
+typedef int flex_int32_t;
+typedef unsigned char flex_uint8_t;
+typedef unsigned short int flex_uint16_t;
+typedef unsigned int flex_uint32_t;
+#endif /* ! C99 */
+
+/* Limits of integral types. */
+#ifndef INT8_MIN
+#define INT8_MIN (-128)
+#endif
+#ifndef INT16_MIN
+#define INT16_MIN (-32767-1)
+#endif
+#ifndef INT32_MIN
+#define INT32_MIN (-2147483647-1)
+#endif
+#ifndef INT8_MAX
+#define INT8_MAX (127)
+#endif
+#ifndef INT16_MAX
+#define INT16_MAX (32767)
+#endif
+#ifndef INT32_MAX
+#define INT32_MAX (2147483647)
+#endif
+#ifndef UINT8_MAX
+#define UINT8_MAX (255U)
+#endif
+#ifndef UINT16_MAX
+#define UINT16_MAX (65535U)
+#endif
+#ifndef UINT32_MAX
+#define UINT32_MAX (4294967295U)
+#endif
+
+#endif /* ! FLEXINT_H */
+
+#ifdef __cplusplus
+
+/* The "const" storage-class-modifier is valid. */
+#define YY_USE_CONST
+
+#else /* ! __cplusplus */
+
+/* C99 requires __STDC__ to be defined as 1. */
+#if defined (__STDC__)
+
+#define YY_USE_CONST
+
+#endif /* defined (__STDC__) */
+#endif /* ! __cplusplus */
+
+#ifdef YY_USE_CONST
+#define yyconst const
+#else
+#define yyconst
+#endif
+
+/* Returned upon end-of-file. */
+#define YY_NULL 0
+
+/* Promotes a possibly negative, possibly signed char to an unsigned
+ * integer for use as an array index. If the signed char is negative,
+ * we want to instead treat it as an 8-bit unsigned char, hence the
+ * double cast.
+ */
+#define YY_SC_TO_UI(c) ((unsigned int) (unsigned char) c)
+
+/* Enter a start condition. This macro really ought to take a parameter,
+ * but we do it the disgusting crufty way forced on us by the ()-less
+ * definition of BEGIN.
+ */
+#define BEGIN (yy_start) = 1 + 2 *
+
+/* Translate the current start state into a value that can be later handed
+ * to BEGIN to return to the state. The YYSTATE alias is for lex
+ * compatibility.
+ */
+#define YY_START (((yy_start) - 1) / 2)
+#define YYSTATE YY_START
+
+/* Action number for EOF rule of a given start state. */
+#define YY_STATE_EOF(state) (YY_END_OF_BUFFER + state + 1)
+
+/* Special action meaning "start processing a new file". */
+#define YY_NEW_FILE yyrestart(yyin )
+
+#define YY_END_OF_BUFFER_CHAR 0
+
+/* Size of default input buffer. */
+#ifndef YY_BUF_SIZE
+#define YY_BUF_SIZE 16384
+#endif
+
+/* The state buf must be large enough to hold one state per character in the main buffer.
+ */
+#define YY_STATE_BUF_SIZE ((YY_BUF_SIZE + 2) * sizeof(yy_state_type))
+
+#ifndef YY_TYPEDEF_YY_BUFFER_STATE
+#define YY_TYPEDEF_YY_BUFFER_STATE
+typedef struct yy_buffer_state *YY_BUFFER_STATE;
+#endif
+
+extern int yyleng;
+
+extern FILE *yyin, *yyout;
+
+#define EOB_ACT_CONTINUE_SCAN 0
+#define EOB_ACT_END_OF_FILE 1
+#define EOB_ACT_LAST_MATCH 2
+
+ #define YY_LESS_LINENO(n)
+
+/* Return all but the first "n" matched characters back to the input stream. */
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ *yy_cp = (yy_hold_char); \
+ YY_RESTORE_YY_MORE_OFFSET \
+ (yy_c_buf_p) = yy_cp = yy_bp + yyless_macro_arg - YY_MORE_ADJ; \
+ YY_DO_BEFORE_ACTION; /* set up yytext again */ \
+ } \
+ while ( 0 )
+
+#define unput(c) yyunput( c, (yytext_ptr) )
+
+#ifndef YY_TYPEDEF_YY_SIZE_T
+#define YY_TYPEDEF_YY_SIZE_T
+typedef size_t yy_size_t;
+#endif
+
+#ifndef YY_STRUCT_YY_BUFFER_STATE
+#define YY_STRUCT_YY_BUFFER_STATE
+struct yy_buffer_state
+ {
+ FILE *yy_input_file;
+
+ char *yy_ch_buf; /* input buffer */
+ char *yy_buf_pos; /* current position in input buffer */
+
+ /* Size of input buffer in bytes, not including room for EOB
+ * characters.
+ */
+ yy_size_t yy_buf_size;
+
+ /* Number of characters read into yy_ch_buf, not including EOB
+ * characters.
+ */
+ int yy_n_chars;
+
+ /* Whether we "own" the buffer - i.e., we know we created it,
+ * and can realloc() it to grow it, and should free() it to
+ * delete it.
+ */
+ int yy_is_our_buffer;
+
+ /* Whether this is an "interactive" input source; if so, and
+ * if we're using stdio for input, then we want to use getc()
+ * instead of fread(), to make sure we stop fetching input after
+ * each newline.
+ */
+ int yy_is_interactive;
+
+ /* Whether we're considered to be at the beginning of a line.
+ * If so, '^' rules will be active on the next match, otherwise
+ * not.
+ */
+ int yy_at_bol;
+
+ int yy_bs_lineno; /**< The line count. */
+ int yy_bs_column; /**< The column count. */
+
+ /* Whether to try to fill the input buffer when we reach the
+ * end of it.
+ */
+ int yy_fill_buffer;
+
+ int yy_buffer_status;
+
+#define YY_BUFFER_NEW 0
+#define YY_BUFFER_NORMAL 1
+ /* When an EOF's been seen but there's still some text to process
+ * then we mark the buffer as YY_EOF_PENDING, to indicate that we
+ * shouldn't try reading from the input source any more. We might
+ * still have a bunch of tokens to match, though, because of
+ * possible backing-up.
+ *
+ * When we actually see the EOF, we change the status to "new"
+ * (via yyrestart()), so that the user can continue scanning by
+ * just pointing yyin at a new input file.
+ */
+#define YY_BUFFER_EOF_PENDING 2
+
+ };
+#endif /* !YY_STRUCT_YY_BUFFER_STATE */
+
+/* Stack of input buffers. */
+static size_t yy_buffer_stack_top = 0; /**< index of top of stack. */
+static size_t yy_buffer_stack_max = 0; /**< capacity of stack. */
+static YY_BUFFER_STATE * yy_buffer_stack = 0; /**< Stack as an array. */
+
+/* We provide macros for accessing buffer states in case in the
+ * future we want to put the buffer states in a more general
+ * "scanner state".
+ *
+ * Returns the top of the stack, or NULL.
+ */
+#define YY_CURRENT_BUFFER ( (yy_buffer_stack) \
+ ? (yy_buffer_stack)[(yy_buffer_stack_top)] \
+ : NULL)
+
+/* Same as previous macro, but useful when we know that the buffer stack is not
+ * NULL or when we need an lvalue. For internal use only.
+ */
+#define YY_CURRENT_BUFFER_LVALUE (yy_buffer_stack)[(yy_buffer_stack_top)]
+
+/* yy_hold_char holds the character lost when yytext is formed. */
+static char yy_hold_char;
+static int yy_n_chars; /* number of characters read into yy_ch_buf */
+int yyleng;
+
+/* Points to current character in buffer. */
+static char *yy_c_buf_p = (char *) 0;
+static int yy_init = 0; /* whether we need to initialize */
+static int yy_start = 0; /* start state number */
+
+/* Flag which is used to allow yywrap()'s to do buffer switches
+ * instead of setting up a fresh yyin. A bit of a hack ...
+ */
+static int yy_did_buffer_switch_on_eof;
+
+void yyrestart (FILE *input_file );
+void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer );
+YY_BUFFER_STATE yy_create_buffer (FILE *file,int size );
+void yy_delete_buffer (YY_BUFFER_STATE b );
+void yy_flush_buffer (YY_BUFFER_STATE b );
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer );
+void yypop_buffer_state (void );
+
+static void yyensure_buffer_stack (void );
+static void yy_load_buffer_state (void );
+static void yy_init_buffer (YY_BUFFER_STATE b,FILE *file );
+
+#define YY_FLUSH_BUFFER yy_flush_buffer(YY_CURRENT_BUFFER )
+
+YY_BUFFER_STATE yy_scan_buffer (char *base,yy_size_t size );
+YY_BUFFER_STATE yy_scan_string (yyconst char *yy_str );
+YY_BUFFER_STATE yy_scan_bytes (yyconst char *bytes,int len );
+
+void *yyalloc (yy_size_t );
+void *yyrealloc (void *,yy_size_t );
+void yyfree (void * );
+
+#define yy_new_buffer yy_create_buffer
+
+#define yy_set_interactive(is_interactive) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){ \
+ yyensure_buffer_stack (); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ yy_create_buffer(yyin,YY_BUF_SIZE ); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_is_interactive = is_interactive; \
+ }
+
+#define yy_set_bol(at_bol) \
+ { \
+ if ( ! YY_CURRENT_BUFFER ){\
+ yyensure_buffer_stack (); \
+ YY_CURRENT_BUFFER_LVALUE = \
+ yy_create_buffer(yyin,YY_BUF_SIZE ); \
+ } \
+ YY_CURRENT_BUFFER_LVALUE->yy_at_bol = at_bol; \
+ }
+
+#define YY_AT_BOL() (YY_CURRENT_BUFFER_LVALUE->yy_at_bol)
+
+/* Begin user sect3 */
+
+#define yywrap(n) 1
+#define YY_SKIP_YYWRAP
+
+typedef unsigned char YY_CHAR;
+
+FILE *yyin = (FILE *) 0, *yyout = (FILE *) 0;
+
+typedef int yy_state_type;
+
+extern int yylineno;
+
+int yylineno = 1;
+
+extern char *yytext;
+#define yytext_ptr yytext
+
+static yy_state_type yy_get_previous_state (void );
+static yy_state_type yy_try_NUL_trans (yy_state_type current_state );
+static int yy_get_next_buffer (void );
+static void yy_fatal_error (yyconst char msg[] );
+
+/* Done after the current pattern has been matched and before the
+ * corresponding action - sets up yytext.
+ */
+#define YY_DO_BEFORE_ACTION \
+ (yytext_ptr) = yy_bp; \
+ yyleng = (size_t) (yy_cp - yy_bp); \
+ (yy_hold_char) = *yy_cp; \
+ *yy_cp = '\0'; \
+ (yy_c_buf_p) = yy_cp;
+
+#define YY_NUM_RULES 17
+#define YY_END_OF_BUFFER 18
+/* This struct is not used in this scanner,
+ but its presence is necessary. */
+struct yy_trans_info
+ {
+ flex_int32_t yy_verify;
+ flex_int32_t yy_nxt;
+ };
+static yyconst flex_int16_t yy_acclist[100] =
+ { 0,
+ 18, 15, 17, 16, 17, 15, 17, 15, 17, 15,
+ 17, 15, 17, 15, 17, 15, 17, 14, 15, 17,
+ 13, 15, 17, 7, 15, 17, 7, 15, 17, 7,
+ 15, 17, 7, 15, 17, 7, 15, 17, 7, 15,
+ 17, 7, 15, 17, 15, 17, 15, 17, 10, 15,
+ 17, 15, 17, 7, 7, 7, 7, 7,16390, 7,
+ 7, 7, 10, 8, 7, 7, 7, 8198, 7, 7,
+ 7, 9, 11, 12, 7, 7, 7,16389, 7, 7,
+ 7, 4, 1, 7,16389, 8197, 7,16389, 7,16389,
+ 7,16390,16386,16386,16386, 8194, 8194,16387, 8195
+
+ } ;
+
+static yyconst flex_int16_t yy_accept[100] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 2, 4, 6,
+ 8, 10, 12, 14, 16, 18, 21, 24, 27, 30,
+ 33, 36, 39, 42, 45, 47, 49, 52, 54, 54,
+ 54, 54, 54, 54, 54, 55, 56, 57, 58, 60,
+ 61, 62, 63, 63, 63, 64, 64, 64, 64, 64,
+ 64, 64, 64, 65, 66, 67, 68, 69, 70, 71,
+ 72, 72, 73, 73, 74, 74, 75, 75, 75, 75,
+ 75, 75, 76, 77, 79, 80, 81, 82, 82, 82,
+ 83, 83, 84, 86, 87, 89, 91, 93, 94, 95,
+ 96, 97, 98, 98, 98, 98, 99, 100, 100
+
+ } ;
+
+static yyconst flex_int32_t yy_meta[257] =
+ { 0,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 2, 1, 3, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 4, 4, 1, 4, 4, 4,
+ 4, 4, 4, 4, 4, 4, 4, 1, 1, 1,
+ 1, 1, 1, 1, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 1, 1, 6, 1, 5, 1, 5, 5, 5, 5,
+
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 5, 1,
+ 1, 1, 1, 5, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 5, 1, 1, 1, 1, 1, 5, 1, 1,
+ 1, 1, 1, 1, 5, 1, 1, 1, 1, 1,
+
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
+ 1, 1, 1, 1, 1, 7
+ } ;
+
+static yyconst flex_int16_t yy_base[110] =
+ { 0,
+ 0, 7, 115, 0, 301, 0, 161, 525, 525, 0,
+ 0, 0, 2, 46, 0, 525, 525, 0, 5, 5,
+ 2, 9, 3, 0, 0, 0, 0, 0, 10, 5,
+ 16, 22, 47, 123, 0, 13, 22, 26, 2, 13,
+ 27, 30, 63, 120, 0, 60, 63, 64, 56, 70,
+ 43, 117, 525, 67, 59, 54, 9, 70, 68, 59,
+ 57, 525, 114, 525, 0, 525, 58, 61, 11, 60,
+ 16, 63, 18, 23, 64, 63, 138, 139, 125, 29,
+ 142, 235, 237, 243, 245, 250, 252, 263, 276, 281,
+ 283, 289, 160, 165, 172, 291, 296, 525, 496, 3,
+
+ 499, 2, 1, 501, 0, 505, 509, 514, 518
+ } ;
+
+static yyconst flex_int16_t yy_def[110] =
+ { 0,
+ 99, 99, 99, 3, 99, 5, 98, 98, 98, 98,
+ 98, 98, 98, 98, 100, 98, 98, 101, 101, 101,
+ 101, 101, 101, 101, 102, 103, 104, 105, 98, 98,
+ 98, 98, 98, 106, 101, 101, 101, 101, 101, 101,
+ 101, 101, 107, 108, 104, 109, 98, 98, 98, 98,
+ 98, 106, 98, 101, 101, 101, 98, 101, 101, 101,
+ 107, 98, 108, 98, 109, 98, 98, 98, 98, 98,
+ 98, 101, 101, 101, 101, 101, 101, 98, 98, 98,
+ 98, 98, 101, 98, 101, 101, 101, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 0, 98, 98,
+
+ 98, 98, 98, 98, 98, 98, 98, 98, 98
+ } ;
+
+static yyconst flex_int16_t yy_nxt[782] =
+ { 0,
+ 98, 98, 98, 98, 46, 44, 43, 34, 98, 9,
+ 57, 57, 98, 98, 57, 98, 9, 57, 57, 80,
+ 80, 57, 98, 80, 82, 82, 80, 80, 82, 98,
+ 80, 84, 84, 57, 98, 84, 98, 80, 80, 98,
+ 57, 80, 80, 98, 98, 98, 98, 82, 98, 80,
+ 98, 98, 98, 98, 84, 98, 98, 98, 98, 98,
+ 80, 98, 98, 98, 98, 98, 98, 10, 29, 98,
+ 38, 42, 11, 12, 10, 41, 98, 30, 31, 11,
+ 12, 32, 36, 37, 13, 47, 39, 48, 49, 50,
+ 54, 13, 66, 40, 55, 56, 58, 59, 60, 10,
+
+ 29, 14, 38, 42, 11, 12, 10, 41, 14, 30,
+ 31, 11, 12, 32, 36, 37, 13, 47, 39, 48,
+ 49, 50, 54, 13, 9, 40, 55, 56, 58, 59,
+ 60, 67, 68, 69, 70, 72, 73, 74, 75, 76,
+ 77, 78, 79, 81, 83, 85, 86, 64, 15, 62,
+ 53, 71, 66, 64, 16, 62, 53, 51, 17, 33,
+ 98, 98, 98, 67, 68, 69, 70, 72, 73, 74,
+ 75, 76, 77, 78, 79, 81, 83, 85, 86, 18,
+ 18, 18, 18, 18, 18, 18, 18, 19, 20, 18,
+ 21, 18, 18, 22, 18, 18, 23, 18, 18, 18,
+
+ 18, 24, 18, 18, 18, 25, 87, 88, 89, 18,
+ 90, 18, 18, 18, 18, 18, 18, 18, 18, 19,
+ 20, 18, 21, 18, 18, 22, 18, 18, 23, 18,
+ 18, 18, 18, 24, 18, 18, 18, 94, 87, 88,
+ 89, 98, 90, 82, 82, 84, 84, 82, 95, 84,
+ 96, 84, 84, 84, 84, 84, 98, 84, 84, 84,
+ 57, 57, 84, 98, 57, 98, 82, 98, 84, 94,
+ 98, 91, 91, 18, 84, 91, 84, 98, 18, 98,
+ 95, 84, 96, 57, 92, 92, 98, 98, 92, 91,
+ 91, 91, 91, 91, 91, 91, 18, 92, 92, 97,
+
+ 97, 92, 18, 97, 97, 97, 98, 92, 97, 18,
+ 9, 98, 91, 98, 91, 98, 98, 98, 98, 98,
+ 92, 98, 97, 98, 98, 98, 98, 97, 98, 98,
+ 98, 98, 98, 98, 26, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 93, 98, 98, 98, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 28, 98, 93, 98, 27, 98, 27, 27, 27,
+
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
+ 27, 27, 27, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 27,
+ 98, 98, 98, 98, 27, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 27, 98, 98, 98, 98, 98, 27, 98,
+ 98, 98, 98, 98, 98, 27, 8, 8, 8, 8,
+
+ 8, 8, 35, 35, 45, 45, 52, 52, 52, 52,
+ 61, 98, 61, 61, 61, 63, 63, 63, 63, 65,
+ 98, 65, 65, 65, 7, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98
+ } ;
+
+static yyconst flex_int16_t yy_chk[782] =
+ { 0,
+ 0, 0, 0, 0, 105, 103, 102, 100, 0, 1,
+ 39, 39, 0, 0, 39, 0, 2, 57, 57, 69,
+ 69, 57, 0, 69, 71, 71, 73, 73, 71, 0,
+ 73, 74, 74, 39, 0, 74, 0, 80, 80, 0,
+ 57, 80, 69, 0, 0, 0, 0, 71, 0, 73,
+ 0, 0, 0, 0, 74, 0, 0, 0, 0, 0,
+ 80, 0, 0, 0, 0, 0, 0, 1, 10, 0,
+ 21, 24, 1, 1, 2, 23, 0, 11, 12, 2,
+ 2, 13, 19, 20, 1, 29, 22, 30, 31, 32,
+ 36, 2, 65, 22, 37, 38, 40, 41, 42, 1,
+
+ 10, 1, 21, 24, 1, 1, 2, 23, 2, 11,
+ 12, 2, 2, 13, 19, 20, 1, 29, 22, 30,
+ 31, 32, 36, 2, 3, 22, 37, 38, 40, 41,
+ 42, 47, 48, 49, 50, 54, 55, 56, 58, 59,
+ 60, 67, 68, 70, 72, 75, 76, 63, 3, 61,
+ 52, 51, 46, 44, 3, 43, 34, 33, 3, 14,
+ 7, 0, 0, 47, 48, 49, 50, 54, 55, 56,
+ 58, 59, 60, 67, 68, 70, 72, 75, 76, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+
+ 3, 3, 3, 3, 3, 3, 77, 78, 79, 3,
+ 81, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
+ 3, 3, 3, 3, 3, 3, 3, 93, 77, 78,
+ 79, 0, 81, 82, 82, 83, 83, 82, 94, 83,
+ 95, 84, 84, 85, 85, 84, 0, 85, 86, 86,
+ 87, 87, 86, 0, 87, 0, 82, 0, 83, 93,
+ 0, 88, 88, 3, 84, 88, 85, 0, 3, 0,
+ 94, 86, 95, 87, 89, 89, 0, 0, 89, 90,
+ 90, 91, 91, 90, 88, 91, 3, 92, 92, 96,
+
+ 96, 92, 3, 96, 97, 97, 0, 89, 97, 3,
+ 5, 0, 90, 0, 91, 0, 0, 0, 0, 0,
+ 92, 0, 96, 0, 0, 0, 0, 97, 0, 0,
+ 0, 0, 0, 0, 5, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 92, 0, 0, 0, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 0, 92, 0, 5, 0, 5, 5, 5,
+
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
+ 5, 5, 5, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 5,
+ 0, 0, 0, 0, 5, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 5, 0, 0, 0, 0, 0, 5, 0,
+ 0, 0, 0, 0, 0, 5, 99, 99, 99, 99,
+
+ 99, 99, 101, 101, 104, 104, 106, 106, 106, 106,
+ 107, 0, 107, 107, 107, 108, 108, 108, 108, 109,
+ 0, 109, 109, 109, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98, 98, 98, 98, 98, 98, 98, 98, 98, 98,
+ 98
+ } ;
+
+static yyconst yy_state_type yy_NUL_trans[98] =
+ { 0,
+ 8, 8, 8, 8, 8, 8, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0
+
+ } ;
+
+extern int yy_flex_debug;
+int yy_flex_debug = 0;
+
+static yy_state_type *yy_state_buf=0, *yy_state_ptr=0;
+static char *yy_full_match;
+static int yy_lp;
+static int yy_looking_for_trail_begin = 0;
+static int yy_full_lp;
+static int *yy_full_state;
+#define YY_TRAILING_MASK 0x2000
+#define YY_TRAILING_HEAD_MASK 0x4000
+#define REJECT \
+{ \
+*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */ \
+yy_cp = (yy_full_match); /* restore poss. backed-over text */ \
+(yy_lp) = (yy_full_lp); /* restore orig. accepting pos. */ \
+(yy_state_ptr) = (yy_full_state); /* restore orig. state */ \
+yy_current_state = *(yy_state_ptr); /* restore curr. state */ \
+++(yy_lp); \
+goto find_rule; \
+}
+
+#define yymore() yymore_used_but_not_detected
+#define YY_MORE_ADJ 0
+#define YY_RESTORE_YY_MORE_OFFSET
+char *yytext;
+#line 1 "tsql.l"
+#line 2 "tsql.l"
+#include "tsql.h"
+
+#define KW(w) {return w;}
+
+
+
+#line 699 "tsql.yy.c"
+
+#define INITIAL 0
+#define INFROM 1
+#define INDML 2
+
+#ifndef YY_NO_UNISTD_H
+/* Special case for "unistd.h", since it is non-ANSI. We include it way
+ * down here because we want the user's section 1 to have been scanned first.
+ * The user has a chance to override it with an option.
+ */
+#include <unistd.h>
+#endif
+
+#ifndef YY_EXTRA_TYPE
+#define YY_EXTRA_TYPE void *
+#endif
+
+static int yy_init_globals (void );
+
+/* Accessor methods to globals.
+ These are made visible to non-reentrant scanners for convenience. */
+
+int yylex_destroy (void );
+
+int yyget_debug (void );
+
+void yyset_debug (int debug_flag );
+
+YY_EXTRA_TYPE yyget_extra (void );
+
+void yyset_extra (YY_EXTRA_TYPE user_defined );
+
+FILE *yyget_in (void );
+
+void yyset_in (FILE * in_str );
+
+FILE *yyget_out (void );
+
+void yyset_out (FILE * out_str );
+
+int yyget_leng (void );
+
+char *yyget_text (void );
+
+int yyget_lineno (void );
+
+void yyset_lineno (int line_number );
+
+/* Macros after this point can all be overridden by user definitions in
+ * section 1.
+ */
+
+#ifndef YY_SKIP_YYWRAP
+#ifdef __cplusplus
+extern "C" int yywrap (void );
+#else
+extern int yywrap (void );
+#endif
+#endif
+
+ static void yyunput (int c,char *buf_ptr );
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char *,yyconst char *,int );
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * );
+#endif
+
+#ifndef YY_NO_INPUT
+
+#ifdef __cplusplus
+static int yyinput (void );
+#else
+static int input (void );
+#endif
+
+#endif
+
+/* Amount of stuff to slurp up with each read. */
+#ifndef YY_READ_BUF_SIZE
+#define YY_READ_BUF_SIZE 8192
+#endif
+
+/* Copy whatever the last rule matched to the standard output. */
+#ifndef ECHO
+/* This used to be an fputs(), but since the string might contain NUL's,
+ * we now use fwrite().
+ */
+#define ECHO do { if (fwrite( yytext, yyleng, 1, yyout )) {} } while (0)
+#endif
+
+/* Gets input and stuffs it into "buf". number of characters read, or YY_NULL,
+ * is returned in "result".
+ */
+#ifndef YY_INPUT
+#define YY_INPUT(buf,result,max_size) \
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_is_interactive ) \
+ { \
+ int c = '*'; \
+ unsigned n; \
+ for ( n = 0; n < max_size && \
+ (c = getc( yyin )) != EOF && c != '\n'; ++n ) \
+ buf[n] = (char) c; \
+ if ( c == '\n' ) \
+ buf[n++] = (char) c; \
+ if ( c == EOF && ferror( yyin ) ) \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ result = n; \
+ } \
+ else \
+ { \
+ errno=0; \
+ while ( (result = fread(buf, 1, max_size, yyin))==0 && ferror(yyin)) \
+ { \
+ if( errno != EINTR) \
+ { \
+ YY_FATAL_ERROR( "input in flex scanner failed" ); \
+ break; \
+ } \
+ errno=0; \
+ clearerr(yyin); \
+ } \
+ }\
+\
+
+#endif
+
+/* No semi-colon after return; correct usage is to write "yyterminate();" -
+ * we don't want an extra ';' after the "return" because that will cause
+ * some compilers to complain about unreachable statements.
+ */
+#ifndef yyterminate
+#define yyterminate() return YY_NULL
+#endif
+
+/* Number of entries by which start-condition stack grows. */
+#ifndef YY_START_STACK_INCR
+#define YY_START_STACK_INCR 25
+#endif
+
+/* Report a fatal error. */
+#ifndef YY_FATAL_ERROR
+#define YY_FATAL_ERROR(msg) yy_fatal_error( msg )
+#endif
+
+/* end tables serialization structures and prototypes */
+
+/* Default declaration of generated scanner - a define so the user can
+ * easily add parameters.
+ */
+#ifndef YY_DECL
+#define YY_DECL_IS_OURS 1
+
+extern int yylex (void);
+
+#define YY_DECL int yylex (void)
+#endif /* !YY_DECL */
+
+/* Code executed at the beginning of each rule, after yytext and yyleng
+ * have been set up.
+ */
+#ifndef YY_USER_ACTION
+#define YY_USER_ACTION
+#endif
+
+/* Code executed at the end of each rule. */
+#ifndef YY_BREAK
+#define YY_BREAK break;
+#endif
+
+#define YY_RULE_SETUP \
+ YY_USER_ACTION
+
+/** The main scanner function which does all the work.
+ */
+YY_DECL
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp, *yy_bp;
+ register int yy_act;
+
+#line 20 "tsql.l"
+
+
+#line 886 "tsql.yy.c"
+
+ if ( !(yy_init) )
+ {
+ (yy_init) = 1;
+
+#ifdef YY_USER_INIT
+ YY_USER_INIT;
+#endif
+
+ /* Create the reject buffer large enough to save one state per allowed character. */
+ if ( ! (yy_state_buf) )
+ (yy_state_buf) = (yy_state_type *)yyalloc(YY_STATE_BUF_SIZE );
+ if ( ! (yy_state_buf) )
+ YY_FATAL_ERROR( "out of dynamic memory in yylex()" );
+
+ if ( ! (yy_start) )
+ (yy_start) = 1; /* first start state */
+
+ if ( ! yyin )
+ yyin = stdin;
+
+ if ( ! yyout )
+ yyout = stdout;
+
+ if ( ! YY_CURRENT_BUFFER ) {
+ yyensure_buffer_stack ();
+ YY_CURRENT_BUFFER_LVALUE =
+ yy_create_buffer(yyin,YY_BUF_SIZE );
+ }
+
+ yy_load_buffer_state( );
+ }
+
+ while ( 1 ) /* loops until end-of-file is reached */
+ {
+ yy_cp = (yy_c_buf_p);
+
+ /* Support of yytext. */
+ *yy_cp = (yy_hold_char);
+
+ /* yy_bp points to the position in yy_ch_buf of the start of
+ * the current run.
+ */
+ yy_bp = yy_cp;
+
+ yy_current_state = (yy_start);
+
+ (yy_state_ptr) = (yy_state_buf);
+ *(yy_state_ptr)++ = yy_current_state;
+
+yy_match:
+ do
+ {
+ register YY_CHAR yy_c = YY_SC_TO_UI(*yy_cp);
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 99 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ *(yy_state_ptr)++ = yy_current_state;
+ ++yy_cp;
+ }
+ while ( yy_base[yy_current_state] != 525 );
+
+yy_find_action:
+ yy_current_state = *--(yy_state_ptr);
+ (yy_lp) = yy_accept[yy_current_state];
+find_rule: /* we branch to this label when backing up */
+ for ( ; ; ) /* until we find what rule we matched */
+ {
+ if ( (yy_lp) && (yy_lp) < yy_accept[yy_current_state + 1] )
+ {
+ yy_act = yy_acclist[(yy_lp)];
+ if ( yy_act & YY_TRAILING_HEAD_MASK ||
+ (yy_looking_for_trail_begin) )
+ {
+ if ( yy_act == (yy_looking_for_trail_begin) )
+ {
+ (yy_looking_for_trail_begin) = 0;
+ yy_act &= ~YY_TRAILING_HEAD_MASK;
+ break;
+ }
+ }
+ else if ( yy_act & YY_TRAILING_MASK )
+ {
+ (yy_looking_for_trail_begin) = yy_act & ~YY_TRAILING_MASK;
+ (yy_looking_for_trail_begin) |= YY_TRAILING_HEAD_MASK;
+ }
+ else
+ {
+ (yy_full_match) = yy_cp;
+ (yy_full_state) = (yy_state_ptr);
+ (yy_full_lp) = (yy_lp);
+ break;
+ }
+ ++(yy_lp);
+ goto find_rule;
+ }
+ --yy_cp;
+ yy_current_state = *--(yy_state_ptr);
+ (yy_lp) = yy_accept[yy_current_state];
+ }
+
+ YY_DO_BEFORE_ACTION;
+
+do_action: /* This label is used only to access EOF actions. */
+
+ switch ( yy_act )
+ { /* beginning of action switch */
+case 1:
+/* rule 1 can match eol */
+*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */
+(yy_c_buf_p) = yy_cp = yy_bp + 4;
+YY_DO_BEFORE_ACTION; /* set up yytext again */
+YY_RULE_SETUP
+#line 22 "tsql.l"
+{BEGIN INFROM; KW(FROM);}
+ YY_BREAK
+case 2:
+/* rule 2 can match eol */
+YY_RULE_SETUP
+#line 23 "tsql.l"
+{BEGIN INDML; KW(INSUP);}
+ YY_BREAK
+case 3:
+/* rule 3 can match eol */
+YY_RULE_SETUP
+#line 24 "tsql.l"
+{BEGIN INDML; KW(INSUP);}
+ YY_BREAK
+case 4:
+/* rule 4 can match eol */
+*yy_cp = (yy_hold_char); /* undo effects of setting up yytext */
+(yy_c_buf_p) = yy_cp = yy_bp + 4;
+YY_DO_BEFORE_ACTION; /* set up yytext again */
+YY_RULE_SETUP
+#line 25 "tsql.l"
+{BEGIN INFROM; KW(JOIN);}
+ YY_BREAK
+case 5:
+/* rule 5 can match eol */
+YY_RULE_SETUP
+#line 26 "tsql.l"
+{BEGIN INITIAL;}
+ YY_BREAK
+case 6:
+/* rule 6 can match eol */
+YY_RULE_SETUP
+#line 27 "tsql.l"
+{BEGIN INITIAL;}
+ YY_BREAK
+case 7:
+YY_RULE_SETUP
+#line 28 "tsql.l"
+{KW(TOKEN);}
+ YY_BREAK
+case 8:
+YY_RULE_SETUP
+#line 29 "tsql.l"
+{KW(TOKEN);}
+ YY_BREAK
+case 9:
+YY_RULE_SETUP
+#line 30 "tsql.l"
+{KW(TOKEN);}
+ YY_BREAK
+case 10:
+YY_RULE_SETUP
+#line 31 "tsql.l"
+{BEGIN INITIAL; KW(TOKEN);}
+ YY_BREAK
+case 11:
+YY_RULE_SETUP
+#line 32 "tsql.l"
+{BEGIN INITIAL; KW(TOKEN);}
+ YY_BREAK
+case 12:
+YY_RULE_SETUP
+#line 33 "tsql.l"
+{BEGIN INITIAL; KW(TOKEN);}
+ YY_BREAK
+case 13:
+YY_RULE_SETUP
+#line 34 "tsql.l"
+{KW(COMMA);}
+ YY_BREAK
+case 14:
+YY_RULE_SETUP
+#line 35 "tsql.l"
+{BEGIN INITIAL;}
+ YY_BREAK
+case 15:
+YY_RULE_SETUP
+#line 36 "tsql.l"
+;
+ YY_BREAK
+case 16:
+/* rule 16 can match eol */
+YY_RULE_SETUP
+#line 37 "tsql.l"
+;
+ YY_BREAK
+case 17:
+YY_RULE_SETUP
+#line 40 "tsql.l"
+ECHO;
+ YY_BREAK
+#line 1096 "tsql.yy.c"
+ case YY_STATE_EOF(INITIAL):
+ case YY_STATE_EOF(INFROM):
+ case YY_STATE_EOF(INDML):
+ yyterminate();
+
+ case YY_END_OF_BUFFER:
+ {
+ /* Amount of text matched not including the EOB char. */
+ int yy_amount_of_matched_text = (int) (yy_cp - (yytext_ptr)) - 1;
+
+ /* Undo the effects of YY_DO_BEFORE_ACTION. */
+ *yy_cp = (yy_hold_char);
+ YY_RESTORE_YY_MORE_OFFSET
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_NEW )
+ {
+ /* We're scanning a new file or input source. It's
+ * possible that this happened because the user
+ * just pointed yyin at a new source and called
+ * yylex(). If so, then we have to assure
+ * consistency between YY_CURRENT_BUFFER and our
+ * globals. Here is the right place to do so, because
+ * this is the first action (other than possibly a
+ * back-up) that will match for the new input source.
+ */
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ YY_CURRENT_BUFFER_LVALUE->yy_input_file = yyin;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status = YY_BUFFER_NORMAL;
+ }
+
+ /* Note that here we test for yy_c_buf_p "<=" to the position
+ * of the first EOB in the buffer, since yy_c_buf_p will
+ * already have been incremented past the NUL character
+ * (since all states make transitions on EOB to the
+ * end-of-buffer state). Contrast this with the test
+ * in input().
+ */
+ if ( (yy_c_buf_p) <= &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+ { /* This was really a NUL. */
+ yy_state_type yy_next_state;
+
+ (yy_c_buf_p) = (yytext_ptr) + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( );
+
+ /* Okay, we're now positioned to make the NUL
+ * transition. We couldn't have
+ * yy_get_previous_state() go ahead and do it
+ * for us because it doesn't know how to deal
+ * with the possibility of jamming (and we don't
+ * want to build jamming into it because then it
+ * will run more slowly).
+ */
+
+ yy_next_state = yy_try_NUL_trans( yy_current_state );
+
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+
+ if ( yy_next_state )
+ {
+ /* Consume the NUL. */
+ yy_cp = ++(yy_c_buf_p);
+ yy_current_state = yy_next_state;
+ goto yy_match;
+ }
+
+ else
+ {
+ yy_cp = (yy_c_buf_p);
+ goto yy_find_action;
+ }
+ }
+
+ else switch ( yy_get_next_buffer( ) )
+ {
+ case EOB_ACT_END_OF_FILE:
+ {
+ (yy_did_buffer_switch_on_eof) = 0;
+
+ if ( yywrap( ) )
+ {
+ /* Note: because we've taken care in
+ * yy_get_next_buffer() to have set up
+ * yytext, we can now set up
+ * yy_c_buf_p so that if some total
+ * hoser (like flex itself) wants to
+ * call the scanner after we return the
+ * YY_NULL, it'll still work - another
+ * YY_NULL will get returned.
+ */
+ (yy_c_buf_p) = (yytext_ptr) + YY_MORE_ADJ;
+
+ yy_act = YY_STATE_EOF(YY_START);
+ goto do_action;
+ }
+
+ else
+ {
+ if ( ! (yy_did_buffer_switch_on_eof) )
+ YY_NEW_FILE;
+ }
+ break;
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ (yy_c_buf_p) =
+ (yytext_ptr) + yy_amount_of_matched_text;
+
+ yy_current_state = yy_get_previous_state( );
+
+ yy_cp = (yy_c_buf_p);
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+ goto yy_match;
+
+ case EOB_ACT_LAST_MATCH:
+ (yy_c_buf_p) =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)];
+
+ yy_current_state = yy_get_previous_state( );
+
+ yy_cp = (yy_c_buf_p);
+ yy_bp = (yytext_ptr) + YY_MORE_ADJ;
+ goto yy_find_action;
+ }
+ break;
+ }
+
+ default:
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--no action found" );
+ } /* end of action switch */
+ } /* end of scanning one token */
+} /* end of yylex */
+
+/* yy_get_next_buffer - try to read in a new buffer
+ *
+ * Returns a code representing an action:
+ * EOB_ACT_LAST_MATCH -
+ * EOB_ACT_CONTINUE_SCAN - continue scanning from current position
+ * EOB_ACT_END_OF_FILE - end of file
+ */
+static int yy_get_next_buffer (void)
+{
+ register char *dest = YY_CURRENT_BUFFER_LVALUE->yy_ch_buf;
+ register char *source = (yytext_ptr);
+ register int number_to_move, i;
+ int ret_val;
+
+ if ( (yy_c_buf_p) > &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] )
+ YY_FATAL_ERROR(
+ "fatal flex scanner internal error--end of buffer missed" );
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_fill_buffer == 0 )
+ { /* Don't try to fill the buffer, so this is an EOF. */
+ if ( (yy_c_buf_p) - (yytext_ptr) - YY_MORE_ADJ == 1 )
+ {
+ /* We matched a single character, the EOB, so
+ * treat this as a final EOF.
+ */
+ return EOB_ACT_END_OF_FILE;
+ }
+
+ else
+ {
+ /* We matched some text prior to the EOB, first
+ * process it.
+ */
+ return EOB_ACT_LAST_MATCH;
+ }
+ }
+
+ /* Try to read more data. */
+
+ /* First move last chars to start of buffer. */
+ number_to_move = (int) ((yy_c_buf_p) - (yytext_ptr)) - 1;
+
+ for ( i = 0; i < number_to_move; ++i )
+ *(dest++) = *(source++);
+
+ if ( YY_CURRENT_BUFFER_LVALUE->yy_buffer_status == YY_BUFFER_EOF_PENDING )
+ /* don't do the read, it's not guaranteed to return an EOF,
+ * just force an EOF
+ */
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars) = 0;
+
+ else
+ {
+ int num_to_read =
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size - number_to_move - 1;
+
+ while ( num_to_read <= 0 )
+ { /* Not enough room in the buffer - grow it. */
+
+ YY_FATAL_ERROR(
+"input buffer overflow, can't enlarge buffer because scanner uses REJECT" );
+
+ }
+
+ if ( num_to_read > YY_READ_BUF_SIZE )
+ num_to_read = YY_READ_BUF_SIZE;
+
+ /* Read in more data. */
+ YY_INPUT( (&YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move]),
+ (yy_n_chars), (size_t) num_to_read );
+
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ if ( (yy_n_chars) == 0 )
+ {
+ if ( number_to_move == YY_MORE_ADJ )
+ {
+ ret_val = EOB_ACT_END_OF_FILE;
+ yyrestart(yyin );
+ }
+
+ else
+ {
+ ret_val = EOB_ACT_LAST_MATCH;
+ YY_CURRENT_BUFFER_LVALUE->yy_buffer_status =
+ YY_BUFFER_EOF_PENDING;
+ }
+ }
+
+ else
+ ret_val = EOB_ACT_CONTINUE_SCAN;
+
+ if ((yy_size_t) ((yy_n_chars) + number_to_move) > YY_CURRENT_BUFFER_LVALUE->yy_buf_size) {
+ /* Extend the array by 50%, plus the number we really need. */
+ yy_size_t new_size = (yy_n_chars) + number_to_move + ((yy_n_chars) >> 1);
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf = (char *) yyrealloc((void *) YY_CURRENT_BUFFER_LVALUE->yy_ch_buf,new_size );
+ if ( ! YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_get_next_buffer()" );
+ }
+
+ (yy_n_chars) += number_to_move;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] = YY_END_OF_BUFFER_CHAR;
+ YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars) + 1] = YY_END_OF_BUFFER_CHAR;
+
+ (yytext_ptr) = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[0];
+
+ return ret_val;
+}
+
+/* yy_get_previous_state - get the state just before the EOB char was reached */
+
+ static yy_state_type yy_get_previous_state (void)
+{
+ register yy_state_type yy_current_state;
+ register char *yy_cp;
+
+ yy_current_state = (yy_start);
+
+ (yy_state_ptr) = (yy_state_buf);
+ *(yy_state_ptr)++ = yy_current_state;
+
+ for ( yy_cp = (yytext_ptr) + YY_MORE_ADJ; yy_cp < (yy_c_buf_p); ++yy_cp )
+ {
+ if ( *yy_cp )
+ {
+ register YY_CHAR yy_c = YY_SC_TO_UI(*yy_cp);
+ while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
+ {
+ yy_current_state = (int) yy_def[yy_current_state];
+ if ( yy_current_state >= 99 )
+ yy_c = yy_meta[(unsigned int) yy_c];
+ }
+ yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
+ }
+ else
+ yy_current_state = yy_NUL_trans[yy_current_state];
+ *(yy_state_ptr)++ = yy_current_state;
+ }
+
+ return yy_current_state;
+}
+
+/* yy_try_NUL_trans - try to make a transition on the NUL character
+ *
+ * synopsis
+ * next_state = yy_try_NUL_trans( current_state );
+ */
+ static yy_state_type yy_try_NUL_trans (yy_state_type yy_current_state )
+{
+ register int yy_is_jam;
+
+ yy_current_state = yy_NUL_trans[yy_current_state];
+ yy_is_jam = (yy_current_state == 0);
+
+ return yy_is_jam ? 0 : yy_current_state;
+}
+
+ static void yyunput (int c, register char * yy_bp )
+{
+ register char *yy_cp;
+
+ yy_cp = (yy_c_buf_p);
+
+ /* undo effects of setting up yytext */
+ *yy_cp = (yy_hold_char);
+
+ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+ { /* need to shift things up to make room */
+ /* +2 for EOB chars. */
+ register int number_to_move = (yy_n_chars) + 2;
+ register char *dest = &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_size + 2];
+ register char *source =
+ &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[number_to_move];
+
+ while ( source > YY_CURRENT_BUFFER_LVALUE->yy_ch_buf )
+ *--dest = *--source;
+
+ yy_cp += (int) (dest - source);
+ yy_bp += (int) (dest - source);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars =
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_buf_size;
+
+ if ( yy_cp < YY_CURRENT_BUFFER_LVALUE->yy_ch_buf + 2 )
+ YY_FATAL_ERROR( "flex scanner push-back overflow" );
+ }
+
+ *--yy_cp = (char) c;
+
+ (yytext_ptr) = yy_bp;
+ (yy_hold_char) = *yy_cp;
+ (yy_c_buf_p) = yy_cp;
+}
+
+#ifndef YY_NO_INPUT
+#ifdef __cplusplus
+ static int yyinput (void)
+#else
+ static int input (void)
+#endif
+
+{
+ int c;
+
+ *(yy_c_buf_p) = (yy_hold_char);
+
+ if ( *(yy_c_buf_p) == YY_END_OF_BUFFER_CHAR )
+ {
+ /* yy_c_buf_p now points to the character we want to return.
+ * If this occurs *before* the EOB characters, then it's a
+ * valid NUL; if not, then we've hit the end of the buffer.
+ */
+ if ( (yy_c_buf_p) < &YY_CURRENT_BUFFER_LVALUE->yy_ch_buf[(yy_n_chars)] )
+ /* This was really a NUL. */
+ *(yy_c_buf_p) = '\0';
+
+ else
+ { /* need more input */
+ int offset = (yy_c_buf_p) - (yytext_ptr);
+ ++(yy_c_buf_p);
+
+ switch ( yy_get_next_buffer( ) )
+ {
+ case EOB_ACT_LAST_MATCH:
+ /* This happens because yy_g_n_b()
+ * sees that we've accumulated a
+ * token and flags that we need to
+ * try matching the token before
+ * proceeding. But for input(),
+ * there's no matching to consider.
+ * So convert the EOB_ACT_LAST_MATCH
+ * to EOB_ACT_END_OF_FILE.
+ */
+
+ /* Reset buffer status. */
+ yyrestart(yyin );
+
+ /*FALLTHROUGH*/
+
+ case EOB_ACT_END_OF_FILE:
+ {
+ if ( yywrap( ) )
+ return EOF;
+
+ if ( ! (yy_did_buffer_switch_on_eof) )
+ YY_NEW_FILE;
+#ifdef __cplusplus
+ return yyinput();
+#else
+ return input();
+#endif
+ }
+
+ case EOB_ACT_CONTINUE_SCAN:
+ (yy_c_buf_p) = (yytext_ptr) + offset;
+ break;
+ }
+ }
+ }
+
+ c = *(unsigned char *) (yy_c_buf_p); /* cast for 8-bit char's */
+ *(yy_c_buf_p) = '\0'; /* preserve yytext */
+ (yy_hold_char) = *++(yy_c_buf_p);
+
+ return c;
+}
+#endif /* ifndef YY_NO_INPUT */
+
+/** Immediately switch to a different input stream.
+ * @param input_file A readable stream.
+ *
+ * @note This function does not reset the start condition to @c INITIAL .
+ */
+ void yyrestart (FILE * input_file )
+{
+
+ if ( ! YY_CURRENT_BUFFER ){
+ yyensure_buffer_stack ();
+ YY_CURRENT_BUFFER_LVALUE =
+ yy_create_buffer(yyin,YY_BUF_SIZE );
+ }
+
+ yy_init_buffer(YY_CURRENT_BUFFER,input_file );
+ yy_load_buffer_state( );
+}
+
+/** Switch to a different input buffer.
+ * @param new_buffer The new input buffer.
+ *
+ */
+ void yy_switch_to_buffer (YY_BUFFER_STATE new_buffer )
+{
+
+ /* TODO. We should be able to replace this entire function body
+ * with
+ * yypop_buffer_state();
+ * yypush_buffer_state(new_buffer);
+ */
+ yyensure_buffer_stack ();
+ if ( YY_CURRENT_BUFFER == new_buffer )
+ return;
+
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *(yy_c_buf_p) = (yy_hold_char);
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+ yy_load_buffer_state( );
+
+ /* We don't actually know whether we did this switch during
+ * EOF (yywrap()) processing, but the only time this flag
+ * is looked at is after yywrap() is called, so it's safe
+ * to go ahead and always set it.
+ */
+ (yy_did_buffer_switch_on_eof) = 1;
+}
+
+static void yy_load_buffer_state (void)
+{
+ (yy_n_chars) = YY_CURRENT_BUFFER_LVALUE->yy_n_chars;
+ (yytext_ptr) = (yy_c_buf_p) = YY_CURRENT_BUFFER_LVALUE->yy_buf_pos;
+ yyin = YY_CURRENT_BUFFER_LVALUE->yy_input_file;
+ (yy_hold_char) = *(yy_c_buf_p);
+}
+
+/** Allocate and initialize an input buffer state.
+ * @param file A readable stream.
+ * @param size The character buffer size in bytes. When in doubt, use @c YY_BUF_SIZE.
+ *
+ * @return the allocated buffer state.
+ */
+ YY_BUFFER_STATE yy_create_buffer (FILE * file, int size )
+{
+ YY_BUFFER_STATE b;
+
+ b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_buf_size = size;
+
+ /* yy_ch_buf has to be 2 characters longer than the size given because
+ * we need to put in 2 end-of-buffer characters.
+ */
+ b->yy_ch_buf = (char *) yyalloc(b->yy_buf_size + 2 );
+ if ( ! b->yy_ch_buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_create_buffer()" );
+
+ b->yy_is_our_buffer = 1;
+
+ yy_init_buffer(b,file );
+
+ return b;
+}
+
+/** Destroy the buffer.
+ * @param b a buffer created with yy_create_buffer()
+ *
+ */
+ void yy_delete_buffer (YY_BUFFER_STATE b )
+{
+
+ if ( ! b )
+ return;
+
+ if ( b == YY_CURRENT_BUFFER ) /* Not sure if we should pop here. */
+ YY_CURRENT_BUFFER_LVALUE = (YY_BUFFER_STATE) 0;
+
+ if ( b->yy_is_our_buffer )
+ yyfree((void *) b->yy_ch_buf );
+
+ yyfree((void *) b );
+}
+
+#ifndef __cplusplus
+extern int isatty (int );
+#endif /* __cplusplus */
+
+/* Initializes or reinitializes a buffer.
+ * This function is sometimes called more than once on the same buffer,
+ * such as during a yyrestart() or at EOF.
+ */
+ static void yy_init_buffer (YY_BUFFER_STATE b, FILE * file )
+
+{
+ int oerrno = errno;
+
+ yy_flush_buffer(b );
+
+ b->yy_input_file = file;
+ b->yy_fill_buffer = 1;
+
+ /* If b is the current buffer, then yy_init_buffer was _probably_
+ * called from yyrestart() or through yy_get_next_buffer.
+ * In that case, we don't want to reset the lineno or column.
+ */
+ if (b != YY_CURRENT_BUFFER){
+ b->yy_bs_lineno = 1;
+ b->yy_bs_column = 0;
+ }
+
+ b->yy_is_interactive = file ? (isatty( fileno(file) ) > 0) : 0;
+
+ errno = oerrno;
+}
+
+/** Discard all buffered characters. On the next scan, YY_INPUT will be called.
+ * @param b the buffer state to be flushed, usually @c YY_CURRENT_BUFFER.
+ *
+ */
+ void yy_flush_buffer (YY_BUFFER_STATE b )
+{
+ if ( ! b )
+ return;
+
+ b->yy_n_chars = 0;
+
+ /* We always need two end-of-buffer characters. The first causes
+ * a transition to the end-of-buffer state. The second causes
+ * a jam in that state.
+ */
+ b->yy_ch_buf[0] = YY_END_OF_BUFFER_CHAR;
+ b->yy_ch_buf[1] = YY_END_OF_BUFFER_CHAR;
+
+ b->yy_buf_pos = &b->yy_ch_buf[0];
+
+ b->yy_at_bol = 1;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ if ( b == YY_CURRENT_BUFFER )
+ yy_load_buffer_state( );
+}
+
+/** Pushes the new state onto the stack. The new state becomes
+ * the current state. This function will allocate the stack
+ * if necessary.
+ * @param new_buffer The new state.
+ *
+ */
+void yypush_buffer_state (YY_BUFFER_STATE new_buffer )
+{
+ if (new_buffer == NULL)
+ return;
+
+ yyensure_buffer_stack();
+
+ /* This block is copied from yy_switch_to_buffer. */
+ if ( YY_CURRENT_BUFFER )
+ {
+ /* Flush out information for old buffer. */
+ *(yy_c_buf_p) = (yy_hold_char);
+ YY_CURRENT_BUFFER_LVALUE->yy_buf_pos = (yy_c_buf_p);
+ YY_CURRENT_BUFFER_LVALUE->yy_n_chars = (yy_n_chars);
+ }
+
+ /* Only push if top exists. Otherwise, replace top. */
+ if (YY_CURRENT_BUFFER)
+ (yy_buffer_stack_top)++;
+ YY_CURRENT_BUFFER_LVALUE = new_buffer;
+
+ /* copied from yy_switch_to_buffer. */
+ yy_load_buffer_state( );
+ (yy_did_buffer_switch_on_eof) = 1;
+}
+
+/** Removes and deletes the top of the stack, if present.
+ * The next element becomes the new top.
+ *
+ */
+void yypop_buffer_state (void)
+{
+ if (!YY_CURRENT_BUFFER)
+ return;
+
+ yy_delete_buffer(YY_CURRENT_BUFFER );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ if ((yy_buffer_stack_top) > 0)
+ --(yy_buffer_stack_top);
+
+ if (YY_CURRENT_BUFFER) {
+ yy_load_buffer_state( );
+ (yy_did_buffer_switch_on_eof) = 1;
+ }
+}
+
+/* Allocates the stack if it does not exist.
+ * Guarantees space for at least one push.
+ */
+static void yyensure_buffer_stack (void)
+{
+ int num_to_alloc;
+
+ if (!(yy_buffer_stack)) {
+
+ /* First allocation is just for 2 elements, since we don't know if this
+ * scanner will even need a stack. We use 2 instead of 1 to avoid an
+ * immediate realloc on the next call.
+ */
+ num_to_alloc = 1;
+ (yy_buffer_stack) = (struct yy_buffer_state**)yyalloc
+ (num_to_alloc * sizeof(struct yy_buffer_state*)
+ );
+ if ( ! (yy_buffer_stack) )
+ YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+
+ memset((yy_buffer_stack), 0, num_to_alloc * sizeof(struct yy_buffer_state*));
+
+ (yy_buffer_stack_max) = num_to_alloc;
+ (yy_buffer_stack_top) = 0;
+ return;
+ }
+
+ if ((yy_buffer_stack_top) >= ((yy_buffer_stack_max)) - 1){
+
+ /* Increase the buffer to prepare for a possible push. */
+ int grow_size = 8 /* arbitrary grow size */;
+
+ num_to_alloc = (yy_buffer_stack_max) + grow_size;
+ (yy_buffer_stack) = (struct yy_buffer_state**)yyrealloc
+ ((yy_buffer_stack),
+ num_to_alloc * sizeof(struct yy_buffer_state*)
+ );
+ if ( ! (yy_buffer_stack) )
+ YY_FATAL_ERROR( "out of dynamic memory in yyensure_buffer_stack()" );
+
+ /* zero only the new slots.*/
+ memset((yy_buffer_stack) + (yy_buffer_stack_max), 0, grow_size * sizeof(struct yy_buffer_state*));
+ (yy_buffer_stack_max) = num_to_alloc;
+ }
+}
+
+/** Setup the input buffer state to scan directly from a user-specified character buffer.
+ * @param base the character buffer
+ * @param size the size in bytes of the character buffer
+ *
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_buffer (char * base, yy_size_t size )
+{
+ YY_BUFFER_STATE b;
+
+ if ( size < 2 ||
+ base[size-2] != YY_END_OF_BUFFER_CHAR ||
+ base[size-1] != YY_END_OF_BUFFER_CHAR )
+ /* They forgot to leave room for the EOB's. */
+ return 0;
+
+ b = (YY_BUFFER_STATE) yyalloc(sizeof( struct yy_buffer_state ) );
+ if ( ! b )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_buffer()" );
+
+ b->yy_buf_size = size - 2; /* "- 2" to take care of EOB's */
+ b->yy_buf_pos = b->yy_ch_buf = base;
+ b->yy_is_our_buffer = 0;
+ b->yy_input_file = 0;
+ b->yy_n_chars = b->yy_buf_size;
+ b->yy_is_interactive = 0;
+ b->yy_at_bol = 1;
+ b->yy_fill_buffer = 0;
+ b->yy_buffer_status = YY_BUFFER_NEW;
+
+ yy_switch_to_buffer(b );
+
+ return b;
+}
+
+/** Setup the input buffer state to scan a string. The next call to yylex() will
+ * scan from a @e copy of @a str.
+ * @param yystr a NUL-terminated string to scan
+ *
+ * @return the newly allocated buffer state object.
+ * @note If you want to scan bytes that may contain NUL values, then use
+ * yy_scan_bytes() instead.
+ */
+YY_BUFFER_STATE yy_scan_string (yyconst char * yystr )
+{
+
+ return yy_scan_bytes(yystr,strlen(yystr) );
+}
+
+/** Setup the input buffer state to scan the given bytes. The next call to yylex() will
+ * scan from a @e copy of @a bytes.
+ * @param bytes the byte buffer to scan
+ * @param len the number of bytes in the buffer pointed to by @a bytes.
+ *
+ * @return the newly allocated buffer state object.
+ */
+YY_BUFFER_STATE yy_scan_bytes (yyconst char * yybytes, int _yybytes_len )
+{
+ YY_BUFFER_STATE b;
+ char *buf;
+ yy_size_t n;
+ int i;
+
+ /* Get memory for full buffer, including space for trailing EOB's. */
+ n = _yybytes_len + 2;
+ buf = (char *) yyalloc(n );
+ if ( ! buf )
+ YY_FATAL_ERROR( "out of dynamic memory in yy_scan_bytes()" );
+
+ for ( i = 0; i < _yybytes_len; ++i )
+ buf[i] = yybytes[i];
+
+ buf[_yybytes_len] = buf[_yybytes_len+1] = YY_END_OF_BUFFER_CHAR;
+
+ b = yy_scan_buffer(buf,n );
+ if ( ! b )
+ YY_FATAL_ERROR( "bad buffer in yy_scan_bytes()" );
+
+ /* It's okay to grow etc. this buffer, and we should throw it
+ * away when we're done.
+ */
+ b->yy_is_our_buffer = 1;
+
+ return b;
+}
+
+#ifndef YY_EXIT_FAILURE
+#define YY_EXIT_FAILURE 2
+#endif
+
+static void yy_fatal_error (yyconst char* msg )
+{
+ (void) fprintf( stderr, "%s\n", msg );
+ exit( YY_EXIT_FAILURE );
+}
+
+/* Redefine yyless() so it works in section 3 code. */
+
+#undef yyless
+#define yyless(n) \
+ do \
+ { \
+ /* Undo effects of setting up yytext. */ \
+ int yyless_macro_arg = (n); \
+ YY_LESS_LINENO(yyless_macro_arg);\
+ yytext[yyleng] = (yy_hold_char); \
+ (yy_c_buf_p) = yytext + yyless_macro_arg; \
+ (yy_hold_char) = *(yy_c_buf_p); \
+ *(yy_c_buf_p) = '\0'; \
+ yyleng = yyless_macro_arg; \
+ } \
+ while ( 0 )
+
+/* Accessor methods (get/set functions) to struct members. */
+
+/** Get the current line number.
+ *
+ */
+int yyget_lineno (void)
+{
+
+ return yylineno;
+}
+
+/** Get the input stream.
+ *
+ */
+FILE *yyget_in (void)
+{
+ return yyin;
+}
+
+/** Get the output stream.
+ *
+ */
+FILE *yyget_out (void)
+{
+ return yyout;
+}
+
+/** Get the length of the current token.
+ *
+ */
+int yyget_leng (void)
+{
+ return yyleng;
+}
+
+/** Get the current token.
+ *
+ */
+
+char *yyget_text (void)
+{
+ return yytext;
+}
+
+/** Set the current line number.
+ * @param line_number
+ *
+ */
+void yyset_lineno (int line_number )
+{
+
+ yylineno = line_number;
+}
+
+/** Set the input stream. This does not discard the current
+ * input buffer.
+ * @param in_str A readable stream.
+ *
+ * @see yy_switch_to_buffer
+ */
+void yyset_in (FILE * in_str )
+{
+ yyin = in_str ;
+}
+
+void yyset_out (FILE * out_str )
+{
+ yyout = out_str ;
+}
+
+int yyget_debug (void)
+{
+ return yy_flex_debug;
+}
+
+void yyset_debug (int bdebug )
+{
+ yy_flex_debug = bdebug ;
+}
+
+static int yy_init_globals (void)
+{
+ /* Initialization is the same as for the non-reentrant scanner.
+ * This function is called from yylex_destroy(), so don't allocate here.
+ */
+
+ (yy_buffer_stack) = 0;
+ (yy_buffer_stack_top) = 0;
+ (yy_buffer_stack_max) = 0;
+ (yy_c_buf_p) = (char *) 0;
+ (yy_init) = 0;
+ (yy_start) = 0;
+
+ (yy_state_buf) = 0;
+ (yy_state_ptr) = 0;
+ (yy_full_match) = 0;
+ (yy_lp) = 0;
+
+/* Defined in main.c */
+#ifdef YY_STDINIT
+ yyin = stdin;
+ yyout = stdout;
+#else
+ yyin = (FILE *) 0;
+ yyout = (FILE *) 0;
+#endif
+
+ /* For future reference: Set errno on error, since we are called by
+ * yylex_init()
+ */
+ return 0;
+}
+
+/* yylex_destroy is for both reentrant and non-reentrant scanners. */
+int yylex_destroy (void)
+{
+
+ /* Pop the buffer stack, destroying each element. */
+ while(YY_CURRENT_BUFFER){
+ yy_delete_buffer(YY_CURRENT_BUFFER );
+ YY_CURRENT_BUFFER_LVALUE = NULL;
+ yypop_buffer_state();
+ }
+
+ /* Destroy the stack itself. */
+ yyfree((yy_buffer_stack) );
+ (yy_buffer_stack) = NULL;
+
+ yyfree ( (yy_state_buf) );
+ (yy_state_buf) = NULL;
+
+ /* Reset the globals. This is important in a non-reentrant scanner so the next time
+ * yylex() is called, initialization will occur. */
+ yy_init_globals( );
+
+ return 0;
+}
+
+/*
+ * Internal utility routines.
+ */
+
+#ifndef yytext_ptr
+static void yy_flex_strncpy (char* s1, yyconst char * s2, int n )
+{
+ register int i;
+ for ( i = 0; i < n; ++i )
+ s1[i] = s2[i];
+}
+#endif
+
+#ifdef YY_NEED_STRLEN
+static int yy_flex_strlen (yyconst char * s )
+{
+ register int n;
+ for ( n = 0; s[n]; ++n )
+ ;
+
+ return n;
+}
+#endif
+
+void *yyalloc (yy_size_t size )
+{
+ return (void *) malloc( size );
+}
+
+void *yyrealloc (void * ptr, yy_size_t size )
+{
+ /* The cast to (char *) in the following accommodates both
+ * implementations that use char* generic pointers, and those
+ * that use void* generic pointers. It works with the latter
+ * because both ANSI C and C++ allow castless assignment from
+ * any pointer type to void*, and deal with argument conversions
+ * as though doing an assignment.
+ */
+ return (void *) realloc( (char *) ptr, size );
+}
+
+void yyfree (void * ptr )
+{
+ free( (char *) ptr ); /* see yyrealloc() for (char *) cast */
+}
+
+#define YYTABLES_NAME "yytables"
+
+#line 40 "tsql.l"
+
+
+
+int testlex(char *buffer)
+{
+ yy_scan_string(buffer);
+ int rl;
+
+ while ((rl=yylex())!=0){
+ printf("Token: %i yytext: %s\n", rl, yytext);
+ }
+ yylex_destroy();
+ return 0;
+}
+
+extern void *ParseAlloc(void *(*mallocProc)(size_t));
+extern void ParseFree(void *p, void (*freeProc)(void*));
+extern void Parse(void *yyp, int yymajor, void* yyminor);
+void parseSql(char* sql) {
+ int lr;
+ void* pParser = ParseAlloc(malloc);
+
+ yy_scan_string(sql);
+
+ while ((lr=yylex())!=0){
+ Parse(pParser, lr, strdup(yytext));
+ }
+ Parse(pParser, 0, NULL);
+ ParseFree(pParser, free);
+ yylex_destroy();
+}
+
diff --git a/src/sqsh_readline.c b/src/sqsh_readline.c
index 2e351db..b16784a 100644
--- a/src/sqsh_readline.c
+++ b/src/sqsh_readline.c
@@ -24,32 +24,21 @@
*/
#include <stdio.h>
#include <ctype.h>
+#include <regex.h>
#include "sqsh_config.h"
+#include "sqsh_env.h"
#include "sqsh_error.h"
+#include "sqsh_expand.h" /* sqsh-2.1.6 */
#include "sqsh_global.h"
-#include "sqsh_env.h"
-#include "sqsh_stdin.h"
+#include "sqsh_init.h"
#include "sqsh_readline.h"
-#include "sqsh_expand.h" /* sqsh-2.1.6 */
-
-#if defined(USE_READLINE)
-#include <readline/readline.h>
-
-/*
- * Readline history functions - for some reason not all
- * readline installs have history.h available, so we do
- * this.
- */
-extern void stifle_history();
-extern int read_history();
-extern int write_history();
-extern void add_history();
-
-#endif /* USE_READLINE */
+#include "sqsh_stdin.h"
+#include "sqsh_varbuf.h"
+#include "sqsh_parser/sqsh_parser.h"
/*-- Current Version --*/
#if !defined(lint) && !defined(__LINT__)
-static char RCS_Id[] = "$Id: sqsh_readline.c,v 1.3 2009/04/14 10:41:33 mwesdorp Exp $" ;
+static char RCS_Id[] = "$Id: sqsh_readline.c,v 1.14 2013/12/12 11:36:52 mwesdorp Exp $" ;
USE(RCS_Id)
#endif /* !defined(lint) */
@@ -65,6 +54,18 @@ static char* sqsh_generator _ANSI_ARGS(( char*, int )) ;
#endif
/*
+ * sqsh-2.1.8 - Function prototypes for new feature column name completion.
+ */
+static int sqsh_readline_addcol _ANSI_ARGS(( char* )) ;
+static int sqsh_readline_clearcol _ANSI_ARGS(( void )) ;
+static int DynColnameLoad _ANSI_ARGS(( char*, char* )) ;
+
+/*
+ * sqsh-2.2.0 - Function prototypes for new feature readline_histignore.
+ */
+static int regex_match _ANSI_ARGS(( char*, char* )) ;
+
+/*
* If GNU Readline support is compiled in, this data structure is
* used to contain the active list of keywords.
*/
@@ -76,6 +77,14 @@ typedef struct keyword_st {
/*-- Linked list of keywords --*/
static keyword_t *sg_keyword_start = NULL ;
static keyword_t *sg_keyword_end = NULL ;
+static keyword_t *sg_colname_start = NULL ;
+static keyword_t *sg_colname_end = NULL ;
+
+/*
+ * sqsh-2.3 - Variable sg_rl_string points to varbuf buffer
+ * to prevent data overflows.
+*/
+static varbuf_t *sg_rl_string = NULL ;
#endif /* USE_READLINE */
@@ -105,6 +114,8 @@ int sqsh_readline_init()
return True;
}
+ DBG(sqsh_debug( DEBUG_READLINE, "sqsh_readline_init: Initializing\n" );)
+
/*
* Set up the limit on the size of the readline history
* buffer according to the value of $readline_history.
@@ -136,16 +147,38 @@ int sqsh_readline_init()
if (sqsh_expand (readline_history, exp_buf, 0) != False)
read_history( varbuf_getstr(exp_buf) );
else
- fprintf( stderr, "sqsh: Error expanding $readline_history: %s\n",
- sqsh_get_errstr() );
+ fprintf( stderr, "sqsh: Error expanding $readline_history: %s\n", sqsh_get_errstr() );
varbuf_destroy (exp_buf);
}
- DBG(sqsh_debug( DEBUG_READLINE, "sqsh_readline_init: Initializing\n" );)
+ /*
+ * sqsh-2.1.8: Moved loading keyword_file from sqsh_main.c to here.
+ * If the user has requested some form of keyword completion
+ * then attempt to read the contents of the keywords file.
+ */
+ (void) sqsh_readline_load ();
rl_readline_name = "sqsh" ;
- rl_completion_entry_function = (rl_compentry_func_t*)sqsh_generator ;
- rl_attempted_completion_function = (rl_completion_func_t *)sqsh_completion ;
+ rl_completion_entry_function = (rl_compentry_func_t *) sqsh_generator ;
+ rl_attempted_completion_function = (rl_completion_func_t *) sqsh_completion ;
+
+ /*
+ * sqsh-2.1.8 - Remove '@' and '$' from the readline default list of word break
+ * characters by assigning a new list of word break characters to the variable
+ * rl_completer_word_break_characters. The @ and $ characters may be part
+ * of object/column names and would otherwise lead to problems with TAB completion
+ * when keyword_dynamic is enabled.
+ */
+ rl_completer_word_break_characters = " \t\n\"\\'`><=;|&{(";
+
+ /*
+ * sqsh-2.3 - Initialize variable sg_rl_string.
+ */
+ if( (sg_rl_string = varbuf_create (16384)) == NULL ) {
+ sqsh_set_error( sqsh_get_error(), "sg_rl_string: %s", sqsh_get_errstr() ) ;
+ return False ;
+ }
+
#endif /* USE_READLINE */
return True ;
@@ -186,6 +219,15 @@ int sqsh_readline_exit()
sqsh_get_errstr() );
varbuf_destroy (exp_buf);
}
+
+ /*
+ * sqsh-2.3 - Cleanup sg_rl_string.
+ */
+ if( sg_rl_string != NULL) {
+ varbuf_destroy ( sg_rl_string );
+ sg_rl_string = NULL;
+ }
+
#endif /* USE_READLINE */
return True;
@@ -200,77 +242,135 @@ int sqsh_readline_exit()
char* sqsh_readline( prompt )
char *prompt;
{
- static char str[4096];
- char *line;
+ static char str[16384];
+
#if defined(USE_READLINE)
+ char *line;
char *cp;
- /* sqsh-2.1.6 - New variables */
+ /* sqsh-2.1.6 - New variable */
char *ignoreeof = NULL;
+ /* sqsh-2.2.0 - New variables */
+ char *readline_histignore;
+ char *p1, *p2;
+ int match;
+
+ sqsh_set_error( SQSH_E_NONE, NULL );
+ if (prompt == NULL)
+ {
+ return ( sqsh_stdin_fgets( str, sizeof( str ) ) );
+ }
/* sqsh-2.1.6 feature - Expand color prompt */
prompt = expand_color_prompt (prompt, True);
- if (prompt != NULL)
+
+ /*
+ * sqsh-2.1.6 feature - Obtain environment variable ignoreeof. This will
+ * indicate if we have to ignore ^D yes or no.
+ */
+ env_get( g_env, "ignoreeof", &ignoreeof );
+ if (ignoreeof == NULL || *ignoreeof == '0')
{
/*
- * sqsh-2.1.6 feature - Obtain environment variable ignoreeof. This will
- * indicate if we have to ignore ^D yes or no.
+ * Standard behaviour:
+ * Since we have no way of capturing any real error conditions
+ * from readline, if it returns NULL we just have to assume
+ * that we have hit EOF, and not some error condition. From what
+ * we can tell from the readline library, there is no way to
+ * differentiate the two.
*/
- env_get( g_env, "ignoreeof", &ignoreeof );
- if (ignoreeof == NULL || *ignoreeof == '0')
+ if ((line = readline( prompt )) == NULL)
{
- /*
- * Standard behaviour:
- * Since we have no way of capturing any real error conditions
- * from readline, if it returns NULL we just have to assume
- * that we have hit EOF, and not some error condition. From what
- * we can tell from the readline library, there is no way to
- * differentiate the two.
- */
- if ((line = readline( prompt )) == NULL)
- {
- sqsh_set_error( SQSH_E_NONE, NULL );
- return NULL;
- }
+ return NULL;
}
- else
- {
- /*
- ** If ignoreeof is defined True, continue with readline
- ** as long as NULL is returned (accidentally C-d pressed).
- */
- while ((line = readline( prompt )) == NULL) {
- fprintf (stdout, "\nUse \"exit\" or \"quit\" to leave the sqsh shell.\n");
- fflush (stdout);
- }
+ }
+ else
+ {
+ /*
+ ** If ignoreeof is defined True, continue with readline
+ ** as long as NULL is returned (accidentally C-d pressed).
+ */
+ while ((line = readline( prompt )) == NULL) {
+ fprintf (stdout, "\nUse \"exit\" or \"quit\" to leave the sqsh shell.\n");
+ fflush (stdout);
}
+ }
+ /*
+ * Attempt to find out if there is anything in this line except
+ * for white-space. If there isn't then don't save it to the
+ * history.
+ */
+ for (cp = line; *cp != '\0' && isspace((int)*cp); ++cp);
+ if (*cp != '\0')
+ {
/*
- * Attempt to find out if there is anything in this line except
- * for white-space. If there isn't then don't save it to the
- * history.
- */
- for (cp = line; *cp != '\0' && isspace((int)*cp); ++cp);
-
- if (*cp != '\0')
+ * sqsh-2.2.0 - If $readline_histignore is set, then do not add the line to
+ * the readline history if it matches the provided regular expression or
+ * equals one of the colon separated list of keywords.
+ * if $readline_histignore starts with RE: then it is considered a regular
+ * expression that is evaluated with function regex_match.
+ * Rationale is to filter out the 'go', 'lo', 'mo', quit, etc.
+ * statements from the readline history.
+ */
+ match = False;
+ env_get( g_env, "readline_histignore", &readline_histignore );
+ if (readline_histignore != NULL && *readline_histignore != '\0')
{
- add_history( line );
- }
-
- /*
- * Since readline mallocs line every time and doesn't append a
- * newline, we make a copy of the current line, adding the newline
- * and free the readline copy.
- */
- sqsh_set_error( SQSH_E_NONE, NULL );
- sprintf( str, "%s\n", line );
- free( line );
+ /*
+ * Duplicate the variable to a work buffer so we
+ * can modify it. What we want to do is strip of begin
+ * and end double quotes, if they exists.
+ */
+ readline_histignore = sqsh_strdup (readline_histignore);
+ cp = readline_histignore;
+ if ( cp != NULL && *cp == '"' && *(cp+strlen(cp)-1) == '"' )
+ {
+ *(cp+strlen(cp)-1) = '\0';
+ cp = readline_histignore + 1;
+ }
- return str;
+ if ( cp != NULL && strncmp (cp, "RE:", 3) == 0 )
+ {
+ /*
+ * readline_histignore contains an extended regular expression
+ * if the string starts with RE:
+ */
+ cp = cp + 3;
+ if (regex_match (cp, line) == 0)
+ match = True;
+ }
+ else
+ {
+ for (p1 = cp; p1 != NULL && match == False; p1 = p2)
+ {
+ if ( (p2 = strchr(p1, ':')) != NULL )
+ *p2++ = '\0';
+ if ( strcmp (line, p1) == 0 )
+ match = True;
+ }
+ }
+ if ( readline_histignore != NULL )
+ free (readline_histignore);
+ }
+ if ( match == False )
+ add_history( line );
}
-#endif
+ /*
+ * Since readline mallocs line every time and doesn't append a
+ * newline, we make a copy of the current line, adding the newline
+ * and free the readline copy.
+ * sqsh-2.3 - Use a flexible buffer instead of an array to store
+ * the line. This is to prevent data overflows.
+ */
+ varbuf_strcpy ( sg_rl_string, line );
+ varbuf_strcat ( sg_rl_string, "\n" );
+ free( line );
+ return (varbuf_getstr( sg_rl_string ));
+
+#else /* USE_READLINE */
/*
* If the user supplied a prompt, then print it out. Otherwise
@@ -286,15 +386,46 @@ char* sqsh_readline( prompt )
* Keep trying to read a line until we hit feof(stdin), or while
* we are getting interrupted by signal handlers.
*/
- line = sqsh_stdin_fgets(str, sizeof( str ));
+ return ( sqsh_stdin_fgets( str, sizeof( str )));
- if (line == NULL)
+#endif
+
+}
+
+/*
+ * sqsh_readline_load ():
+ *
+ * sqsh-2.1.8: Check and expand keyword_file variable and call sqsh_readline_read
+ * to suck in the keyword list.
+ */
+int sqsh_readline_load ( void )
+{
+#if !defined(USE_READLINE)
+ sqsh_set_error(SQSH_E_EXIST, "sqsh compiled without readline support" ) ;
+ return False ;
+#else
+ char *keyword_file;
+ varbuf_t *exp_buf;
+ int ret = False ;
+
+ env_get( g_env, "keyword_file", &keyword_file );
+ if ( keyword_file != NULL && *keyword_file != '\0')
{
- return(NULL);
+ exp_buf = varbuf_create( 512 );
+ if (exp_buf == NULL)
+ {
+ fprintf( stderr, "sqsh: %s\n", sqsh_get_errstr() );
+ sqsh_exit( 255 );
+ }
+ if (sqsh_expand( keyword_file, exp_buf, 0 ) != False)
+ ret = sqsh_readline_read( varbuf_getstr( exp_buf) );
+ else
+ fprintf( stderr, "sqsh: Error expanding $keyword_file: %s\n",
+ sqsh_get_errstr() );
+ varbuf_destroy( exp_buf );
}
-
- sqsh_set_error( SQSH_E_NONE, NULL );
- return line;
+ return ret;
+#endif
}
/*
@@ -331,7 +462,7 @@ int sqsh_readline_read( filename )
/*-- Skip whitespace --*/
while( ch != EOF && isspace((int)ch) )
ch = sqsh_getc(infile) ;
-
+
idx = 0 ;
while( ch != EOF && !(isspace((int)ch)) ) {
keyword[idx++] = ch ;
@@ -380,7 +511,7 @@ int sqsh_readline_add( keyword )
}
k->k_nxt = NULL ;
- DBG(sqsh_debug( DEBUG_READLINE, "sqsh_readline_add: Adding '%s'\n",
+ DBG(sqsh_debug( DEBUG_READLINE, "sqsh_readline_add: Adding '%s'\n",
k->k_word ) ;)
if( sg_keyword_end == NULL )
@@ -424,7 +555,7 @@ int sqsh_readline_clear()
#if defined(USE_READLINE)
/*
- * This giant list is the complete list of key words avialable in
+ * This giant list is the complete list of key words avialable in
* in Sybase System 10. It is used by the readline completion
* generator function to do keyword completion. Note, this list
* must remain in sorted order (case insensitive).
@@ -434,245 +565,303 @@ int sqsh_readline_clear()
* relatively useless for completion. Also, there are several
* undocumented key words in here that aren't very useful to most
* humans.
+ * sqsh-2.1.8 - Added all missing reserved words of ASE 15.7.
*/
static char *sqsh_statements[] = {
"abs",
"acos",
- "add",
- "all",
- "alter",
- "and",
- "any",
- "arith_overflow",
- "as",
- "asc",
+ "add",
+ "all",
+ "alter",
+ "and",
+ "any",
+ "arith_overflow",
+ "as",
+ "asc",
"ascii",
"asin",
- "at",
+ "at",
"atan",
"atn2",
- "authorization",
- "avg",
- "begin",
- "between",
- "break",
- "browse",
- "bulk",
- "by",
- "cascade",
+ "authorization",
+ "avg",
+ "begin",
+ "between",
+ "break",
+ "browse",
+ "bulk",
+ "by",
+ "cascade",
+ "case",
"ceiling",
"char",
- "char_convert",
+ "char_convert",
"char_length",
"charindex",
- "check",
- "checkpoint",
- "close",
- "clustered",
+ "check",
+ "checkpoint",
+ "close",
+ "clustered",
+ "coalesce",
"col_length",
"col_name",
- "commit",
- "compute",
- "confirm",
- "constraint",
- "continue",
- "controlrow",
- "convert",
+ "commit",
+ "compressed",
+ "compute",
+ "confirm",
+ "connect",
+ "constraint",
+ "continue",
+ "controlrow",
+ "convert",
"cos",
"cot",
- "count",
- "create",
- "current",
- "cursor",
+ "count",
+ "count_big",
+ "create",
+ "current",
+ "cursor",
"curunreservedpgs",
"data_pgs",
- "database",
+ "database",
"dateadd",
"datediff",
"datename",
"datepart",
"db_id",
"db_name",
- "dbcc",
- "deallocate",
- "declare",
- "default",
- "define",
+ "dbcc",
+ "deallocate",
+ "declare",
+ "decrypt",
+ "decrypt_default",
+ "default",
+ "define",
"degrees",
- "delete",
- "desc",
+ "delete",
+ "desc",
+ "deterministic",
"difference",
- "disk",
- "distinct",
- "double",
- "drop",
- "dummy",
- "dump",
- "else",
- "end",
- "endtran",
- "errlvl",
- "errordata",
- "errorexit",
- "escape",
- "except",
- "execute",
- "exists",
- "exit",
+ "disk",
+ "distinct",
+ "double",
+ "drop",
+ "dual_control",
+ "dummy",
+ "dump",
+ "else",
+ "encrypt",
+ "end",
+ "endtran",
+ "errlvl",
+ "errordata",
+ "errorexit",
+ "escape",
+ "except",
+ "exclusive",
+ "exec",
+ "execute",
+ "exists",
+ "exit",
"exp",
- "fetch",
- "fillfactor",
+ "exp_row_size",
+ "external",
+ "fetch",
+ "fillfactor",
"floor",
- "for",
- "foreign",
- "from",
+ "for",
+ "foreign",
+ "from",
"getdate",
- "goto",
- "grant",
- "group",
- "having",
+ "goto",
+ "grant",
+ "group",
+ "having",
"hextoint",
- "holdlock",
+ "holdlock",
"host_name",
- "identity",
- "identity_insert",
- "if",
- "in",
- "index",
+ "identity",
+ "identity_gap",
+ "identity_insert",
+ "identity_start",
+ "if",
+ "in",
+ "index",
"index_col",
- "insert",
- "intersect",
- "into",
+ "inout",
+ "insensitive",
+ "insert",
+ "install",
+ "intersect",
+ "into",
"inttohex",
- "is",
+ "is",
"isnull",
- "isolation",
- "key",
- "kill",
+ "isolation",
+ "jar",
+ "join",
+ "key",
+ "kill",
"lct_admin",
- "level",
- "like",
- "lineno",
- "load",
- "log",
+ "level",
+ "like",
+ "lineno",
+ "load",
+ "lob_compression",
+ "lock",
+ "log",
"log10",
"lower",
"ltrim",
- "max",
- "min",
- "mirror",
- "mirrorexit",
- "national",
- "noholdlock",
- "nonclustered",
- "not",
- "null",
- "numeric_truncation",
+ "materialized",
+ "max",
+ "max_rows_per_page",
+ "min",
+ "mirror",
+ "mirrorexit",
+ "modify",
+ "national",
+ "noholdlock",
+ "nonclustered",
+ "not",
+ "null",
+ "nullif",
+ "numeric_truncation",
"object_id",
"object_name",
- "of",
- "off",
- "offsets",
- "on",
- "once",
- "only",
- "open",
- "option",
- "or",
- "order",
- "over",
- "param",
+ "of",
+ "off",
+ "offsets",
+ "on",
+ "once",
+ "online",
+ "only",
+ "open",
+ "option",
+ "or",
+ "order",
+ "out",
+ "output",
+ "over",
+ "param",
+ "partition",
"patindex",
- "permanent",
+ "perm",
+ "permanent",
"pi",
- "plan",
+ "plan",
"power",
- "precision",
- "prepare",
- "primary",
- "print",
- "privileges",
+ "precision",
+ "prepare",
+ "primary",
+ "print",
+ "privileges",
+ "proc",
"proc_role",
- "procedure",
- "processexit",
- "public",
+ "procedure",
+ "processexit",
+ "proxy_table",
+ "public",
+ "quiesce",
"radians",
- "raiserror",
+ "raiserror",
"rand",
- "read",
- "readtext",
- "reconfigure",
- "references",
- "replace",
+ "read",
+ "readpast",
+ "readtext",
+ "reconfigure",
+ "references",
+ "release_locks_on_close",
+ "remove",
+ "reorg",
+ "replace",
"replicate",
+ "replication",
"reserved_pgs",
- "restree",
- "return",
+ "reservepagegap",
+ "restree",
+ "return",
+ "returns",
"reverse",
- "revoke",
+ "revoke",
"right",
- "role",
- "rollback",
+ "role",
+ "rollback",
"round",
"rowcnt",
- "rowcount",
- "rows",
+ "rowcount",
+ "rows",
"rtrim",
- "rule",
- "save",
- "schema",
- "select",
- "set",
- "setuser",
- "shared",
+ "rule",
+ "save",
+ "schema",
+ "scroll",
+ "select",
+ "semi_sensitive",
+ "set",
+ "setuser",
+ "shared",
"show_role",
- "shutdown",
+ "shutdown",
"sign",
"sin",
+ "some",
"soundex",
"space",
"sqrt",
- "statement",
- "statistics",
+ "statement",
+ "statistics",
"str",
- "stripe",
+ "stringsize",
+ "stripe",
"stuff",
"substring",
- "sum",
+ "sum",
"suser_id",
"suser_name",
- "syb_identity",
- "table",
+ "syb_identity",
+ "syb_restree",
+ "syb_terminate",
+ "table",
"tan",
- "temporary",
- "terminate",
- "textsize",
- "to",
- "transaction",
- "trigger",
- "truncate",
- "tsequal",
- "union",
- "unique",
- "update",
+ "temp",
+ "temporary",
+ "terminate",
+ "textsize",
+ "to",
+ "tracefile",
+ "tran",
+ "transaction",
+ "trigger",
+ "truncate",
+ "tsequal",
+ "union",
+ "unique",
+ "unpartition",
+ "update",
"upper",
- "use",
+ "use",
"used_pgs",
- "user",
+ "user",
"user_id",
"user_name",
- "user_option",
- "using",
+ "user_option",
+ "using",
"valid_name",
- "values",
- "varying",
- "view",
- "waitfor",
- "where",
- "while",
- "with",
- "work",
- "writetext"
+ "values",
+ "varying",
+ "view",
+ "waitfor",
+ "when",
+ "where",
+ "while",
+ "with",
+ "work",
+ "writetext",
+ "xmlextract",
+ "xmlparse",
+ "xmltable",
+ "xmltest"
} ;
/*
@@ -692,10 +881,14 @@ static char* sqsh_generator( text, state )
int low, high, middle;
int len;
int nitems;
- int r;
+ int r;
char *str;
char *cptr;
char *word;
+ char *keyword_dynamic;
+ char objname[256];
+ varbuf_t *vb;
+ char *tn;
len = strlen(text);
nitems = sizeof(sqsh_statements) / sizeof(char*);
@@ -706,7 +899,7 @@ static char* sqsh_generator( text, state )
* the user even wants statement completion. If he doesn't, then
* don't do anything.
*/
- if (state == 0)
+ if (state == 0)
{
env_get( g_env, "keyword_completion", &keyword_completion );
@@ -714,10 +907,51 @@ static char* sqsh_generator( text, state )
return NULL;
/*
+ * sqsh-2.1.8: In case keyword_dynamic is enabled, check if the user
+ * wants to autocomplete a column/parameter name.
+ */
+ env_get( g_env, "keyword_dynamic", &keyword_dynamic );
+ if (keyword_dynamic != NULL && *keyword_dynamic != '0')
+ {
+ /*
+ * sqsh-2.1.8: If the text string contains a dot, then assume the
+ * first part is an object name and the second part is the column
+ * name we want to autocomplete. Obtain the objname from the text
+ * and query all the column/parameter names for this object and
+ * store them in a linked list.
+ * sqsh-2.4 : Added code to generate a completion list for aliased
+ * objectnames as well. Code contributed by K.-M. Hansche.
+ */
+ for ( idx = strlen(text)-1; idx >= 0 && text[idx] != '.'; idx-- );
+ if ( idx >= 0 && text[idx] == '.' )
+ {
+ strncpy ( objname, text, idx );
+ objname[idx] = '\0';
+ vb = varbuf_create ( varbuf_getlen(g_sqlbuf) + strlen(rl_line_buffer) );
+ if (vb == NULL)
+ {
+ fprintf (stderr, "sqsh: %s\n", sqsh_get_errstr());
+ sqsh_exit (255);
+ }
+ varbuf_strcpy ( vb, varbuf_getstr(g_sqlbuf) );
+ varbuf_strcat ( vb, rl_line_buffer );
+
+ parseSql ( varbuf_getstr(vb) );
+ tn = getTableForAlias ( objname );
+ (void) DynColnameLoad ( (tn != NULL) ? tn : objname, objname );
+
+ varbuf_destroy(vb);
+ delTableDefs();
+ }
+ else if (sg_colname_start != NULL)
+ sqsh_readline_clearcol ();
+ }
+
+ /*
* If the user has supplied their own keyword completion list
* then we want to ignore the built-in one.
*/
- if (sg_keyword_start != NULL)
+ if ((sg_keyword_start != NULL) || (sg_colname_start != NULL))
{
DBG(sqsh_debug(DEBUG_READLINE, "sqsh_generator: Using user list\n" );)
@@ -725,7 +959,7 @@ static char* sqsh_generator( text, state )
* How's this for efficiency? A nice O(n) search of our list
* of keywords. Ok, so it ain't so elegant. Sue me.
*/
- cur = sg_keyword_start;
+ cur = sg_colname_start != NULL ? sg_colname_start : sg_keyword_start;
if (*keyword_completion == '4') /* Exact */
{
for (; cur != NULL && strncmp( cur->k_word, text, len ) != 0;
@@ -736,24 +970,29 @@ static char* sqsh_generator( text, state )
for (; cur != NULL && strncasecmp( cur->k_word, text, len ) != 0;
cur = cur->k_nxt );
}
-
+
/*
* If we failed to find anything, then give up and return
* NULL to the caller indicating that we are all done or
* have not found a match.
+ * sqsh-2.5 : No results? Then try filename completion.
*/
if (cur == NULL)
- return NULL;
-
+ {
+ if (sg_colname_start != NULL)
+ sqsh_readline_clearcol();
+ return ( rl_filename_completion_function (text, state) );
+ }
+
/*
* Otherwise, save a pointer to the word that matched
* so that we can figure out what to do next.
*/
word = cur->k_word;
- }
+ }
else
{
- DBG(sqsh_debug(DEBUG_READLINE,
+ DBG(sqsh_debug(DEBUG_READLINE,
"sqsh_generator: Using internal list\n" );)
/*
@@ -777,22 +1016,23 @@ static char* sqsh_generator( text, state )
}
/*
- * If we couldn't even find a partial match, then give up
+ * If we couldn't even find a partial match, then give up
* and return NULL.
+ * sqsh-2.5 - Try filename completion instead.
*/
if (low > high)
- return NULL;
-
+ return( rl_filename_completion_function (text, state) );
+
/*
* Now, we have found an entry which matches (at least partially)
* the value of text. However, we haven't necessarily found the
- * first on in our sorted list, so we need to back up until we
+ * first on in our sorted list, so we need to back up until we
* find it.
*/
for (idx = middle;
idx > 0 && strncasecmp( sqsh_statements[idx-1], text, len ) == 0;
--idx);
-
+
word = sqsh_statements[idx];
}
@@ -805,29 +1045,48 @@ static char* sqsh_generator( text, state )
* we want to traverse to the next item in the list and see
* if it matches the partial text that was passed in.
*/
- if (sg_keyword_start != NULL)
+ if ((sg_keyword_start != NULL) || (sg_colname_start != NULL))
{
/*
* If we are already at the end of the list then don't
* bother to return anything.
+ * sqsh-2.5 : Try filename completion instead.
*/
if (cur == NULL)
- return NULL;
+ {
+ if (sg_colname_start != NULL)
+ sqsh_readline_clearcol();
+ return( rl_filename_completion_function (text, state) );
+ }
/*
- * Traverse on through the list until we find another
+ * Traverse on through the list until we find another
* match or reach the end of the list.
*/
- for (cur = cur->k_nxt;
- cur != NULL && strncasecmp( cur->k_word, text, len ) != 0;
- cur = cur->k_nxt );
-
+ if (*keyword_completion == '4') /* Exact */
+ {
+ for (cur = cur->k_nxt;
+ cur != NULL && strncmp( cur->k_word, text, len ) != 0;
+ cur = cur->k_nxt );
+ }
+ else
+ {
+ for (cur = cur->k_nxt;
+ cur != NULL && strncasecmp( cur->k_word, text, len ) != 0;
+ cur = cur->k_nxt );
+ }
+
/*
* If we hit the end, then we let the caller know that
* we are all done.
+ * sqsh-2.5 : Try filename completion instead.
*/
if (cur == NULL)
- return NULL;
+ {
+ if (sg_colname_start != NULL)
+ sqsh_readline_clearcol();
+ return( rl_filename_completion_function (text, state) );
+ }
word = cur->k_word;
@@ -840,7 +1099,7 @@ static char* sqsh_generator( text, state )
*/
++idx;
if (idx >= nitems || strncasecmp(sqsh_statements[idx],text,len) != 0)
- return NULL;
+ return( rl_filename_completion_function (text, state) );
word = sqsh_statements[idx];
}
}
@@ -852,49 +1111,49 @@ static char* sqsh_generator( text, state )
* requested the 'keyword_completion' variable and return
* it.
*/
- str = (char*)malloc( (strlen(word) + 1) * sizeof(char) );
-
- if (str == NULL)
+ if ((str = (char*) malloc( (strlen(word) + 1) * sizeof(char) )) == NULL)
{
+ if (sg_colname_start != NULL)
+ sqsh_readline_clearcol();
return NULL;
}
switch (*keyword_completion)
{
case '1': /* Lower case */
-
+
for (cptr = str; *word != '\0'; ++word, ++cptr)
{
- *cptr = tolower(*word);
+ *cptr = tolower( (int) *word);
}
*cptr = '\0';
break;
-
+
case '2': /* Upper case */
for (cptr = str; *word != '\0'; ++word, ++cptr)
{
- *cptr = toupper(*word);
+ *cptr = toupper( (int) *word);
}
*cptr = '\0';
break;
-
+
case '3': /* Smart */
for (cptr = str; *word != '\0'; ++word, ++cptr)
{
if (isupper((int)*text))
{
- *cptr = toupper(*word);
+ *cptr = toupper( (int) *word);
}
else
{
- *cptr = tolower(*word);
+ *cptr = tolower( (int) *word);
}
}
*cptr = '\0';
break;
-
+
case '4': /* Exact */
default:
strcpy( str, word );
@@ -911,4 +1170,244 @@ static char** sqsh_completion( text, start, end )
return (char **)rl_completion_matches( text, (rl_compentry_func_t*)sqsh_generator ) ;
}
+
+/*
+ * sqsh-2.1.8 - New feature: dynamic column name completion.
+ *
+ * The next local functions implement the dynamic column name completion feature.
+ * To keep it simple, I just used my own copies of some of the above functions to
+ * distinguish them from the existing functions that are being used by the keyword
+ * completion function, instead of adapting these functions for generic use.
+ */
+
+
+/*
+ * sqsh_readline_addcol()
+ *
+ * sqsh-2.1.8: Add a new column name to the readline keyword completion list.
+ */
+static int sqsh_readline_addcol( keyword )
+ char *keyword ;
+{
+ keyword_t *k ;
+
+ /*-- Allocate a new structure --*/
+ if( (k = (keyword_t*)malloc(sizeof(keyword_t))) == NULL ) {
+ sqsh_set_error( SQSH_E_NOMEM, NULL ) ;
+ return False ;
+ }
+
+ /*-- Create the keyword --*/
+ if( (k->k_word = sqsh_strdup( keyword )) == NULL ) {
+ free( k ) ;
+ sqsh_set_error( SQSH_E_NOMEM, NULL ) ;
+ return False ;
+ }
+ k->k_nxt = NULL ;
+
+ DBG(sqsh_debug( DEBUG_READLINE, "sqsh_readline_add: Adding '%s'\n",
+ k->k_word ) ;)
+
+ if( sg_colname_end == NULL )
+ sg_colname_start = sg_colname_end = k ;
+ else {
+ sg_colname_end->k_nxt = k ;
+ sg_colname_end = k ;
+ }
+
+ return True ;
+}
+
+
+/*
+ * sqsh_readline_clearcol():
+ *
+ * sqsh-2.1.8: Clears the contents of the object specific column name linked list.
+ */
+static int sqsh_readline_clearcol()
+{
+ keyword_t *k, *n ;
+
+ k = sg_colname_start ;
+ while( k != NULL ) {
+ n = k->k_nxt ;
+ free( k->k_word ) ;
+ free( k ) ;
+ k = n ;
+ }
+
+ sg_colname_start = sg_colname_end = NULL ;
+ return True ;
+}
+
+
+/*
+ * Function: DynColnameLoad()
+ *
+ * sqsh-2.1.8 - Dynamically execute a query to obtain the column names of
+ * an existing table, view or stored procedure.
+ * sqsh-2.4 - Also take the database into account. An object may be
+ * specified as master.dbo.sysdatabases, or dbo.sysusages
+ * or syscolumns for example, the last two expected to
+ * exist in the current database.
+ *
+ */
+static int DynColnameLoad (objname, alias)
+ char *objname;
+ char *alias;
+{
+ CS_COMMAND *cmd;
+ CS_DATAFMT columns[1];
+ CS_RETCODE ret;
+ CS_RETCODE results_ret;
+ CS_INT result_type;
+ CS_INT count;
+ CS_INT idx;
+ CS_INT datalength[1];
+ CS_SMALLINT indicator [1];
+ CS_CHAR name [256];
+ CS_CHAR query [768];
+ CS_CHAR dbname [256];
+ char *cptr;
+
+
+ if (sg_colname_start != NULL)
+ {
+ sqsh_readline_clearcol();
+ }
+ if ( g_connection == NULL )
+ {
+ DBG(sqsh_debug(DEBUG_ERROR, "DynColnameLoad: g_connection is not initialized.\n"));
+ return (CS_FAIL);
+ }
+ if (ct_cmd_alloc( g_connection, &cmd ) != CS_SUCCEED)
+ {
+ DBG(sqsh_debug(DEBUG_ERROR, "DynColnameLoad: Call to ct_cmd_alloc failed.\n"));
+ return (CS_FAIL);
+ }
+ /*
+ * sqsh-2.4 - If the objectname contains two dots, then the first part specifies
+ * the database name, the second part the owner name (may be empty) and the last
+ * part the objectname itself.
+ */
+ if ((cptr = strchr( objname, '.' )) != NULL && strchr( cptr + 1, '.' ) != NULL)
+ {
+ idx = (CS_INT) (cptr - objname);
+ strncpy (dbname, objname, idx);
+ dbname[idx] = '\0';
+ sprintf (query, "select \'%s.\' + name from %s..syscolumns where id=object_id(\'%s\') order by name"
+ ,alias, dbname, objname);
+ }
+ else
+ sprintf (query, "select \'%s.\' + name from syscolumns where id=object_id(\'%s\') order by name"
+ ,alias, objname);
+
+ if (ct_command( cmd, /* Command Structure */
+ CS_LANG_CMD, /* Command Type */
+ query, /* Query Buffer */
+ CS_NULLTERM, /* Buffer Length */
+ CS_UNUSED /* Options */
+ ) != CS_SUCCEED)
+ {
+ ct_cmd_drop( cmd );
+ DBG(sqsh_debug(DEBUG_ERROR, "DynColnameLoad: Call to ct_command failed.\n"));
+ return (CS_FAIL);
+ }
+ if (ct_send( cmd ) != CS_SUCCEED)
+ {
+ ct_cmd_drop( cmd );
+ DBG(sqsh_debug(DEBUG_ERROR, "DynColnameLoad: Call to ct_send failed.\n"));
+ return (CS_FAIL);
+ }
+
+ while ((results_ret = ct_results(cmd, &result_type)) == CS_SUCCEED)
+ {
+ switch ((int) result_type)
+ {
+ case CS_ROW_RESULT:
+ columns[0].datatype = CS_CHAR_TYPE;
+ columns[0].format = CS_FMT_NULLTERM;
+ columns[0].maxlength = 255;
+ columns[0].count = 1;
+ columns[0].locale = NULL;
+ ct_bind(cmd, 1, &columns[0], name, &datalength[0], &indicator[0]);
+
+ while (ct_fetch(cmd, CS_UNUSED, CS_UNUSED, CS_UNUSED, &count) == CS_SUCCEED)
+ {
+ /* Remove trailing blanks, tabs and newlines, just in case */
+ for ( idx = strlen(name) - 1;
+ idx >= 0 && (name[idx] == ' ' || name[idx] == '\t' || name[idx] == '\n');
+ name[idx--] = '\0');
+
+ sqsh_readline_addcol ( name ); /* Add name to linked list of colnames */
+ }
+ break;
+
+ case CS_CMD_SUCCEED:
+ DBG(sqsh_debug(DEBUG_ERROR, "DynColnameLoad: No rows returned from query.\n"));
+ ret = CS_FAIL;
+ break;
+
+ case CS_CMD_FAIL:
+ DBG(sqsh_debug(DEBUG_ERROR, "DynColnameLoad: Error encountered during query processing.\n"));
+ ret = CS_FAIL;
+ break;
+
+ case CS_CMD_DONE:
+ break;
+
+ default:
+ DBG(sqsh_debug(DEBUG_ERROR, "DynColnameLoad: Unexpected error encountered. (1)\n"));
+ ret = CS_FAIL;
+ break;
+ }
+ }
+
+ switch ((int) results_ret)
+ {
+ case CS_END_RESULTS:
+ ret = CS_SUCCEED;
+ break;
+
+ case CS_FAIL:
+ DBG(sqsh_debug(DEBUG_ERROR, "DynColnameLoad: Unexpected error encountered. (2)\n"));
+ ret = CS_FAIL;
+ break;
+
+ default:
+ DBG(sqsh_debug(DEBUG_ERROR, "DynColnameLoad: Unexpected error encountered. (3)\n"));
+ ret = CS_FAIL;
+ break;
+ }
+ ct_cmd_drop( cmd );
+ if (ret == CS_FAIL)
+ sqsh_readline_clearcol();
+
+ return ( ret );
+}
+
+
+/*
+ * sqsh-2.2.0 - Function regex_match.
+ *
+ * Match string against the extended regular expression in
+ * pattern, treating errors as no match.
+ *
+ * Return 0 for match, not 0 for no match.
+*/
+static int regex_match (pattern, string)
+ char *pattern;
+ char *string;
+{
+ regex_t re;
+ int status;
+
+
+ if ((status = regcomp (&re, pattern, REG_EXTENDED|REG_NOSUB|REG_ICASE) != 0))
+ return (status);
+ status = regexec (&re, string, (size_t) 0, NULL, 0);
+ regfree (&re);
+ return (status);
+}
+
#endif /* USE_READLINE */
diff --git a/src/sqsh_readline.h b/src/sqsh_readline.h
index 257b8da..ede5c90 100644
--- a/src/sqsh_readline.h
+++ b/src/sqsh_readline.h
@@ -25,12 +25,40 @@
#ifndef sqsh_readline_h_included
#define sqsh_readline_h_included
+#if defined(USE_READLINE)
+#include <readline/readline.h>
+
+/*
+ * Readline history functions - for some reason not all
+ * readline installs have history.h available, so we do
+ * this.
+ */
+#if !defined (PARAMS)
+# if defined (__STDC__) || defined (__GNUC__) || defined (__cplusplus)
+# define PARAMS(protos) protos
+# else
+# define PARAMS(protos) ()
+# endif
+#endif /* PARAMS */
+
+extern void _rl_clear_screen PARAMS((void));
+
+#if !defined (_HISTORY_H_)
+extern void stifle_history PARAMS((int));
+extern int unstifle_history PARAMS((void));
+extern int read_history PARAMS((const char *));
+extern int write_history PARAMS((const char *));
+extern void add_history PARAMS((const char *));
+#endif /*_HISTORY_H_ */
+
+#endif /* USE_READLINE */
+
/*-- Prototypes --*/
int sqsh_readline_init _ANSI_ARGS(( void ));
int sqsh_readline_exit _ANSI_ARGS(( void ));
char* sqsh_readline _ANSI_ARGS(( char* )) ;
+int sqsh_readline_load _ANSI_ARGS(( void )) ;
int sqsh_readline_read _ANSI_ARGS(( char* )) ;
int sqsh_readline_add _ANSI_ARGS(( char* )) ;
int sqsh_readline_clear _ANSI_ARGS(( void )) ;
-
#endif /* sqsh_readline_h_included */
diff --git a/src/var.h b/src/var.h
index ec796b9..586a0f7 100644
--- a/src/var.h
+++ b/src/var.h
@@ -60,6 +60,10 @@ int var_set_bcp_colsep _ANSI_ARGS(( env_t*, char*, char** )) ;
int var_set_bcp_rowsep _ANSI_ARGS(( env_t*, char*, char** )) ;
int var_set_bcp_trim _ANSI_ARGS(( env_t*, char*, char** )) ;
int var_set_maxlen _ANSI_ARGS(( env_t*, char*, char** )) ;
+int var_set_datefmt _ANSI_ARGS(( env_t*, char*, char** )) ;
+int var_set_timefmt _ANSI_ARGS(( env_t*, char*, char** )) ;
+int var_set_lconv _ANSI_ARGS(( env_t*, char*, char** )) ;
+int var_set_p2fname _ANSI_ARGS(( env_t*, char*, char** )) ;
/*-- Retrieval validation functions --*/
int var_get_date _ANSI_ARGS(( env_t*, char*, char** )) ;
@@ -78,6 +82,8 @@ int var_get_bcp_rowsep _ANSI_ARGS(( env_t*, char*, char** )) ;
int var_get_bcp_trim _ANSI_ARGS(( env_t*, char*, char** )) ;
int var_get_interactive _ANSI_ARGS(( env_t*, char*, char** )) ;
int var_get_maxlen _ANSI_ARGS(( env_t*, char*, char** )) ;
+int var_get_datefmt _ANSI_ARGS(( env_t*, char*, char** )) ;
+int var_get_timefmt _ANSI_ARGS(( env_t*, char*, char** )) ;
#ifdef SQSH_INIT
@@ -100,13 +106,13 @@ static var_entry_t sg_var_entry[] = {
{ "banner", "1", var_set_bool, NULL },
{ "batch_failcount", "0", var_set_add, NULL },
{ "batch_pause", "0", var_set_bool, NULL },
- { "bcp_colsep", NULL, var_set_bcp_colsep, var_get_bcp_colsep},
- { "bcp_rowsep", NULL, var_set_bcp_rowsep, var_get_bcp_rowsep},
- { "bcp_trim", NULL, var_set_bcp_trim, var_get_bcp_trim},
- { "chained", NULL, var_set_bool, NULL }, /* XXX */
+ { "bcp_colsep", "|", var_set_bcp_colsep, var_get_bcp_colsep},
+ { "bcp_rowsep", "|", var_set_bcp_rowsep, var_get_bcp_rowsep},
+ { "bcp_trim", "1", var_set_bcp_trim, var_get_bcp_trim},
+ { "chained", NULL, var_set_bool, NULL },
{ "charset", NULL, var_set_nullstr, NULL },
{ "clear_on_fail", "1", var_set_bool, NULL },
- { "colsep", NULL, var_set_colsep, var_get_colsep },
+ { "colsep", " ", var_set_colsep, var_get_colsep },
{ "colwidth", "32", var_set_colwidth, var_get_colwidth},
{ "DISPLAY", NULL, var_set_env, var_get_env },
{ "database", NULL, var_set_nullstr, NULL },
@@ -124,51 +130,50 @@ static var_entry_t sg_var_entry[] = {
{ "footers", "1", var_set_bool, NULL },
{ "headers", "1", var_set_bool, NULL },
{ "help_dir", SQSH_HELP, var_set_path_r, NULL },
- { "history", SQSH_HISTORY, NULL, NULL },
+ { "history", SQSH_HISTORY, var_set_nullstr, NULL },
{ "history_shorthand","0", var_set_bool, NULL },
{ "histnum", "0", var_set_int, NULL },
{ "histsave", "1", var_set_bool, NULL },
{ "histsize", "10", var_set_histsize, NULL },
{ "hostname", NULL, var_set_nullstr, NULL },
{ "ifs", "\n\f\r\t\v", var_set_esc, NULL },
- { "interactive", "1", NULL, var_get_interactive },
- { "interfaces", NULL, var_set_interfaces, NULL },
+ { "interactive", "1", var_set_readonly, var_get_interactive },
+ { "interfaces", NULL, var_set_interfaces, NULL },
{ "keyword_completion", "0", var_set_completion, NULL },
- { "keyword_file", SQSH_WORDS, NULL, NULL },
+ { "keyword_file", SQSH_WORDS, var_set_nullstr, NULL },
{ "language", NULL, var_set_nullstr, NULL },
{ "lineno", "1", var_set_add, NULL },
- { "linesep", NULL, var_set_linesep, var_get_linesep },
+ { "linesep", "\n\t", var_set_linesep, var_get_linesep },
{ "lock", NULL, var_set_lock, NULL },
- { "maxlen", NULL, var_set_maxlen, var_get_maxlen },
+ { "maxlen", "32768", var_set_maxlen, var_get_maxlen },
{ "newline_go", "0", var_set_bool, NULL },
{ "output_parms", "1", var_set_outputparms, var_get_outputparms },
{ "packet_size", NULL, var_set_packet, NULL },
{ "password", "", var_set_password, NULL },
{ "password_retry", "1", var_set_bool, NULL },
- { "prompt", "\\\\${lineno}> ",NULL, NULL },
- { "prompt2", "\\\\${lineno}--> ",NULL, NULL },
- { "rcfile", SQSH_RC, NULL, NULL },
- { "repeat_batch", "0", var_set_bool, NULL },
- { "readline_history",SQSH_RLHISTORY, NULL, NULL },
+ { "prompt", "\\\\${lineno}> ",var_set_nullstr, NULL },
+ { "prompt2", "\\\\${lineno}--> ",var_set_nullstr, NULL },
+ { "rcfile", SQSH_RC, var_set_nullstr, NULL },
+ { "repeat_batch", "0", var_set_bool, NULL },
+ { "readline_history",SQSH_RLHISTORY, var_set_nullstr, NULL },
{ "readline_histsize","100", var_set_rl_histsize, NULL },
- { "semicolon_hack", "0", var_set_bool, NULL },
- { "semicolon_cmd", "\\go", var_set_nullstr, NULL },
+ { "semicolon_hack", "0", var_set_bool, NULL },
+ { "semicolon_cmd", "\\go", var_set_nullstr, NULL },
{ "session", SQSH_SESSION, var_set_nullstr, NULL },
- { "start_connected", "1", var_set_bool, NULL },
- { "statistics", "0", var_set_bool, NULL },
- { "style", "horiz", var_set_style, var_get_style },
- { "thresh_display", "0", var_set_severity, NULL },
- { "thresh_exit", "0", var_set_int, NULL },
- { "thresh_fail", "11", var_set_severity, NULL },
- { "tmp_dir", SQSH_TMP, NULL, NULL },
- { "username", NULL, NULL, NULL },
+ { "statistics", "0", var_set_bool, NULL },
+ { "style", "horizontal", var_set_style, var_get_style },
+ { "thresh_display", "0", var_set_severity, NULL },
+ { "thresh_exit", "0", var_set_int, NULL },
+ { "thresh_fail", "11", var_set_severity, NULL },
+ { "tmp_dir", SQSH_TMP, var_set_nullstr, NULL },
+ { "username", NULL, var_set_nullstr, NULL },
{ "version", SQSH_VERSION, var_set_readonly, NULL },
{ "width", NULL, var_set_width, var_get_width },
{ "xgeom", NULL, var_set_xgeom, var_get_xgeom },
{ "date", "%d-%b-%y", var_set_notempty, var_get_date },
{ "time", "%H:%M:%S", var_set_notempty, var_get_time },
/* sqsh-2.1.6 - New variables */
- { "appname", "sqsh-2.1.7", var_set_nullstr, NULL },
+ { "appname", SQSH_VERSION, var_set_nullstr, NULL },
{ "histunique", "0", var_set_bool, NULL },
{ "ignoreeof", "0", var_set_bool, NULL },
{ "login_timeout", NULL, var_set_nullint, NULL },
@@ -183,6 +188,35 @@ static var_entry_t sg_var_entry[] = {
{ "hist_auto_save", "0", var_set_int, NULL },
{ "xwin_title", NULL, var_set_nullstr, NULL },
{ "term_title", NULL, var_set_nullstr, NULL },
+#if defined(USE_READLINE)
+ /* sqsh-2.1.8 - New variables */
+ { "keyword_dynamic", "0", var_set_bool, NULL },
+ { "keyword_query", SQSH_KEYQUERY, var_set_nullstr, NULL },
+#endif
+ /* sqsh-2.1.9 - New variables */
+ { "datefmt", NULL, var_set_datefmt, var_get_datefmt },
+ { "timefmt", NULL, var_set_timefmt, var_get_timefmt },
+ /* sqsh-2.2.0 - New or missing variables in global env added */
+ { "autouse", NULL, var_set_nullstr, NULL },
+ { "debug_tds_logdata",NULL, var_set_nullstr, NULL },
+ { "debug_tds_capture",NULL, var_set_nullstr, NULL },
+ { "histmerge", "0", var_set_bool, NULL },
+ { "readline_histignore", NULL, var_set_nullstr, NULL },
+ { "script", NULL, var_set_nullstr, NULL },
+ { "semicolon_hack2", "0", var_set_bool, NULL },
+ { "tds_version", NULL, var_set_nullstr, NULL },
+ /* sqsh-2.3 - New variable */
+ { "localeconv", "0", var_set_lconv, NULL },
+ /* sqsh-2.4 - New variable */
+ { "usedbcheck", "0", var_set_bool, NULL },
+ /* sqsh-2.5 - New variables */
+ { "nosepline", "0", var_set_bool, NULL },
+ { "p2faxm", NULL, var_set_nullint, NULL },
+ { "p2fname", NULL, var_set_p2fname, NULL },
+#if defined(__ansi__)
+ { "builddate", __DATE__, var_set_readonly, NULL },
+ { "buildtime", __TIME__, var_set_readonly, NULL },
+#endif
} ;
#endif /* SQSH_INIT */
diff --git a/src/var_ctlib.c b/src/var_ctlib.c
index d84abb3..c9384cb 100644
--- a/src/var_ctlib.c
+++ b/src/var_ctlib.c
@@ -34,7 +34,7 @@
/*-- Current Version --*/
#if !defined(lint) && !defined(__LINT__)
-static char RCS_Id[] = "$Id: var_ctlib.c,v 1.2 2009/04/14 10:22:18 mwesdorp Exp $" ;
+static char RCS_Id[] = "$Id: var_ctlib.c,v 1.3 2013/12/24 13:23:19 mwesdorp Exp $" ;
USE(RCS_Id)
#endif /* !defined(lint) */
@@ -107,12 +107,15 @@ int var_set_packet( env, var_name, var_value )
return False;
}
+ if (*var_value == NULL)
+ return True;
+
packet_size = atoi(*var_value);
if (packet_size <= 0 || (packet_size % 512) != 0)
{
sqsh_set_error( SQSH_E_INVAL,
- "Invalid packet size. Must a multiple of 512 bytes" );
+ "Invalid packet size. Must be a multiple of 512 bytes" );
return False;
}
diff --git a/src/var_debug.c b/src/var_debug.c
index 60ef639..cac311c 100644
--- a/src/var_debug.c
+++ b/src/var_debug.c
@@ -32,7 +32,7 @@
/*-- Current Version --*/
#if !defined(lint) && !defined(__LINT__)
-static char RCS_Id[] = "$Id: var_debug.c,v 1.1.1.1 2004/04/07 12:35:03 chunkm0nkey Exp $" ;
+static char RCS_Id[] = "$Id: var_debug.c,v 1.5 2014/03/12 14:40:42 mwesdorp Exp $" ;
USE(RCS_Id)
#endif /* !defined(lint) */
@@ -55,6 +55,8 @@ struct debug_st {
{ "ERROR", DEBUG_ERROR },
{ "EXPAND", DEBUG_EXPAND },
{ "FD", DEBUG_FD },
+ { "HISTORY", DEBUG_HISTORY },
+ { "HIST", DEBUG_HISTORY },
{ "JOB", DEBUG_JOB },
{ "READLINE", DEBUG_READLINE},
{ "RL", DEBUG_READLINE},
@@ -63,6 +65,7 @@ struct debug_st {
{ "SIG", DEBUG_SIG },
{ "SIGCHLD", DEBUG_SIGCLD },
{ "SIGCLD", DEBUG_SIGCLD },
+ { "TDS", DEBUG_TDS },
} ;
#endif
@@ -91,7 +94,7 @@ int var_set_debug( env, var_name, var_value )
int nitems ;
char error_msg[256];
- if( *var_value == NULL || strcmp(*var_value, "NULL") == 0 ) {
+ if( *var_value == NULL || strcasecmp(*var_value, "NULL") == 0 ) {
sqsh_debug_level( 0 ) ;
*var_value="0" ;
return True ;
@@ -103,17 +106,17 @@ int var_set_debug( env, var_name, var_value )
while( *str != '\0' ) {
/*-- Skip leading white space --*/
- for( ; *str != '\0' && isspace(*str); ++str ) ;
+ for( ; *str != '\0' && isspace( (int) *str); ++str ) ;
- for( i = 0; *str != '\0' && !(isspace(*str)) && *str != '|'; ++str ) {
+ for( i = 0; *str != '\0' && !(isspace( (int) *str)) && *str != '|'; ++str ) {
if( i < sizeof(flag_name) )
flag_name[i++] = *str ;
}
flag_name[i] = '\0' ;
- if( isspace(*str) ) {
+ if( isspace( (int) *str) ) {
/*-- Skip leading white space --*/
- for( ++str; *str != '\0' && isspace(*str); ++str ) ;
+ for( ++str; *str != '\0' && isspace( (int) *str); ++str ) ;
if( !(*str == '\0' || *str == '|') ) {
sqsh_set_error( SQSH_E_INVAL,
@@ -125,7 +128,7 @@ int var_set_debug( env, var_name, var_value )
if( *str != '\0' )
++str ;
- if( isdigit(*flag_name) )
+ if( isdigit( (int) *flag_name) )
debug_flags |= atoi(flag_name) ;
else {
for( i = 0; i < nitems; i++ ) {
diff --git a/src/var_dsp.c b/src/var_dsp.c
index a3fb678..4dffb47 100644
--- a/src/var_dsp.c
+++ b/src/var_dsp.c
@@ -34,7 +34,7 @@
/*-- Current Version --*/
#if !defined(lint) && !defined(__LINT__)
-static char RCS_Id[] = "$Id: var_dsp.c,v 1.3 2009/12/23 12:47:46 mwesdorp Exp $";
+static char RCS_Id[] = "$Id: var_dsp.c,v 1.7 2014/03/12 14:40:43 mwesdorp Exp $";
USE(RCS_Id)
#endif /* !defined(lint) */
@@ -80,36 +80,24 @@ int var_set_fltfmt( env, var_name, var_value )
if (strcmp( var_name, "float" ) == 0)
{
- if (dsp_prop( DSP_SET,
- DSP_FLOAT_PREC,
- (void*)&prec,
- DSP_UNUSED ) != DSP_SUCCEED)
+ if (dsp_prop( DSP_SET, DSP_FLOAT_PREC, (void*)&prec, DSP_UNUSED ) != DSP_SUCCEED)
{
return False;
}
- if (dsp_prop( DSP_SET,
- DSP_FLOAT_SCALE,
- (void*)&scale,
- DSP_UNUSED ) != DSP_SUCCEED)
+ if (dsp_prop( DSP_SET, DSP_FLOAT_SCALE, (void*)&scale, DSP_UNUSED ) != DSP_SUCCEED)
{
return False;
}
}
else
{
- if (dsp_prop( DSP_SET,
- DSP_REAL_PREC,
- (void*)&prec,
- DSP_UNUSED ) != DSP_SUCCEED)
+ if (dsp_prop( DSP_SET, DSP_REAL_PREC, (void*)&prec, DSP_UNUSED ) != DSP_SUCCEED)
{
return False;
}
- if (dsp_prop( DSP_SET,
- DSP_REAL_SCALE,
- (void*)&scale,
- DSP_UNUSED ) != DSP_SUCCEED)
+ if (dsp_prop( DSP_SET, DSP_REAL_SCALE, (void*)&scale, DSP_UNUSED ) != DSP_SUCCEED)
{
return False;
}
@@ -118,15 +106,20 @@ int var_set_fltfmt( env, var_name, var_value )
return True;
}
+/*
+ * sqsh-2.1.9 - Implement date and time datatype conversion routines.
+ * New and modified functions: var_set_datetime, var_get_datetime,
+ * var_set_datefmt, var_get_datefmt, var_set_timefmt, var_get_timefmt.
+ */
int var_set_datetime( env, var_name, var_value )
env_t *env ;
char *var_name ;
char **var_value ;
{
- if (dsp_prop( DSP_SET,
- DSP_DATEFMT,
- (void*)(*(var_value)),
- DSP_NULLTERM ) != DSP_SUCCEED)
+ if ( *var_value == NULL || strcasecmp( *var_value, "NULL" ) == 0 || **var_value == '\0' )
+ *var_value = NULL ;
+
+ if (dsp_prop( DSP_SET, DSP_DATETIMEFMT, (void*)(*(var_value)), DSP_NULLTERM ) != DSP_SUCCEED)
{
return False;
}
@@ -141,10 +134,71 @@ int var_get_datetime( env, var_name, var_value )
{
static char date_str[64];
- if (dsp_prop( DSP_GET,
- DSP_DATEFMT,
- (void*)date_str,
- sizeof(date_str) ) != DSP_SUCCEED)
+ if (dsp_prop( DSP_GET, DSP_DATETIMEFMT, (void*)date_str, sizeof(date_str) ) != DSP_SUCCEED)
+ {
+ return False;
+ }
+
+ *var_value = date_str;
+ return True;
+}
+
+int var_set_datefmt( env, var_name, var_value )
+ env_t *env ;
+ char *var_name ;
+ char **var_value ;
+{
+ if ( *var_value == NULL || strcasecmp( *var_value, "NULL" ) == 0 || **var_value == '\0' )
+ *var_value = NULL ;
+
+ if (dsp_prop( DSP_SET, DSP_DATEFMT, (void*)(*(var_value)), DSP_NULLTERM ) != DSP_SUCCEED)
+ {
+ return False;
+ }
+
+ return True;
+}
+
+int var_get_datefmt( env, var_name, var_value )
+ env_t *env ;
+ char *var_name ;
+ char **var_value ;
+{
+ static char date_str[64];
+
+ if (dsp_prop( DSP_GET, DSP_DATEFMT, (void*)date_str, sizeof(date_str) ) != DSP_SUCCEED)
+ {
+ return False;
+ }
+
+ *var_value = date_str;
+ return True;
+}
+
+int var_set_timefmt( env, var_name, var_value )
+ env_t *env ;
+ char *var_name ;
+ char **var_value ;
+{
+ if ( *var_value == NULL || strcasecmp( *var_value, "NULL" ) == 0 || **var_value == '\0' )
+ *var_value = NULL ;
+
+ if (dsp_prop( DSP_SET, DSP_TIMEFMT, (void*)(*(var_value)), DSP_NULLTERM ) != DSP_SUCCEED)
+ {
+ return False;
+ }
+
+ return True;
+}
+
+int var_get_timefmt( env, var_name, var_value )
+ env_t *env ;
+ char *var_name ;
+ char **var_value ;
+{
+ static char date_str[64];
+
+ if (dsp_prop( DSP_GET, DSP_TIMEFMT, (void*)date_str, sizeof(date_str) ) != DSP_SUCCEED)
{
return False;
}
@@ -158,7 +212,7 @@ int var_set_style( env, var_name, var_value )
char *var_name;
char **var_value;
{
- int dsp_style;
+ int style;
if (*var_value == NULL)
{
@@ -170,36 +224,36 @@ int var_set_style( env, var_name, var_value )
strcmp( *var_value, "horiz" ) == 0 ||
strcmp( *var_value, "horizontal" ) == 0)
{
- dsp_style = DSP_HORIZ;
+ style = DSP_HORIZ;
}
else if (strcmp( *var_value, "vert" ) == 0 ||
strcmp( *var_value, "vertical" ) == 0)
{
- dsp_style = DSP_VERT;
+ style = DSP_VERT;
}
else if (strcmp( *var_value, "bcp" ) == 0)
{
- dsp_style = DSP_BCP;
+ style = DSP_BCP;
}
else if (strcmp( *var_value, "csv" ) == 0)
{
- dsp_style = DSP_CSV;
+ style = DSP_CSV;
}
else if (strcmp( *var_value, "html" ) == 0)
{
- dsp_style = DSP_HTML;
+ style = DSP_HTML;
}
else if (strcmp( *var_value, "none" ) == 0)
{
- dsp_style = DSP_NONE;
+ style = DSP_NONE;
}
else if (strcmp( *var_value, "meta" ) == 0)
{
- dsp_style = DSP_META;
+ style = DSP_META;
}
else if (strcmp( *var_value, "pretty" ) == 0)
{
- dsp_style = DSP_PRETTY;
+ style = DSP_PRETTY;
}
else
{
@@ -207,14 +261,13 @@ int var_set_style( env, var_name, var_value )
return False;
}
- if (dsp_prop( DSP_SET,
- DSP_STYLE,
- (void*)&dsp_style,
- DSP_UNUSED ) != DSP_SUCCEED)
+ if (dsp_prop( DSP_SET, DSP_STYLE, (void*)&style, DSP_UNUSED ) != DSP_SUCCEED)
{
return False;
}
+ DBG(sqsh_debug(DEBUG_SCREEN,"var_set_style: Display style now set to %s\n", *var_value);)
+
return True;
}
@@ -223,17 +276,14 @@ int var_get_style( env, var_name, var_value )
char *var_name;
char **var_value;
{
- int dsp_style;
+ int style;
- if (dsp_prop( DSP_GET,
- DSP_STYLE,
- (void*)&dsp_style,
- DSP_UNUSED ) != DSP_SUCCEED)
+ if (dsp_prop( DSP_GET, DSP_STYLE, (void*)&style, DSP_UNUSED ) != DSP_SUCCEED)
{
return False;
}
- switch (dsp_style)
+ switch (style)
{
case DSP_HORIZ:
*var_value = "horizontal";
@@ -272,29 +322,45 @@ int var_set_colwidth( env, var_name, var_value )
char *var_name;
char **var_value;
{
- int width;
+ int colwidth;
if (var_set_nullint( env, var_name, var_value ) == False)
{
return False;
}
- width = atoi(*var_value);
+ colwidth = (*var_value != NULL) ? atoi(*var_value) : 30;
- if (dsp_prop( DSP_SET,
- DSP_COLWIDTH,
- (void*)&width,
- DSP_UNUSED ) != DSP_SUCCEED)
+ if (dsp_prop( DSP_SET, DSP_COLWIDTH, (void*)&colwidth, DSP_UNUSED ) != DSP_SUCCEED)
{
return False;
}
- DBG(sqsh_debug(DEBUG_SCREEN,"var_set_colwidth: Column width now set to %s\n",
- *var_value);)
+ DBG(sqsh_debug(DEBUG_SCREEN,"var_set_colwidth: Column width now set to %s\n", *var_value);)
return True ;
}
+int var_get_colwidth( env, var_name, var_value )
+ env_t *env;
+ char *var_name;
+ char **var_value;
+{
+ static char nbr[16];
+ int colwidth;
+
+ if (dsp_prop( DSP_GET, DSP_COLWIDTH, (void*)&colwidth, DSP_UNUSED ) != DSP_SUCCEED)
+ {
+ *var_value = NULL;
+ return False;
+ }
+
+ sprintf( nbr, "%d", colwidth );
+
+ *var_value = nbr;
+ return True;
+}
+
int var_set_outputparms( env, var_name, var_value )
env_t *env;
char *var_name;
@@ -309,17 +375,12 @@ int var_set_outputparms( env, var_name, var_value )
outputparms = atoi(*var_value);
- if (dsp_prop( DSP_SET,
- DSP_OUTPUTPARMS,
- (void*)&outputparms,
- DSP_UNUSED ) != DSP_SUCCEED)
+ if (dsp_prop( DSP_SET, DSP_OUTPUTPARMS, (void*)&outputparms, DSP_UNUSED ) != DSP_SUCCEED)
{
return False;
}
- DBG(sqsh_debug(DEBUG_SCREEN,
- "var_set_output_parms: Column width now set to %s\n",
- *var_value);)
+ DBG(sqsh_debug(DEBUG_SCREEN, "var_set_output_parms: Output parameters now set to %s\n", *var_value);)
return True;
}
@@ -332,10 +393,7 @@ int var_get_outputparms( env, var_name, var_value )
static char nbr[4];
int outputparms;
- if (dsp_prop( DSP_GET,
- DSP_OUTPUTPARMS,
- (void*)&outputparms,
- DSP_UNUSED ) != DSP_SUCCEED)
+ if (dsp_prop( DSP_GET, DSP_OUTPUTPARMS, (void*)&outputparms, DSP_UNUSED ) != DSP_SUCCEED)
{
*var_value = NULL;
return False;
@@ -359,18 +417,14 @@ int var_set_width( env, var_name, var_value )
return False;
}
- width = atoi(*var_value);
+ width = (*var_value != NULL) ? atoi(*var_value) : 0;
- if (dsp_prop( DSP_SET,
- DSP_WIDTH,
- (void*)&width,
- DSP_UNUSED ) != DSP_SUCCEED)
+ if (dsp_prop( DSP_SET, DSP_WIDTH, (void*)&width, DSP_UNUSED ) != DSP_SUCCEED)
{
return False;
}
- DBG(sqsh_debug(DEBUG_SCREEN,"var_set_width: Width now set to %s\n",
- *var_value);)
+ DBG(sqsh_debug(DEBUG_SCREEN,"var_set_width: Width now set to %s\n", *var_value);)
return True ;
}
@@ -383,33 +437,7 @@ int var_get_width( env, var_name, var_value )
static char nbr[16];
int width;
- if (dsp_prop( DSP_GET,
- DSP_WIDTH,
- (void*)&width,
- DSP_UNUSED ) != DSP_SUCCEED)
- {
- *var_value = NULL;
- return False;
- }
-
- sprintf( nbr, "%d", width );
-
- *var_value = nbr;
- return True;
-}
-
-int var_get_colwidth( env, var_name, var_value )
- env_t *env;
- char *var_name;
- char **var_value;
-{
- static char nbr[16];
- int width;
-
- if (dsp_prop( DSP_GET,
- DSP_COLWIDTH,
- (void*)&width,
- DSP_UNUSED ) != DSP_SUCCEED)
+ if (dsp_prop( DSP_GET, DSP_WIDTH, (void*)&width, DSP_UNUSED ) != DSP_SUCCEED)
{
*var_value = NULL;
return False;
@@ -426,19 +454,18 @@ int var_set_colsep( env, var_name, var_value )
char *var_name;
char **var_value;
{
- if (var_set_nullstr( env, var_name, var_value ) == False)
+ if (var_set_esc( env, var_name, var_value ) == False)
{
return False;
}
- if (dsp_prop( DSP_SET,
- DSP_COLSEP,
- (void*)(*var_value),
- DSP_NULLTERM ) != DSP_SUCCEED)
+ if (dsp_prop( DSP_SET, DSP_COLSEP, (void*)(*var_value), DSP_NULLTERM ) != DSP_SUCCEED)
{
return False;
}
+ DBG(sqsh_debug(DEBUG_SCREEN,"var_set_colsep: Column separator now set to %s\n", *var_value);)
+
return True ;
}
@@ -449,10 +476,7 @@ int var_get_colsep( env, var_name, var_value )
{
static char colsep[32];
- if (dsp_prop( DSP_GET,
- DSP_COLSEP,
- (void*)colsep,
- sizeof(colsep) ) != DSP_SUCCEED)
+ if (dsp_prop( DSP_GET, DSP_COLSEP, (void*)colsep, sizeof(colsep) ) != DSP_SUCCEED)
{
*var_value = NULL;
return False;
@@ -467,17 +491,18 @@ int var_set_bcp_colsep( env, var_name, var_value )
char *var_name;
char **var_value;
{
- if (var_set_nullstr( env, var_name, var_value ) == False)
+ if (var_set_esc( env, var_name, var_value ) == False)
{
return False;
}
- if (dsp_prop( DSP_SET, DSP_BCP_COLSEP, (void*)(*var_value), DSP_NULLTERM )
- != DSP_SUCCEED)
+ if (dsp_prop( DSP_SET, DSP_BCP_COLSEP, (void*)(*var_value), DSP_NULLTERM ) != DSP_SUCCEED)
{
return False;
}
+ DBG(sqsh_debug(DEBUG_SCREEN,"var_set_bcp_colsep: BCP column separator now set to %s\n", *var_value);)
+
return True ;
}
@@ -486,16 +511,15 @@ int var_get_bcp_colsep( env, var_name, var_value )
char *var_name;
char **var_value;
{
- static char colsep[32];
+ static char bcp_colsep[32];
- if (dsp_prop( DSP_GET, DSP_BCP_COLSEP, (void*)colsep, sizeof(colsep) )
- != DSP_SUCCEED)
+ if (dsp_prop( DSP_GET, DSP_BCP_COLSEP, (void*)bcp_colsep, sizeof(bcp_colsep) ) != DSP_SUCCEED)
{
*var_value = NULL;
return False;
}
- *var_value = colsep;
+ *var_value = bcp_colsep;
return True ;
}
@@ -504,17 +528,18 @@ int var_set_bcp_rowsep( env, var_name, var_value )
char *var_name;
char **var_value;
{
- if (var_set_nullstr( env, var_name, var_value ) == False)
+ if (var_set_esc( env, var_name, var_value ) == False)
{
return False;
}
- if (dsp_prop( DSP_SET, DSP_BCP_ROWSEP, (void*)(*var_value), DSP_NULLTERM )
- != DSP_SUCCEED)
+ if (dsp_prop( DSP_SET, DSP_BCP_ROWSEP, (void*)(*var_value), DSP_NULLTERM ) != DSP_SUCCEED)
{
return False;
}
+ DBG(sqsh_debug(DEBUG_SCREEN,"var_set_bcp_rowsep: BCP row separator now set to %s\n", *var_value);)
+
return True ;
}
@@ -523,16 +548,15 @@ int var_get_bcp_rowsep( env, var_name, var_value )
char *var_name;
char **var_value;
{
- static char rowsep[32];
+ static char bcp_rowsep[32];
- if (dsp_prop( DSP_GET, DSP_BCP_ROWSEP, (void*)rowsep, sizeof(rowsep) )
- != DSP_SUCCEED)
+ if (dsp_prop( DSP_GET, DSP_BCP_ROWSEP, (void*)bcp_rowsep, sizeof(bcp_rowsep) ) != DSP_SUCCEED)
{
*var_value = NULL;
return False;
}
- *var_value = rowsep;
+ *var_value = bcp_rowsep;
return True ;
}
@@ -541,7 +565,7 @@ int var_set_bcp_trim( env, var_name, var_value )
char *var_name;
char **var_value;
{
- int trim;
+ int bcp_trim;
if (var_set_bool( env, var_name, var_value ) == False)
{
@@ -551,19 +575,20 @@ int var_set_bcp_trim( env, var_name, var_value )
/* MW: Applied fix from patch 2061950 by Klaus-Martin Hansche. */
if (strcmp(*var_value , "1") == 0)
{
- trim = True;
+ bcp_trim = True;
}
else
{
- trim = False;
+ bcp_trim = False;
}
- if (dsp_prop( DSP_SET, DSP_BCP_TRIM, (void*)&trim, DSP_UNUSED )
- != DSP_SUCCEED)
+ if (dsp_prop( DSP_SET, DSP_BCP_TRIM, (void*)&bcp_trim, DSP_UNUSED ) != DSP_SUCCEED)
{
return False;
}
+ DBG(sqsh_debug(DEBUG_SCREEN,"var_set_bcp_trim: BCP trim now set to %s\n", *var_value);)
+
return True ;
}
@@ -572,15 +597,14 @@ int var_get_bcp_trim( env, var_name, var_value )
char *var_name;
char **var_value;
{
- int trim;
+ int bcp_trim;
- if (dsp_prop( DSP_GET, DSP_BCP_TRIM, (void*)&trim, DSP_UNUSED )
- != DSP_SUCCEED)
+ if (dsp_prop( DSP_GET, DSP_BCP_TRIM, (void*)&bcp_trim, DSP_UNUSED ) != DSP_SUCCEED)
{
return False;
}
- if (trim == True)
+ if (bcp_trim == True)
{
*var_value = "1";
}
@@ -596,19 +620,18 @@ int var_set_linesep( env, var_name, var_value )
char *var_name;
char **var_value;
{
- if (var_set_nullstr( env, var_name, var_value ) == False)
+ if (var_set_esc( env, var_name, var_value ) == False)
{
return False;
}
- if (dsp_prop( DSP_SET,
- DSP_LINESEP,
- (void*)(*var_value),
- DSP_NULLTERM ) != DSP_SUCCEED)
+ if (dsp_prop( DSP_SET, DSP_LINESEP, (void*)(*var_value), DSP_NULLTERM ) != DSP_SUCCEED)
{
return False;
}
+ DBG(sqsh_debug(DEBUG_SCREEN,"var_set_linesep: Line separator now set to %s\n", *var_value);)
+
return True ;
}
@@ -619,10 +642,7 @@ int var_get_linesep( env, var_name, var_value )
{
static char linesep[32];
- if (dsp_prop( DSP_GET,
- DSP_LINESEP,
- (void*)linesep,
- sizeof(linesep) ) != DSP_SUCCEED)
+ if (dsp_prop( DSP_GET, DSP_LINESEP, (void*)linesep, sizeof(linesep) ) != DSP_SUCCEED)
{
*var_value = NULL;
return False;
@@ -673,14 +693,13 @@ int var_set_xgeom( env, var_name, var_value )
return False;
}
- if (dsp_prop( DSP_SET,
- DSP_XGEOM,
- (void*)(*var_value),
- DSP_NULLTERM) != DSP_SUCCEED)
+ if (dsp_prop( DSP_SET, DSP_XGEOM, (void*)(*var_value), DSP_NULLTERM) != DSP_SUCCEED)
{
return False;
}
+ DBG(sqsh_debug(DEBUG_SCREEN,"var_set_xgeom: Xgeom now set to %s\n", *var_value);)
+
return True;
}
@@ -691,10 +710,7 @@ int var_get_xgeom( env, var_name, var_value )
{
static char xgeom[32];
- if (dsp_prop( DSP_GET,
- DSP_XGEOM,
- (void*)xgeom,
- sizeof(xgeom) ) != DSP_SUCCEED)
+ if (dsp_prop( DSP_GET, DSP_XGEOM, (void*)xgeom, sizeof(xgeom) ) != DSP_SUCCEED)
{
*var_value = NULL;
return False;
@@ -716,16 +732,14 @@ int var_set_maxlen( env, var_name, var_value )
return False;
}
- maxlen = atoi(*var_value);
+ maxlen = (*var_value != NULL) ? atoi(*var_value) : 0;
- if (dsp_prop( DSP_SET, DSP_MAXLEN, (void*)&maxlen, DSP_UNUSED )
- != DSP_SUCCEED)
+ if (dsp_prop( DSP_SET, DSP_MAXLEN, (void*)&maxlen, DSP_UNUSED ) != DSP_SUCCEED)
{
return False;
}
- DBG(sqsh_debug(DEBUG_SCREEN,
- "var_set_maxlen: Maximum column width now set to %s\n", *var_value);)
+ DBG(sqsh_debug(DEBUG_SCREEN, "var_set_maxlen: Maximum column width now set to %s\n", *var_value);)
return True ;
}
@@ -738,8 +752,7 @@ int var_get_maxlen( env, var_name, var_value )
static char nbr[16];
int maxlen;
- if (dsp_prop( DSP_GET, DSP_MAXLEN, (void*)&maxlen, DSP_UNUSED)
- != DSP_SUCCEED)
+ if (dsp_prop( DSP_GET, DSP_MAXLEN, (void*)&maxlen, DSP_UNUSED) != DSP_SUCCEED)
{
*var_value = NULL;
return False;
diff --git a/src/var_misc.c b/src/var_misc.c
index 648e097..a0881fa 100644
--- a/src/var_misc.c
+++ b/src/var_misc.c
@@ -29,10 +29,13 @@
#include "sqsh_error.h"
#include "sqsh_stdin.h"
#include "var.h"
+#include "sqsh_global.h"
+#include "sqsh_fd.h"
+#include "sqsh_expand.h"
/*-- Current Version --*/
#if !defined(lint) && !defined(__LINT__)
-static char RCS_Id[] = "$Id: var_misc.c,v 1.1.1.1 2004/04/07 12:35:05 chunkm0nkey Exp $" ;
+static char RCS_Id[] = "$Id: var_misc.c,v 1.8 2014/03/12 14:40:43 mwesdorp Exp $" ;
USE(RCS_Id)
#endif /* !defined(lint) */
@@ -113,7 +116,7 @@ int var_set_esc( env, var_name, var_value )
/*
* Allow them to set the string to a null value.
*/
- if( *var_value == NULL || strcmp(*var_value,"NULL") == 0 ) {
+ if( var_value == NULL || *var_value == NULL || strcasecmp(*var_value,"NULL") == 0 ) {
*var_value = NULL ;
return True ;
}
@@ -124,7 +127,7 @@ int var_set_esc( env, var_name, var_value )
if( *src == '\\' ) {
++src ;
switch( *src ) {
- case 'n' :
+ case 'n' :
*dst++ = '\n' ;
break ;
case 'f' :
@@ -189,7 +192,7 @@ int var_set_notempty( env, var_name, var_value )
sqsh_set_error( SQSH_E_INVAL, "Invalid value" ) ;
return False ;
}
-
+
return True ;
}
@@ -218,7 +221,7 @@ int var_set_bool( env, var_name, var_value )
return True ;
/*-- Map True or Yes to 1 --*/
- if( strcasecmp( *var_value, "True" ) == 0 ||
+ if( strcasecmp( *var_value, "True" ) == 0 ||
strcasecmp( *var_value, "Yes" ) == 0 ||
strcasecmp( *var_value, "On" ) == 0 ) {
*var_value = "1" ;
@@ -226,7 +229,7 @@ int var_set_bool( env, var_name, var_value )
}
/*-- Map False or No to 0 --*/
- if( strcasecmp( *var_value, "False" ) == 0 ||
+ if( strcasecmp( *var_value, "False" ) == 0 ||
strcasecmp( *var_value, "No" ) == 0 ||
strcasecmp( *var_value, "Off" ) == 0 ) {
*var_value = "0" ;
@@ -244,8 +247,10 @@ int var_set_nullint( env, var_name, var_value )
{
char *cptr ;
- if( *var_value == NULL || strcmp(*var_value, "NULL") == 0 )
- *var_value = "0" ;
+ if( var_value == NULL || *var_value == NULL || strcasecmp(*var_value, "NULL") == 0 ) {
+ *var_value = NULL ;
+ return True;
+ }
/*-- Skip whitespace --*/
for( cptr = *var_value; *cptr != '\0' && isspace( (int)*cptr ); ++cptr ) ;
@@ -269,7 +274,7 @@ int var_set_nullstr( env, var_name, var_value )
char *var_name ;
char **var_value ;
{
- if( *var_value == NULL || strcmp( *var_value, "NULL" ) == 0 )
+ if( var_value == NULL || *var_value == NULL || strcasecmp( *var_value, "NULL" ) == 0 )
*var_value = NULL ;
return True ;
@@ -286,7 +291,7 @@ int var_set_int( env, var_name, var_value )
char **var_value ;
{
/*-- Can't set it a NULL value --*/
- if( var_value == NULL || *var_value == NULL ) {
+ if( var_value == NULL || *var_value == NULL || strcasecmp(*var_value, "NULL") == 0) {
sqsh_set_error( SQSH_E_INVAL, "Invalid integer expression" ) ;
return False ;
}
@@ -330,7 +335,7 @@ int var_set_add( env, var_name, var_value )
if( !isdigit((int)*value) )
n = value + 1 ;
- else
+ else
n = value ;
/*-- Check the digits --*/
@@ -411,3 +416,132 @@ int var_set_path_r( env, var_name, var_value )
return True;
}
+
+/*
+ * var_set_lconv() - sqsh-2.3
+ *
+ * Validation function for setting variable localeconv (1/0, True/False, Yes/No)
+ * When set to true, initialize variable g_lconv to localeconv(), NULL otherwise.
+ * Returns True if validation succeed, False otherwise.
+ */
+int var_set_lconv( env, var_name, var_value )
+ env_t *env ;
+ char *var_name ;
+ char **var_value ;
+{
+ /*
+ * Perform simple validations.
+ */
+ if( var_value == NULL || *var_value == NULL || **var_value == '\0' ) {
+ sqsh_set_error( SQSH_E_INVAL, "Invalid boolean value" ) ;
+ return False ;
+ }
+
+ /*-- Map True or Yes to 1 --*/
+ if( strcasecmp( *var_value, "True" ) == 0 ||
+ strcasecmp( *var_value, "Yes" ) == 0 ||
+ strcasecmp( *var_value, "On" ) == 0 ) {
+ *var_value = "1" ;
+ }
+ /*-- Map False or No to 0 --*/
+ else if( strcasecmp( *var_value, "False" ) == 0 ||
+ strcasecmp( *var_value, "No" ) == 0 ||
+ strcasecmp( *var_value, "Off" ) == 0 ) {
+ *var_value = "0" ;
+ }
+
+ if( strcmp( *var_value, "1" ) == 0 )
+ {
+#if defined(HAVE_LOCALE_H) && defined(HAVE_SETLOCALE) && defined(HAVE_LOCALECONV)
+ setlocale ( LC_ALL, "" );
+ g_lconv = localeconv();
+ return True;
+#else
+ g_lconv = NULL;
+ *var_value = "0" ;
+ sqsh_set_error( SQSH_E_INVAL, "setlocale() and/or localeconv() not available" ) ;
+ return False;
+#endif
+ }
+ else if( strcmp( *var_value, "0" ) == 0 )
+ {
+#if defined(HAVE_LOCALE_H) && defined(HAVE_SETLOCALE)
+ setlocale ( LC_ALL, "C" );
+#endif
+ g_lconv = NULL;
+ return True;
+ }
+
+ sqsh_set_error( SQSH_E_INVAL, "Invalid boolean value" ) ;
+ return False ;
+}
+
+/*
+ * sqsh-2.5 - New feature p2f (Print to File)
+ * Assume var_name == "p2fname"
+ */
+int var_set_p2fname( env, var_name, var_value )
+ env_t *env ;
+ char *var_name ;
+ char **var_value ;
+{
+ varbuf_t *exp_buf = NULL;
+ FILE *nfp = NULL;
+ char *exp_fn;
+
+
+ if ( var_name == NULL || strcmp(var_name, "p2fname") != 0 )
+ {
+ sqsh_set_error( SQSH_E_INVAL, "var_set_p2fname: Unexpected variable name %s", var_name == NULL ? "NULL" : var_name ) ;
+ return False;
+ }
+
+ if ( var_value == NULL || *var_value == NULL || strcasecmp( *var_value, "NULL" ) == 0 )
+ {
+ *var_value = NULL ;
+ }
+ else {
+ if ((exp_buf = varbuf_create( 512 )) == NULL)
+ {
+ fprintf( stderr, "sqsh: %s\n", sqsh_get_errstr() );
+ sqsh_set_error( SQSH_E_INVAL, "Unable to expand filename %s", *var_value ) ;
+ *var_value = NULL ;
+ return False;
+ }
+
+ if (sqsh_expand( *var_value, exp_buf, 0 ) != False)
+ {
+ exp_fn = varbuf_getstr( exp_buf );
+ }
+ else
+ {
+ sqsh_set_error( SQSH_E_INVAL, "Unable to expand filename %s", *var_value ) ;
+ *var_value = NULL ;
+ varbuf_destroy( exp_buf );
+ return False;
+ }
+
+ if( (nfp = fopen( exp_fn, "a" )) == NULL)
+ {
+ sqsh_set_error( SQSH_E_INVAL, "Unable to open file %s", exp_fn ) ;
+ *var_value = NULL ;
+ varbuf_destroy( exp_buf );
+ return False;
+ }
+ varbuf_destroy( exp_buf );
+ }
+
+ /*
+ * If we come here, the fopen of the new file was successfull, or the p2fname variable is
+ * set to NULL. Either way, we can close the original file pointer if it is open
+ * and assign g_p2f_fp the new file pointer value (that still might be NULL).
+ */
+ if (g_p2f_fp != NULL)
+ {
+ fclose (g_p2f_fp);
+ }
+ g_p2f_fp = nfp;
+
+ return True ;
+}
+
diff --git a/src/var_passwd.c b/src/var_passwd.c
index 0f22819..2b1b781 100644
--- a/src/var_passwd.c
+++ b/src/var_passwd.c
@@ -31,7 +31,7 @@
/*-- Current Version --*/
#if !defined(lint) && !defined(__LINT__)
-static char RCS_Id[] = "$Id: var_passwd.c,v 1.2 2005/04/05 16:17:42 mpeppler Exp $";
+static char RCS_Id[] = "$Id: var_passwd.c,v 1.3 2014/03/12 14:40:43 mwesdorp Exp $";
USE(RCS_Id)
#endif /* !defined(lint) */
@@ -45,7 +45,7 @@ int var_set_lock( env, var_name, var_value )
/*
* Allow them to set the string to a null value.
*/
- if ( *var_value == NULL || strcmp(*var_value,"NULL") == 0 ) {
+ if ( *var_value == NULL || strcasecmp(*var_value,"NULL") == 0 ) {
/*-- Free up the old value --*/
if (g_lock != NULL)
@@ -105,11 +105,11 @@ int var_set_password( env, var_name, var_value )
/*
* Allow them to set the string to a null value.
*/
- if ( *var_value == NULL || strcmp(*var_value,"NULL") == 0 ) {
+ if ( *var_value == NULL || strcasecmp(*var_value,"NULL") == 0 ) {
- /* Helmut Ruholl adds the strcmp() to handle password
+ /* Helmut Ruholl adds the strcasecmp() to handle password
resets in .sqsh_session. mpeppler 2004-12-07 */
- if (*var_value != NULL && strcmp(*var_value, "NULL"))
+ if (*var_value != NULL && strcasecmp(*var_value, "NULL"))
{
g_password_set = False;
}
diff --git a/src/var_readline.c b/src/var_readline.c
index ac5865e..e6e41d7 100644
--- a/src/var_readline.c
+++ b/src/var_readline.c
@@ -27,17 +27,12 @@
#include "sqsh_config.h"
#include "sqsh_env.h"
#include "sqsh_error.h"
+#include "sqsh_readline.h"
#include "var.h"
-#if defined(USE_READLINE)
-#include <readline/readline.h>
-extern void stifle_history();
-extern void unstifle_history();
-#endif
-
/*-- Current Version --*/
#if !defined(lint) && !defined(__LINT__)
-static char RCS_Id[] = "$Id: var_readline.c,v 1.1.1.1 2004/04/07 12:35:04 chunkm0nkey Exp $" ;
+static char RCS_Id[] = "$Id: var_readline.c,v 1.3 2013/12/24 13:23:19 mwesdorp Exp $" ;
USE(RCS_Id)
#endif /* !defined(lint) */
@@ -53,7 +48,7 @@ int var_set_rl_histsize( env, var_name, var_value )
return False;
}
- stifle_value = atoi(*var_value);
+ stifle_value = (*var_value != NULL) ? atoi(*var_value) : 0;
#if defined(USE_READLINE)
if (stifle_value <= 0)