better usage message
more sensible output for "vips max" or "vips getpoint"
This commit is contained in:
parent
b80b503474
commit
3bceb5286b
51
TODO
51
TODO
@ -24,57 +24,6 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
- try
|
|
||||||
|
|
||||||
$ vips getpoint
|
|
||||||
usage:
|
|
||||||
getpoint in out-array x y
|
|
||||||
read a point from an image
|
|
||||||
where:
|
|
||||||
in - Input image, input VipsImage
|
|
||||||
out-array - Array of output values, output VipsArrayDouble
|
|
||||||
x - Getpoint to read from, input gint
|
|
||||||
y - Getpoint to read from, input gint
|
|
||||||
|
|
||||||
$ vips max
|
|
||||||
usage:
|
|
||||||
max in out
|
|
||||||
find image maximum
|
|
||||||
where:
|
|
||||||
in - Input image, input VipsImage
|
|
||||||
out - Output value, output gdouble
|
|
||||||
optional arguments:
|
|
||||||
x - Horizontal position of maximum, output gint
|
|
||||||
y - Vertical position of maximum, output gint
|
|
||||||
size - Number of maximum values to find, input gint
|
|
||||||
out-array - Array of output values, output VipsArrayDouble
|
|
||||||
x-array - Array of horizontal positions, output VipsArrayInt
|
|
||||||
y-array - Array of vertical positions, output VipsArrayInt
|
|
||||||
|
|
||||||
don't list out-array or out as args in the usage line, since they don't need
|
|
||||||
an arg ... these args should be in a separate section, I guess?
|
|
||||||
|
|
||||||
put description first
|
|
||||||
|
|
||||||
should be:
|
|
||||||
|
|
||||||
$ vips getpoint
|
|
||||||
read a point from an image
|
|
||||||
usage:
|
|
||||||
getpoint in x y
|
|
||||||
prints:
|
|
||||||
out-array
|
|
||||||
where:
|
|
||||||
in - Input image, input VipsImage
|
|
||||||
out-array - Array of output values, output VipsArrayDouble
|
|
||||||
x - Getpoint to read from, input gint
|
|
||||||
y - Getpoint to read from, input gint
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
- need to do mosaicing
|
- need to do mosaicing
|
||||||
|
|
||||||
- now vips_linear() has uchar output, can we do something with orc?
|
- now vips_linear() has uchar output, can we do something with orc?
|
||||||
|
@ -304,6 +304,7 @@ typedef void *(*VipsArgumentClassMapFn)( VipsObjectClass *, GParamSpec *,
|
|||||||
VipsArgumentClass *, void *a, void *b );
|
VipsArgumentClass *, void *a, void *b );
|
||||||
void *vips_argument_class_map( VipsObjectClass *object_class,
|
void *vips_argument_class_map( VipsObjectClass *object_class,
|
||||||
VipsArgumentClassMapFn fn, void *a, void *b );
|
VipsArgumentClassMapFn fn, void *a, void *b );
|
||||||
|
gboolean vips_argument_class_needsstring( VipsArgumentClass *argument_class );
|
||||||
int vips_object_get_argument( VipsObject *object, const char *name,
|
int vips_object_get_argument( VipsObject *object, const char *name,
|
||||||
GParamSpec **pspec,
|
GParamSpec **pspec,
|
||||||
VipsArgumentClass **argument_class,
|
VipsArgumentClass **argument_class,
|
||||||
|
@ -472,6 +472,40 @@ vips_argument_class_map( VipsObjectClass *object_class,
|
|||||||
return( NULL );
|
return( NULL );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Does an vipsargument need an argument to write to? For example, an image
|
||||||
|
* output needs a filename, a double output just prints.
|
||||||
|
*/
|
||||||
|
gboolean
|
||||||
|
vips_argument_class_needsstring( VipsArgumentClass *argument_class )
|
||||||
|
{
|
||||||
|
GParamSpec *pspec = ((VipsArgument *) argument_class)->pspec;
|
||||||
|
|
||||||
|
GType otype;
|
||||||
|
VipsObjectClass *oclass;
|
||||||
|
|
||||||
|
if( G_IS_PARAM_SPEC_BOOLEAN( pspec ) )
|
||||||
|
/* Bools, input or output, don't need args.
|
||||||
|
*/
|
||||||
|
return( FALSE );
|
||||||
|
|
||||||
|
if( argument_class->flags & VIPS_ARGUMENT_INPUT )
|
||||||
|
/* All other inputs need something.
|
||||||
|
*/
|
||||||
|
return( TRUE );
|
||||||
|
|
||||||
|
/* Just output objects.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if( (otype = G_PARAM_SPEC_VALUE_TYPE( pspec )) &&
|
||||||
|
g_type_is_a( otype, VIPS_TYPE_OBJECT ) &&
|
||||||
|
(oclass = g_type_class_ref( otype )) )
|
||||||
|
/* For now, only vipsobject subclasses can ask for args.
|
||||||
|
*/
|
||||||
|
return( oclass->output_needs_arg );
|
||||||
|
else
|
||||||
|
return( FALSE );
|
||||||
|
}
|
||||||
|
|
||||||
/* Create a VipsArgumentInstance for each installed argument property. Ideally
|
/* Create a VipsArgumentInstance for each installed argument property. Ideally
|
||||||
* we'd do this during _init() but g_object_class_find_property() does not seem
|
* we'd do this during _init() but g_object_class_find_property() does not seem
|
||||||
* to work then :-( so we have to delay it until first access. See
|
* to work then :-( so we have to delay it until first access. See
|
||||||
@ -1766,8 +1800,6 @@ vips_object_argument_needsstring( VipsObject *object, const char *name )
|
|||||||
GParamSpec *pspec;
|
GParamSpec *pspec;
|
||||||
VipsArgumentClass *argument_class;
|
VipsArgumentClass *argument_class;
|
||||||
VipsArgumentInstance *argument_instance;
|
VipsArgumentInstance *argument_instance;
|
||||||
GType otype;
|
|
||||||
VipsObjectClass *oclass;
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf( "vips_object_argument_needsstring: %s\n", name );
|
printf( "vips_object_argument_needsstring: %s\n", name );
|
||||||
@ -1777,27 +1809,7 @@ vips_object_argument_needsstring( VipsObject *object, const char *name )
|
|||||||
&pspec, &argument_class, &argument_instance ) )
|
&pspec, &argument_class, &argument_instance ) )
|
||||||
return( -1 );
|
return( -1 );
|
||||||
|
|
||||||
if( G_IS_PARAM_SPEC_BOOLEAN( pspec ) )
|
return( vips_argument_class_needsstring( argument_class ) );
|
||||||
/* Bools, input or output, don't need args.
|
|
||||||
*/
|
|
||||||
return( FALSE );
|
|
||||||
|
|
||||||
if( argument_class->flags & VIPS_ARGUMENT_INPUT )
|
|
||||||
/* All other inputs need something.
|
|
||||||
*/
|
|
||||||
return( TRUE );
|
|
||||||
|
|
||||||
/* Just output objects.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if( (otype = G_PARAM_SPEC_VALUE_TYPE( pspec )) &&
|
|
||||||
g_type_is_a( otype, VIPS_TYPE_OBJECT ) &&
|
|
||||||
(oclass = g_type_class_ref( otype )) )
|
|
||||||
/* For now, only vipsobject subclasses can ask for args.
|
|
||||||
*/
|
|
||||||
return( oclass->output_needs_arg );
|
|
||||||
else
|
|
||||||
return( FALSE );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
@ -119,30 +119,67 @@ vips_operation_dispose( GObject *gobject )
|
|||||||
G_OBJECT_CLASS( vips_operation_parent_class )->dispose( gobject );
|
G_OBJECT_CLASS( vips_operation_parent_class )->dispose( gobject );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* What to show about the argument.
|
/* Three basic types of command-line argument.
|
||||||
|
*
|
||||||
|
* INPUTS: things like an input image, there is a filename argument on the
|
||||||
|
* command-line which is used to construct the operation argument.
|
||||||
|
*
|
||||||
|
* NOARG_OUTPUT: things like the result of VipsMax, there's no correspondiong
|
||||||
|
* command-line argument, we just print the value.
|
||||||
|
*
|
||||||
|
* OPTIONS: optional arguments.
|
||||||
|
*
|
||||||
|
* NONE: hide this thing.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
USAGE_INPUTS,
|
||||||
|
USAGE_NOARG_OUTPUT,
|
||||||
|
USAGE_OPTIONS,
|
||||||
|
USAGE_NONE
|
||||||
|
} UsageType;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char *message; /* header message on first print */
|
char *message; /* header message on first print */
|
||||||
gboolean required; /* show required args or optional */
|
UsageType type; /* Type of arg to select */
|
||||||
gboolean oftype; /* "is of type" message */
|
gboolean oftype; /* Show as "of type" */
|
||||||
int n; /* Arg number */
|
int n; /* Arg number */
|
||||||
} VipsOperationClassUsage;
|
} VipsOperationClassUsage;
|
||||||
|
|
||||||
|
/* Put an arg into one the categories above.
|
||||||
|
*/
|
||||||
|
static UsageType
|
||||||
|
vips_operation_class_usage_classify( VipsArgumentClass *argument_class )
|
||||||
|
{
|
||||||
|
if( !(argument_class->flags & VIPS_ARGUMENT_CONSTRUCT) ||
|
||||||
|
(argument_class->flags & VIPS_ARGUMENT_DEPRECATED) )
|
||||||
|
return( USAGE_NONE );
|
||||||
|
|
||||||
|
if( !(argument_class->flags & VIPS_ARGUMENT_REQUIRED) )
|
||||||
|
return( USAGE_OPTIONS );
|
||||||
|
|
||||||
|
if( vips_argument_class_needsstring( argument_class ) )
|
||||||
|
return( USAGE_INPUTS );
|
||||||
|
|
||||||
|
if( (argument_class->flags & VIPS_ARGUMENT_OUTPUT) &&
|
||||||
|
!vips_argument_class_needsstring( argument_class ) )
|
||||||
|
return( USAGE_NOARG_OUTPUT );
|
||||||
|
|
||||||
|
return( USAGE_NONE );
|
||||||
|
}
|
||||||
|
|
||||||
static void *
|
static void *
|
||||||
vips_operation_class_usage_arg( VipsObjectClass *object_class,
|
vips_operation_class_usage_arg( VipsObjectClass *object_class,
|
||||||
GParamSpec *pspec, VipsArgumentClass *argument_class,
|
GParamSpec *pspec, VipsArgumentClass *argument_class,
|
||||||
VipsBuf *buf, VipsOperationClassUsage *usage )
|
VipsBuf *buf, VipsOperationClassUsage *usage )
|
||||||
{
|
{
|
||||||
/* Only show construct args ... others are internal.
|
if( usage->type ==
|
||||||
*/
|
vips_operation_class_usage_classify( argument_class ) ) {
|
||||||
if( usage->required ==
|
if( usage->message &&
|
||||||
((argument_class->flags & VIPS_ARGUMENT_REQUIRED) != 0) &&
|
usage->n == 0 )
|
||||||
(argument_class->flags & VIPS_ARGUMENT_CONSTRUCT) &&
|
|
||||||
!(argument_class->flags & VIPS_ARGUMENT_DEPRECATED) ) {
|
|
||||||
if( usage->message && usage->n == 0 )
|
|
||||||
vips_buf_appendf( buf, "%s\n", usage->message );
|
vips_buf_appendf( buf, "%s\n", usage->message );
|
||||||
|
|
||||||
if( usage->oftype ) {
|
if( usage->oftype )
|
||||||
vips_buf_appendf( buf, " %-12s - %s, %s %s\n",
|
vips_buf_appendf( buf, " %-12s - %s, %s %s\n",
|
||||||
g_param_spec_get_name( pspec ),
|
g_param_spec_get_name( pspec ),
|
||||||
g_param_spec_get_blurb( pspec ),
|
g_param_spec_get_blurb( pspec ),
|
||||||
@ -150,11 +187,11 @@ vips_operation_class_usage_arg( VipsObjectClass *object_class,
|
|||||||
_( "input" ) : _( "output" ),
|
_( "input" ) : _( "output" ),
|
||||||
g_type_name(
|
g_type_name(
|
||||||
G_PARAM_SPEC_VALUE_TYPE( pspec ) ) );
|
G_PARAM_SPEC_VALUE_TYPE( pspec ) ) );
|
||||||
}
|
|
||||||
else {
|
else {
|
||||||
if( usage->n > 0 )
|
if( usage->n > 0 )
|
||||||
vips_buf_appends( buf, " " );
|
vips_buf_appends( buf, " " );
|
||||||
vips_buf_appends( buf, g_param_spec_get_name( pspec ) );
|
vips_buf_appends( buf,
|
||||||
|
g_param_spec_get_name( pspec ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
usage->n += 1;
|
usage->n += 1;
|
||||||
@ -170,11 +207,14 @@ vips_operation_usage( VipsOperationClass *class, VipsBuf *buf )
|
|||||||
|
|
||||||
VipsOperationClassUsage usage;
|
VipsOperationClassUsage usage;
|
||||||
|
|
||||||
|
vips_buf_appendf( buf, "%s\n", object_class->description );
|
||||||
|
vips_buf_appendf( buf, "usage:\n" );
|
||||||
|
|
||||||
/* First pass through args: show the required names.
|
/* First pass through args: show the required names.
|
||||||
*/
|
*/
|
||||||
vips_buf_appendf( buf, " %s ", object_class->nickname );
|
vips_buf_appendf( buf, " %s ", object_class->nickname );
|
||||||
usage.message = NULL;
|
usage.message = NULL;
|
||||||
usage.required = TRUE;
|
usage.type = USAGE_INPUTS;
|
||||||
usage.oftype = FALSE;
|
usage.oftype = FALSE;
|
||||||
usage.n = 0;
|
usage.n = 0;
|
||||||
vips_argument_class_map( object_class,
|
vips_argument_class_map( object_class,
|
||||||
@ -182,12 +222,21 @@ vips_operation_usage( VipsOperationClass *class, VipsBuf *buf )
|
|||||||
buf, &usage );
|
buf, &usage );
|
||||||
vips_buf_appends( buf, "\n" );
|
vips_buf_appends( buf, "\n" );
|
||||||
|
|
||||||
vips_buf_appendf( buf, "%s\n", object_class->description );
|
|
||||||
|
|
||||||
/* Show required types.
|
/* Show required types.
|
||||||
*/
|
*/
|
||||||
usage.message = "where:";
|
usage.message = "where:";
|
||||||
usage.required = TRUE;
|
usage.type = USAGE_INPUTS;
|
||||||
|
usage.oftype = TRUE;
|
||||||
|
usage.n = 0;
|
||||||
|
vips_argument_class_map( object_class,
|
||||||
|
(VipsArgumentClassMapFn) vips_operation_class_usage_arg,
|
||||||
|
buf, &usage );
|
||||||
|
|
||||||
|
/* Show outputs with no input arg (eg. output maximum value for
|
||||||
|
* vips_max()).
|
||||||
|
*/
|
||||||
|
usage.message = "outputs:";
|
||||||
|
usage.type = USAGE_NOARG_OUTPUT;
|
||||||
usage.oftype = TRUE;
|
usage.oftype = TRUE;
|
||||||
usage.n = 0;
|
usage.n = 0;
|
||||||
vips_argument_class_map( object_class,
|
vips_argument_class_map( object_class,
|
||||||
@ -197,7 +246,7 @@ vips_operation_usage( VipsOperationClass *class, VipsBuf *buf )
|
|||||||
/* Show optional args.
|
/* Show optional args.
|
||||||
*/
|
*/
|
||||||
usage.message = "optional arguments:";
|
usage.message = "optional arguments:";
|
||||||
usage.required = FALSE;
|
usage.type = USAGE_OPTIONS;
|
||||||
usage.oftype = TRUE;
|
usage.oftype = TRUE;
|
||||||
usage.n = 0;
|
usage.n = 0;
|
||||||
vips_argument_class_map( object_class,
|
vips_argument_class_map( object_class,
|
||||||
@ -367,8 +416,7 @@ vips_operation_class_print_usage( VipsOperationClass *operation_class )
|
|||||||
VipsBuf buf = VIPS_BUF_STATIC( str );
|
VipsBuf buf = VIPS_BUF_STATIC( str );
|
||||||
|
|
||||||
operation_class->usage( operation_class, &buf );
|
operation_class->usage( operation_class, &buf );
|
||||||
printf( "%s", _( "usage:" ) );
|
printf( "%s", vips_buf_all( &buf ) );
|
||||||
printf( "\n%s", vips_buf_all( &buf ) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
VipsOperation *
|
VipsOperation *
|
||||||
|
Loading…
Reference in New Issue
Block a user