From e8b313f75d564832dd0cef3eef6056717e07c0fd Mon Sep 17 00:00:00 2001 From: Nick Bowler Date: Wed, 22 Jun 2011 20:30:41 -0400 Subject: [PATCH] Implement the interactive cdecl99 loop. Bring in gnulib for getopt_long and readline support. --- .gitignore | 4 +++ .gitmodules | 3 ++ Makefile.am | 7 +++-- bootstrap | 13 +++++++++ configure.ac | 11 +++++-- gnulib | 1 + m4/.gitignore | 25 ++++++++++++++++ m4/gnulib-cache.m4 | 38 +++++++++++++++++++++++++ src/cdecl99.c | 71 ++++++++++++++++++++++++++++++++++++++++------ 9 files changed, 159 insertions(+), 14 deletions(-) create mode 100644 .gitmodules create mode 100755 bootstrap create mode 160000 gnulib create mode 100644 m4/gnulib-cache.m4 diff --git a/.gitignore b/.gitignore index 191edd0..bc85844 100644 --- a/.gitignore +++ b/.gitignore @@ -17,4 +17,8 @@ Makefile.in /missing /stamp-h1 /install-sh +/arg-nonnull.h +/warn-on-use.h +/c++defs.h +/lib /cdecl99 diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..009ae43 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "gnulib"] + path = gnulib + url = git://git.savannah.gnu.org/gnulib.git diff --git a/Makefile.am b/Makefile.am index 8f82af4..7bc77dc 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,9 +1,12 @@ ACLOCAL_AMFLAGS = -I m4 +SUBDIRS = lib . +CPPFLAGS = -I$(top_builddir)/lib -I$(top_srcdir)/lib + MAINTAINERCLEANFILES = src/scan.c src/scan.h src/scan.stamp \ src/parse.c src/parse.h src/parse.stamp -EXTRA_DIST = src/parse.stamp src/scan.stamp +EXTRA_DIST = m4/gnulib-cache.m4 src/parse.stamp src/scan.stamp include_HEADERS = src/cdecl.h noinst_HEADERS = src/scan.h src/parse.h @@ -14,7 +17,7 @@ libcdecl_la_SOURCES = src/scan.c src/parse.c src/parse-decl.c src/typemap.c bin_PROGRAMS = cdecl99 cdecl99_SOURCES = src/cdecl99.c -cdecl99_LDADD = libcdecl.la +cdecl99_LDADD = libcdecl.la lib/libgnu.la src/parse.lo: src/scan.h src/scan.lo: src/parse.h diff --git a/bootstrap b/bootstrap new file mode 100755 index 0000000..fa13580 --- /dev/null +++ b/bootstrap @@ -0,0 +1,13 @@ +#!/bin/sh + +trap 'exit 1' USR1 +die() { printf '%s\n' "$@" 1>&2; kill -USR1 $$; } + +git submodule update --init || echo "Failed to update Gnulib sources from git." +if test -x gnulib/gnulib-tool; then + gnulib/gnulib-tool --update || die "Failed to update Gnulib." +else + die "Gnulib sources are not properly installed in gnulib/." +fi + +autoreconf -fis diff --git a/configure.ac b/configure.ac index 5596f74..3718430 100644 --- a/configure.ac +++ b/configure.ac @@ -7,6 +7,10 @@ AM_INIT_AUTOMAKE([-Wall -Werror foreign subdir-objects]) AM_SILENT_RULES([yes]) AC_PROG_CC_C99 +gl_EARLY + +LT_INIT +gl_INIT AC_ARG_VAR([FLEX], [Command to invoke flex. Defaults to flex.]) AC_ARG_VAR([FLEXFLAGS], [Additional options to pass to flex.]) @@ -16,7 +20,8 @@ AC_ARG_VAR([BISON], [Command to invoke GNU Bison. Defaults to bison.]) AC_ARG_VAR([BISONFLAGS], [Additional options to pass to Bison.]) AC_CHECK_PROGS([BISON], [bison], [bison]) -LT_INIT - -AC_CONFIG_FILES([Makefile]) +AC_CONFIG_FILES([ + lib/Makefile + Makefile +]) AC_OUTPUT diff --git a/gnulib b/gnulib new file mode 160000 index 0000000..90d0c49 --- /dev/null +++ b/gnulib @@ -0,0 +1 @@ +Subproject commit 90d0c4909f2b77d711ea6332a99a9332ff1bab36 diff --git a/m4/.gitignore b/m4/.gitignore index 38066dd..377fc87 100644 --- a/m4/.gitignore +++ b/m4/.gitignore @@ -1,5 +1,30 @@ +00gnulib.m4 +errno_h.m4 +extensions.m4 +getdelim.m4 +getline.m4 +getopt.m4 +gnulib-common.m4 +gnulib-comp.m4 +gnulib-tool.m4 +include_next.m4 +lib-ld.m4 +lib-link.m4 +lib-prefix.m4 libtool.m4 +longlong.m4 ltoptions.m4 ltsugar.m4 ltversion.m4 lt~obsolete.m4 +malloc.m4 +multiarch.m4 +readline.m4 +realloc.m4 +stddef_h.m4 +stdint.m4 +stdio_h.m4 +stdlib_h.m4 +unistd_h.m4 +warn-on-use.m4 +wchar_t.m4 diff --git a/m4/gnulib-cache.m4 b/m4/gnulib-cache.m4 new file mode 100644 index 0000000..fdf347b --- /dev/null +++ b/m4/gnulib-cache.m4 @@ -0,0 +1,38 @@ +# Copyright (C) 2002-2011 Free Software Foundation, Inc. +# +# This file is free software, distributed under the terms of the GNU +# General Public License. As a special exception to the GNU General +# Public License, this file may be distributed as part of a program +# that contains a configuration script generated by Autoconf, under +# the same distribution terms as the rest of that program. +# +# Generated by gnulib-tool. +# +# This file represents the specification of how gnulib-tool is used. +# It acts as a cache: It is written and read by gnulib-tool. +# In projects that use version control, this file is meant to be put under +# version control, like the configure.ac and various Makefile.am files. + + +# Specification in the form of a command-line invocation: +# gnulib-tool --import --dir=. --lib=libgnu --source-base=lib --m4-base=m4 --doc-base=doc --tests-base=tests --aux-dir=. --no-conditional-dependencies --libtool --macro-prefix=gl --no-vc-files getopt-gnu readline + +# Specification in the form of a few gnulib-tool.m4 macro invocations: +gl_LOCAL_DIR([]) +gl_MODULES([ + getopt-gnu + readline +]) +gl_AVOID([]) +gl_SOURCE_BASE([lib]) +gl_M4_BASE([m4]) +gl_PO_BASE([]) +gl_DOC_BASE([doc]) +gl_TESTS_BASE([tests]) +gl_LIB([libgnu]) +gl_MAKEFILE_NAME([]) +gl_LIBTOOL +gl_MACRO_PREFIX([gl]) +gl_PO_DOMAIN([]) +gl_WITNESS_C_DOMAIN([]) +gl_VC_FILES([false]) diff --git a/src/cdecl99.c b/src/cdecl99.c index 6eb07cc..76e64bc 100644 --- a/src/cdecl99.c +++ b/src/cdecl99.c @@ -1,21 +1,74 @@ +#include #include #include +#include +#include "readline.h" #include "cdecl.h" -int main(int argc, char **argv) +static const char *progname = "cdecl99"; +static const char sopts[] = "VH"; +static const struct option lopts[] = { + { "version", 0, NULL, 'V' }, + { "help", 0, NULL, 'H' }, + { 0 } +}; + +static void print_version(void) +{ + puts(PACKAGE_STRING); + puts("Copyright (C) 2011 Nick Bowler."); + puts("License GPLv3+: GNU GPL version 3 or later ."); + puts("This is free software: you are free to change and redistribute it."); + puts("There is NO WARRANTY, to the extent permitted by law."); +} + +static void print_usage(FILE *f) +{ + fprintf(f, "Usage: %s [options]\n", progname); +} + +static void print_help(void) +{ + print_usage(stdout); + puts("Detailed help coming soon."); +} + +static int repl(void) { struct cdecl *decl; + print_version(); - if (argc < 2) { - fprintf(stderr, "usage: cdecl99 decl\n"); - return EXIT_FAILURE; + for (char *line; (line = readline("> ")); free(line)) { + decl = cdecl_parse_decl(line); + cdecl_free(decl); } - decl = cdecl_parse_decl(argv[1]); - if (!decl) { - return EXIT_FAILURE; + return 0; +} + +int main(int argc, char **argv) +{ + int opt; + + if (argc > 0) + progname = argv[0]; + + while ((opt = getopt_long(argc, argv, sopts, lopts, NULL)) != -1) { + switch (opt) { + case 'V': + print_version(); + return EXIT_SUCCESS; + case 'H': + print_help(); + return EXIT_SUCCESS; + default: + print_usage(stderr); + return EXIT_FAILURE; + } } - cdecl_free(decl); - return 0; + if (repl() != 0) + return EXIT_FAILURE; + + return EXIT_SUCCESS; } -- 2.43.2