new CLI done

the new cli interface is done, try "vips add a.jpg b.jpg out.jpg", or
"vips add".
This commit is contained in:
John Cupitt 2011-05-16 17:10:08 +01:00
parent 8c6697c40a
commit 6cb6d2289b
11 changed files with 237 additions and 118 deletions

View File

@ -56,6 +56,7 @@
- added vips_image_get_data()
- updated German translation (thanks Chris)
- fixed typo in im_conv() overflow estimation which could cause errors
- vips.c has new action syntax, knows about vips8 operations
30/11/10 started 7.24.0
- bump for new stable

6
TODO
View File

@ -1,12 +1,6 @@
- we seem to have code shared between object and operation:
vips_object_set_arg() and vips_object_set_required_test(), common this up
currently adding stuff to operation.c to set args from strings, with extra
logic for things like create image from filename ... useful for object.c
as well?
test booltest and imtest flags

View File

@ -71,7 +71,9 @@ G_DEFINE_ABSTRACT_TYPE( VipsArithmetic, vips_arithmetic, VIPS_TYPE_OPERATION );
static int
vips_arithmetic_build( VipsObject *object )
{
#ifdef DEBUG
VipsArithmetic *arithmetic = VIPS_ARITHMETIC( object );
#endif /*DEBUG*/
if( VIPS_OBJECT_CLASS( vips_arithmetic_parent_class )->build( object ) )
return( -1 );
@ -82,10 +84,12 @@ vips_arithmetic_build( VipsObject *object )
* At the moment we _generate() in binary.c and unary.c.
*/
#ifdef DEBUG
printf( "vips_arithmetic_build: booltest = %d\n",
arithmetic->booltest );
printf( "vips_arithmetic_build: imtest = %p\n",
arithmetic->imtest );
#endif /*DEBUG*/
return( 0 );
}

42
libvips/fred# Normal file
View File

