summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--CMakeLists.txt119
-rw-r--r--config.h.cmake138
-rw-r--r--release_it.bat31
-rwxr-xr-xrelease_it.sh42
-rw-r--r--src/CMakeLists.txt50
-rw-r--r--src/getopt.c200
7 files changed, 581 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index 9cfb3a6..f690a0b 100644
--- a/.gitignore
+++ b/.gitignore
@@ -31,3 +31,4 @@ scanners.c
bstrlib.txt
stmd.dSYM/*
stmd
+build
diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644
index 0000000..b19d98f
--- /dev/null
+++ b/CMakeLists.txt
@@ -0,0 +1,119 @@
+project(stmd)
+cmake_minimum_required(VERSION 2.8)
+
+set(PROJECT_NAME "stmd")
+
+set(PROJECT_VERSION_MAJOR 0)
+set(PROJECT_VERSION_MINOR 0)
+set(PROJECT_VERSION_PATCH 1)
+set(PROJECT_VERSION ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}.${PROJECT_VERSION_PATCH} )
+
+include (CheckIncludeFile)
+CHECK_INCLUDE_FILE (stdbool.h HAVE_STDBOOL_H)
+
+#option(${PROJECT_NAME}_WITH_DOCS "generate Documentation" OFF)
+#option(${PROJECT_NAME}_WITH_TESTS "enable testing" ON)
+option(CMAKE_SUPPRESS_REGENERATION "suppress rules to re-run cmake on changes (warning: no dependency checks!)?" OFF)
+if (MSVC)
+ set(RE2C ${CMAKE_CURRENT_SOURCE_DIR}/re2c)
+else(MSVC)
+ set(RE2C re2c)
+endif(MSVC)
+
+if (MSVC)
+ option(PROJECT_LINK_MSVC_MT "link with /MT instead of /MD (use msvc runtime dlls versus static linked)" ON)
+ # see http://msdn.microsoft.com/en-us/library/2kzt1wy3%28VS.71%29.aspx
+ if (PROJECT_LINK_MSVC_MT)
+ set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
+ set(CMAKE_C_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /MTd")
+ set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
+ set(CMAKE_C_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /MT")
+ endif (PROJECT_LINK_MSVC_MT)
+
+ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} /INCREMENTAL:NO")
+ set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /W4")
+ set(CMAKE_C_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /W4")
+
+ set_property(DIRECTORY APPEND PROPERTY COMPILE_DEFINITIONS _CRT_SECURE_NO_WARNINGS UNICODE)
+ set(CMAKE_FIND_LIBRARY_PREFIXES "")
+ set(CMAKE_FIND_LIBRARY_SUFFIXES ".lib")
+ set(CMAKE_STATIC_LIBRARY_PREFIX "lib")
+ set(CMAKE_STATIC_LIBRARY_SUFFIX ".lib")
+ set(CMAKE_SHARED_LIBRARY_PREFIX "") # lib
+ set(CMAKE_SHARED_LIBRARY_SUFFIX ".dll") # .so
+ set(CMAKE_IMPORT_LIBRARY_PREFIX "")
+ set(CMAKE_IMPORT_LIBRARY_SUFFIX ".lib")
+ set(CMAKE_EXECUTABLE_SUFFIX ".exe") # .exe
+ set(CMAKE_LINK_LIBRARY_SUFFIX ".lib")
+ set(CMAKE_DL_LIBS "")
+ set(CMAKE_DEBUG_POSTFIX "d")
+ add_definitions(-DUNICODE -D_UNICODE)
+else(MSVC)
+ list(APPEND CMAKE_CXX_FLAGS "-Wall -Wunused-variable -Wno-long-long")
+ #-pedantic
+ list(APPEND CMAKE_C_FLAGS "-Wall -Wunused-variable -Wno-long-long")
+endif(MSVC)
+
+# create config.h
+configure_file( ${CMAKE_CURRENT_SOURCE_DIR}/config.h.cmake
+ ${CMAKE_CURRENT_BINARY_DIR}/config.h)
+
+# set include directories
+get_filename_component(CONFIG_INCLUDE ${CMAKE_CURRENT_BINARY_DIR}/config.h PATH)
+include_directories(include ${CONFIG_INCLUDE})
+
+install(DIRECTORY include DESTINATION .
+ COMPONENT devel
+ FILES_MATCHING PATTERN "*.h"
+ PATTERN .svn EXCLUDE
+ )
+install(FILES ${CMAKE_CURRENT_BINARY_DIR}/config.h
+ DESTINATION include/${PROJECT_NAME}
+ COMPONENT devel)
+
+add_subdirectory(src)
+
+include(InstallRequiredSystemLibraries)
+
+set(CPACK_GENERATOR TGZ ZIP)
+if(WIN32 AND NOT CYGWIN)
+ set(CPACK_GENERATOR NSIS ${CPACK_GENERATOR})
+endif(WIN32 AND NOT CYGWIN)
+if(APPLE)
+ set(CPACK_GENERATOR DragNDrop ${CPACK_GENERATOR})
+endif(APPLE)
+if (UNIX AND NOT APPLE AND NOT WIN32)
+ set(CPACK_GENERATOR DEB ${CPACK_GENERATOR})
+endif (UNIX AND NOT APPLE AND NOT WIN32)
+
+set(CPACK_SOURCE_PACKAGE_FILE_NAME ${PROJECT_NAME}-src-${PROJECT_VERSION})
+set(CPACK_SOURCE_GENERATOR TGZ ZIP)
+set(CPACK_PACKAGE_CONTACT http://talk.commonmark.org/)
+set(CPACK_PACKAGE_DESCRIPTION_SUMMARY ${PROJECT_NAME})
+set(CPACK_PACKAGE_VENDOR "${PROJECT_NAME} Development Team")
+set(CPACK_PACKAGE_DESCRIPTION_FILE "${CMAKE_CURRENT_SOURCE_DIR}/README.md")
+set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/LICENSE")
+set(CPACK_PACKAGE_VERSION_MAJOR "${PROJECT_VERSION_MAJOR}")
+set(CPACK_PACKAGE_VERSION_MINOR "${PROJECT_VERSION_MINOR}")
+set(CPACK_PACKAGE_VERSION_PATCH "${PROJECT_VERSION_PATCH}")
+set(CPACK_SOURCE_IGNORE_FILES "/docs/html;/autom4te.cache;/build/;/win32/;/.svn/;~$;${CPACK_SOURCE_IGNORE_FILES}")
+
+if(WIN32 AND NOT UNIX)
+ set(CPACK_PACKAGE_INSTALL_DIRECTORY "${PROJECT_NAME}\\\\${PROJECT_VERSION}")
+ # There is a bug in NSI that does not handle full unix paths properly. Make
+ # sure there is at least one set of four (4) backlashes.
+ # set(CPACK_PACKAGE_ICON "${CMake_SOURCE_DIR}/Utilities/Release\\\\InstallIcon.bmp")
+ set(CPACK_NSIS_INSTALLED_ICON_NAME "bin\\\\${PROJECT_NAME}.exe")
+ set(CPACK_NSIS_DISPLAY_NAME "${CPACK_PACKAGE_INSTALL_DIRECTORY} ${PROJECT_NAME}")
+ set(CPACK_NSIS_HELP_LINK "http://commonmark.org/")
+ set(CPACK_NSIS_URL_INFO_ABOUT "http://commonmark.org/")
+ set(CPACK_NSIS_CONTACT "http://talk.commonmark.org/")
+ set(CPACK_NSIS_MODIFY_PATH ON)
+ set(CPACK_NSIS_MENU_LINKS "doc/html/index.html;Documentation")
+else(WIN32 AND NOT UNIX)
+ set(CPACK_PACKAGE_INSTALL_DIRECTORY "${PROJECT_NAME}/${PROJECT_VERSION}")
+ set(CPACK_STRIP_FILES "bin/${PROJECT_NAME}")
+ set(CPACK_SOURCE_STRIP_FILES "")
+endif(WIN32 AND NOT UNIX)
+set(CPACK_PACKAGE_EXECUTABLES ${PROJECT_NAME};${PROJECT_NAME})
+include(CPack)
diff --git a/config.h.cmake b/config.h.cmake
new file mode 100644
index 0000000..263010a
--- /dev/null
+++ b/config.h.cmake
@@ -0,0 +1,138 @@
+/* config.h.in. Generated from configure.ac by autoheader. */
+
+/* Define to 1 if you have the `atof' function. */
+#cmakedefine HAVE_ATOF
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#cmakedefine HAVE_DLFCN_H
+
+/* Define to 1 if you have the `gettimeofday' function. */
+#cmakedefine HAVE_GETTIMEOFDAY
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#cmakedefine HAVE_INTTYPES_H
+
+/* Define to 1 if you have the 'mysqlclient' library (-lmysqlclient). */
+#cmakedefine HAVE_LIBMYSQLCLIENT
+
+/* Define to 1 if you have the `pq' library (-lpq). */
+#cmakedefine HAVE_LIBPQ
+
+/* Define to 1 if you have the `sqlite3' library (-lsqlite3). */
+#cmakedefine HAVE_LIBSQLITE3
+
+/* Define to 1 if you have the `localtime_r' function. */
+#cmakedefine HAVE_LOCALTIME_R
+
+/* Define to 1 if your system has a GNU libc compatible `malloc' function, and
+ to 0 otherwise. */
+#cmakedefine HAVE_MALLOC
+
+/* Define to 1 if you have the <memory.h> header file. */
+#cmakedefine HAVE_MEMORY_H
+
+/* Define to 1 if you have the `memset' function. */
+#cmakedefine HAVE_MEMSET
+
+/* Define to 1 if you have the `mktime' function. */
+#cmakedefine HAVE_MKTIME
+
+/* Define to 1 if your system has a GNU libc compatible `realloc' function,
+ and to 0 otherwise. */
+#cmakedefine HAVE_REALLOC
+
+/* Define to 1 if stdbool.h conforms to C99. */
+#cmakedefine HAVE_STDBOOL_H
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#cmakedefine HAVE_STDINT_H
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#cmakedefine HAVE_STDLIB_H
+
+/* Define to 1 if you have the `strchr' function. */
+#cmakedefine HAVE_STRCHR
+
+/* Define to 1 if you have the `strdup' function. */
+#cmakedefine HAVE_STRDUP
+
+/* Define to 1 if you have the <strings.h> header file. */
+#cmakedefine HAVE_STRINGS_H
+
+/* Define to 1 if you have the <string.h> header file. */
+#cmakedefine HAVE_STRING_H
+
+/* Define to 1 if you have the `strrchr' function. */
+#cmakedefine HAVE_STRRCHR
+
+/* Define to 1 if you have the `strstr' function. */
+#cmakedefine HAVE_STRSTR
+
+/* Define to 1 if you have the `strtof' function. */
+#cmakedefine HAVE_STRTOF
+
+/* Define to 1 if you have the `strtol' function. */
+#cmakedefine HAVE_STRTOL
+
+/* Define to 1 if you have the `strtoll' function. */
+#cmakedefine HAVE_STRTOLL
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#cmakedefine HAVE_SYS_STAT_H
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#cmakedefine HAVE_SYS_TIME_H
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#cmakedefine HAVE_SYS_TYPES_H
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#cmakedefine HAVE_UNISTD_H
+
+/* Define to 1 if the system has the type `_Bool'. */
+#cmakedefine HAVE__BOOL
+
+/* Name of package */
+#cmakedefine PACKAGE
+
+/* Define to the address where bug reports for this package should be sent. */
+#cmakedefine PACKAGE_BUGREPORT
+
+/* Define to the full name of this package. */
+#cmakedefine PACKAGE_NAME
+
+/* Define to the full name and version of this package. */
+#cmakedefine PACKAGE_STRING
+
+/* Define to the one symbol short name of this package. */
+#cmakedefine PACKAGE_TARNAME
+
+/* Define to the version of this package. */
+#cmakedefine PACKAGE_VERSION
+
+/* Define to 1 if you have the ANSI C header files. */
+#cmakedefine STDC_HEADERS
+
+/* Define to 1 if you can safely include both <sys/time.h> and <time.h>. */
+#cmakedefine TIME_WITH_SYS_TIME
+
+/* Version number of package */
+#cmakedefine VERSION
+
+/* Define to empty if `const' does not conform to ANSI C. */
+#cmakedefine const
+
+/* Define to `__inline__' or `__inline' if that's what the C compiler
+ calls it, or to nothing if 'inline' is not supported under any name. */
+#ifndef __cplusplus
+#undef inline
+#endif
+
+/* Define to rpl_malloc if the replacement function should be used. */
+#cmakedefine malloc
+
+/* Define to rpl_realloc if the replacement function should be used. */
+#cmakedefine realloc
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+#cmakedefine size_t
diff --git a/release_it.bat b/release_it.bat
new file mode 100644
index 0000000..3ab2837
--- /dev/null
+++ b/release_it.bat
@@ -0,0 +1,31 @@
+
+set PATH=%PATH%;C:\Program Files (x86)\CMake 2.8\bin
+
+set CMAKE_BUILDDIR=build\vc
+set STARTDIR=%CD%
+
+@if NOT "%VS100COMNTOOLS%"=="" (call "%VS100COMNTOOLS%\vsvars32.bat" & goto VS_END)
+@if NOT "%VS90COMNTOOLS%"=="" (call "%VS90COMNTOOLS%\vsvars32.bat" & goto VS_END)
+@if NOT "%VS80COMNTOOLS%"=="" (call "%VS80COMNTOOLS%\vsvars32.bat" & goto VS_END)
+@if NOT "%VS71COMNTOOLS%"=="" (call "%VS71COMNTOOLS%\vsvars32.bat" & goto VS_END)
+
+:VS_END
+
+cd %STARTDIR%
+
+set CMAKE_BUILDDIR=build\vc
+mkdir %CMAKE_BUILDDIR%
+
+cd %CMAKE_BUILDDIR%
+
+del CMakeCache.txt
+
+cmake -D STMD_MSVC_MT:BOOL=OFF %STARTDIR%
+rem -D stmd_DOCS:bool=ON -D stmd_WITH_TESTS:bool=ON -DCXXTEST_INCLUDE_DIR=%STARTDIR%\3rdparty\cxxtest -DCXXTEST_PYTHON_TESTGEN_EXECUTABLE=%STARTDIR%\3rdparty\cxxtest\bin\cxxtestgen
+cpack --config CPackSourceConfig.cmake
+cd %STARTDIR%
+cmake --build %CMAKE_BUILDDIR% --target all --target test --target package
+rem --target package_source
+
+
+pause
diff --git a/release_it.sh b/release_it.sh
new file mode 100755
index 0000000..b83772a
--- /dev/null
+++ b/release_it.sh
@@ -0,0 +1,42 @@
+#!/bin/sh
+
+HOST_SYSTEM=`uname -s`
+HOST_ARCH=`uname -m`
+STARTDIR=`pwd`
+
+CMAKE_BUILDDIR=build/$HOST_ARCH-$HOST_SYSTEM
+
+mkdir -p $CMAKE_BUILDDIR
+
+cd $CMAKE_BUILDDIR
+
+if test $HOST_SYSTEM = "Darwin" ; then
+ cmake -DChronolog_WITH_DOCS:bool=ON \
+ -DChronolog_WITH_TESTS:bool=ON \
+ -DCMAKE_OSX_SYSROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk \
+ $STARTDIR;
+ cd $STARTDIR
+
+ mkdir -p build/Xcode
+ cd build/Xcode
+ cmake -DChronolog_WITH_DOCS:bool=ON \
+ -DChronolog_WITH_TESTS:bool=ON \
+ -DCXXTEST_INCLUDE_DIR=3rdparty/cxxtest \
+ -DCMAKE_OSX_SYSROOT=/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.8.sdk \
+ -G Xcode $STARTDIR;
+ cd $STARTDIR
+
+elif test $HOST_SYSTEM = "Linux" ; then
+ cmake -DChronolog_WITH_DOCS:bool=ON \
+ -DChronolog_WITH_TESTS:bool=ON \
+ $STARTDIR;
+else
+ echo "not supported";
+fi
+
+cd $CMAKE_BUILDDIR
+cpack --config CPackSourceConfig.cmake
+cmake --build . --target all --target test --target package
+cmake --build . --target package_source
+cd $STARTDIR
+
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
new file mode 100644
index 0000000..203e5bf
--- /dev/null
+++ b/src/CMakeLists.txt
@@ -0,0 +1,50 @@
+set(PROGRAM_stmd "stmd")
+set(PROGRAM_stmd_SOURCES blocks.c
+ inlines.c
+ main.c
+ debug.h
+ getopt.c
+ print.c
+ scanners.h
+ scanners.c
+ scanners.re
+ stmd.h
+ utf8.h utf8.c
+ buffer.h buffer.c
+ references.h references.c
+ html/html.c
+ html/html_unescape.h
+ html/html_unescape.gperf
+ html/houdini.h
+ html/houdini_href_e.c
+ html/houdini_html_e.c
+ html/houdini_html_u.c
+)
+
+include_directories(. html)
+
+if (MSVC)
+ file(TO_NATIVE_PATH ${CMAKE_CURRENT_SOURCE_DIR} DOS_CURRENT_SOURCE_DIR)
+ add_custom_command( OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/scanners.c
+ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/scanners.re
+ COMMAND ${RE2C} --case-insensitive -b -i ${DOS_CURRENT_SOURCE_DIR}\\scanners.re >${DOS_CURRENT_SOURCE_DIR}\\scanners.c)
+else(MSVC)
+ add_custom_command( OUTPUT ${CMAKE_CURRENT_SOURCE_DIR}/scanners.c
+ DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/scanners.re
+ COMMAND ${RE2C} --case-insensitive -b -i ${CMAKE_CURRENT_SOURCE_DIR}/scanners.re >${CMAKE_CURRENT_SOURCE_DIR}/scanners.c)
+endif(MSVC)
+
+add_executable(${PROGRAM_stmd}
+ ${PROGRAM_stmd_SOURCES})
+
+if (MSVC)
+set_property(TARGET ${PROGRAM_stmd}
+ APPEND PROPERTY LINK_FLAGS /INCREMENTAL:NO)
+# if sometimes libs are needed ...
+#target_link_libraries(${PROGRAM_chronolog})
+endif(MSVC)
+install(TARGETS ${PROGRAM_stmd}
+RUNTIME DESTINATION bin
+BUNDLE DESTINATION /Applications)
+
+
diff --git a/src/getopt.c b/src/getopt.c
new file mode 100644
index 0000000..c0aa182
--- /dev/null
+++ b/src/getopt.c
@@ -0,0 +1,200 @@
+/* $Id: getopt.c 4022 2008-03-31 06:11:07Z rra $
+ *
+ * Replacement implementation of getopt.
+ *
+ * This is a replacement implementation for getopt based on the my_getopt
+ * distribution by Benjamin Sittler. Only the getopt interface is included,
+ * since remctl doesn't use GNU long options, and the code has been rearranged
+ * and reworked somewhat to fit with the remctl coding style.
+ *
+ * Copyright 1997, 2000, 2001, 2002 Benjamin Sittler
+ * Copyright 2008 Russ Allbery <rra@stanford.edu>
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include <config.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+/*
+ * If we're running the test suite, rename getopt and the global variables to
+ * avoid conflicts with the system version.
+ */
+#if TESTING
+# define getopt test_getopt
+int test_getopt(int, char **, const char *);
+# define optind test_optind
+# define opterr test_opterr
+# define optopt test_optopt
+# define optarg test_optarg
+#endif
+
+/* Initialize global interface variables. */
+int optind = 1;
+int opterr = 1;
+int optopt = 0;
+char *optarg = NULL;
+
+/*
+ * This is the plain old UNIX getopt, with GNU-style extensions. If you're
+ * porting some piece of UNIX software, this is all you need. It supports
+ * GNU-style permutation and optional arguments, but does not support the GNU
+ * -W extension.
+ *
+ * This function is not re-entrant or thread-safe, has static variables, and
+ * generally isn't a great interface, but normally you only call it once.
+ */
+int
+getopt(int argc, char *argv[], const char *optstring)
+{
+ const char *p;
+ size_t offset = 0;
+ char mode = '\0';
+ int colon_mode = 0;
+ int option = -1;
+
+ /* Holds the current position in the parameter being parsed. */
+ static int charind = 0;
+
+ /*
+ * By default, getopt permutes argv as it scans and leaves all non-options
+ * at the end. This can be changed with the first character of optstring
+ * or the environment variable POSIXLY_CORRECT. With a first character of
+ * '+' or when POSIXLY_CORRECT is set, option processing stops at the
+ * first non-option. If the first character is '-', each non-option argv
+ * element is handled as if it were the argument of an option with
+ * character code 1. mode holds this character.
+ *
+ * After the optional leading '+' and '-', optstring may contain ':'. If
+ * present, missing arguments return ':' instead of '?'. colon_mode holds
+ * this setting.
+ */
+ if (getenv("POSIXLY_CORRECT") != NULL) {
+ mode = '+';
+ colon_mode = '+';
+ } else {
+ if (optstring[offset] == '+' || optstring[offset] == '-') {
+ mode = optstring[offset];
+ offset++;
+ }
+ if (optstring[offset] == ':') {
+ colon_mode = 1;
+ offset++;
+ }
+ }
+
+ /*
+ * charind holds where we left off. If it's set, we were in the middle
+ * of an argv element; if not, we pick up with the next element of
+ * optind.
+ */
+ optarg = NULL;
+ if (charind == 0) {
+ if (optind >= argc)
+ option = -1;
+ else if (strcmp(argv[optind], "--") == 0) {
+ optind++;
+ option = -1;
+ } else if (argv[optind][0] != '-' || argv[optind][1] == '\0') {
+ char *tmp;
+ int i, j, k, end;
+
+ if (mode == '+')
+ option = -1;
+ else if (mode == '-') {
+ optarg = argv[optind];
+ optind++;
+ option = 1;
+ } else {
+ for (i = optind + 1, j = optind; i < argc; i++)
+ if ((argv[i][0] == '-') && (argv[i][1] != '\0')) {
+ optind = i;
+ option = getopt(argc, argv, optstring);
+ while (i > j) {
+ --i;
+ tmp = argv[i];
+ end = (charind == 0) ? optind - 1 : optind;
+ for (k = i; k + 1 <= end; k++) {
+ argv[k] = argv[k + 1];
+ }
+ argv[end] = tmp;
+ --optind;
+ }
+ break;
+ }
+ if (i == argc)
+ option = -1;
+ }
+ return option;
+ } else {
+ charind = 1;
+ }
+ }
+ if (charind != 0) {
+ optopt = argv[optind][charind];
+ for (p = optstring + offset; *p != '\0'; p++)
+ if (optopt == *p) {
+ p++;
+ if (*p == ':') {
+ if (argv[optind][charind + 1] != '\0') {
+ optarg = &argv[optind][charind + 1];
+ optind++;
+ charind = 0;
+ } else {
+ p++;
+ if (*p != ':') {
+ charind = 0;
+ optind++;
+ if (optind >= argc) {
+ if (opterr)
+ fprintf(stderr, "%s: option requires"
+ " an argument -- %c\n", argv[0],
+ optopt);
+ option = colon_mode ? ':' : '?';
+ goto done;
+ } else {
+ optarg = argv[optind];
+ optind++;
+ }
+ }
+ }
+ }
+ option = optopt;
+ }
+ if (option == -1) {
+ if (opterr)
+ fprintf(stderr, "%s: illegal option -- %c\n", argv[0], optopt);
+ option = '?';
+ }
+ }
+
+done:
+ if (charind != 0) {
+ charind++;
+ if (argv[optind][charind] == '\0') {
+ optind++;
+ charind = 0;
+ }
+ }
+ if (optind > argc)
+ optind = argc;
+ return option;
+}