Skip to content

Commit 15dfd61

Browse files
committed
add batch mode interface
needs a bit of polish still
1 parent 1b5d2ab commit 15dfd61

File tree

9 files changed

+426
-318
lines changed

9 files changed

+426
-318
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
- support `ninja test`
77
- fix bands -> height image to matrix conversion
88
- fix `to_colour`
9+
- add `nip4-batch` batch mode interface
910

1011
## 9.0.0-10 29025/02/18
1112

TODO

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,6 @@
1-
- fix --test
1+
- open test.ws, edit defs, "main = 12;", process, ws is not marked as modified
22

3-
test_snip.def is failing
4-
5-
need def load in batch mode
6-
7-
runs
8-
9-
nip4 --test test_snip.def
3+
- check all batch mode flags
104

115
- try to save and restore image view scale and position
126

src/app.c

Lines changed: 10 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -98,12 +98,10 @@ app_init(App *app)
9898
static void
9999
app_activate(GApplication *gapp)
100100
{
101-
if (!main_option_batch) {
102-
Mainwindow *main;
101+
Mainwindow *main;
103102

104-
main = mainwindow_new(APP(gapp), NULL);
105-
gtk_window_present(GTK_WINDOW(main));
106-
}
103+
main = mainwindow_new(APP(gapp), NULL);
104+
gtk_window_present(GTK_WINDOW(main));
107105
}
108106

109107
static void *
@@ -288,40 +286,16 @@ app_open(GApplication *app, GFile **files, int n_files, const char *hint)
288286
printf("app_open:\n");
289287
#endif /*DEBUG*/
290288

291-
if (main_option_batch) {
292-
Workspacegroup *wsg;
293-
294-
wsg = NULL;
295-
for (int i = 0; i < n_files; i++) {
296-
g_autofree char *filename = g_file_get_path(files[i]);
289+
Mainwindow *main = mainwindow_new(APP(app), NULL);
297290

298-
wsg = workspacegroup_new_from_file(main_workspaceroot,
299-
filename, filename);
300-
if (!wsg)
301-
error_alert(NULL);
302-
}
291+
gtk_window_present(GTK_WINDOW(main));
303292

304-
if (wsg &&
305-
main_option_print_main) {
306-
Workspace *ws = workspacegroup_get_workspace(wsg);
307-
Symbol *sym = compile_lookup(ws->sym->expr->compile, "main");
308-
309-
if (sym)
310-
main_print_main(sym);
311-
}
312-
}
313-
else {
314-
Mainwindow *main = mainwindow_new(APP(app), NULL);
293+
for (int i = 0; i < n_files; i++)
294+
mainwindow_open(main, files[i]);
315295

316-
gtk_window_present(GTK_WINDOW(main));
317-
318-
for (int i = 0; i < n_files; i++)
319-
mainwindow_open(main, files[i]);
320-
321-
if (n_files > 0 &&
322-
mainwindow_is_empty(main))
323-
gtk_window_destroy(GTK_WINDOW(main));
324-
}
296+
if (n_files > 0 &&
297+
mainwindow_is_empty(main))
298+
gtk_window_destroy(GTK_WINDOW(main));
325299
}
326300

327301
static void

src/main-batch.c

