aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar axel <axel@liljencrantz.se>2007-04-22 20:03:12 +1000
committerGravatar axel <axel@liljencrantz.se>2007-04-22 20:03:12 +1000
commit2872df66d70556b9f655c4a33ee3538674f554df (patch)
treebb34779292284827135f4148ba511a1ae2645c46
parent45412f2b1f9b1b97fce85533a9d3fe0309e5c090 (diff)
Add source code prettyfier program called fish_indent
darcs-hash:20070422100312-ac50b-a073999b7dc172259c8200f3e740c921647222a0.gz
-rw-r--r--Makefile.in18
-rw-r--r--configure.ac28
-rw-r--r--doc_src/fish_indent.txt17
-rw-r--r--fish.spec.in23
-rw-r--r--fish_indent.c328
5 files changed, 391 insertions, 23 deletions
diff --git a/Makefile.in b/Makefile.in
index d25f4ce3..5f5a6d4b 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -64,6 +64,7 @@ CFLAGS = @CFLAGS@ $(MACROS)
CPPFLAGS = @CPPFLAGS@
LDFLAGS = @LIBS@ @LDFLAGS@
LDFLAGS_FISH = ${LDFLAGS} @LIBS_FISH@ @LDFLAGS_FISH@
+LDFLAGS_FISH_INDENT = ${LDFLAGS} @LIBS_FISH_INDENT@
LDFLAGS_FISH_PAGER = ${LDFLAGS} @LIBS_FISH_PAGER@
LDFLAGS_FISHD = ${LDFLAGS} @LIBS_FISHD@
LDFLAGS_MIMEDB = ${LDFLAGS} @LIBS_MIMEDB@
@@ -95,6 +96,8 @@ FISH_OBJS := function.o builtin.o complete.o env.o exec.o expand.o \
signal.o io.o parse_util.o common.o screen.o path.o \
parser_keywords.o
+FISH_INDENT_OBJS := fish_indent.o print_help.o common.o \
+parser_keywords.o wutil.o tokenizer.o
#
# Additional files used by builtin.o
@@ -190,7 +193,7 @@ MAIN_DIR_FILES_UNSORTED := Doxyfile Doxyfile.user Doxyfile.help.in \
$(COMMON_FILES) $(COMMON_FILES:.c=.h) $(FISH_OBJS:.o=.c) \
fish.spec.in INSTALL README user_doc.head.html xsel-0.9.6.tar \
ChangeLog config.sub config.guess fish_tests.c main.c fish_pager.c \
- fishd.c seq.in make_vcs_completions.fish
+ fishd.c seq.in make_vcs_completions.fish $(FISH_INDENT_OBJS:.o=.c)
#
# The sorting is not meaningful in itself, but it has the side effect
@@ -241,7 +244,7 @@ FUNCTIONS_DIR_FILES := $(wildcard share/functions/*.fish)
# Programs to install
#
-SIMPLE_PROGRAMS := fish set_color mimedb count fish_pager fishd
+SIMPLE_PROGRAMS := fish set_color mimedb count fish_pager fishd fish_indent
PROGRAMS := $(SIMPLE_PROGRAMS) @XSEL@ @SEQ_FALLBACK@
@@ -746,6 +749,14 @@ tokenizer_test: tokenizer.c tokenizer.h wutil.o common.o
#
+# Build the fish_indent program.
+#
+
+fish_indent: $(FISH_INDENT_OBJS)
+ $(CC) $(FISH_INDENT_OBJS) $(LDFLAGS_FISH_INDENT) -o $@
+
+
+#
# Neat little program to show output from terminal
#
@@ -869,8 +880,7 @@ distclean: clean
clean:
rm -f *.o doc.h doc.tmp doc_src/*.doxygen doc_src/*.c doc_src/*.o doc_src/commands.hdr
rm -f tests/tmp.err tests/tmp.out tests/tmp.status tests/foo.txt
- rm -f tokenizer_test fish key_reader set_color mimedb
- rm -f fishd fish_pager count fish_tests
+ rm -f $(PROGRAMS) fish_tests tokenizer_test key_reader
rm -f fish-@PACKAGE_VERSION@.tar
rm -f fish-@PACKAGE_VERSION@.tar.gz
rm -f fish-@PACKAGE_VERSION@.tar.bz2
diff --git a/configure.ac b/configure.ac
index 0d044bc1..d410f2d5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -20,6 +20,7 @@ AC_SUBST( docdir )
AC_SUBST( HAVE_GETTEXT )
AC_SUBST( LDFLAGS_FISH )
AC_SUBST( LIBS_FISH )
+AC_SUBST( LIBS_FISH_INDENT )
AC_SUBST( LIBS_FISH_PAGER )
AC_SUBST( LIBS_FISHD )
AC_SUBST( LIBS_MIMEDB )
@@ -481,9 +482,20 @@ AC_SEARCH_LIBS( iconv_open, iconv, , [AC_MSG_ERROR([Could not find an iconv impl
LIBS_FISH=$LIBS
LIBS=$LIBS_COMMON
+#
+# Check for libraries needed by fish_indent.
+#
+
+LIBS_COMMON=$LIBS
+LIBS=""
+if test x$local_gettext != xno; then
+ AC_SEARCH_LIBS( gettext, intl,,)
+fi
+LIBS_FISH_INDENT=$LIBS
+LIBS=$LIBS_COMMON
#
-# Check for libraries needed by fishd.
+# Check for libraries needed by fish_pager.
#
LIBS_COMMON=$LIBS
@@ -492,12 +504,12 @@ if test x$local_gettext != xno; then
AC_SEARCH_LIBS( gettext, intl,,)
fi
AC_SEARCH_LIBS( connect, socket, , [AC_MSG_ERROR([Cannot find the socket library, needed to build this package.] )] )
-LIBS_FISHD=$LIBS
+AC_SEARCH_LIBS( setupterm, [ncurses curses], , [AC_MSG_ERROR([Could not find a curses implementation, needed to build fish])] )
+LIBS_FISH_PAGER=$LIBS
LIBS=$LIBS_COMMON
-
#
-# Check for libraries needed by mimedb.
+# Check for libraries needed by fishd.
#
LIBS_COMMON=$LIBS
@@ -505,12 +517,12 @@ LIBS=""
if test x$local_gettext != xno; then
AC_SEARCH_LIBS( gettext, intl,,)
fi
+AC_SEARCH_LIBS( connect, socket, , [AC_MSG_ERROR([Cannot find the socket library, needed to build this package.] )] )
LIBS_FISHD=$LIBS
LIBS=$LIBS_COMMON
-
#
-# Check for libraries needed by fish_pager.
+# Check for libraries needed by mimedb.
#
LIBS_COMMON=$LIBS
@@ -518,9 +530,7 @@ LIBS=""
if test x$local_gettext != xno; then
AC_SEARCH_LIBS( gettext, intl,,)
fi
-AC_SEARCH_LIBS( connect, socket, , [AC_MSG_ERROR([Cannot find the socket library, needed to build this package.] )] )
-AC_SEARCH_LIBS( setupterm, [ncurses curses], , [AC_MSG_ERROR([Could not find a curses implementation, needed to build fish])] )
-LIBS_FISH_PAGER=$LIBS
+LIBS_FISHD=$LIBS
LIBS=$LIBS_COMMON
diff --git a/doc_src/fish_indent.txt b/doc_src/fish_indent.txt
new file mode 100644
index 00000000..b05a40da
--- /dev/null
+++ b/doc_src/fish_indent.txt
@@ -0,0 +1,17 @@
+\section fish_indent fish_indent - indenter and prettyfier
+
+\subsection fish_indent-synopsis Synopsis
+ <tt>fish_indent [options]</tt>
+
+\subsection fish_indent-description Description
+
+\c fish_indent is used to indent or otherwise prettyfy a piece of fish
+code. \c fish_indent reads commands from standard input and outputs
+them to standard output.
+
+\c fish_indent underatands the following options:
+
+- <tt>-h</tt> or <tt>--help</tt> displays this help message and then exits
+- <tt>-i</tt> or <tt>--no-indent</tt> do not indent commands
+- <tt>-v</tt> or <tt>--version</tt> displays the current fish version and then exits
+
diff --git a/fish.spec.in b/fish.spec.in
index 31be307d..ee47dfcd 100644
--- a/fish.spec.in
+++ b/fish.spec.in
@@ -115,22 +115,24 @@ fi
%doc %_datadir/doc/%{name}-%{version}
# man files
+%_mandir/man1/count.1*
%_mandir/man1/fish.1*
-%_mandir/man1/xsel.1x*
+%_mandir/man1/fish_pager.1*
+%_mandir/man1/fish_indent.1*
+%_mandir/man1/fishd.1*
%_mandir/man1/mimedb.1*
%_mandir/man1/set_color.1*
-%_mandir/man1/count.1*
-%_mandir/man1/fishd.1*
-%_mandir/man1/fish_pager.1*
+%_mandir/man1/xsel.1x*
# The program binaries
+%attr(0755,root,root) %_bindir/count
%attr(0755,root,root) %_bindir/fish
-%attr(0755,root,root) %_bindir/fishd
+%attr(0755,root,root) %_bindir/fish_indent
%attr(0755,root,root) %_bindir/fish_pager
-%attr(0755,root,root) %_bindir/xsel
-%attr(0755,root,root) %_bindir/set_color
+%attr(0755,root,root) %_bindir/fishd
%attr(0755,root,root) %_bindir/mimedb
-%attr(0755,root,root) %_bindir/count
+%attr(0755,root,root) %_bindir/set_color
+%attr(0755,root,root) %_bindir/xsel
# Configuration files
%config %_sysconfdir/fish/config.fish
@@ -156,9 +158,10 @@ fi
-
-
%changelog
+* Sat Apr 21 2007 Axel Liljencrantz<axel@liljencrantz.se> 1.23.0-0
+- Add fish_indent command
+
* Thu Feb 8 2007 Axel Liljencrantz<axel@liljencrantz.se> 1.22.3-0
- Tell rpm about the help pages in %_datadir/fish/man/
diff --git a/fish_indent.c b/fish_indent.c
new file mode 100644
index 00000000..edf8cd42
--- /dev/null
+++ b/fish_indent.c
@@ -0,0 +1,328 @@
+/*
+Copyright (C) 2005-2006 Axel Liljencrantz
+
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 2 as
+published by the Free Software Foundation.
+
+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, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+*/
+
+
+/** \file main.c
+ The main loop of <tt>fish</tt>.
+*/
+
+#include "config.h"
+
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <wchar.h>
+#include <string.h>
+#include <unistd.h>
+#include <errno.h>
+#include <unistd.h>
+#include <termios.h>
+#include <fcntl.h>
+
+#ifdef HAVE_GETOPT_H
+#include <getopt.h>
+#endif
+
+#include <locale.h>
+#include <signal.h>
+
+#include "fallback.h"
+#include "util.h"
+
+#include "common.h"
+#include "wutil.h"
+#include "halloc.h"
+#include "halloc_util.h"
+#include "tokenizer.h"
+#include "print_help.h"
+#include "parser_keywords.h"
+
+/**
+ The string describing the single-character options accepted by the main fish binary
+*/
+#define GETOPT_STRING "hvi"
+
+void read_file( FILE *f, string_buffer_t *b )
+{
+ while( 1 )
+ {
+ wint_t c = fgetwc( f );
+ if( c == WEOF )
+ {
+ break;
+ }
+
+ sb_append_char( b, c );
+ }
+}
+
+static void insert_tabs( string_buffer_t *out, int indent )
+{
+ int i;
+
+ for( i=0; i<indent; i++ )
+ {
+ sb_append( out, L"\t" );
+ }
+
+}
+
+static int indent( string_buffer_t *out, wchar_t *in, int flags )
+{
+ tokenizer tok;
+ int res=0;
+ int is_command = 1;
+ int indent = 0;
+ int do_indent = 1;
+
+ tok_init( &tok, in, TOK_SHOW_COMMENTS );
+
+ for( ; tok_has_next( &tok ); tok_next( &tok ) )
+ {
+ int type = tok_last_type( &tok );
+ wchar_t *last = tok_last( &tok );
+
+ switch( type )
+ {
+ case TOK_STRING:
+ {
+ if( is_command )
+ {
+ int next_indent = indent;
+ is_command = 0;
+
+ wchar_t *unesc = unescape( last, UNESCAPE_SPECIAL );
+
+ if( parser_keywords_is_block( unesc ) )
+ {
+ next_indent++;
+ }
+ else if( wcscmp( unesc, L"else" ) == 0 )
+ {
+ indent--;
+ }
+ else if( wcscmp( unesc, L"end" ) == 0 )
+ {
+ indent--;
+ next_indent--;
+ }
+
+
+ if( do_indent && flags)
+ {
+ insert_tabs( out, indent );
+ }
+
+ sb_printf( out, L"%ls ", last );
+
+ indent = next_indent;
+
+ }
+ else
+ {
+ sb_printf( out, L"%ls ", last );
+ }
+
+ break;
+ }
+
+ case TOK_END:
+ {
+ sb_append( out, L"\n" );
+ do_indent = 1;
+ is_command = 1;
+ break;
+ }
+
+ case TOK_PIPE:
+ {
+ sb_append( out, L"| " );
+ is_command = 1;
+ break;
+ }
+
+ case TOK_REDIRECT_OUT:
+ case TOK_REDIRECT_APPEND:
+ case TOK_REDIRECT_IN:
+ case TOK_REDIRECT_FD:
+ {
+ sb_append( out, last );
+ switch( type )
+ {
+ case TOK_REDIRECT_OUT:
+ sb_append( out, L"> " );
+ break;
+
+ case TOK_REDIRECT_APPEND:
+ sb_append( out, L">> " );
+ break;
+
+ case TOK_REDIRECT_IN:
+ sb_append( out, L"< " );
+ break;
+
+ case TOK_REDIRECT_FD:
+ sb_append( out, L">& " );
+ break;
+
+ }
+ break;
+ }
+
+
+ case TOK_BACKGROUND:
+ {
+ sb_append( out, L"&\n" );
+ do_indent = 1;
+ is_command = 1;
+ break;
+ }
+
+
+ case TOK_COMMENT:
+ {
+ sb_printf( out, L"%ls", last );
+ do_indent = 1;
+ break;
+ }
+
+ default:
+ {
+ debug( 0, L"Unknown wha? %ls", last );
+ exit(1);
+ }
+ }
+
+ }
+
+ tok_destroy( &tok );
+
+ return res;
+}
+
+
+int main( int argc, char **argv )
+{
+ string_buffer_t sb_in;
+ string_buffer_t sb_out;
+
+ int do_indent=1;
+
+ wsetlocale( LC_ALL, L"" );
+ program_name=L"fish_indent";
+
+ while( 1 )
+ {
+ static struct option
+ long_options[] =
+ {
+ {
+ "no-indent", no_argument, 0, 'i'
+ }
+ ,
+ {
+ "help", no_argument, 0, 'h'
+ }
+ ,
+ {
+ "version", no_argument, 0, 'v'
+ }
+ ,
+ {
+ 0, 0, 0, 0
+ }
+ }
+ ;
+
+ int opt_index = 0;
+
+ int opt = getopt_long( argc,
+ argv,
+ GETOPT_STRING,
+ long_options,
+ &opt_index );
+
+ if( opt == -1 )
+ break;
+
+ switch( opt )
+ {
+ case 0:
+ {
+ break;
+ }
+
+ case 'h':
+ {
+ print_help( "fish_indent", 1 );
+ exit( 0 );
+ break;
+ }
+
+ case 'v':
+ {
+ fwprintf( stderr,
+ _(L"%ls, version %s\n"),
+ program_name,
+ PACKAGE_VERSION );
+ exit( 0 );
+ }
+
+ case 'i':
+ {
+ do_indent = 0;
+ break;
+ }
+
+
+ case '?':
+ {
+ exit( 1 );
+ }
+
+ }
+ }
+
+ halloc_util_init();
+
+ sb_init( &sb_in );
+ sb_init( &sb_out );
+
+ read_file( stdin, &sb_in );
+
+ wutil_init();
+
+ if( !indent( &sb_out, (wchar_t *)sb_in.buff, do_indent ) )
+ {
+
+ fwprintf( stdout, L"%ls", sb_out.buff );
+ }
+ else
+ {
+ /*
+ Indenting failed - print original input
+ */
+ fwprintf( stdout, L"%ls", sb_in.buff );
+ }
+
+
+ wutil_destroy();
+
+ halloc_util_destroy();
+
+ return 0;
+}