summaryrefslogtreecommitdiffstats
path: root/third_party/heimdal/lib/sl
diff options
context:
space:
mode:
Diffstat (limited to 'third_party/heimdal/lib/sl')
-rw-r--r--third_party/heimdal/lib/sl/ChangeLog329
-rw-r--r--third_party/heimdal/lib/sl/Makefile.am50
-rw-r--r--third_party/heimdal/lib/sl/NTMakefile74
-rw-r--r--third_party/heimdal/lib/sl/roken_rename.h67
-rw-r--r--third_party/heimdal/lib/sl/sl.c528
-rw-r--r--third_party/heimdal/lib/sl/sl.h71
-rw-r--r--third_party/heimdal/lib/sl/sl_locl.h45
-rw-r--r--third_party/heimdal/lib/sl/slc-gram.y791
-rw-r--r--third_party/heimdal/lib/sl/slc-lex.l158
-rw-r--r--third_party/heimdal/lib/sl/slc.h56
-rw-r--r--third_party/heimdal/lib/sl/test_sl.c98
11 files changed, 2267 insertions, 0 deletions
diff --git a/third_party/heimdal/lib/sl/ChangeLog b/third_party/heimdal/lib/sl/ChangeLog
new file mode 100644
index 0000000..485e1dc
--- /dev/null
+++ b/third_party/heimdal/lib/sl/ChangeLog
@@ -0,0 +1,329 @@
+2008-05-05 Love Hörnquist Åstrand <lha@vit.local>
+
+ * drop libss and make_cmds
+
+2007-07-17 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * Makefile.am: roken_rename.h is a dist_ source k
+
+ * Makefile.am: split source files in dist and nodist.
+
+2007-07-10 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * Makefile.am: New library version.
+
+2007-06-18 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * sl.c: make compile.
+
+ * sl.c: Pass in pointer to strlen().
+
+ * sl.c (sl_make_argv): use memmove since we are dealing with
+ overlapping strings.
+
+2007-06-09 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * Makefile.am: don't clean yacc/lex files in CLEANFILES,
+ maintainers clean will do that for us.
+
+2007-06-01 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * slc-gram.y (main): also fclose yyin.
+
+2007-04-20 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * Makefile.am: Add dependency on slc-gram.h for slc-lex.c, breaks
+ in disttree with make -j
+
+2006-12-29 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * test_sl.c: Fix caseing for case-sensitive filesystems
+
+2006-12-27 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * test_sl.c: catch test that should fail but didn't
+
+ * test_sl.c: Test more quoting variants.
+
+ * sl_locl.h: Include <ctype.h>.
+
+ * test_sl.c: test sl_make_argv
+
+ * sl.c (sl_make_argv): Add quoting support (both "" and \ style).
+
+2006-12-05 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * sl.c: Use strcspn to remove \n from fgets result. Prompted by
+ change by Ray Lai of OpenBSD via Björn Sandell.
+
+2006-10-19 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * Makefile.am (ES): add roken_rename.h
+
+2006-08-30 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * sl.c (sl_slc_help): remove return
+
+2006-08-28 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * sl.h: Add sl_slc_help.
+
+ * sl.c: Add sl_slc_help.
+
+2005-07-27 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * slc-gram.y (gen_wrapper): use the generated version of name for
+ function, if no function is is used, also use the generated name
+ for the structure name.
+
+2005-06-16 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * slc-gram.y: fix a merge error
+
+ * slc-gram.y: rename optind to optidx, rename variables to avoid
+ shadowing
+
+ * make_cmds.c: rename optind to optidx, move variable define to
+ avoid shadowing
+
+ * ss.c: rename index to idx
+
+ * sl.c: use rk_UNCONST to un-constify
+
+2005-05-10 Dave Love <fx@gnu.org>
+
+ * slc-lex.l: Include <stdlib.h>.
+
+2005-05-09 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * sl.c (sl_command_loop): new return code -2 for EOF
+ (sl_loop): treat all return value from sl_command_loop >= 0 as ok, and
+ continue.
+
+2005-04-29 Dave Love <fx@gnu.org>
+
+ * Makefile.am (LDADD): Add libsl.la.
+
+2005-04-19 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * slc-gram.y: include <config.h> since defines _GNU_SOURCE if
+ needed, avoid asprintf warning
+
+2005-01-21 Dave Love <d.love@dl.ac.uk>
+
+ * slc-gram.y: include <roken.h>
+
+2005-01-09 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * slc-gram.y: cast argument to isalnum to unsigned char
+
+2004-09-22 Johan Danielsson <joda@pdc.kth.se>
+
+ * slc-gram.y: add support for "strings" and "negative-flag" types,
+ plus some usability tweaks and bug fixes
+
+2004-07-05 Johan Danielsson <joda@pdc.kth.se>
+
+ * slc-gram.y: add min_args/max_args checking
+
+2004-06-21 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * slc-gram.y: pull in <stdlib.h> and <vers.h> to avoid warnings
+
+2004-03-02 Love Hörnquist Åstrand <lha@it.su.se>
+
+ * sl.h: make it possible to use libsl from c++
+ From: Mattias Amnefelt <mattiasa@kth.se>
+
+2002-05-19 Johan Danielsson <joda@pdc.kth.se>
+
+ * Makefile.am: just link mk_cmds against libsl; avoids libtool
+ problem
+
+2001-07-09 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am: add getprogname.c libss.la:add libcom_err.la noted
+ by Leif Johansson <leifj@it.su.se>
+
+2001-05-17 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am: bump versions to 1:2:1 and 1:4:1
+
+2001-05-06 Assar Westerlund <assar@sics.se>
+
+ * roken_rename.h (strdup): add
+
+2001-03-06 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am: re do the roken-renaming properly
+
+2001-02-13 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am: add more functions to rename
+
+2001-01-26 Johan Danielsson <joda@pdc.kth.se>
+
+ * sl.h: proto
+
+ * sl.c (sl_command_loop): try to handle user pressing C-c
+
+2000-12-11 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am (libss_la_LDFLAGS): bump version to 1:2:1
+
+2000-08-19 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am: add dependencies for libss/libsl shared libraries
+
+2000-07-25 Johan Danielsson <joda@pdc.kth.se>
+
+ * Makefile.am: bump ss version to 1:1:1
+
+2000-06-27 Assar Westerlund <assar@sics.se>
+
+ * parse.y (yyerror): static-ize
+ * make_cmds.h (error_message, yylex): add prototypes
+ * lex.l: fix prototypes and kill warnings
+
+2000-05-24 Assar Westerlund <assar@sics.se>
+
+ * ss.h (SS_ET_COMMAND_NOT_FOUND): add
+ * ss.c: check allocation and return some other error codes too
+
+2000-04-29 Assar Westerlund <assar@sics.se>
+
+ * Makefile.in: add LIB_tgetent. From Derrick J Brashear
+ <shadow@dementia.org>
+
+2000-04-03 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am: set version to 1:0:1
+
+2000-03-07 Assar Westerlund <assar@sics.se>
+
+ * sl.h (SL_BADCOMMAND): define
+ (sl_apropos): add prototype
+
+ * sl.c: mandoc-generation
+ (sl_apropos): stolen from arla
+
+2000-01-06 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am: bump both versions to 0:1:0
+
+1999-12-16 Assar Westerlund <assar@sics.se>
+
+ * parse.y (name2number): not used here. remove.
+
+Thu Apr 1 17:03:59 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * make_cmds.c: use getarg
+
+Tue Mar 23 14:36:21 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * Makefile.am: don't rename
+
+Sun Mar 21 14:13:29 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * Makefile.am: don't roken-rename
+
+Sat Mar 20 03:43:30 1999 Assar Westerlund <assar@sics.se>
+
+ * parse.y: replace return with YYACCEPT
+
+Fri Mar 19 14:53:20 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * Makefile.am: add libss; add version-info
+
+Thu Mar 18 15:07:06 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * Makefile.am: clean lex.c parse.c parse.h
+
+ * Makefile.am: install ss.h
+
+ * Makefile.am: include Makefile.am.common
+
+Thu Mar 11 15:01:01 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * parse.y: prototype for error_message
+
+Tue Feb 9 23:45:37 1999 Johan Danielsson <joda@hella.pdc.kth.se>
+
+ * Makefile.in: add snprintf.o to make_cmds
+
+Sun Nov 22 10:46:23 1998 Assar Westerlund <assar@sics.se>
+
+ * sl.c (sl_command_loop): remove unused variable
+
+ * ss.c (ss_error): remove unused variable
+
+ * make_cmds.c: include err.h
+ (main): remove unused variable
+
+ * Makefile.in (WFLAGS): set
+
+Sun Sep 27 01:28:21 1998 Assar Westerlund <assar@sics.se>
+
+ * make_cmds.c: clean-up and simplification
+
+Mon May 25 02:54:13 1998 Assar Westerlund <assar@sics.se>
+
+ * Makefile.in (clean): try to remove shared library debris
+
+ * Makefile.in: make symlink magic work
+
+Sun Apr 19 10:00:26 1998 Assar Westerlund <assar@sics.se>
+
+ * Makefile.in: add symlink magic for linux
+
+Sun Apr 5 09:21:43 1998 Assar Westerlund <assar@sics.se>
+
+ * parse.y: define alloca to malloc in case we're using bison but
+ don't have alloca
+
+Sat Mar 28 11:39:00 1998 Assar Westerlund <assar@sics.se>
+
+ * sl.c (sl_loop): s/2/1
+
+Sat Mar 21 00:46:51 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * sl.c (sl_loop): check that there is at least one argument before
+ calling sl_command
+
+Sun Mar 1 05:14:37 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * sl.c (sl_loop): Fix general broken-ness.
+
+ * sl.c: Cleanup printing of help strings.
+
+Thu Feb 26 02:22:02 1998 Assar Westerlund <assar@sics.se>
+
+ * Makefile.am: @LEXLIB@
+
+Sat Feb 21 15:18:21 1998 assar westerlund <assar@sics.se>
+
+ * Makefile.in: set YACC and LEX
+
+Mon Feb 16 16:08:25 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * Makefile.am: Some fixes for ss/mk_cmds.
+
+Sun Feb 15 05:12:11 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * Makefile.in: Install libsl under the `libss' name too. Install
+ mk_cmds, and ss.h.
+
+ * make_cmds.c: A mk_cmds clone that creates SL structures.
+
+ * ss.c: SS compatibility functions.
+
+ * sl.c: Move command line split to function `sl_make_argv'.
+
+Tue Feb 3 16:45:44 1998 Johan Danielsson <joda@emma.pdc.kth.se>
+
+ * sl.c: Add sl_command_loop, that is the loop body of sl_loop.
+
+Mon Oct 20 01:13:21 1997 Assar Westerlund <assar@sics.se>
+
+ * sl.c (sl_help): actually use the `help' field of `SL_cmd'
+
diff --git a/third_party/heimdal/lib/sl/Makefile.am b/third_party/heimdal/lib/sl/Makefile.am
new file mode 100644
index 0000000..c962c7a
--- /dev/null
+++ b/third_party/heimdal/lib/sl/Makefile.am
@@ -0,0 +1,50 @@
+# $Id$
+
+include $(top_srcdir)/Makefile.am.common
+
+if do_roken_rename
+ES = strtok_r.c snprintf.c strdup.c strupr.c
+endif
+
+AM_CPPFLAGS += $(ROKEN_RENAME)
+
+AM_YFLAGS = -d -o slc-gram.c
+AM_LFLAGS = @FLEXNOUNPUTARGS@
+
+include_HEADERS = sl.h
+
+lib_LTLIBRARIES = libsl.la
+libsl_la_LDFLAGS = -version-info 2:1:2
+
+libsl_la_LIBADD = @LIB_readline@
+
+dist_libsl_la_SOURCES = sl_locl.h sl.c roken_rename.h
+nodist_libsl_la_SOURCES = $(ES)
+
+TESTS = test_sl
+check_PROGRAMS = $(TESTS)
+
+# install these?
+
+libexec_heimdal_PROGRAMS = slc
+
+slc_SOURCES = slc-gram.y slc-lex.l slc.h
+
+CLEANFILES = snprintf.c strtok_r.c strdup.c strupr.c slc-lex.c
+
+LDADD = libsl.la $(LIB_roken)
+
+slc_LDADD = $(LEXLIB) $(LDADD)
+
+strtok_r.c:
+ $(LN_S) $(srcdir)/../roken/strtok_r.c .
+snprintf.c:
+ $(LN_S) $(srcdir)/../roken/snprintf.c .
+strdup.c:
+ $(LN_S) $(srcdir)/../roken/strdup.c .
+strupr.c:
+ $(LN_S) $(srcdir)/../roken/strupr.c .
+
+slc-lex.c: slc-gram.h
+
+EXTRA_DIST = NTMakefile
diff --git a/third_party/heimdal/lib/sl/NTMakefile b/third_party/heimdal/lib/sl/NTMakefile
new file mode 100644
index 0000000..ac398c7
--- /dev/null
+++ b/third_party/heimdal/lib/sl/NTMakefile
@@ -0,0 +1,74 @@
+########################################################################
+#
+# Copyright (c) 2009, Secure Endpoints Inc.
+# All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+#
+# - Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+#
+# - Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the
+# distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+# COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+
+RELDIR=lib\sl
+
+!include ../../windows/NTMakefile.w32
+
+INCFILES=$(INCDIR)\sl.h
+
+$(LIBSL): $(OBJ)\sl.obj
+ $(LIBCON)
+
+$(BINDIR)\slc.exe: $(OBJ)\slc-gram.obj $(OBJ)\slc-lex.obj
+ $(EXECONLINK) $(LIBROKEN) $(LIBVERS)
+ $(EXEPREP_NOHEIM)
+
+$(OBJ)\slc-gram.c: slc-gram.y
+ $(YACC) -o $@ --defines=$(@R).h slc-gram.y
+
+$(OBJ)\slc-gram.obj: $(OBJ)\slc-gram.c
+ $(C2OBJ) -I$(SRC)\$(RELDIR)
+
+$(OBJ)\slc-lex.c: slc-lex.l
+ $(LEX) -o$@ slc-lex.l
+
+$(OBJ)\slc-lex.obj: $(OBJ)\slc-lex.c
+ $(C2OBJ) -I$(SRC)\$(RELDIR) -DYY_NO_UNISTD_H
+
+$(OBJ)\test_sl.exe: $(OBJ)\test_sl.obj
+ $(EXECONLINK) $(LIBSL) $(LIBVERS) $(LIBROKEN)
+ $(EXEPREP_NODIST)
+
+all:: $(INCFILES) $(LIBSL) $(BINDIR)\slc.exe
+
+clean::
+ -$(RM) $(LIBSL)
+ -$(RM) $(BINDIR)\slc.*
+
+test-binaries: $(OBJ)\test_sl.exe
+
+test-run:
+ cd $(OBJ)
+ -test_sl.exe
+ cd $(SRC)\$(RELDIR)
+
+test:: test-binaries test-run
diff --git a/third_party/heimdal/lib/sl/roken_rename.h b/third_party/heimdal/lib/sl/roken_rename.h
new file mode 100644
index 0000000..a198efc
--- /dev/null
+++ b/third_party/heimdal/lib/sl/roken_rename.h
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 1998 - 2001 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* $Id$ */
+
+#ifndef __roken_rename_h__
+#define __roken_rename_h__
+
+#ifndef HAVE_STRTOK_R
+#define rk_strtok_r _sl_strtok_r
+#endif
+#ifndef HAVE_SNPRINTF
+#define rk_snprintf _sl_snprintf
+#endif
+#ifndef HAVE_ASPRINTF
+#define rk_asprintf _sl_asprintf
+#endif
+#ifndef HAVE_ASNPRINTF
+#define rk_asnprintf _sl_asnprintf
+#endif
+#ifndef HAVE_VASPRINTF
+#define rk_vasprintf _sl_vasprintf
+#endif
+#ifndef HAVE_VASNPRINTF
+#define rk_vasnprintf _sl_vasnprintf
+#endif
+#ifndef HAVE_VSNPRINTF
+#define rk_vsnprintf _sl_vsnprintf
+#endif
+#ifndef HAVE_STRUPR
+#define rk_strupr _sl_strupr
+#endif
+#ifndef HAVE_STRDUP
+#define rk_strdup _sl_strdup
+#endif
+
+#endif /* __roken_rename_h__ */
diff --git a/third_party/heimdal/lib/sl/sl.c b/third_party/heimdal/lib/sl/sl.c
new file mode 100644
index 0000000..c67cc52
--- /dev/null
+++ b/third_party/heimdal/lib/sl/sl.c
@@ -0,0 +1,528 @@
+/*
+ * Copyright (c) 1995 - 2006 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include "sl_locl.h"
+#include <setjmp.h>
+
+static void
+mandoc_template(SL_cmd *cmds,
+ const char *extra_string)
+{
+ SL_cmd *c, *prev;
+ char timestr[64], cmd[64];
+ const char *p;
+ time_t t;
+
+ printf(".\\\" Things to fix:\n");
+ printf(".\\\" * correct section, and operating system\n");
+ printf(".\\\" * remove Op from mandatory flags\n");
+ printf(".\\\" * use better macros for arguments (like .Pa for files)\n");
+ printf(".\\\"\n");
+ t = time(NULL);
+ strftime(timestr, sizeof(timestr), "%b %d, %Y", localtime(&t));
+ printf(".Dd %s\n", timestr);
+#ifdef HAVE_GETPROGNAME
+ p = getprogname();
+#else
+ p = "unknown-application";
+#endif
+ strncpy(cmd, p, sizeof(cmd));
+ cmd[sizeof(cmd)-1] = '\0';
+ strupr(cmd);
+
+ printf(".Dt %s SECTION\n", cmd);
+ printf(".Os OPERATING_SYSTEM\n");
+ printf(".Sh NAME\n");
+ printf(".Nm %s\n", p);
+ printf(".Nd\n");
+ printf("in search of a description\n");
+ printf(".Sh SYNOPSIS\n");
+ printf(".Nm\n");
+ for(c = cmds; c->name; ++c) {
+/* if (c->func == NULL)
+ continue; */
+ printf(".Op Fl %s", c->name);
+ printf("\n");
+
+ }
+ if (extra_string && *extra_string)
+ printf (".Ar %s\n", extra_string);
+ printf(".Sh DESCRIPTION\n");
+ printf("Supported options:\n");
+ printf(".Bl -tag -width Ds\n");
+ prev = NULL;
+ for(c = cmds; c->name; ++c) {
+ if (c->func) {
+ if (prev)
+ printf ("\n%s\n", prev->usage);
+
+ printf (".It Fl %s", c->name);
+ prev = c;
+ } else
+ printf (", %s\n", c->name);
+ }
+ if (prev)
+ printf ("\n%s\n", prev->usage);
+
+ printf(".El\n");
+ printf(".\\\".Sh ENVIRONMENT\n");
+ printf(".\\\".Sh FILES\n");
+ printf(".\\\".Sh EXAMPLES\n");
+ printf(".\\\".Sh DIAGNOSTICS\n");
+ printf(".\\\".Sh SEE ALSO\n");
+ printf(".\\\".Sh STANDARDS\n");
+ printf(".\\\".Sh HISTORY\n");
+ printf(".\\\".Sh AUTHORS\n");
+ printf(".\\\".Sh BUGS\n");
+}
+
+SL_cmd *
+sl_match (SL_cmd *cmds, char *cmd, int exactp)
+{
+ SL_cmd *c, *current = NULL, *partial_cmd = NULL;
+ int partial_match = 0;
+
+ for (c = cmds; c->name; ++c) {
+ if (c->func)
+ current = c;
+ if (strcmp (cmd, c->name) == 0)
+ return current;
+ else if (strncmp (cmd, c->name, strlen(cmd)) == 0 &&
+ partial_cmd != current) {
+ ++partial_match;
+ partial_cmd = current;
+ }
+ }
+ if (partial_match == 1 && !exactp)
+ return partial_cmd;
+ else
+ return NULL;
+}
+
+void
+sl_help (SL_cmd *cmds, int argc, char **argv)
+{
+ SL_cmd *c, *prev_c;
+
+ if (getenv("SLMANDOC")) {
+ mandoc_template(cmds, NULL);
+ return;
+ }
+
+ if (argc == 1) {
+ prev_c = NULL;
+ for (c = cmds; c->name; ++c) {
+ if (c->func) {
+ if(prev_c)
+ printf ("\n\t%s%s", prev_c->usage ? prev_c->usage : "",
+ prev_c->usage ? "\n" : "");
+ prev_c = c;
+ printf ("%s", c->name);
+ } else
+ printf (", %s", c->name);
+ }
+ if(prev_c)
+ printf ("\n\t%s%s", prev_c->usage ? prev_c->usage : "",
+ prev_c->usage ? "\n" : "");
+ } else {
+ c = sl_match (cmds, argv[1], 0);
+ if (c == NULL)
+ printf ("No such command: %s. "
+ "Try \"help\" for a list of all commands\n",
+ argv[1]);
+ else {
+ printf ("%s\t%s\n", c->name, c->usage);
+ if(c->help && *c->help)
+ printf ("%s\n", c->help);
+ if((++c)->name && c->func == NULL) {
+ printf ("Synonyms:");
+ while (c->name && c->func == NULL)
+ printf ("\t%s", (c++)->name);
+ printf ("\n");
+ }
+ }
+ }
+}
+
+#ifdef HAVE_READLINE
+
+char *readline(char *prompt);
+void add_history(char *p);
+
+#else
+
+static char *
+readline(char *prompt)
+{
+ char buf[BUFSIZ];
+ printf ("%s", prompt);
+ fflush (stdout);
+ if(fgets(buf, sizeof(buf), stdin) == NULL)
+ return NULL;
+ buf[strcspn(buf, "\r\n")] = '\0';
+ return strdup(buf);
+}
+
+static void
+add_history(char *p)
+{
+}
+
+#endif
+
+int
+sl_command(SL_cmd *cmds, int argc, char **argv)
+{
+ SL_cmd *c;
+ c = sl_match (cmds, argv[0], 0);
+ if (c == NULL)
+ return -1;
+ return (*c->func)(argc, argv);
+}
+
+struct sl_data {
+ int max_count;
+ char **ptr;
+};
+
+int
+sl_make_argv(char *line, int *ret_argc, char ***ret_argv)
+{
+ char *p, *begining;
+ int argc, nargv;
+ char **argv;
+ int quote = 0;
+
+ nargv = 10;
+ argv = malloc(nargv * sizeof(*argv));
+ if(argv == NULL)
+ return ENOMEM;
+ argc = 0;
+
+ p = line;
+
+ while(isspace((unsigned char)*p))
+ p++;
+ begining = p;
+
+ while (1) {
+ if (*p == '\0') {
+ ;
+ } else if (*p == '"') {
+ quote = !quote;
+ memmove(&p[0], &p[1], strlen(&p[1]) + 1);
+ continue;
+ } else if (*p == '\\') {
+ if (p[1] == '\0')
+ goto failed;
+ memmove(&p[0], &p[1], strlen(&p[1]) + 1);
+ p += 1;
+ continue;
+ } else if (quote || !isspace((unsigned char)*p)) {
+ p++;
+ continue;
+ } else
+ *p++ = '\0';
+ if (quote)
+ goto failed;
+ if(argc == nargv - 1) {
+ char **tmp;
+ nargv *= 2;
+ tmp = realloc (argv, nargv * sizeof(*argv));
+ if (tmp == NULL) {
+ free(argv);
+ return ENOMEM;
+ }
+ argv = tmp;
+ }
+ argv[argc++] = begining;
+ while(isspace((unsigned char)*p))
+ p++;
+ if (*p == '\0')
+ break;
+ begining = p;
+ }
+ argv[argc] = NULL;
+ *ret_argc = argc;
+ *ret_argv = argv;
+ return 0;
+failed:
+ free(argv);
+ return ERANGE;
+}
+
+static jmp_buf sl_jmp;
+
+static void sl_sigint(int sig)
+{
+ longjmp(sl_jmp, 1);
+}
+
+static char *sl_readline(const char *prompt)
+{
+ char *s;
+ void (*old)(int);
+ old = signal(SIGINT, sl_sigint);
+ if(setjmp(sl_jmp))
+ printf("\n");
+ s = readline(rk_UNCONST(prompt));
+ signal(SIGINT, old);
+ return s;
+}
+
+/* return values:
+ * 0 on success,
+ * -1 on fatal error,
+ * -2 if EOF, or
+ * return value of command */
+int
+sl_command_loop(SL_cmd *cmds, const char *prompt, void **data)
+{
+ int ret = 0;
+ char *buf = NULL;
+ int argc;
+ char **argv;
+ int continued = 0;
+
+ do {
+ char *buf2;
+ size_t len;
+
+ buf2 = sl_readline(buf == NULL ? prompt : "> ");
+ if (buf2 == NULL) {
+ free(buf);
+ return -2;
+ }
+
+ if (buf) {
+ char *tmp = NULL;
+
+ if (asprintf(&tmp, "%s %s", buf, buf2) == -1 || tmp == NULL) {
+ fprintf(stderr, "sl_loop: out of memory\n");
+ free(buf2);
+ free(buf);
+ return -1;
+ }
+ free(buf2);
+ free(buf);
+ buf = tmp;
+ } else {
+ buf = buf2;
+ }
+
+ len = strlen(buf);
+ continued = (len > 0 && buf[len - 1] == '\\');
+ if (continued)
+ buf[len - 1] = '\0';
+ } while (continued);
+
+ if(*buf)
+ add_history(buf);
+ ret = sl_make_argv(buf, &argc, &argv);
+ if(ret) {
+ fprintf(stderr, "sl_loop: out of memory\n");
+ free(buf);
+ return -1;
+ }
+ if (argc >= 1) {
+ ret = sl_command(cmds, argc, argv);
+ if(ret == -1) {
+ sl_did_you_mean(cmds, argv[0]);
+ ret = 1;
+ }
+ }
+ free(buf);
+ free(argv);
+ return ret;
+}
+
+int
+sl_loop(SL_cmd *cmds, const char *prompt)
+{
+ void *data = NULL;
+ int ret;
+ while((ret = sl_command_loop(cmds, prompt, &data)) >= 0)
+ ;
+ return ret;
+}
+
+void
+sl_apropos (SL_cmd *cmd, const char *topic)
+{
+ for (; cmd->name != NULL; ++cmd)
+ if (cmd->usage != NULL && strstr(cmd->usage, topic) != NULL)
+ printf ("%-20s%s\n", cmd->name, cmd->usage);
+}
+
+/*
+ * Help to be used with slc.
+ */
+
+void
+sl_slc_help (SL_cmd *cmds, int argc, char **argv)
+{
+ if(argc == 0) {
+ sl_help(cmds, 1, argv - 1 /* XXX */);
+ } else {
+ SL_cmd *c = sl_match (cmds, argv[0], 0);
+ if(c == NULL) {
+ fprintf (stderr, "No such command: %s. "
+ "Try \"help\" for a list of commands\n",
+ argv[0]);
+ } else {
+ if(c->func) {
+ static char help[] = "--help";
+ char *fake[3];
+ fake[0] = argv[0];
+ fake[1] = help;
+ fake[2] = NULL;
+ (*c->func)(2, fake);
+ fprintf(stderr, "\n");
+ }
+ if(c->help && *c->help)
+ fprintf (stderr, "%s\n", c->help);
+ if((++c)->name && c->func == NULL) {
+ int f = 0;
+ fprintf (stderr, "Synonyms:");
+ while (c->name && c->func == NULL) {
+ fprintf (stderr, "%s%s", f ? ", " : " ", (c++)->name);
+ f = 1;
+ }
+ fprintf (stderr, "\n");
+ }
+ }
+ }
+}
+
+/* OptimalStringAlignmentDistance */
+
+static int
+osad(const char *s1, const char *s2)
+{
+ size_t l1 = strlen(s1), l2 = strlen(s2), i, j;
+ int *row0, *row1, *row2, *tmp, cost;
+
+ row0 = calloc(sizeof(int), l2 + 1);
+ row1 = calloc(sizeof(int), l2 + 1);
+ row2 = calloc(sizeof(int), l2 + 1);
+
+ for (j = 0; j < l2 + 1; j++)
+ row1[j] = j;
+
+ for (i = 0; i < l1; i++) {
+
+ row2[0] = i + 1;
+
+ for (j = 0; j < l2; j++) {
+
+ row2[j + 1] = row1[j] + (s1[i] != s2[j]); /* substitute */
+
+ if (row2[j + 1] > row1[j + 1] + 1) /* delete */
+ row2[j + 1] = row1[j + 1] + 1;
+ if (row2[j + 1] > row2[j] + 1) /* insert */
+ row2[j + 1] = row2[j] + 1;
+ if (j > 0 && i > 0 && s1[i - 1] != s2[j - 1] && s1[i - 1] == s2[j] && s1[i] == s2[j - 1] && row2[j + 1] < row0[j - 1]) /* transposition */
+ row2[j + 1] = row0[j - 1] + 1;
+ }
+
+ tmp = row0;
+ row0 = row1;
+ row1 = row2;
+ row2 = tmp;
+ }
+
+ cost = row1[l2];
+
+ free(row0);
+ free(row1);
+ free(row2);
+
+ return cost;
+}
+
+/**
+ * Will propose a list of command that are almost matching the command
+ * used, if there is no matching, will ask the user to use "help".
+ *
+ * @param cmds command array to use for matching
+ * @param match the command that didn't exists
+ */
+
+void
+sl_did_you_mean(SL_cmd *cmds, const char *match)
+{
+ int *metrics, best_match = INT_MAX;
+ SL_cmd *c;
+ size_t n;
+
+ for (n = 0, c = cmds; c->name; c++, n++)
+ ;
+ if (n == 0)
+ return;
+ metrics = calloc(n, sizeof(metrics[0]));
+ if (metrics == NULL)
+ return;
+
+ for (n = 0; cmds[n].name; n++) {
+ metrics[n] = osad(match, cmds[n].name);
+ if (metrics[n] < best_match)
+ best_match = metrics[n];
+ }
+ if (best_match == INT_MAX) {
+ free(metrics);
+ fprintf(stderr, "What kind of command is %s", match);
+ return;
+ }
+
+ /* if match distance is low, propose that for the user */
+ if (best_match < 7) {
+
+ fprintf(stderr, "error: %s is not a known command, did you mean ?\n", match);
+ for (n = 0; cmds[n].name; n++) {
+ if (metrics[n] == best_match) {
+ fprintf(stderr, "\t%s\n", cmds[n].name);
+ }
+ }
+ fprintf(stderr, "\n");
+
+ } else {
+
+ fprintf(stderr, "error: %s is not a command, use \"help\" for more list of commands.\n", match);
+ }
+
+ free(metrics);
+
+ return;
+}
diff --git a/third_party/heimdal/lib/sl/sl.h b/third_party/heimdal/lib/sl/sl.h
new file mode 100644
index 0000000..affdb6e
--- /dev/null
+++ b/third_party/heimdal/lib/sl/sl.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 1995 - 2004 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* $Id$ */
+
+#ifndef _SL_H
+#define _SL_H
+
+#define SL_BADCOMMAND -1
+
+typedef int (*cmd_func)(int, char **);
+
+struct sl_cmd {
+ const char *name;
+ cmd_func func;
+ const char *usage;
+ const char *help;
+};
+
+typedef struct sl_cmd SL_cmd;
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+void sl_help (SL_cmd *, int argc, char **argv);
+int sl_loop (SL_cmd *, const char *prompt);
+int sl_command_loop (SL_cmd *cmds, const char *prompt, void **data);
+int sl_command (SL_cmd *cmds, int argc, char **argv);
+int sl_make_argv(char*, int*, char***);
+void sl_apropos (SL_cmd *cmd, const char *topic);
+SL_cmd *sl_match (SL_cmd *cmds, char *cmd, int exactp);
+void sl_slc_help (SL_cmd *cmds, int argc, char **argv);
+void sl_did_you_mean(SL_cmd *cmds, const char *match);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _SL_H */
diff --git a/third_party/heimdal/lib/sl/sl_locl.h b/third_party/heimdal/lib/sl/sl_locl.h
new file mode 100644
index 0000000..50eeade
--- /dev/null
+++ b/third_party/heimdal/lib/sl/sl_locl.h
@@ -0,0 +1,45 @@
+/*
+ * Copyright (c) 1995, 1996, 1997, 1998 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* $Id$ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdarg.h>
+#include <ctype.h>
+
+#include <roken.h>
+
+#include <sl.h>
diff --git a/third_party/heimdal/lib/sl/slc-gram.y b/third_party/heimdal/lib/sl/slc-gram.y
new file mode 100644
index 0000000..eed7fc1
--- /dev/null
+++ b/third_party/heimdal/lib/sl/slc-gram.y
@@ -0,0 +1,791 @@
+%{
+/*
+ * Copyright (c) 2004-2006 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include <config.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <err.h>
+#include <ctype.h>
+#include <limits.h>
+#include <getarg.h>
+#include <vers.h>
+#include <roken.h>
+
+#include "slc.h"
+extern FILE *yyin;
+extern struct assignment *assignment;
+
+/* Declarations for Bison:
+ */
+#define YYMALLOC malloc
+#define YYFREE free
+
+%}
+
+%union {
+ char *string;
+ struct assignment *assignment;
+}
+
+%token <string> LITERAL
+%token <string> STRING
+%type <assignment> assignment assignments
+
+%start start
+
+%%
+
+start : assignments
+ {
+ assignment = $1;
+ }
+ ;
+
+assignments : assignment assignments
+ {
+ $1->next = $2;
+ $$ = $1;
+ }
+ | assignment
+ ;
+
+assignment : LITERAL '=' STRING
+ {
+ $$ = malloc(sizeof(*$$));
+ $$->name = $1;
+ $$->type = a_value;
+ $$->lineno = lineno;
+ $$->u.value = $3;
+ $$->next = NULL;
+ }
+ | LITERAL '=' '{' assignments '}'
+ {
+ $$ = malloc(sizeof(*$$));
+ $$->name = $1;
+ $$->type = a_assignment;
+ $$->lineno = lineno;
+ $$->u.assignment = $4;
+ $$->next = NULL;
+ }
+ ;
+
+%%
+char *filename;
+FILE *cfile, *hfile;
+int error_flag;
+struct assignment *assignment;
+
+
+static void
+ex(struct assignment *a, const char *fmt, ...)
+{
+ va_list ap;
+ fprintf(stderr, "%s:%d: ", a->name, a->lineno);
+ va_start(ap, fmt);
+ vfprintf(stderr, fmt, ap);
+ va_end(ap);
+ fprintf(stderr, "\n");
+}
+
+
+
+static int
+check_option(struct assignment *as)
+{
+ struct assignment *a;
+ int seen_long = 0;
+ int seen_name = 0;
+ int seen_short = 0;
+ int seen_type = 0;
+ int seen_argument = 0;
+ int seen_help = 0;
+ int seen_default = 0;
+ int ret = 0;
+
+ for(a = as; a != NULL; a = a->next) {
+ if(strcmp(a->name, "long") == 0)
+ seen_long++;
+ else if(strcmp(a->name, "short") == 0)
+ seen_short++;
+ else if(strcmp(a->name, "name") == 0)
+ seen_name++;
+ else if(strcmp(a->name, "type") == 0)
+ seen_type++;
+ else if(strcmp(a->name, "argument") == 0)
+ seen_argument++;
+ else if(strcmp(a->name, "help") == 0)
+ seen_help++;
+ else if(strcmp(a->name, "default") == 0)
+ seen_default++;
+ else {
+ ex(a, "unknown name %s", a->name);
+ ret++;
+ }
+ }
+ if(seen_long == 0 && seen_short == 0) {
+ ex(as, "neither long nor short option");
+ ret++;
+ }
+ if (seen_long == 0 && seen_name == 0) {
+ ex(as, "either of long or name option must be used");
+ ret++;
+ }
+ if(seen_long > 1) {
+ ex(as, "multiple long options");
+ ret++;
+ }
+ if(seen_short > 1) {
+ ex(as, "multiple short options");
+ ret++;
+ }
+ if(seen_type > 1) {
+ ex(as, "multiple types");
+ ret++;
+ }
+ if(seen_argument > 1) {
+ ex(as, "multiple arguments");
+ ret++;
+ }
+ if(seen_help > 1) {
+ ex(as, "multiple help strings");
+ ret++;
+ }
+ if(seen_default > 1) {
+ ex(as, "multiple default values");
+ ret++;
+ }
+ return ret;
+}
+
+static int
+check_command(struct assignment *as)
+{
+ struct assignment *a;
+ int seen_name = 0;
+ int seen_function = 0;
+ int seen_help = 0;
+ int seen_argument = 0;
+ int seen_minargs = 0;
+ int seen_maxargs = 0;
+ int ret = 0;
+ for(a = as; a != NULL; a = a->next) {
+ if(strcmp(a->name, "name") == 0)
+ seen_name++;
+ else if(strcmp(a->name, "function") == 0) {
+ seen_function++;
+ } else if(strcmp(a->name, "option") == 0)
+ ret += check_option(a->u.assignment);
+ else if(strcmp(a->name, "help") == 0) {
+ seen_help++;
+ } else if(strcmp(a->name, "argument") == 0) {
+ seen_argument++;
+ } else if(strcmp(a->name, "min_args") == 0) {
+ seen_minargs++;
+ } else if(strcmp(a->name, "max_args") == 0) {
+ seen_maxargs++;
+ } else {
+ ex(a, "unknown name: %s", a->name);
+ ret++;
+ }
+ }
+ if(seen_name == 0) {
+ ex(as, "no command name");
+ ret++;
+ }
+ if(seen_function > 1) {
+ ex(as, "multiple function names");
+ ret++;
+ }
+ if(seen_help > 1) {
+ ex(as, "multiple help strings");
+ ret++;
+ }
+ if(seen_argument > 1) {
+ ex(as, "multiple argument strings");
+ ret++;
+ }
+ if(seen_minargs > 1) {
+ ex(as, "multiple min_args strings");
+ ret++;
+ }
+ if(seen_maxargs > 1) {
+ ex(as, "multiple max_args strings");
+ ret++;
+ }
+
+ return ret;
+}
+
+static int
+check(struct assignment *as)
+{
+ struct assignment *a;
+ int ret = 0;
+ for(a = as; a != NULL; a = a->next) {
+ if (strcmp(a->name, "command") != 0) {
+ fprintf(stderr, "unknown type %s line %d\n", a->name, a->lineno);
+ ret++;
+ continue;
+ }
+ if(a->type != a_assignment) {
+ fprintf(stderr, "bad command definition %s line %d\n", a->name, a->lineno);
+ ret++;
+ continue;
+ }
+ ret += check_command(a->u.assignment);
+ }
+ return ret;
+}
+
+static struct assignment *
+find_next(struct assignment *as, const char *name)
+{
+ for(as = as->next; as != NULL; as = as->next) {
+ if(strcmp(as->name, name) == 0)
+ return as;
+ }
+ return NULL;
+}
+
+static struct assignment *
+find(struct assignment *as, const char *name)
+{
+ for(; as != NULL; as = as->next) {
+ if(strcmp(as->name, name) == 0)
+ return as;
+ }
+ return NULL;
+}
+
+static void
+space(FILE *f, int level)
+{
+ fprintf(f, "%*.*s", level * 4, level * 4, " ");
+}
+
+static void
+cprint(int level, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ space(cfile, level);
+ vfprintf(cfile, fmt, ap);
+ va_end(ap);
+}
+
+static void
+hprint(int level, const char *fmt, ...)
+{
+ va_list ap;
+ va_start(ap, fmt);
+ space(hfile, level);
+ vfprintf(hfile, fmt, ap);
+ va_end(ap);
+}
+
+static void gen_name(char *str);
+
+static void
+gen_command(struct assignment *as)
+{
+ struct assignment *a, *b;
+ char *f;
+ a = find(as, "name");
+ f = strdup(a->u.value);
+ gen_name(f);
+ cprint(1, " { ");
+ fprintf(cfile, "\"%s\", ", a->u.value);
+ fprintf(cfile, "%s_wrap, ", f);
+ free(f);
+ b = find(as, "argument");
+ if(b)
+ fprintf(cfile, "\"%s %s\", ", a->u.value, b->u.value);
+ else
+ fprintf(cfile, "\"%s\", ", a->u.value);
+ b = find(as, "help");
+ if(b)
+ fprintf(cfile, "\"%s\"", b->u.value);
+ else
+ fprintf(cfile, "NULL");
+ fprintf(cfile, " },\n");
+ for(a = a->next; a != NULL; a = a->next)
+ if(strcmp(a->name, "name") == 0)
+ cprint(1, " { \"%s\", NULL, NULL, NULL },\n", a->u.value);
+ cprint(0, "\n");
+}
+
+static void
+gen_name(char *str)
+{
+ char *p;
+ for(p = str; *p != '\0'; p++)
+ if(!isalnum((unsigned char)*p))
+ *p = '_';
+}
+
+static char *
+make_name(struct assignment *as)
+{
+ struct assignment *lopt;
+ struct assignment *type;
+ char *s;
+ int ret;
+
+ lopt = find(as, "long");
+ if(lopt == NULL)
+ lopt = find(as, "name");
+ if(lopt == NULL)
+ return NULL;
+
+ type = find(as, "type");
+ if(strcmp(type->u.value, "-flag") == 0)
+ ret = asprintf(&s, "%s_flag", lopt->u.value);
+ else
+ ret = asprintf(&s, "%s_%s", lopt->u.value, type->u.value);
+ if (ret == -1)
+ return NULL;
+ gen_name(s);
+ return s;
+}
+
+
+static void defval_int(const char *name, struct assignment *defval)
+{
+ if(defval != NULL)
+ cprint(1, "opt.%s = %s;\n", name, defval->u.value);
+ else
+ cprint(1, "opt.%s = 0;\n", name);
+}
+static void defval_neg_flag(const char *name, struct assignment *defval)
+{
+ if(defval != NULL)
+ cprint(1, "opt.%s = %s;\n", name, defval->u.value);
+ else
+ cprint(1, "opt.%s = 1;\n", name);
+}
+static void defval_string(const char *name, struct assignment *defval)
+{
+ if(defval != NULL)
+ cprint(1, "opt.%s = (char *)(uintptr_t)\"%s\";\n", name, defval->u.value);
+ else
+ cprint(1, "opt.%s = NULL;\n", name);
+}
+static void defval_strings(const char *name, struct assignment *defval)
+{
+ cprint(1, "opt.%s.num_strings = 0;\n", name);
+ cprint(1, "opt.%s.strings = NULL;\n", name);
+}
+
+static void free_strings(const char *name)
+{
+ cprint(1, "free_getarg_strings (&opt.%s);\n", name);
+}
+
+struct type_handler {
+ const char *typename;
+ const char *c_type;
+ const char *getarg_type;
+ void (*defval)(const char*, struct assignment*);
+ void (*free)(const char*);
+} type_handlers[] = {
+ { "integer",
+ "int",
+ "arg_integer",
+ defval_int,
+ NULL
+ },
+ { "string",
+ "char*",
+ "arg_string",
+ defval_string,
+ NULL
+ },
+ { "strings",
+ "struct getarg_strings",
+ "arg_strings",
+ defval_strings,
+ free_strings
+ },
+ { "flag",
+ "int",
+ "arg_flag",
+ defval_int,
+ NULL
+ },
+ { "-flag",
+ "int",
+ "arg_negative_flag",
+ defval_neg_flag,
+ NULL
+ },
+ { NULL, NULL, NULL, NULL, NULL }
+};
+
+static struct type_handler *find_handler(struct assignment *type)
+{
+ struct type_handler *th;
+ for(th = type_handlers; th->typename != NULL; th++)
+ if(strcmp(type->u.value, th->typename) == 0)
+ return th;
+ ex(type, "unknown type \"%s\"", type->u.value);
+ exit(1);
+}
+
+static void
+gen_options(struct assignment *opt1, const char *name)
+{
+ struct assignment *tmp;
+
+ hprint(0, "struct %s_options {\n", name);
+
+ for(tmp = opt1;
+ tmp != NULL;
+ tmp = find_next(tmp, "option")) {
+ struct assignment *type;
+ struct type_handler *th;
+ char *s;
+
+ s = make_name(tmp->u.assignment);
+ type = find(tmp->u.assignment, "type");
+ th = find_handler(type);
+ hprint(1, "%s %s;\n", th->c_type, s);
+ free(s);
+ }
+ hprint(0, "};\n");
+}
+
+static void
+gen_wrapper(struct assignment *as)
+{
+ struct assignment *name;
+ struct assignment *arg;
+ struct assignment *opt1;
+ struct assignment *function;
+ struct assignment *tmp;
+ char *n, *f;
+ int nargs = 0;
+ int narguments = 0;
+
+ name = find(as, "name");
+ n = strdup(name->u.value);
+ gen_name(n);
+ arg = find(as, "argument");
+ if (arg)
+ narguments++;
+ opt1 = find(as, "option");
+ function = find(as, "function");
+ if(function)
+ f = function->u.value;
+ else
+ f = n;
+
+
+ if(opt1 != NULL) {
+ gen_options(opt1, n);
+ hprint(0, "int %s(struct %s_options*, int, char **);\n", f, n);
+ } else {
+ hprint(0, "int %s(void*, int, char **);\n", f);
+ }
+
+ fprintf(cfile, "static int\n");
+ fprintf(cfile, "%s_wrap(int argc, char **argv)\n", n);
+ fprintf(cfile, "{\n");
+ if(opt1 != NULL)
+ cprint(1, "struct %s_options opt;\n", n);
+ cprint(1, "int ret;\n");
+ cprint(1, "int optidx = 0;\n");
+ cprint(1, "struct getargs args[] = {\n");
+ for(tmp = find(as, "option");
+ tmp != NULL;
+ tmp = find_next(tmp, "option")) {
+ struct assignment *type = find(tmp->u.assignment, "type");
+ struct assignment *lopt = find(tmp->u.assignment, "long");
+ struct assignment *sopt = find(tmp->u.assignment, "short");
+ struct assignment *aarg = find(tmp->u.assignment, "argument");
+ struct assignment *help = find(tmp->u.assignment, "help");
+
+ struct type_handler *th;
+
+ cprint(2, "{ ");
+ if(lopt)
+ fprintf(cfile, "\"%s\", ", lopt->u.value);
+ else
+ fprintf(cfile, "NULL, ");
+ if(sopt)
+ fprintf(cfile, "'%c', ", *sopt->u.value);
+ else
+ fprintf(cfile, "0, ");
+ th = find_handler(type);
+ fprintf(cfile, "%s, ", th->getarg_type);
+ fprintf(cfile, "NULL, ");
+ if(help)
+ fprintf(cfile, "\"%s\", ", help->u.value);
+ else
+ fprintf(cfile, "NULL, ");
+ if(aarg) {
+ fprintf(cfile, "\"%s\"", aarg->u.value);
+ narguments++;
+ } else
+ fprintf(cfile, "NULL");
+ fprintf(cfile, " },\n");
+ }
+ cprint(2, "{ \"help\", 'h', arg_flag, NULL, NULL, NULL }\n");
+ cprint(1, "};\n");
+ cprint(1, "int help_flag = 0;\n");
+
+ for(tmp = find(as, "option");
+ tmp != NULL;
+ tmp = find_next(tmp, "option")) {
+ char *s;
+ struct assignment *type = find(tmp->u.assignment, "type");
+
+ struct assignment *defval = find(tmp->u.assignment, "default");
+
+ struct type_handler *th;
+
+ s = make_name(tmp->u.assignment);
+ th = find_handler(type);
+ (*th->defval)(s, defval);
+ free(s);
+ }
+
+ for(tmp = find(as, "option");
+ tmp != NULL;
+ tmp = find_next(tmp, "option")) {
+ char *s;
+ s = make_name(tmp->u.assignment);
+ cprint(1, "args[%d].value = &opt.%s;\n", nargs++, s);
+ free(s);
+ }
+ cprint(1, "args[%d].value = &help_flag;\n", nargs++);
+ cprint(1, "if(getarg(args, %d, argc, argv, &optidx))\n", nargs);
+ cprint(2, "goto usage;\n");
+
+ {
+ int min_args = -1;
+ int max_args = -1;
+ char *end;
+ if(narguments == 0) {
+ max_args = 0;
+ } else {
+ if((tmp = find(as, "min_args")) != NULL) {
+ min_args = strtol(tmp->u.value, &end, 0);
+ if(*end != '\0') {
+ ex(tmp, "min_args is not numeric");
+ exit(1);
+ }
+ if(min_args < 0) {
+ ex(tmp, "min_args must be non-negative");
+ exit(1);
+ }
+ }
+ if((tmp = find(as, "max_args")) != NULL) {
+ max_args = strtol(tmp->u.value, &end, 0);
+ if(*end != '\0') {
+ ex(tmp, "max_args is not numeric");
+ exit(1);
+ }
+ if(max_args < 0) {
+ ex(tmp, "max_args must be non-negative");
+ exit(1);
+ }
+ }
+ }
+ if(min_args != -1 || max_args != -1) {
+ if(min_args == max_args) {
+ cprint(1, "if(argc - optidx != %d) {\n",
+ min_args);
+ cprint(2, "fprintf(stderr, \"Need exactly %u parameters (%%u given).\\n\\n\", argc - optidx);\n", min_args);
+ cprint(2, "goto usage;\n");
+ cprint(1, "}\n");
+ } else {
+ if(max_args != -1) {
+ cprint(1, "if(argc - optidx > %d) {\n", max_args);
+ cprint(2, "fprintf(stderr, \"Arguments given (%%u) are more than expected (%u).\\n\\n\", argc - optidx);\n", max_args);
+ cprint(2, "goto usage;\n");
+ cprint(1, "}\n");
+ }
+ if(min_args != -1) {
+ cprint(1, "if(argc - optidx < %d) {\n", min_args);
+ cprint(2, "fprintf(stderr, \"Arguments given (%%u) are less than expected (%u).\\n\\n\", argc - optidx);\n", min_args);
+ cprint(2, "goto usage;\n");
+ cprint(1, "}\n");
+ }
+ }
+ }
+ }
+
+ cprint(1, "if(help_flag)\n");
+ cprint(2, "goto usage;\n");
+
+ cprint(1, "ret = %s(%s, argc - optidx, argv + optidx);\n",
+ f, opt1 ? "&opt": "NULL");
+
+ /* free allocated data */
+ for(tmp = find(as, "option");
+ tmp != NULL;
+ tmp = find_next(tmp, "option")) {
+ char *s;
+ struct assignment *type = find(tmp->u.assignment, "type");
+ struct type_handler *th;
+ th = find_handler(type);
+ if(th->free == NULL)
+ continue;
+ s = make_name(tmp->u.assignment);
+ (*th->free)(s);
+ free(s);
+ }
+ cprint(1, "return ret;\n");
+
+ cprint(0, "usage:\n");
+ cprint(1, "arg_printusage (args, %d, \"%s\", \"%s\");\n", nargs,
+ name->u.value, arg ? arg->u.value : "");
+ /* free allocated data */
+ for(tmp = find(as, "option");
+ tmp != NULL;
+ tmp = find_next(tmp, "option")) {
+ char *s;
+ struct assignment *type = find(tmp->u.assignment, "type");
+ struct type_handler *th;
+ th = find_handler(type);
+ if(th->free == NULL)
+ continue;
+ s = make_name(tmp->u.assignment);
+ (*th->free)(s);
+ free(s);
+ }
+ cprint(1, "return 1;\n");
+ cprint(0, "}\n");
+ cprint(0, "\n");
+ free(n);
+}
+
+char cname[PATH_MAX];
+char hname[PATH_MAX];
+
+static void
+gen(struct assignment *as)
+{
+ struct assignment *a;
+ cprint(0, "#include <stdio.h>\n");
+ cprint(0, "#include <stdint.h>\n");
+ cprint(0, "#include <getarg.h>\n");
+ cprint(0, "#include <sl.h>\n");
+ cprint(0, "#include \"%s\"\n\n", hname);
+
+ hprint(0, "#include <stdio.h>\n");
+ hprint(0, "#include <sl.h>\n");
+ hprint(0, "\n");
+
+
+ for(a = as; a != NULL; a = a->next)
+ gen_wrapper(a->u.assignment);
+
+ cprint(0, "SL_cmd commands[] = {\n");
+ for(a = as; a != NULL; a = a->next)
+ gen_command(a->u.assignment);
+ cprint(1, "{ NULL, NULL, NULL, NULL }\n");
+ cprint(0, "};\n");
+
+ hprint(0, "extern SL_cmd commands[];\n");
+}
+
+int version_flag;
+int help_flag;
+struct getargs args[] = {
+ { "version", 0, arg_flag, &version_flag, NULL, NULL },
+ { "help", 0, arg_flag, &help_flag, NULL, NULL }
+};
+int num_args = sizeof(args) / sizeof(args[0]);
+
+static void
+usage(int code)
+{
+ arg_printusage(args, num_args, NULL, "command-table");
+ exit(code);
+}
+
+int
+main(int argc, char **argv)
+{
+ char *p;
+
+ int optidx = 0;
+
+ setprogname(argv[0]);
+ if(getarg(args, num_args, argc, argv, &optidx))
+ usage(1);
+ if(help_flag)
+ usage(0);
+ if(version_flag) {
+ print_version(NULL);
+ exit(0);
+ }
+
+ if(argc == optidx)
+ usage(1);
+
+ filename = argv[optidx];
+ yyin = fopen(filename, "r");
+ if(yyin == NULL)
+ err(1, "%s", filename);
+ p = strrchr(filename, '/');
+ if(p)
+ strlcpy(cname, p + 1, sizeof(cname));
+ else
+ strlcpy(cname, filename, sizeof(cname));
+ p = strrchr(cname, '.');
+ if(p)
+ *p = '\0';
+ strlcpy(hname, cname, sizeof(hname));
+ strlcat(cname, ".c", sizeof(cname));
+ strlcat(hname, ".h", sizeof(hname));
+ yyparse();
+ if(error_flag)
+ exit(1);
+ if(check(assignment) == 0) {
+ cfile = fopen(cname, "w");
+ if(cfile == NULL)
+ err(1, "%s", cname);
+ hfile = fopen(hname, "w");
+ if(hfile == NULL)
+ err(1, "%s", hname);
+ gen(assignment);
+ fclose(cfile);
+ fclose(hfile);
+ }
+ fclose(yyin);
+ return 0;
+}
diff --git a/third_party/heimdal/lib/sl/slc-lex.l b/third_party/heimdal/lib/sl/slc-lex.l
new file mode 100644
index 0000000..3a37302
--- /dev/null
+++ b/third_party/heimdal/lib/sl/slc-lex.l
@@ -0,0 +1,158 @@
+%{
+/*
+ * Copyright (c) 2004 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* $Id$ */
+
+#undef ECHO
+
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include "slc.h"
+#include "slc-gram.h"
+unsigned lineno = 1;
+
+static void handle_comment(void);
+static char * handle_string(void);
+
+#define YY_NO_UNPUT
+
+#undef ECHO
+
+%}
+
+%%
+[A-Za-z][-A-Za-z0-9_]* {
+ yylval.string = strdup ((const char *)yytext);
+ return LITERAL;
+ }
+"\"" { yylval.string = handle_string(); return STRING; }
+\n { ++lineno; }
+\/\* { handle_comment(); }
+[={}] { return *yytext; }
+[ \t] ;
+%%
+
+void
+error_message (const char *format, ...)
+{
+ va_list args;
+
+ va_start (args, format);
+ fprintf (stderr, "%s:%d: ", filename, lineno);
+ vfprintf (stderr, format, args);
+ va_end (args);
+ error_flag++;
+}
+
+void
+yyerror (const char *s)
+{
+ error_message("%s\n", s);
+}
+
+static void
+handle_comment(void)
+{
+ int c;
+ int start_lineno = lineno;
+ int level = 1;
+ int seen_star = 0;
+ int seen_slash = 0;
+ while((c = input()) != EOF) {
+ if(c == '/') {
+ if(seen_star) {
+ if(--level == 0)
+ return;
+ seen_star = 0;
+ continue;
+ }
+ seen_slash = 1;
+ continue;
+ } else if(c == '*') {
+ if(seen_slash) {
+ level++;
+ seen_star = seen_slash = 0;
+ continue;
+ }
+ seen_star = 1;
+ continue;
+ }
+ seen_star = seen_slash = 0;
+ if(c == '\n') {
+ lineno++;
+ continue;
+ }
+ }
+ if(c == EOF)
+ error_message("unterminated comment, possibly started on line %d\n", start_lineno);
+}
+
+static char *
+handle_string(void)
+{
+ char x[1024];
+ int i = 0;
+ int c;
+ int quote = 0;
+ while((c = input()) != EOF){
+ if(quote) {
+ x[i++] = '\\';
+ x[i++] = c;
+ quote = 0;
+ continue;
+ }
+ if(c == '\n'){
+ error_message("unterminated string");
+ lineno++;
+ break;
+ }
+ if(c == '\\'){
+ quote++;
+ continue;
+ }
+ if(c == '\"')
+ break;
+ x[i++] = c;
+ }
+ x[i] = '\0';
+ return strdup(x);
+}
+
+int
+yywrap ()
+{
+ return 1;
+}
diff --git a/third_party/heimdal/lib/sl/slc.h b/third_party/heimdal/lib/sl/slc.h
new file mode 100644
index 0000000..e4dc2cb
--- /dev/null
+++ b/third_party/heimdal/lib/sl/slc.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright (c) 2004 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of the Institute nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/* $Id$ */
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+
+struct assignment {
+ char *name;
+ enum { a_value, a_assignment } type;
+ union {
+ char *value;
+ struct assignment *assignment;
+ } u;
+ unsigned int lineno;
+ struct assignment *next;
+};
+
+extern char *filename;
+extern int error_flag;
+void error_message (const char *format, ...);
+int yylex(void);
+void yyerror (const char *s);
+#define yyerror yyerror
+extern unsigned lineno;
diff --git a/third_party/heimdal/lib/sl/test_sl.c b/third_party/heimdal/lib/sl/test_sl.c
new file mode 100644
index 0000000..9b9c1f7
--- /dev/null
+++ b/third_party/heimdal/lib/sl/test_sl.c
@@ -0,0 +1,98 @@
+/*
+ * Copyright (c) 2006 Kungliga Tekniska Högskolan
+ * (Royal Institute of Technology, Stockholm, Sweden).
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of KTH nor the names of its contributors may be
+ * used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
+
+#include "sl_locl.h"
+
+struct {
+ int ok;
+ const char *line;
+ int argc;
+ const char *argv[4];
+} lines[] = {
+ { 1, "", 1, { "" } },
+ { 1, "foo", 1, { "foo" } },
+ { 1, "foo bar", 2, { "foo", "bar" }},
+ { 1, "foo bar baz", 3, { "foo", "bar", "baz" }},
+ { 1, "foobar baz", 2, { "foobar", "baz" }},
+ { 1, " foo", 1, { "foo" } },
+ { 1, "foo ", 1, { "foo" } },
+ { 1, " foo ", 1, { "foo" } },
+ { 1, " foo bar", 2, { "foo", "bar" } },
+ { 1, "foo\\ bar", 1, { "foo bar" } },
+ { 1, "\"foo bar\"", 1, { "foo bar" } },
+ { 1, "\"foo\\ bar\"", 1, { "foo bar" } },
+ { 1, "\"foo\\\" bar\"", 1, { "foo\" bar" } },
+ { 1, "\"\"f\"\"oo\"\"", 1, { "foo" } },
+ { 1, "\"foobar\"baz", 1, { "foobarbaz" }},
+ { 1, "foo\tbar baz", 3, { "foo", "bar", "baz" }},
+ { 1, "\"foo bar\" baz", 2, { "foo bar", "baz" }},
+ { 1, "\"foo bar baz\"", 1, { "foo bar baz" }},
+ { 1, "\\\"foo bar baz", 3, { "\"foo", "bar", "baz" }},
+ { 1, "\\ foo bar baz", 3, { " foo", "bar", "baz" }},
+ { 1, "foo\\\\\\\"barbaz", 1, { "foo\\\"barbaz" }},
+ { 1, "foobar\\\" baz", 2, { "foobar\"", "baz" }},
+ { 1, "foobar\\ \\ baz", 1, { "foobar baz" }},
+ { 0, "\\", 0, { "" }},
+ { 0, "\"", 0, { "" }}
+};
+
+int
+main(int argc, char **argv)
+{
+ int ret, i;
+
+ for (i = 0; i < sizeof(lines)/sizeof(lines[0]); i++) {
+ int j, rargc = 0;
+ char **rargv = NULL;
+ char *buf = strdup(lines[i].line);
+
+ ret = sl_make_argv(buf, &rargc, &rargv);
+ if (ret) {
+ if (!lines[i].ok)
+ goto next;
+ errx(1, "sl_make_argv test %d failed", i);
+ } else if (!lines[i].ok)
+ errx(1, "sl_make_argv passed test %d when it shouldn't", i);
+ if (rargc != lines[i].argc)
+ errx(1, "result argc (%d) != should be argc (%d) for test %d",
+ rargc, lines[i].argc, i);
+ for (j = 0; j < rargc; j++)
+ if (strcmp(rargv[j], lines[i].argv[j]) != 0)
+ errx(1, "result argv (%s) != should be argv (%s) for test %d",
+ rargv[j], lines[i].argv[j], i);
+ next:
+ free(buf);
+ free(rargv);
+ }
+
+ return 0;
+}