@ -0,0 +1,42 @@
Making install in include
make[1]: Entering directory `/home/john/GIT/libvips/libvips/include'
Making install in vips
make[2]: Entering directory `/home/john/GIT/libvips/libvips/include/vips'
glib-mkenums --template enumtemplate \
../../../libvips/include/vips/memory.h ../../../libvips/include/vips/util.h ../../../libvips/include/vips/buf.h ../../../libvips/include/vips/image.h ../../../libvips/include/vips/object.h > xgen-geth && \
( cmp -s xgen-geth enumtypes.h || cp xgen-geth enumtypes.h ) && \
rm -f xgen-geth
make[3]: Entering directory `/home/john/GIT/libvips/libvips/include/vips'
make[3]: Nothing to be done for `install-exec-am'.
glib-mkenums --template enumtemplate \
../../../libvips/include/vips/memory.h ../../../libvips/include/vips/util.h ../../../libvips/include/vips/buf.h ../../../libvips/include/vips/image.h ../../../libvips/include/vips/object.h > xgen-geth && \
( cmp -s xgen-geth enumtypes.h || cp xgen-geth enumtypes.h ) && \
rm -f xgen-geth
test -z "/home/john/vips/include/vips" || /bin/mkdir -p "/home/john/vips/include/vips"
/usr/bin/install -c -m 644 almostdeprecated.h deprecated.h arithmetic.h boolean.h buf.h colour.h conversion.h convolution.h debug.h dispatch.h disp.h enumtypes.h error.h operation.h format.h inplace.h generate.h header.h histograms_lut.h freq_filt.h image.h interpolate.h intl.h mask.h memory.h morphology.h mosaicing.h other.h video.h cimg_funcs.h object.h private.h rect.h region.h relational.h resample.h semaphore.h threadpool.h thread.h transform.h '/home/john/vips/include/vips'
/usr/bin/install -c -m 644 util.h version.h vector.h vips7compat.h vips.h '/home/john/vips/include/vips'
make[3]: Leaving directory `/home/john/GIT/libvips/libvips/include/vips'
make[2]: Leaving directory `/home/john/GIT/libvips/libvips/include/vips'
make[2]: Entering directory `/home/john/GIT/libvips/libvips/include'
make[3]: Entering directory `/home/john/GIT/libvips/libvips/include'
make[3]: Nothing to be done for `install-exec-am'.
make[3]: Nothing to be done for `install-data-am'.
make[3]: Leaving directory `/home/john/GIT/libvips/libvips/include'
make[2]: Leaving directory `/home/john/GIT/libvips/libvips/include'
make[1]: Leaving directory `/home/john/GIT/libvips/libvips/include'
Making install in arithmetic
make[1]: Entering directory `/home/john/GIT/libvips/libvips/arithmetic'
/bin/bash ../../libtool --tag=CC --mode=compile gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I../.. -I../../libvips/include -DDEBUG_FATAL -DDEBUG_LEAK -pthread -fopenmp -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/pango-1.0 -I/usr/include/libxml2 -I/usr/include/libpng12 -I/usr/include/libexif -I/usr/include/glib-2.0 -I/usr/include/freetype2 -I/usr/include/OpenEXR -I/usr/include/ImageMagick -I/home/john/vips/include/orc-0.4 -g -Wall -MT arith_dispatch.lo -MD -MP -MF .deps/arith_dispatch.Tpo -c -o arith_dispatch.lo arith_dispatch.c
libtool: compile: gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I../.. -I../../libvips/include -DDEBUG_FATAL -DDEBUG_LEAK -pthread -fopenmp -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/pango-1.0 -I/usr/include/libxml2 -I/usr/include/libpng12 -I/usr/include/libexif -I/usr/include/glib-2.0 -I/usr/include/freetype2 -I/usr/include/OpenEXR -I/usr/include/ImageMagick -I/home/john/vips/include/orc-0.4 -g -Wall -MT arith_dispatch.lo -MD -MP -MF .deps/arith_dispatch.Tpo -c arith_dispatch.c -fPIC -DPIC -o .libs/arith_dispatch.o
libtool: compile: gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I../.. -I../../libvips/include -DDEBUG_FATAL -DDEBUG_LEAK -pthread -fopenmp -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/pango-1.0 -I/usr/include/libxml2 -I/usr/include/libpng12 -I/usr/include/libexif -I/usr/include/glib-2.0 -I/usr/include/freetype2 -I/usr/include/OpenEXR -I/usr/include/ImageMagick -I/home/john/vips/include/orc-0.4 -g -Wall -MT arith_dispatch.lo -MD -MP -MF .deps/arith_dispatch.Tpo -c arith_dispatch.c -o arith_dispatch.o >/dev/null 2>&1
mv -f .deps/arith_dispatch.Tpo .deps/arith_dispatch.Plo
/bin/bash ../../libtool --tag=CC --mode=compile gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I../.. -I../../libvips/include -DDEBUG_FATAL -DDEBUG_LEAK -pthread -fopenmp -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/pango-1.0 -I/usr/include/libxml2 -I/usr/include/libpng12 -I/usr/include/libexif -I/usr/include/glib-2.0 -I/usr/include/freetype2 -I/usr/include/OpenEXR -I/usr/include/ImageMagick -I/home/john/vips/include/orc-0.4 -g -Wall -MT im_abs.lo -MD -MP -MF .deps/im_abs.Tpo -c -o im_abs.lo im_abs.c
libtool: compile: gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I../.. -I../../libvips/include -DDEBUG_FATAL -DDEBUG_LEAK -pthread -fopenmp -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/pango-1.0 -I/usr/include/libxml2 -I/usr/include/libpng12 -I/usr/include/libexif -I/usr/include/glib-2.0 -I/usr/include/freetype2 -I/usr/include/OpenEXR -I/usr/include/ImageMagick -I/home/john/vips/include/orc-0.4 -g -Wall -MT im_abs.lo -MD -MP -MF .deps/im_abs.Tpo -c im_abs.c -fPIC -DPIC -o .libs/im_abs.o
libtool: compile: gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I../.. -I../../libvips/include -DDEBUG_FATAL -DDEBUG_LEAK -pthread -fopenmp -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/pango-1.0 -I/usr/include/libxml2 -I/usr/include/libpng12 -I/usr/include/libexif -I/usr/include/glib-2.0 -I/usr/include/freetype2 -I/usr/include/OpenEXR -I/usr/include/ImageMagick -I/home/john/vips/include/orc-0.4 -g -Wall -MT im_abs.lo -MD -MP -MF .deps/im_abs.Tpo -c im_abs.c -o im_abs.o >/dev/null 2>&1
mv -f .deps/im_abs.Tpo .deps/im_abs.Plo
/bin/bash ../../libtool --tag=CC --mode=compile gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I../.. -I../../libvips/include -DDEBUG_FATAL -DDEBUG_LEAK -pthread -fopenmp -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/pango-1.0 -I/usr/include/libxml2 -I/usr/include/libpng12 -I/usr/include/libexif -I/usr/include/glib-2.0 -I/usr/include/freetype2 -I/usr/include/OpenEXR -I/usr/include/ImageMagick -I/home/john/vips/include/orc-0.4 -g -Wall -MT im_avg.lo -MD -MP -MF .deps/im_avg.Tpo -c -o im_avg.lo im_avg.c
libtool: compile: gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I../.. -I../../libvips/include -DDEBUG_FATAL -DDEBUG_LEAK -pthread -fopenmp -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/pango-1.0 -I/usr/include/libxml2 -I/usr/include/libpng12 -I/usr/include/libexif -I/usr/include/glib-2.0 -I/usr/include/freetype2 -I/usr/include/OpenEXR -I/usr/include/ImageMagick -I/home/john/vips/include/orc-0.4 -g -Wall -MT im_avg.lo -MD -MP -MF .deps/im_avg.Tpo -c im_avg.c -fPIC -DPIC -o .libs/im_avg.o
libtool: compile: gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I../.. -I../../libvips/include -DDEBUG_FATAL -DDEBUG_LEAK -pthread -fopenmp -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/pango-1.0 -I/usr/include/libxml2 -I/usr/include/libpng12 -I/usr/include/libexif -I/usr/include/glib-2.0 -I/usr/include/freetype2 -I/usr/include/OpenEXR -I/usr/include/ImageMagick -I/home/john/vips/include/orc-0.4 -g -Wall -MT im_avg.lo -MD -MP -MF .deps/im_avg.Tpo -c im_avg.c -o im_avg.o >/dev/null 2>&1
mv -f .deps/im_avg.Tpo .deps/im_avg.Plo
/bin/bash ../../libtool --tag=CC --mode=compile gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I../.. -I../../libvips/include -DDEBUG_FATAL -DDEBUG_LEAK -pthread -fopenmp -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/pango-1.0 -I/usr/include/libxml2 -I/usr/include/libpng12 -I/usr/include/libexif -I/usr/include/glib-2.0 -I/usr/include/freetype2 -I/usr/include/OpenEXR -I/usr/include/ImageMagick -I/home/john/vips/include/orc-0.4 -g -Wall -MT im_bandmean.lo -MD -MP -MF .deps/im_bandmean.Tpo -c -o im_bandmean.lo im_bandmean.c
libtool: compile: gcc -std=gnu99 -DHAVE_CONFIG_H -I. -I../.. -I../../libvips/include -DDEBUG_FATAL -DDEBUG_LEAK -pthread -fopenmp -I/usr/lib/x86_64-linux-gnu/glib-2.0/include -I/usr/include/pango-1.0 -I/usr/include/libxml2 -I/usr/include/libpng12 -I/usr/include/libexif -I/usr/include/glib-2.0 -I/usr/include/freetype2 -I/usr/include/OpenEXR -I/usr/include/ImageMagick -I/home/john/vips/include/orc-0.4 -g -Wall -MT im_bandmean.lo -MD -MP -MF .deps/im_bandmean.Tpo -c im_bandmean.c -fPIC -DPIC -o .libs/im_bandmean.o

