support optional output args in the cli
the cli interface now supports optional output args ... C API next
This commit is contained in:
parent
bbaef3dad1
commit
7fe104fee6
@ -4,6 +4,7 @@
|
|||||||
- added VIPS_ARGUMENT_APPEND to help control arg ordering
|
- added VIPS_ARGUMENT_APPEND to help control arg ordering
|
||||||
- generate has a 'stop' param to signal successful early termination
|
- generate has a 'stop' param to signal successful early termination
|
||||||
- added optional output args, eg. x/y for min
|
- added optional output args, eg. x/y for min
|
||||||
|
- CLI supports optional output args
|
||||||
|
|
||||||
10/8/11 started 7.26.3
|
10/8/11 started 7.26.3
|
||||||
- don't use G_VALUE_COLLECT_INIT(), many platforms do not have a glib this
|
- don't use G_VALUE_COLLECT_INIT(), many platforms do not have a glib this
|
||||||
|
31
TODO
31
TODO
@ -1,34 +1,3 @@
|
|||||||
- see TODO comment on vips_call_options_set()
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
- cmd line interface needs to print optional output args, if requested
|
|
||||||
|
|
||||||
eg.
|
|
||||||
|
|
||||||
$ vips min fred.v
|
|
||||||
12
|
|
||||||
$ vips min -x fred.v
|
|
||||||
12
|
|
||||||
300
|
|
||||||
|
|
||||||
the switch is there, but breaks an assert:
|
|
||||||
|
|
||||||
$ vips min -x babe.jpg
|
|
||||||
VIPS:ERROR:object.c:1178:vips_object_set_argument_from_string: assertion
|
|
||||||
failed: (argument_class->flags & VIPS_ARGUMENT_INPUT)
|
|
||||||
Aborted
|
|
||||||
|
|
||||||
options are being made incorrectly:
|
|
||||||
|
|
||||||
$ vips min --help
|
|
||||||
-y, --y=gint Vertical position of minimum
|
|
||||||
|
|
||||||
--y should not have an arg
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
- C interface needs to look for optional output args in final psss, eg.
|
- C interface needs to look for optional output args in final psss, eg.
|
||||||
|
|
||||||
vips_min( im, &min,
|
vips_min( im, &min,
|
||||||
|
@ -134,6 +134,10 @@ typedef struct _VipsArgumentClass {
|
|||||||
typedef struct _VipsArgumentInstance {
|
typedef struct _VipsArgumentInstance {
|
||||||
VipsArgument parent;
|
VipsArgument parent;
|
||||||
|
|
||||||
|
/* The class we are part of.
|
||||||
|
*/
|
||||||
|
VipsArgumentClass *argument_class;
|
||||||
|
|
||||||
/* The object we are attached to.
|
/* The object we are attached to.
|
||||||
*/
|
*/
|
||||||
VipsObject *object;
|
VipsObject *object;
|
||||||
@ -154,9 +158,9 @@ typedef struct _VipsArgumentInstance {
|
|||||||
typedef GHashTable VipsArgumentTable;
|
typedef GHashTable VipsArgumentTable;
|
||||||
|
|
||||||
VipsArgumentInstance *vips__argument_get_instance( VipsArgumentClass *,
|
VipsArgumentInstance *vips__argument_get_instance( VipsArgumentClass *,
|
||||||
VipsObject *);
|
VipsObject * );
|
||||||
VipsArgument *vips__argument_table_lookup( VipsArgumentTable *,
|
VipsArgument *vips__argument_table_lookup( VipsArgumentTable *,
|
||||||
GParamSpec *);
|
GParamSpec * );
|
||||||
void vips__object_set_member( VipsObject *object, GParamSpec *pspec,
|
void vips__object_set_member( VipsObject *object, GParamSpec *pspec,
|
||||||
GObject **member, GObject *argument );
|
GObject **member, GObject *argument );
|
||||||
typedef void *(*VipsArgumentMapFn)( VipsObject *, GParamSpec *,
|
typedef void *(*VipsArgumentMapFn)( VipsObject *, GParamSpec *,
|
||||||
|
@ -366,6 +366,7 @@ vips_argument_init( VipsObject *object )
|
|||||||
argument_instance = g_new( VipsArgumentInstance, 1 );
|
argument_instance = g_new( VipsArgumentInstance, 1 );
|
||||||
|
|
||||||
((VipsArgument *) argument_instance)->pspec = pspec;
|
((VipsArgument *) argument_instance)->pspec = pspec;
|
||||||
|
argument_instance->argument_class = argument_class;
|
||||||
argument_instance->object = object;
|
argument_instance->object = object;
|
||||||
argument_instance->assigned = FALSE;
|
argument_instance->assigned = FALSE;
|
||||||
argument_instance->close_id = 0;
|
argument_instance->close_id = 0;
|
||||||
|
@ -504,7 +504,7 @@ vips_call_split( const char *operation_name, va_list optional, ... )
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
vips_call_find_pspec_char( VipsObject *object,
|
vips_call_find_pspec( VipsObject *object,
|
||||||
GParamSpec *pspec,
|
GParamSpec *pspec,
|
||||||
VipsArgumentClass *argument_class,
|
VipsArgumentClass *argument_class,
|
||||||
VipsArgumentInstance *argument_instance,
|
VipsArgumentInstance *argument_instance,
|
||||||
@ -512,31 +512,42 @@ vips_call_find_pspec_char( VipsObject *object,
|
|||||||
{
|
{
|
||||||
const char *name = (const char *) a;
|
const char *name = (const char *) a;
|
||||||
|
|
||||||
|
/* One char names we assume are "-x" style abbreviations, longer names
|
||||||
|
* we match the whole string.
|
||||||
|
*/
|
||||||
if( !(argument_class->flags & VIPS_ARGUMENT_REQUIRED) &&
|
if( !(argument_class->flags & VIPS_ARGUMENT_REQUIRED) &&
|
||||||
(argument_class->flags & VIPS_ARGUMENT_CONSTRUCT) &&
|
(argument_class->flags & VIPS_ARGUMENT_CONSTRUCT) &&
|
||||||
!argument_instance->assigned &&
|
!argument_instance->assigned )
|
||||||
g_param_spec_get_name( pspec )[0] == name[0] )
|
if( (strlen( name ) == 1 &&
|
||||||
return( pspec );
|
g_param_spec_get_name( pspec )[0] == name[0]) ||
|
||||||
|
strcmp( g_param_spec_get_name( pspec ), name ) == 0 )
|
||||||
|
return( argument_instance );
|
||||||
|
|
||||||
return( NULL );
|
return( NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void *
|
/* Keep this stuff around for output args.
|
||||||
vips_call_find_pspec_name( VipsObject *object,
|
*/
|
||||||
GParamSpec *pspec,
|
typedef struct _VipsCallOptionOutput {
|
||||||
VipsArgumentClass *argument_class,
|
VipsArgumentInstance *argument_instance;
|
||||||
VipsArgumentInstance *argument_instance,
|
const char *value;
|
||||||
void *a, void *b )
|
} VipsCallOptionOutput;
|
||||||
|
|
||||||
|
static void
|
||||||
|
vips_call_option_output( VipsObject *object,
|
||||||
|
VipsCallOptionOutput *output )
|
||||||
{
|
{
|
||||||
const char *name = (const char *) a;
|
VipsArgumentInstance *argument_instance = output->argument_instance;
|
||||||
|
GParamSpec *pspec = ((VipsArgument *) argument_instance)->pspec;
|
||||||
|
|
||||||
if( !(argument_class->flags & VIPS_ARGUMENT_REQUIRED) &&
|
if( vips_object_get_argument_to_string( object,
|
||||||
(argument_class->flags & VIPS_ARGUMENT_CONSTRUCT) &&
|
g_param_spec_get_name( pspec ), output->value ) ) {
|
||||||
!argument_instance->assigned &&
|
/* FIXME .. Hmm what can we do here? If an arg is image
|
||||||
strcmp( g_param_spec_get_name( pspec ), name ) == 0 )
|
* output, for example, we will lose the error.
|
||||||
return( pspec );
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
return( NULL );
|
g_free( output );
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -545,6 +556,8 @@ vips_call_options_set( const gchar *option_name, const gchar *value,
|
|||||||
{
|
{
|
||||||
VipsOperation *operation = (VipsOperation *) data;
|
VipsOperation *operation = (VipsOperation *) data;
|
||||||
const char *name;
|
const char *name;
|
||||||
|
VipsArgumentInstance *argument_instance;
|
||||||
|
VipsArgumentClass *argument_class;
|
||||||
GParamSpec *pspec;
|
GParamSpec *pspec;
|
||||||
|
|
||||||
VIPS_DEBUG_MSG( "vips_call_options_set: %s = %s\n",
|
VIPS_DEBUG_MSG( "vips_call_options_set: %s = %s\n",
|
||||||
@ -555,34 +568,39 @@ vips_call_options_set( const gchar *option_name, const gchar *value,
|
|||||||
for( name = option_name; *name == '-'; name++ )
|
for( name = option_name; *name == '-'; name++ )
|
||||||
;
|
;
|
||||||
|
|
||||||
/* If this is a single-character name, find the first unset pspec with
|
if( !(argument_instance = (VipsArgumentInstance *)
|
||||||
* that initial. Otherwise, search for a spec of that name.
|
vips_argument_map(
|
||||||
*/
|
|
||||||
if( strlen( name ) == 1 )
|
|
||||||
pspec = (GParamSpec *) vips_argument_map(
|
|
||||||
VIPS_OBJECT( operation ),
|
VIPS_OBJECT( operation ),
|
||||||
vips_call_find_pspec_char,
|
vips_call_find_pspec, (void *) name, NULL )) ) {
|
||||||
(void *) name, NULL );
|
|
||||||
else
|
|
||||||
pspec = (GParamSpec *) vips_argument_map(
|
|
||||||
VIPS_OBJECT( operation ),
|
|
||||||
vips_call_find_pspec_name,
|
|
||||||
(void *) name, NULL );
|
|
||||||
if( !pspec ) {
|
|
||||||
vips_error( VIPS_OBJECT( operation )->nickname,
|
vips_error( VIPS_OBJECT( operation )->nickname,
|
||||||
_( "unknown argument '%s'" ), name );
|
_( "unknown argument '%s'" ), name );
|
||||||
return( FALSE );
|
return( FALSE );
|
||||||
}
|
}
|
||||||
|
argument_class = argument_instance->argument_class;
|
||||||
|
pspec = ((VipsArgument *) argument_instance)->pspec;
|
||||||
|
|
||||||
/*
|
if( (argument_class->flags & VIPS_ARGUMENT_INPUT) ) {
|
||||||
*
|
if( vips_object_set_argument_from_string(
|
||||||
* FIXME ... for output args, need to attach a close callback to
|
VIPS_OBJECT( operation ),
|
||||||
* operation to write the value
|
g_param_spec_get_name( pspec ), value ) )
|
||||||
*
|
return( FALSE );
|
||||||
*/
|
}
|
||||||
if( vips_object_set_argument_from_string( VIPS_OBJECT( operation ),
|
else if( (argument_class->flags & VIPS_ARGUMENT_OUTPUT) ) {
|
||||||
name, value ) )
|
VipsCallOptionOutput *output;
|
||||||
return( FALSE );
|
|
||||||
|
/* We can't do output now, we have to attach a callback to do
|
||||||
|
* the processing after the operation has run.
|
||||||
|
*
|
||||||
|
* FIXME ... something like posteval or postbuild might be
|
||||||
|
* better for this?
|
||||||
|
*/
|
||||||
|
output = g_new( VipsCallOptionOutput, 1 );
|
||||||
|
output->argument_instance = argument_instance;
|
||||||
|
output->value = value;
|
||||||
|
g_signal_connect( operation, "preclose",
|
||||||
|
G_CALLBACK( vips_call_option_output ),
|
||||||
|
output );
|
||||||
|
}
|
||||||
|
|
||||||
return( TRUE );
|
return( TRUE );
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user