/**
   set_color builtin
*/
static int builtin_set_color(parser_t &parser, wchar_t **argv)
{
    /** Variables used for parsing the argument list */
    const struct woption long_options[] =
    {
        { L"background", required_argument, 0, 'b'},
        { L"help", no_argument, 0, 'h' },
        { L"bold", no_argument, 0, 'o' },
        { L"underline", no_argument, 0, 'u' },
        { L"version", no_argument, 0, 'v' },
        { L"print-colors", no_argument, 0, 'c' },
        { 0, 0, 0, 0 }
    };

    const wchar_t *short_options = L"b:hvocu";

    int argc = builtin_count_args(argv);

    const wchar_t *bgcolor = NULL;
    bool bold = false, underline=false;
    int errret;

    /* Parse options to obtain the requested operation and the modifiers */
    woptind = 0;
    while (1)
    {
        int c = wgetopt_long(argc, argv, short_options, long_options, 0);

        if (c == -1)
        {
            break;
        }

        switch (c)
        {
            case 0:
                break;

            case 'b':
                bgcolor = woptarg;
                break;

            case 'h':
                builtin_print_help(parser, argv[0], stdout_buffer);
                return STATUS_BUILTIN_OK;

            case 'o':
                bold = true;
                break;

            case 'u':
                underline = true;
                break;

            case 'c':
                print_colors();
                return STATUS_BUILTIN_OK;

            case '?':
                return STATUS_BUILTIN_ERROR;
        }
    }

    /* Remaining argument is foreground color */
    const wchar_t *fgcolor = NULL;
    if (woptind < argc)
    {
        if (woptind + 1 == argc)
        {
            fgcolor = argv[woptind];
        }
        else
        {
            append_format(stderr_buffer,
                          _(L"%ls: Too many arguments\n"),
                          argv[0]);
            return STATUS_BUILTIN_ERROR;
        }
    }

    if (fgcolor == NULL && bgcolor == NULL && !bold && !underline)
    {
        append_format(stderr_buffer,
                      _(L"%ls: Expected an argument\n"),
                      argv[0]);
        return STATUS_BUILTIN_ERROR;
    }

    const rgb_color_t fg = rgb_color_t(fgcolor ? fgcolor : L"");
    if (fgcolor && (fg.is_none() || fg.is_ignore()))
    {
        append_format(stderr_buffer, _(L"%ls: Unknown color '%ls'\n"), argv[0], fgcolor);
        return STATUS_BUILTIN_ERROR;
    }

    const rgb_color_t bg = rgb_color_t(bgcolor ? bgcolor : L"");
    if (bgcolor && (bg.is_none() || bg.is_ignore()))
    {
        append_format(stderr_buffer, _(L"%ls: Unknown color '%ls'\n"), argv[0], bgcolor);
        return STATUS_BUILTIN_ERROR;
    }

    /* Make sure that the term exists */
    if (cur_term == NULL && setupterm(0, STDOUT_FILENO, &errret) == ERR)
    {
        append_format(stderr_buffer, _(L"%ls: Could not set up terminal\n"), argv[0]);
        return STATUS_BUILTIN_ERROR;
    }

    /*
       Test if we have at least basic support for setting fonts, colors
       and related bits - otherwise just give up...
    */
    if (! exit_attribute_mode)
    {
        return STATUS_BUILTIN_ERROR;
    }


    /* Save old output function so we can restore it */
    int (* const saved_writer_func)(char) = output_get_writer();

    /* Set our output function, which writes to a std::string */
    builtin_set_color_output.clear();
    output_set_writer(set_color_builtin_outputter);

    if (bold)
    {
        if (enter_bold_mode)
            writembs(tparm(enter_bold_mode));
    }

    if (underline)
    {
        if (enter_underline_mode)
            writembs(enter_underline_mode);
    }

    if (bgcolor != NULL)
    {
        if (bg.is_normal())
        {
            write_background_color(0);
            writembs(tparm(exit_attribute_mode));
        }
    }

    if (fgcolor != NULL)
    {
        if (fg.is_normal() || fg.is_reset())
        {
            write_foreground_color(0);
            writembs(tparm(exit_attribute_mode));
        }
        else
        {
            write_foreground_color(index_for_color(fg));
        }
    }

    if (bgcolor != NULL)
    {
        if (! bg.is_normal() && ! bg.is_reset())
        {
            write_background_color(index_for_color(bg));
        }
    }

    /* Restore saved writer function */
    output_set_writer(saved_writer_func);

    /* Output the collected string */
    std::string local_output;
    std::swap(builtin_set_color_output, local_output);
    stdout_buffer.append(str2wcstring(local_output));

    return STATUS_BUILTIN_OK;
}
Example #2
0
int main( int argc, char **argv )
{
	char *bgcolor=0;
	char *fgcolor=0;
	bool bold=false;
	bool underline=false;

	while( 1 )
	{
		static struct option
			long_options[] =
			{
				{
					"background", required_argument, 0, 'b' 
				}
				,
				{
					"help", no_argument, 0, 'h' 
				}
				,
				{
					"bold", no_argument, 0, 'o' 
				}
				,
				{
					"underline", no_argument, 0, 'u' 
				}
				,
				{
					"version", no_argument, 0, 'v' 
				}
				,
				{
					"print-colors", no_argument, 0, 'c' 
				}
				,
				{ 
					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 'b':				
				bgcolor = optarg;
				break;
			case 'h':
				print_help( argv[0], 1 );
				exit(0);				
								
			case 'o':
				bold=true;
				break;
				
			case 'u':
				underline=true;
				break;
				
			case 'v':
				check_locale_init();
				fprintf( stderr, _("%s, version %s\n"), SET_COLOR, PACKAGE_VERSION );
				exit( 0 );								

			case 'c':
				print_colors();
				exit(0);
				
			case '?':
				return 1;
				
		}
		
	}		
	
	switch( argc-optind)
	{
		case 0:
//			printf( "no fg\n" );
			break;
			
		case 1:
			fgcolor=argv[optind];
//			printf( "fg %s\n", fgcolor );
			break;
			
		default:
			check_locale_init();
			printf( _("%s: Too many arguments\n"), SET_COLOR );
			return 1;
	}
    
    /* Infer term256 support */
    char *fish_term256 = getenv("fish_term256");
    if (fish_term256) {
        support_term256 = from_string<bool>(fish_term256);
    } else {
        const char *term = getenv("TERM");
        support_term256 = term && strstr(term, "256color");
    }

	if( !fgcolor && !bgcolor && !bold && !underline )
	{
		check_locale_init();
		fprintf( stderr, _("%s: Expected an argument\n"), SET_COLOR );
		print_help( argv[0], 2 );		
		return 1;
	}
    
    rgb_color_t fg = rgb_color_t(fgcolor ? fgcolor : "");
	if( fgcolor && fg.is_none())
	{
		check_locale_init();
		fprintf( stderr, _("%s: Unknown color '%s'\n"), SET_COLOR, fgcolor );
		return 1;		
	}

    rgb_color_t bg = rgb_color_t(bgcolor ? bgcolor : "");
	if( bgcolor && bg.is_none())
	{
		check_locale_init();
		fprintf( stderr, _("%s: Unknown color '%s'\n"), SET_COLOR, bgcolor );
		return 1;		
	}

	setupterm( 0, STDOUT_FILENO, 0);

	if( bold )
	{
		if( enter_bold_mode )
			putp( enter_bold_mode );
	}

	if( underline )
	{
		if( enter_underline_mode )
			putp( enter_underline_mode );
	}

	if( bgcolor )
	{
		if( bg.is_normal() )
		{
            write_background_color(0);
			putp( tparm(exit_attribute_mode) );		
		}	
	}

	if( fgcolor )
	{
		if( fg.is_normal() )
		{
            write_foreground_color(0);
			putp( tparm(exit_attribute_mode) );		
		}	
		else
		{
            write_foreground_color(index_for_color(fg));
		}
	}
	
	if( bgcolor )
	{
		if( ! bg.is_normal() )
		{
            write_background_color(index_for_color(bg));
		}
	}

	if( del_curterm( cur_term ) == ERR )
	{
		fprintf( stderr, "%s", _("Error while closing terminfo") );
	}

}