Lines changed: 254 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,254 @@
1+
// C startup
2+
3+
/*
4+
5+
Copyright (C) 1991-2003 The National Gallery
6+
Copyright (C) 2004-2023 libvips.org
7+
8+
This program is free software; you can redistribute it and/or modify
9+
it under the terms of the GNU General Public License as published by
10+
the Free Software Foundation; either version 2 of the License, or
11+
(at your option) any later version.
12+
13+
This program is distributed in the hope that it will be useful,
14+
but WITHOUT ANY WARRANTY; without even the implied warranty of
15+
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16+
GNU General Public License for more details.
17+
18+
You should have received a copy of the GNU General Public License along
19+
with this program; if not, write to the Free Software Foundation, Inc.,
20+
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21+
22+
*/
23+
24+
/*
25+
#define DEBUG
26+
#define DEBUG_FATAL
27+
*/
28+
29+
#include "nip4.h"
30+
31+
static iOpenFile *main_stdin = NULL;
32+
static char *main_option_script = NULL;
33+
static char *main_option_expression = NULL;
34+
static gboolean main_option_stdin_ws = FALSE;
35+
static gboolean main_option_stdin_def = FALSE;
36+
static char *main_option_output = NULL;
37+
static char **main_option_set = NULL;
38+
static gboolean main_option_version = FALSE;
39+
static gboolean main_option_verbose = FALSE;
40+
static gboolean main_option_test = FALSE;
41+
static char *main_option_prefix = NULL;
42+
43+
static GOptionEntry main_batch_options[] = {
44+
{ "expression", 'e', 0, G_OPTION_ARG_STRING, &main_option_expression,
45+
N_("evaluate and print EXPRESSION"),
46+
"EXPRESSION" },
47+
{ "script", 's', 0, G_OPTION_ARG_FILENAME, &main_option_script,
48+
N_("load FILE as a set of definitions"),
49+
"FILE" },
50+
{ "output", 'o', 0, G_OPTION_ARG_FILENAME, &main_option_output,
51+
N_("write value of 'main' to FILE"), "FILE" },
52+
{ "set", '=', 0, G_OPTION_ARG_STRING_ARRAY, &main_option_set,
53+
N_("set values"), NULL },
54+
{ "verbose", 'V', 0, G_OPTION_ARG_NONE, &main_option_verbose,
55+
N_("verbose error output"), NULL },
56+
{ "no-load-menus", 'm', 0, G_OPTION_ARG_NONE,
57+
&main_option_no_load_menus,
58+
N_("don't load menu definitions"), NULL },
59+
{ "stdin-ws", 'w', 0, G_OPTION_ARG_NONE, &main_option_stdin_ws,
60+
N_("load stdin as a workspace"), NULL },
61+
{ "stdin-def", 'd', 0, G_OPTION_ARG_NONE, &main_option_stdin_def,
62+
N_("load stdin as a set of definitions"), NULL },
63+
{ "time-save", 't', 0, G_OPTION_ARG_NONE, &main_option_time_save,
64+
N_("time image save operations"),
65+
NULL },
66+
{ "profile", 'r', 0, G_OPTION_ARG_NONE, &main_option_profile,
67+
N_("profile workspace calculation"),
68+
NULL },
69+
{ "prefix", 'x', 0, G_OPTION_ARG_FILENAME, &main_option_prefix,
70+
N_("start as if installed to PREFIX"), "PREFIX" },
71+
{ "i18n", 'i', 0, G_OPTION_ARG_NONE, &main_option_i18n,
72+
N_("output strings for internationalisation"),
73+
NULL },
74+
{ "version", 'v', 0, G_OPTION_ARG_NONE, &main_option_version,
75+
N_("print version number"),
76+
NULL },
77+
{ "test", 'T', 0, G_OPTION_ARG_NONE, &main_option_test,
78+
N_("test for errors and quit"), NULL },
79+
{ NULL }
80+
};
81+
82+
/* Print all errors and quit.
83+
*/
84+
static void
85+
main_error_exit(const char *fmt, ...)
86+
{
87+
va_list args;
88+
89+
va_start(args, fmt);
90+
(void) vfprintf(stderr, fmt, args);
91+
va_end(args);
92+
fprintf(stderr, "\n");
93+
94+
if (!g_str_equal(error_get_top(), "")) {
95+
fprintf(stderr, "%s\n", error_get_top());
96+
if (!g_str_equal(error_get_sub(), ""))
97+
fprintf(stderr, "%s\n", error_get_sub());
98+
}
99+
100+
if (main_option_verbose) {
101+
char txt[MAX_STRSIZE];
102+
VipsBuf buf = VIPS_BUF_STATIC(txt);
103+
104+
slist_map(expr_error_all,
105+
(SListMapFn) expr_error_print, &buf);
106+
fprintf(stderr, "%s", vips_buf_all(&buf));
107+
}
108+
109+
exit(1);
110+
}
111+
112+
/* Output a single main.
113+
*/
114+
static void
115+
main_print_main(Symbol *sym)
116+
{
117+
PElement *root;
118+
119+
/* Strict reduction of this object, then print.
120+
*/
121+
root = &sym->expr->root;
122+
if (!symbol_recalculate_check(sym) ||
123+
!reduce_pelement(reduce_context, reduce_spine_strict, root))
124+
main_error_exit(_( "error calculating \"%s\""), symbol_name_scope(sym));
125+
126+
/* FIXME ... need Group for this
127+
if (main_option_output) {
128+
char filename[VIPS_PATH_MAX];
129+
130+
g_strlcpy(filename, main_option_output, VIPS_PATH_MAX);
131+
if (!group_save_item(root, filename))
132+
main_error_exit(_( "error saving \"%s\""),
133+
symbol_name_scope(sym));
134+
}
135+
*/
136+
137+
graph_value(root);
138+
}
139+
140+
static void
141+
main_load_file(char *filename)
142+
{
143+
if (vips_iscasepostfix(filename, ".def")) {
144+
Toolkit *kit;
145+
146+
if (!(kit = toolkit_new_from_file(main_toolkitgroup, filename)))
147+
main_error_exit("unable to load toolkit \"%s\"", filename);
148+
149+
Symbol *sym =
150+
compile_lookup(main_toolkitgroup->root->expr->compile, "main");
151+
if (sym)
152+
main_print_main(sym);
153+
}
154+
else if (vips_iscasepostfix(filename, ".ws")) {
155+
Workspacegroup *wsg;
156+
157+
if (!(wsg = workspacegroup_new_from_file(main_workspaceroot,
158+
filename, filename)))
159+
main_error_exit("unable to load workspace \"%s\"", filename);
160+
161+
Workspace *ws = workspacegroup_get_workspace(wsg);
162+
Symbol *sym = compile_lookup(ws->sym->expr->compile, "main");
163+
if (sym)
164+
main_print_main(sym);
165+
}
166+
else {
167+
printf("FIXME ... batch image load\n");
168+
}
169+
}
170+
171+
int
172+
main(int argc, char **argv)
173+
{
174+
main_option_batch = TRUE;
175+
main_option_no_load_menus = TRUE;
176+
177+
/* Set localised application name.
178+
*/
179+
g_set_application_name(_(PACKAGE));
180+
181+
GOptionContext *context =
182+
g_option_context_new(_("- image processing spreadsheet"));
183+
GOptionGroup *main_group = g_option_group_new(NULL, NULL, NULL, NULL, NULL);
184+
g_option_group_add_entries(main_group, main_batch_options);
185+
vips_add_option_entries(main_group);
186+
g_option_group_set_translation_domain(main_group, GETTEXT_PACKAGE);
187+
g_option_context_set_main_group(context, main_group);
188+
189+
GError *error = NULL;
190+
#ifdef G_OS_WIN32
191+
if (!g_option_context_parse_strv(context, &argv, &error))
192+
#else /*!G_OS_WIN32*/
193+
if (!g_option_context_parse(context, &argc, &argv, &error))
194+
#endif /*G_OS_WIN32*/
195+
{
196+
if (error) {
197+
fprintf(stderr, "%s\n", error->message);
198+
g_error_free(error);
199+
}
200+
201+
vips_error_exit("try \"%s --help\"", g_get_prgname());
202+
}
203+
204+
g_option_context_free(context);
205+
206+
if (main_option_version) {
207+
printf("%s-%s", PACKAGE, VERSION);
208+
printf("\n");
209+
210+
printf(_("linked to vips-%s"), vips_version_string());
211+
printf("\n");
212+
213+
exit(0);
214+
}
215+
216+
/* Override the install guess from vips. This won't pick up msg
217+
* cats sadly :( since we have to init i18n before arg parsing. Handy
218+
* for testing without installing.
219+
*/
220+
if (main_option_prefix)
221+
set_prefix(main_option_prefix);
222+
223+
if (main_option_test)
224+
main_option_verbose = TRUE;
225+
226+
if (main_option_i18n)
227+
/* We'll need to load all menus.
228+
*/
229+
main_option_no_load_menus = FALSE;
230+
231+
/* On Windows, argv is ascii-only ... use this to get a utf-8 version of
232+
* the args.
233+
*/
234+
#ifdef G_OS_WIN32
235+
argv = g_win32_get_command_line();
236+
#endif /*G_OS_WIN32*/
237+
238+
main_startup(argc, argv);
239+
240+
for (int i = 1; i < argc; i++)
241+
main_load_file(argv[i]);
242+
243+
if (main_option_test) {
244+
/* Make sure we've had at least one recomp on everything.
245+
*/
246+
symbol_recalculate_all_force(TRUE);
247+
if (expr_error_all)
248+
main_error_exit("--test: errors found");
249+
}
250+
251+
main_shutdown();
252+
253+
return 0;
254+
}

0 commit comments

Comments
 (0)