View File

@ -44,6 +44,7 @@ void vips_error_system( int err, const char *domain, const char *fmt, ... )
__attribute__((format(printf, 3, 4)));
void vips_verror_system( int err, const char *domain,
const char *fmt, va_list ap );
void vips_error_g( GError **error );
void vips_warn( const char *domain, const char *fmt, ... )
__attribute__((format(printf, 2, 3)));
void vips_vwarn( const char *domain, const char *fmt, va_list ap );

View File

@ -168,6 +168,12 @@ typedef void *(*VipsArgumentMapFn)( VipsObject *, GParamSpec *,
void *vips_argument_map( VipsObject *object,
VipsArgumentMapFn fn, void *a, void *b );
void *vips_argument_is_required( VipsObject *object,
GParamSpec *pspec,
VipsArgumentClass *argument_class,
VipsArgumentInstance *argument_instance,
void *a, void *b );
#define VIPS_TYPE_OBJECT (vips_object_get_type())
#define VIPS_OBJECT( obj ) \
(G_TYPE_CHECK_INSTANCE_CAST( (obj), VIPS_TYPE_OBJECT, VipsObject ))

View File

@ -68,7 +68,7 @@ VipsOperation *vips_operation_new( const char *name );
int vips_call( const char *operation_name, ... );
int vips_call_split( const char *operation_name, va_list optional, ... );
GOptionGroup *vips_call_options( VipsOperation *operation );
void vips_call_options( GOptionGroup *group, VipsOperation *operation );
int vips_call_argv( VipsOperation *operation, int argc, char **argv );
#ifdef __cplusplus

View File

@ -249,6 +249,27 @@ vips_error_system( int err, const char *domain, const char *fmt, ... )
va_end( ap );
}
/**
* vips_error_g:
* @error: glib error pointer
*
* This function sets the glib error pointer from the vips error buffer and
* clears it. It's handy for returning errors to glib functions from vips.
*
* See also: g_set_error().
*/
void
vips_error_g( GError **error )
{
static GQuark vips_domain = 0;
if( !vips_domain )
vips_domain = g_quark_from_string( "libvips" );
g_set_error( error, vips_domain, -1, "%s", vips_error_buffer() );
vips_error_clear();
}
/**
* vips_error_clear:
*

View File

@ -269,6 +269,23 @@ vips_argument_map( VipsObject *object,
return( NULL );
}
/* Handy for vips_argument_map: look for a required arg.
*/
void *
vips_argument_is_required( VipsObject *object,
GParamSpec *pspec,
VipsArgumentClass *argument_class,
VipsArgumentInstance *argument_instance,
void *a, void *b )
{
if( (argument_class->flags & VIPS_ARGUMENT_REQUIRED) &&
(argument_class->flags & VIPS_ARGUMENT_CONSTRUCT) &&
!argument_instance->assigned )
return( pspec );
return( NULL );
}
static void *
vips_argument_init2( VipsObject *object, GParamSpec *pspec,
VipsArgumentClass *argument_class,
@ -1008,8 +1025,10 @@ vips_object_set_argument_from_string( VipsObject *object,
VipsArgumentInstance *argument_instance;
GValue gvalue = { 0 };
#ifdef DEBUG
printf( "vips_object_set_argument_from_string: %s = %s\n",
name, value );
#endif /*DEBUG*/
pspec = g_object_class_find_property( G_OBJECT_CLASS( class ), name );
if( !pspec ) {
@ -1076,21 +1095,6 @@ vips_object_set_argument_from_string( VipsObject *object,
return( 0 );
}
static void *
vips_object_set_required_test( VipsObject *object,
GParamSpec *pspec,
VipsArgumentClass *argument_class,
VipsArgumentInstance *argument_instance,
void *a, void *b )
{
if( (argument_class->flags & VIPS_ARGUMENT_REQUIRED) &&
(argument_class->flags & VIPS_ARGUMENT_CONSTRUCT) &&
!argument_instance->assigned )
return( pspec );
return( NULL );
}
/* Set the first unassigned required arg to the string.
*/
static int
@ -1099,7 +1103,7 @@ vips_object_set_required( VipsObject *object, const char *value )
GParamSpec *pspec;
if( !(pspec = vips_argument_map( object,
vips_object_set_required_test, NULL, NULL )) ) {
vips_argument_is_required, NULL, NULL )) ) {
vips_error( "VipsObject",
_( "no unset required arguments for %s" ), value );
return( -1 );

View File

@ -28,8 +28,8 @@
*/
/*
*/
#define VIPS_DEBUG
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
@ -81,12 +81,13 @@ vips_operation_print_arg( VipsObject *object, GParamSpec *pspec,
if( print->oftype )
vips_buf_appendf( buf, " %s :: %s\n",
pspec->name,
g_type_name( pspec->value_type ) );
g_param_spec_get_name( pspec ),
g_type_name(
G_PARAM_SPEC_VALUE_TYPE( pspec ) ) );
else {
if( print->n > 0 )
vips_buf_appends( buf, ", " );
vips_buf_appends( buf, pspec->name );
vips_buf_appends( buf, g_param_spec_get_name( pspec ) );
}
print->n += 1;
@ -104,7 +105,8 @@ vips_operation_call_argument( VipsObject *object, GParamSpec *pspec,
VipsArgument *argument = (VipsArgument *) argument_class;
printf( " %s: offset = %d ",
argument->pspec->name, argument_class->offset );
g_param_spec_get_name( argument->pspec ),
argument_class->offset );
if( argument_class->flags & VIPS_ARGUMENT_REQUIRED )
printf ("required " );
if( argument_class->flags & VIPS_ARGUMENT_CONSTRUCT )
@ -220,7 +222,7 @@ vips_operation_set_valist (VipsOperation * operation,
* for this class.
*/
if (g_object_class_find_property (G_OBJECT_CLASS (class),
pspec->name) == pspec)
g_param_spec_get_name( pspec )) == pspec)
{
/* End of stuff copy-pasted from vips_argument_map().
@ -246,13 +248,14 @@ vips_operation_set_valist (VipsOperation * operation,
char *str;
str = g_strdup_value_contents (&value);
VIPS_DEBUG_MSG ("\t%s = %s\n", pspec->name, str);
VIPS_DEBUG_MSG ("\t%s = %s\n",
g_param_spec_get_name( pspec ), str);
g_free (str);
}
#endif /*VIPS_DEBUG */
g_object_set_property (G_OBJECT (operation),
pspec->name, &value);
g_param_spec_get_name( pspec ), &value);
g_value_unset (&value);
}
}
@ -356,21 +359,6 @@ vips_call_split( const char *operation_name, va_list optional, ... )
return( result );
}
static void *
vips_object_set_required_test( VipsObject *object,
GParamSpec *pspec,
VipsArgumentClass *argument_class,
VipsArgumentInstance *argument_instance,
void *a, void *b )
{
if( (argument_class->flags & VIPS_ARGUMENT_REQUIRED) &&
(argument_class->flags & VIPS_ARGUMENT_CONSTRUCT) &&
!argument_instance->assigned )
return( pspec );
return( NULL );
}
static int
vips_call_argv_set_required( VipsOperation *operation, const char *value )
{
@ -379,31 +367,95 @@ vips_call_argv_set_required( VipsOperation *operation, const char *value )
/* Search for the first unset required argument.
*/
if( !(pspec = vips_argument_map( VIPS_OBJECT( operation ),
vips_object_set_required_test, NULL, NULL )) ) {
vips_argument_is_required, NULL, NULL )) ) {
vips_error( "VipsOperation",
_( "no unset required arguments for %s" ), value );
return( -1 );
}
if( vips_object_set_argument_from_string( VIPS_OBJECT( operation ),
pspec->name, value ) )
g_param_spec_get_name( pspec ), value ) )
return( -1 );
return( 0 );
}
static void *
vips_call_char_option( VipsObject *object,
GParamSpec *pspec,
VipsArgumentClass *argument_class,
VipsArgumentInstance *argument_instance,
void *a, void *b )
{
const char *name = (const char *) a;
const char *value = (const char *) b;
if( !(argument_class->flags & VIPS_ARGUMENT_REQUIRED) &&
(argument_class->flags & VIPS_ARGUMENT_CONSTRUCT) &&
!argument_instance->assigned &&
g_param_spec_get_name( pspec )[0] == name[0] )
if( vips_object_set_argument_from_string( object,
g_param_spec_get_name( pspec ), value ) )
return( object );
return( NULL );
}
static void *
vips_call_name_option( VipsObject *object,
GParamSpec *pspec,
VipsArgumentClass *argument_class,
VipsArgumentInstance *argument_instance,
void *a, void *b )
{
const char *name = (const char *) a;
const char *value = (const char *) b;
if( !(argument_class->flags & VIPS_ARGUMENT_REQUIRED) &&
(argument_class->flags & VIPS_ARGUMENT_CONSTRUCT) &&
!argument_instance->assigned &&
strcmp( g_param_spec_get_name( pspec ), name ) == 0 )
if( vips_object_set_argument_from_string( object,
g_param_spec_get_name( pspec ), value ) )
return( object );
return( NULL );
}
static gboolean
vips_call_options_set( const gchar *option_name, const gchar *value,
gpointer data, GError **error )
{
VipsOperation *operation = (VipsOperation *) data;
const char *name;
VIPS_DEBUG_MSG( "vips_call_options_set: %s = %s\n",
option_name, value );
if( vips_object_set_argument_from_string( VIPS_OBJECT( operation ),
option_name, value ) )
return( FALSE );
/* Remove any leading "--" from the option name.
*/
for( name = option_name; *name == '-'; name++ )
;
/* If this is a single-character name, find the first unset pspec with
* that initial. Otherwise, search for a spec of that nmae.
*/
if( strlen( name ) == 1 ) {
if( vips_argument_map( VIPS_OBJECT( operation ),
vips_call_char_option,
(void *) name, (void *) value ) ) {
vips_error_g( error );
return( FALSE );
}
}
else {
if( vips_argument_map( VIPS_OBJECT( operation ),
vips_call_name_option,
(void *) name, (void *) value ) ) {
vips_error_g( error );
return( FALSE );
}
}
return( TRUE );
}
@ -442,22 +494,11 @@ vips_call_options_add( VipsObject *object,
return( NULL );
}
GOptionGroup *
vips_call_options( VipsOperation *operation )
void
vips_call_options( GOptionGroup *group, VipsOperation *operation )
{
VipsObjectClass *object_class = VIPS_OBJECT_GET_CLASS( operation );
GOptionGroup *group;
group = g_option_group_new( object_class->nickname,
object_class->description,
_( "Show operation options" ),
operation,
NULL );
(void) vips_argument_map( VIPS_OBJECT( operation ),
vips_call_options_add, group, NULL );
return( group );
}
/* Our main command-line entry point. Optional args should have been set by

View File

@ -66,8 +66,8 @@
/*
#define DEBUG_FATAL
#define DEBUG_LEAK
*/
#define DEBUG
*/
/* Need to disable these sometimes.
#undef DEBUG_FATAL
@ -99,7 +99,7 @@ static GOptionEntry main_option[] = {
N_( "load PLUGIN" ),
N_( "PLUGIN" ) },
{ "version", 'v', 0, G_OPTION_ARG_NONE, &main_option_version,
N_( "print im_version_string" ), NULL },
N_( "print version" ), NULL },
{ NULL }
};
@ -962,6 +962,20 @@ parse_options( GOptionContext *context, int *argc, char **argv )
}
}
static GOptionGroup *
add_main_group( GOptionContext *context, VipsOperation *user_data )
{
GOptionGroup *main_group;
main_group = g_option_group_new( NULL, NULL, NULL, user_data, NULL );
g_option_group_add_entries( main_group, main_option );
g_option_group_set_translation_domain( main_group, GETTEXT_PACKAGE );
g_option_context_set_main_group( context, main_group );
g_option_context_add_group( context, im_get_option_group() );
return( main_group );
}
/* VIPS universal main program.
*/
int
@ -969,9 +983,10 @@ main( int argc, char **argv )
{
char *action;
GOptionContext *context;
GOptionGroup *main_group;
VipsOperation *operation;
im_function *fn;
int i;
int i, j;
gboolean handled;
if( im_init_world( argv[0] ) )
@ -996,69 +1011,61 @@ main( int argc, char **argv )
fprintf( stderr, "*** DEBUG_LEAK: will leak test on exit\n" );
#endif /*!DEBUG_LEAK*/
/* We generate part of our g_options dynamically depending on the
* action, so we can't parse our args before getting the action. So
* therefore the action must always be the first argument.
/* Try to find our action.
*/
action = NULL;
/* Should we try to run the thing we are named as?
*/
if( !im_isprefix( "vips", g_get_prgname() ) ) {
if( !im_isprefix( "vips", g_get_prgname() ) )
action = argv[0];
argv += 1;
argc -= 1;
}
else {
action = argv[1];
/* "Just "vips" with no args.
if( !action ) {
/* Look for the first non-option argument, if any, and make
* that our action.
*/
if( !action )
return( 0 );
for( i = 1; i < argc; i++ )
if( argv[i][0] != '-' ) {
action = argv[i];
argv += 2;
argc -= 2;
/* Remove the action from argv.
*/
for( j = i; j < argc; j++ )
argv[j] = argv[j + 1];
argc -= 1;
break;
}
}
context = g_option_context_new( _( "[ACTION] [OPTIONS] [PARAMETERS] - "
"VIPS driver program" ) );
g_option_context_add_main_entries( context,
main_option, GETTEXT_PACKAGE );
g_option_context_add_group( context, im_get_option_group() );
handled = FALSE;
/* Could be one of our actions.
/* Could be one of our built-in actions.
*/
for( i = 0; i < VIPS_NUMBER( actions ); i++ )
if( strcmp( action, actions[i].name ) == 0 ) {
GOptionGroup *group;
if( action )
for( i = 0; i < VIPS_NUMBER( actions ); i++ )
if( strcmp( action, actions[i].name ) == 0 ) {
main_group = add_main_group( context, NULL );
g_option_group_add_entries( main_group,
actions[i].group );
parse_options( context, &argc, argv );
group = g_option_group_new( actions[i].name,
"vips action", "show action options",
NULL, NULL );
g_option_group_add_entries( group,
actions[i].group );
g_option_context_add_group( context, group );
parse_options( context, &argc, argv );
if( actions[i].action( argc - 1, argv + 1 ) )
error_exit( "%s", action );
if( actions[i].action( argc, argv ) )
error_exit( "%s", action );
handled = TRUE;
break;
}
handled = TRUE;
break;
}
/* Could be a vips7 im_function.
*/
if( !handled && (fn = im_find_function( action )) ) {
if( action && !handled && (fn = im_find_function( action )) ) {
parse_options( context, &argc, argv );
if( im_run_command( action, argc, argv ) ) {
if( argc == 0 )
if( im_run_command( action, argc - 1, argv + 1 ) ) {
if( argc == 1 )
usage( fn );
else
error_exit( NULL );
@ -1070,20 +1077,17 @@ main( int argc, char **argv )
/* Could be a vips8 VipsOperation.
*/
if( !handled && (operation = vips_operation_new( action )) ) {
GOptionGroup *group;
if( !(group = vips_call_options( operation )) )
error_exit( NULL );
g_option_context_add_group( context, group );
if( action && !handled && (operation = vips_operation_new( action )) ) {
main_group = add_main_group( context, operation );
vips_call_options( main_group, operation );
parse_options( context, &argc, argv );
if( vips_call_argv( operation, argc, argv ) ) {
if( argc == 0 ) {
if( vips_call_argv( operation, argc - 1, argv + 1 ) ) {
if( argc == 1 ) {
char *help;
help = g_option_context_get_help( context,
FALSE, group );
FALSE, NULL );
printf( "%s", help );
vips_object_print( VIPS_OBJECT( operation ) );
error_exit( NULL );
@ -1099,6 +1103,7 @@ main( int argc, char **argv )
im_error_clear();
if( !handled ) {
(void) add_main_group( context, NULL );
parse_options( context, &argc, argv );
if( argc > 1 )