/* Copyright (C) 2005-2008 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 fish_indent.c The fish_indent proegram. */ #include "config.h" #include #include #include #include #include #include #ifdef HAVE_GETOPT_H #include #endif #include #include "fallback.h" #include "util.h" #include "common.h" #include "wutil.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" /** Read the entire contents of a file into the specified string_Buffer_t */ static void read_file( FILE *f, string_buffer_t *b ) { while( 1 ) { errno=0; wint_t c = fgetwc( f ); if( c == WEOF ) { if( errno ) { wperror(L"fgetwc"); exit(1); } break; } sb_append_char( b, c ); } } /** Insert the specified number of tabe into the output buffer */ static void insert_tabs( string_buffer_t *out, int indent ) { int i; for( i=0; i" ); } sb_append( out, L" | " ); is_command = 1; break; } case TOK_REDIRECT_OUT: { sb_append( out, L" " ); if ( wcscmp( last, L"2" ) == 0 ) { sb_append( out, L"^" ); } else { if ( wcscmp( last, L"1" ) != 0 ) sb_append( out, last ); sb_append( out, L"> " ); } break; } case TOK_REDIRECT_APPEND: { sb_append( out, L" " ); if ( wcscmp( last, L"2" ) == 0 ) { sb_append( out, L"^^" ); } else { if ( wcscmp( last, L"1" ) != 0 ) sb_append( out, last ); sb_append( out, L">> " ); } break; } case TOK_REDIRECT_IN: { sb_append( out, L" " ); if ( wcscmp( last, L"0" ) != 0 ) sb_append( out, last ); sb_append( out, L"< " ); break; } case TOK_REDIRECT_FD: { sb_append( out, L" " ); if ( wcscmp( last, L"1" ) != 0 ) sb_append( out, last ); sb_append( out, L">& " ); break; } case TOK_BACKGROUND: { sb_append( out, L"&\n" ); do_indent = 1; is_command = 1; break; } case TOK_COMMENT: { if( do_indent && flags) { insert_tabs( out, indent ); } sb_printf( out, L"%ls", last ); do_indent = 1; break; } default: { debug( 0, L"Unknown token '%ls'", last ); exit(1); } } prev_prev_type = prev_type; prev_type = type; } tok_destroy( &tok ); return res; } /** Remove any prefix and suffix newlines from the specified string. Does not allocete a new string, edits the string in place and returns a pointer somewhere into the string. */ static wchar_t *trim( wchar_t *in ) { wchar_t *end; while( *in == L'\n' ) { in++; } end = in + wcslen(in); while( 1 ) { if( end < in+2 ) break; end--; if( (*end == L'\n' ) && ( *(end-1) == L'\n' ) ) *end=0; else break; } return in; } /** The main mathod. Run the program. */ int main( int argc, char **argv ) { string_buffer_t sb_in; string_buffer_t sb_out; int do_indent=1; set_main_thread(); 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 ); } } } 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", trim( (wchar_t *)sb_out.buff) ); } else { /* Indenting failed - print original input */ fwprintf( stdout, L"%ls", (wchar_t *)sb_in.buff ); } wutil_destroy(); return 0; }