diff --git a/man/vips.1 b/man/vips.1 index 403b268a..495a47ab 100644 --- a/man/vips.1 +++ b/man/vips.1 @@ -9,15 +9,25 @@ is the VIPS universal main program. You can use it to run any VIPS operation from the command line, to query the VIPS class hierarchy, and to maintain parts of the VIPS library. -To run a VIPS function, the first argument should be the name of the function -and following arguments should be the function parameters. For example: +To run a VIPS operation, the first argument should be the name of the +operation +and following arguments should be the operation arguments. For example: $ vips invert lena.v lena2.v .SH OPTIONS +.TP +.B -l BASE-NAME, --list=BASE-NAME +List operations below BASE-NAME. This prints a one-line summary of every +operation in vips below the class BASE-NAME, where BASE-NAME may be a full +vips class name, or a nickname. + +If BASE-NAME is not supplied, this will list all classes below VipsOperation. + .TP .B -p PLUGIN, --plugin=PLUGIN -Load PLUGIN. Note that plugins in $VIPSHOME/lib are loaded automatically. +Load PLUGIN. Note that plugins in $VIPSHOME/lib/vips-plugins-MAJOR.MINOR are +loaded automatically. .TP .B -v, --version @@ -25,24 +35,9 @@ Show VIPS version. .SH COMMANDS -.TP -.B list PACKAGE -List operations defined in PACKAGE. PACKAGE can also be "classes", "packages" -or "all". - -.TP -.B cpph PACKAGE -Print C++ header for PACKAGE. PACKAGE can also be a function name, or "all". - -.TP -.B cppc PACKAGE -Print C++ binding for PACKAGE. PACKAGE can also be a function name, or "all". - .TP .B operation-name operation-arguments -Execute a named operation, for example im_invert, or add. Names prefixed with -"im_" are called via the vips7 interface, names without the prefix use the new -vips8 interface. +Execute a named operation, for example add. .SH EXAMPLES @@ -50,7 +45,7 @@ Run a vips8 operation. Operation options must follow the operation name. $ vips insert lena.v lena2.v out.v 0 0 --background "128 0 0" -Get a "usage" message for an operation +Get a "usage" message for an operation. $ vips insert insert image @sub into @main at @x, @y @@ -61,12 +56,29 @@ Get a "usage" message for an operation sub - Sub-image to insert into main image, input VipsImage out - Output image, output VipsImage x - Left edge of sub in main, input gint + default: 0 + min: -100000000, max: 100000000 y - Top edge of sub in main, input gint + default: 0 + min: -100000000, max: 100000000 optional arguments: expand - Expand output to hold all of both inputs, input gboolean + default: false background - Colour for new pixels, input VipsArrayDouble - operation flags: sequential-unbuffered - insert: too few arguments + operation flags: sequential + +List all draw operations. + + $ vips -l draw + VipsDraw (draw), draw operations + VipsDrawink (drawink), draw with ink operations + VipsDrawRect (draw_rect), paint a rectangle on an image + VipsDrawMask (draw_mask), draw a mask on an image + VipsDrawLine (draw_line), draw a line on an image + VipsDrawCircle (draw_circle), draw a circle on an image + VipsDrawFlood (draw_flood), flood-fill an area + VipsDrawImage (draw_image), paint an image into another image + VipsDrawSmudge (draw_smudge), blur a rectangle on an image .SH RETURN VALUE returns 0 on success and non-zero on error. diff --git a/tools/vips.c b/tools/vips.c index 412d65a1..c57c652c 100644 --- a/tools/vips.c +++ b/tools/vips.c @@ -97,9 +97,78 @@ #endif static char *main_option_plugin = NULL; -static gboolean *main_option_version; +static gboolean main_option_version; + +static void * +list_class( GType type ) +{ + VipsObjectClass *class = VIPS_OBJECT_CLASS( g_type_class_ref( type ) ); + int depth = vips_type_depth( type ); + + int i; + + if( class->deprecated ) + return( NULL ); + if( VIPS_IS_OPERATION_CLASS( class ) && + (VIPS_OPERATION_CLASS( class )->flags & + VIPS_OPERATION_DEPRECATED) ) + return( NULL ); + + for( i = 0; i < depth * 2; i++ ) + printf( " " ); + vips_object_print_summary_class( + VIPS_OBJECT_CLASS( g_type_class_ref( type ) ) ); + + return( NULL ); +} + +static void * +test_nickname( GType type, void *data ) +{ + const char *nickname = (const char *) data; + + VipsObjectClass *class; + + if( (class = VIPS_OBJECT_CLASS( g_type_class_ref( type ) )) && + strcmp( class->nickname, nickname ) == 0 ) + return( class ); + + return( NULL ); +} + +static gboolean +parse_main_option_list( const gchar *option_name, const gchar *value, + gpointer data, GError **error ) +{ + VipsObjectClass *class; + + if( value && + (class = (VipsObjectClass *) vips_type_map_all( + g_type_from_name( "VipsObject" ), + test_nickname, (void *) value )) ) { + vips_type_map_all( G_TYPE_FROM_CLASS( class ), + (VipsTypeMapFn) list_class, NULL ); + } + else if( value ) { + vips_error( g_get_prgname(), + _( "'%s' is not the name of a vips class" ), value ); + vips_error_g( error ); + + return( FALSE ); + } + else { + vips_type_map_all( g_type_from_name( "VipsOperation" ), + (VipsTypeMapFn) list_class, NULL ); + } + + exit( 0 ); +} static GOptionEntry main_option[] = { + { "list", 'l', G_OPTION_FLAG_OPTIONAL_ARG, G_OPTION_ARG_CALLBACK, + (GOptionArgFunc) parse_main_option_list, + N_( "list objects" ), + N_( "BASE-NAME" ) }, { "plugin", 'p', 0, G_OPTION_ARG_FILENAME, &main_option_plugin, N_( "load PLUGIN" ), N_( "PLUGIN" ) }, @@ -170,29 +239,6 @@ list_function( im_function *func ) return( NULL ); } -static void * -list_class( GType type ) -{ - VipsObjectClass *class = VIPS_OBJECT_CLASS( g_type_class_ref( type ) ); - int depth = vips_type_depth( type ); - - int i; - - if( class->deprecated ) - return( NULL ); - if( VIPS_IS_OPERATION_CLASS( class ) && - (VIPS_OPERATION_CLASS( class )->flags & - VIPS_OPERATION_DEPRECATED) ) - return( NULL ); - - for( i = 0; i < depth * 2; i++ ) - printf( " " ); - vips_object_print_summary_class( - VIPS_OBJECT_CLASS( g_type_class_ref( type ) ) ); - - return( NULL ); -} - static int print_list( int argc, char **argv ) { @@ -928,17 +974,9 @@ print_cppdefs( int argc, char **argv ) return( 0 ); } -static void action_list( VipsBuf *buf ); - static int print_help( int argc, char **argv ) { - char txt[1024]; - VipsBuf buf = VIPS_BUF_STATIC( txt ); - - action_list( &buf ); - printf( "%s", vips_buf_all( &buf ) ); - return( 0 ); } @@ -971,19 +1009,6 @@ static ActionEntry actions[] = { &empty_options[0], print_help }, }; -static void -action_list( VipsBuf *buf ) -{ - int i; - - vips_buf_appends( buf, _( "possible actions:\n" ) ); - vips_buf_appendf( buf, "%7s - %s\n", - "OPER", _( "execute vips operation OPER" ) ); - for( i = 0; i < VIPS_NUMBER( actions ); i++ ) - vips_buf_appendf( buf, "%7s - %s\n", - actions[i].name, _( actions[i].description ) ); -} - static void parse_options( GOptionContext *context, int *argc, char **argv ) { @@ -998,7 +1023,8 @@ parse_options( GOptionContext *context, int *argc, char **argv ) printf( "%d) %s\n", i, argv[i] ); #endif /*DEBUG*/ - action_list( &buf ); + vips_buf_appendf( &buf, "%7s - %s\n", + "OPER", _( "execute vips operation OPER" ) ); g_option_context_set_summary( context, vips_buf_all( &buf ) ); if( !g_option_context_parse( context, argc, &argv, &error ) ) { @@ -1088,6 +1114,18 @@ main( int argc, char **argv ) */ g_option_context_set_ignore_unknown_options( context, TRUE ); + /* "vips" with no arguments does "vips --help". + */ + if( argc == 1 ) { + char *help; + + help = g_option_context_get_help( context, TRUE, NULL ); + printf( "%s", help ); + g_free( help ); + + exit( 0 ); + } + /* Also disable help output: we want to be able to display full help * in a second pass after all options have been created. */ @@ -1230,7 +1268,6 @@ main( int argc, char **argv ) if( action && !handled ) { - print_help( argc, argv ); vips_error_exit( _( "unknown action \"%s\"" ), action ); }