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() - added vips_image_get_data()
- updated German translation (thanks Chris) - updated German translation (thanks Chris)
- fixed typo in im_conv() overflow estimation which could cause errors - 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 30/11/10 started 7.24.0
- bump for new stable - bump for new stable

6
TODO
View File

@ -1,12 +1,6 @@
- we seem to have code shared between object and operation: - we seem to have code shared between object and operation:
vips_object_set_arg() and vips_object_set_required_test(), common this up 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 static int
vips_arithmetic_build( VipsObject *object ) vips_arithmetic_build( VipsObject *object )
{ {
#ifdef DEBUG
VipsArithmetic *arithmetic = VIPS_ARITHMETIC( object ); VipsArithmetic *arithmetic = VIPS_ARITHMETIC( object );
#endif /*DEBUG*/
if( VIPS_OBJECT_CLASS( vips_arithmetic_parent_class )->build( object ) ) if( VIPS_OBJECT_CLASS( vips_arithmetic_parent_class )->build( object ) )
return( -1 ); return( -1 );
@ -82,10 +84,12 @@ vips_arithmetic_build( VipsObject *object )
* At the moment we _generate() in binary.c and unary.c. * At the moment we _generate() in binary.c and unary.c.
*/ */
#ifdef DEBUG
printf( "vips_arithmetic_build: booltest = %d\n", printf( "vips_arithmetic_build: booltest = %d\n",
arithmetic->booltest ); arithmetic->booltest );
printf( "vips_arithmetic_build: imtest = %p\n", printf( "vips_arithmetic_build: imtest = %p\n",
arithmetic->imtest ); arithmetic->imtest );
#endif /*DEBUG*/
return( 0 ); 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))); __attribute__((format(printf, 3, 4)));
void vips_verror_system( int err, const char *domain, void vips_verror_system( int err, const char *domain,
const char *fmt, va_list ap ); const char *fmt, va_list ap );
void vips_error_g( GError **error );
void vips_warn( const char *domain, const char *fmt, ... ) void vips_warn( const char *domain, const char *fmt, ... )
__attribute__((format(printf, 2, 3))); __attribute__((format(printf, 2, 3)));
void vips_vwarn( const char *domain, const char *fmt, va_list ap ); 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, void *vips_argument_map( VipsObject *object,
VipsArgumentMapFn fn, void *a, void *b ); 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_TYPE_OBJECT (vips_object_get_type())
#define VIPS_OBJECT( obj ) \ #define VIPS_OBJECT( obj ) \
(G_TYPE_CHECK_INSTANCE_CAST( (obj), VIPS_TYPE_OBJECT, VipsObject )) (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( const char *operation_name, ... );
int vips_call_split( const char *operation_name, va_list optional, ... ); 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 ); int vips_call_argv( VipsOperation *operation, int argc, char **argv );
#ifdef __cplusplus #ifdef __cplusplus

View File

@ -249,6 +249,27 @@ vips_error_system( int err, const char *domain, const char *fmt, ... )
va_end( ap ); 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: * vips_error_clear:
* *

View File

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

View File

@ -28,8 +28,8 @@
*/ */
/* /*
*/
#define VIPS_DEBUG #define VIPS_DEBUG
*/
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include <config.h> #include <config.h>
@ -81,12 +81,13 @@ vips_operation_print_arg( VipsObject *object, GParamSpec *pspec,
if( print->oftype ) if( print->oftype )
vips_buf_appendf( buf, " %s :: %s\n", vips_buf_appendf( buf, " %s :: %s\n",
pspec->name, g_param_spec_get_name( pspec ),
g_type_name( pspec->value_type ) ); g_type_name(
G_PARAM_SPEC_VALUE_TYPE( pspec ) ) );
else { else {
if( print->n > 0 ) if( print->n > 0 )
vips_buf_appends( buf, ", " ); vips_buf_appends( buf, ", " );
vips_buf_appends( buf, pspec->name ); vips_buf_appends( buf, g_param_spec_get_name( pspec ) );
} }
print->n += 1; print->n += 1;
@ -104,7 +105,8 @@ vips_operation_call_argument( VipsObject *object, GParamSpec *pspec,
VipsArgument *argument = (VipsArgument *) argument_class; VipsArgument *argument = (VipsArgument *) argument_class;
printf( " %s: offset = %d ", 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 ) if( argument_class->flags & VIPS_ARGUMENT_REQUIRED )
printf ("required " ); printf ("required " );
if( argument_class->flags & VIPS_ARGUMENT_CONSTRUCT ) if( argument_class->flags & VIPS_ARGUMENT_CONSTRUCT )
@ -220,7 +222,7 @@ vips_operation_set_valist (VipsOperation * operation,
* for this class. * for this class.
*/ */
if (g_object_class_find_property (G_OBJECT_CLASS (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(). /* End of stuff copy-pasted from vips_argument_map().
@ -246,13 +248,14 @@ vips_operation_set_valist (VipsOperation * operation,
char *str; char *str;
str = g_strdup_value_contents (&value); 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); g_free (str);
} }
#endif /*VIPS_DEBUG */ #endif /*VIPS_DEBUG */
g_object_set_property (G_OBJECT (operation), g_object_set_property (G_OBJECT (operation),
pspec->name, &value); g_param_spec_get_name( pspec ), &value);
g_value_unset (&value); g_value_unset (&value);
} }
} }
@ -356,21 +359,6 @@ vips_call_split( const char *operation_name, va_list optional, ... )
return( result ); 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 static int
vips_call_argv_set_required( VipsOperation *operation, const char *value ) 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. /* Search for the first unset required argument.
*/ */
if( !(pspec = vips_argument_map( VIPS_OBJECT( operation ), if( !(pspec = vips_argument_map( VIPS_OBJECT( operation ),
vips_object_set_required_test, NULL, NULL )) ) { vips_argument_is_required, NULL, NULL )) ) {
vips_error( "VipsOperation", vips_error( "VipsOperation",
_( "no unset required arguments for %s" ), value ); _( "no unset required arguments for %s" ), value );
return( -1 ); return( -1 );
} }
if( vips_object_set_argument_from_string( VIPS_OBJECT( operation ), if( vips_object_set_argument_from_string( VIPS_OBJECT( operation ),
pspec->name, value ) ) g_param_spec_get_name( pspec ), value ) )
return( -1 ); return( -1 );
return( 0 ); 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 static gboolean
vips_call_options_set( const gchar *option_name, const gchar *value, vips_call_options_set( const gchar *option_name, const gchar *value,
gpointer data, GError **error ) gpointer data, GError **error )
{ {
VipsOperation *operation = (VipsOperation *) data; VipsOperation *operation = (VipsOperation *) data;
const char *name;
VIPS_DEBUG_MSG( "vips_call_options_set: %s = %s\n", VIPS_DEBUG_MSG( "vips_call_options_set: %s = %s\n",
option_name, value ); option_name, value );
if( vips_object_set_argument_from_string( VIPS_OBJECT( operation ), /* Remove any leading "--" from the option name.
option_name, value ) ) */
return( FALSE ); 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 ); return( TRUE );
} }
@ -442,22 +494,11 @@ vips_call_options_add( VipsObject *object,
return( NULL ); return( NULL );
} }
GOptionGroup * void
vips_call_options( VipsOperation *operation ) 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 ), (void) vips_argument_map( VIPS_OBJECT( operation ),
vips_call_options_add, group, NULL ); vips_call_options_add, group, NULL );
return( group );
} }
/* Our main command-line entry point. Optional args should have been set by /* Our main command-line entry point. Optional args should have been set by

View File

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