Add source code prettyfier program called fish_indent

darcs-hash:20070422100312-ac50b-a073999b7dc172259c8200f3e740c921647222a0.gz
This commit is contained in:
axel 2007-04-22 20:03:12 +10:00
parent 45412f2b1f
commit 2872df66d7
5 changed files with 400 additions and 32 deletions

View file

@ -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@
@ -745,6 +748,14 @@ tokenizer_test: tokenizer.c tokenizer.h wutil.o common.o
$(CC) $(CFLAGS) tokenizer.c wutil.o common.o -D TOKENIZER_TEST $(LDFLAGS) -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

View file

@ -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,6 +482,31 @@ 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 fish_pager.
#
LIBS_COMMON=$LIBS
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=$LIBS_COMMON
#
# Check for libraries needed by fishd.
@ -495,7 +521,6 @@ AC_SEARCH_LIBS( connect, socket, , [AC_MSG_ERROR([Cannot find the socket library
LIBS_FISHD=$LIBS
LIBS=$LIBS_COMMON
#
# Check for libraries needed by mimedb.
#
@ -509,21 +534,6 @@ LIBS_FISHD=$LIBS
LIBS=$LIBS_COMMON
#
# Check for libraries needed by fish_pager.
#
LIBS_COMMON=$LIBS
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=$LIBS_COMMON
#
# Check for libraries needed by set_color
#

17
doc_src/fish_indent.txt Normal file
View file

@ -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

View file

@ -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/fish
%attr(0755,root,root) %_bindir/fishd
%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/mimedb
%attr(0755,root,root) %_bindir/count
%attr(0755,root,root) %_bindir/fish
%attr(0755,root,root) %_bindir/fish_indent
%attr(0755,root,root) %_bindir/fish_pager
%attr(0755,root,root) %_bindir/fishd
%attr(0755,root,root) %_bindir/mimedb
%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/

328
fish_indent.c Normal file
View file

@ -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;
}