1 /* GIMP - The GNU Image Manipulation Program
2 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
3 *
4 * plug-in-rc.c
5 * Copyright (C) 2001 Sven Neumann <sven@gimp.org>
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
21 #include "config.h"
22
23 #include <gdk-pixbuf/gdk-pixbuf.h>
24 #include <gegl.h>
25
26 #include "libgimpbase/gimpbase.h"
27 #include "libgimpbase/gimpprotocol.h"
28 #include "libgimpconfig/gimpconfig.h"
29
30 #include "plug-in-types.h"
31
32 #include "core/gimp.h"
33
34 #include "pdb/gimp-pdb-compat.h"
35
36 #include "gimpplugindef.h"
37 #include "gimppluginprocedure.h"
38 #include "plug-in-rc.h"
39
40 #include "gimp-intl.h"
41
42
43 #define PLUG_IN_RC_FILE_VERSION 5
44
45
46 /*
47 * All deserialize functions return G_TOKEN_LEFT_PAREN on success,
48 * or the GTokenType they would have expected but didn't get,
49 * or G_TOKEN_ERROR if the function already set an error itself.
50 */
51
52 static GTokenType plug_in_def_deserialize (Gimp *gimp,
53 GScanner *scanner,
54 GSList **plug_in_defs);
55 static GTokenType plug_in_procedure_deserialize (GScanner *scanner,
56 Gimp *gimp,
57 GFile *file,
58 GimpPlugInProcedure **proc);
59 static GTokenType plug_in_menu_path_deserialize (GScanner *scanner,
60 GimpPlugInProcedure *proc);
61 static GTokenType plug_in_icon_deserialize (GScanner *scanner,
62 GimpPlugInProcedure *proc);
63 static GTokenType plug_in_file_proc_deserialize (GScanner *scanner,
64 GimpPlugInProcedure *proc);
65 static GTokenType plug_in_proc_arg_deserialize (GScanner *scanner,
66 Gimp *gimp,
67 GimpProcedure *procedure,
68 gboolean return_value);
69 static GTokenType plug_in_locale_def_deserialize (GScanner *scanner,
70 GimpPlugInDef *plug_in_def);
71 static GTokenType plug_in_help_def_deserialize (GScanner *scanner,
72 GimpPlugInDef *plug_in_def);
73 static GTokenType plug_in_has_init_deserialize (GScanner *scanner,
74 GimpPlugInDef *plug_in_def);
75
76
77 enum
78 {
79 PROTOCOL_VERSION = 1,
80 FILE_VERSION,
81 PLUG_IN_DEF,
82 PROC_DEF,
83 LOCALE_DEF,
84 HELP_DEF,
85 HAS_INIT,
86 PROC_ARG,
87 MENU_PATH,
88 ICON,
89 LOAD_PROC,
90 SAVE_PROC,
91 EXTENSIONS,
92 PREFIXES,
93 MAGICS,
94 PRIORITY,
95 MIME_TYPES,
96 HANDLES_URI,
97 HANDLES_RAW,
98 THUMB_LOADER
99 };
100
101
102 GSList *
plug_in_rc_parse(Gimp * gimp,GFile * file,GError ** error)103 plug_in_rc_parse (Gimp *gimp,
104 GFile *file,
105 GError **error)
106 {
107 GScanner *scanner;
108 GEnumClass *enum_class;
109 GSList *plug_in_defs = NULL;
110 gint protocol_version = GIMP_PROTOCOL_VERSION;
111 gint file_version = PLUG_IN_RC_FILE_VERSION;
112 GTokenType token;
113
114 g_return_val_if_fail (GIMP_IS_GIMP (gimp), NULL);
115 g_return_val_if_fail (G_IS_FILE (file), NULL);
116 g_return_val_if_fail (error == NULL || *error == NULL, NULL);
117
118 scanner = gimp_scanner_new_gfile (file, error);
119
120 if (! scanner)
121 return NULL;
122
123 enum_class = g_type_class_ref (GIMP_TYPE_ICON_TYPE);
124
125 g_scanner_scope_add_symbol (scanner, 0,
126 "protocol-version",
127 GINT_TO_POINTER (PROTOCOL_VERSION));
128 g_scanner_scope_add_symbol (scanner, 0,
129 "file-version",
130 GINT_TO_POINTER (FILE_VERSION));
131 g_scanner_scope_add_symbol (scanner, 0,
132 "plug-in-def", GINT_TO_POINTER (PLUG_IN_DEF));
133
134 g_scanner_scope_add_symbol (scanner, PLUG_IN_DEF,
135 "proc-def", GINT_TO_POINTER (PROC_DEF));
136 g_scanner_scope_add_symbol (scanner, PLUG_IN_DEF,
137 "locale-def", GINT_TO_POINTER (LOCALE_DEF));
138 g_scanner_scope_add_symbol (scanner, PLUG_IN_DEF,
139 "help-def", GINT_TO_POINTER (HELP_DEF));
140 g_scanner_scope_add_symbol (scanner, PLUG_IN_DEF,
141 "has-init", GINT_TO_POINTER (HAS_INIT));
142 g_scanner_scope_add_symbol (scanner, PLUG_IN_DEF,
143 "proc-arg", GINT_TO_POINTER (PROC_ARG));
144 g_scanner_scope_add_symbol (scanner, PLUG_IN_DEF,
145 "menu-path", GINT_TO_POINTER (MENU_PATH));
146 g_scanner_scope_add_symbol (scanner, PLUG_IN_DEF,
147 "icon", GINT_TO_POINTER (ICON));
148 g_scanner_scope_add_symbol (scanner, PLUG_IN_DEF,
149 "load-proc", GINT_TO_POINTER (LOAD_PROC));
150 g_scanner_scope_add_symbol (scanner, PLUG_IN_DEF,
151 "save-proc", GINT_TO_POINTER (SAVE_PROC));
152
153 g_scanner_scope_add_symbol (scanner, LOAD_PROC,
154 "extensions", GINT_TO_POINTER (EXTENSIONS));
155 g_scanner_scope_add_symbol (scanner, LOAD_PROC,
156 "prefixes", GINT_TO_POINTER (PREFIXES));
157 g_scanner_scope_add_symbol (scanner, LOAD_PROC,
158 "magics", GINT_TO_POINTER (MAGICS));
159 g_scanner_scope_add_symbol (scanner, LOAD_PROC,
160 "priority", GINT_TO_POINTER (PRIORITY));
161 g_scanner_scope_add_symbol (scanner, LOAD_PROC,
162 "mime-types", GINT_TO_POINTER (MIME_TYPES));
163 g_scanner_scope_add_symbol (scanner, LOAD_PROC,
164 "handles-uri", GINT_TO_POINTER (HANDLES_URI));
165 g_scanner_scope_add_symbol (scanner, LOAD_PROC,
166 "handles-raw", GINT_TO_POINTER (HANDLES_RAW));
167 g_scanner_scope_add_symbol (scanner, LOAD_PROC,
168 "thumb-loader", GINT_TO_POINTER (THUMB_LOADER));
169
170 g_scanner_scope_add_symbol (scanner, SAVE_PROC,
171 "extensions", GINT_TO_POINTER (EXTENSIONS));
172 g_scanner_scope_add_symbol (scanner, SAVE_PROC,
173 "prefixes", GINT_TO_POINTER (PREFIXES));
174 g_scanner_scope_add_symbol (scanner, SAVE_PROC,
175 "priority", GINT_TO_POINTER (PRIORITY));
176 g_scanner_scope_add_symbol (scanner, SAVE_PROC,
177 "mime-types", GINT_TO_POINTER (MIME_TYPES));
178 g_scanner_scope_add_symbol (scanner, SAVE_PROC,
179 "handles-uri", GINT_TO_POINTER (HANDLES_URI));
180
181 token = G_TOKEN_LEFT_PAREN;
182
183 while (protocol_version == GIMP_PROTOCOL_VERSION &&
184 file_version == PLUG_IN_RC_FILE_VERSION &&
185 g_scanner_peek_next_token (scanner) == token)
186 {
187 token = g_scanner_get_next_token (scanner);
188
189 switch (token)
190 {
191 case G_TOKEN_LEFT_PAREN:
192 token = G_TOKEN_SYMBOL;
193 break;
194
195 case G_TOKEN_SYMBOL:
196 switch (GPOINTER_TO_INT (scanner->value.v_symbol))
197 {
198 case PROTOCOL_VERSION:
199 token = G_TOKEN_INT;
200 if (gimp_scanner_parse_int (scanner, &protocol_version))
201 token = G_TOKEN_RIGHT_PAREN;
202 break;
203
204 case FILE_VERSION:
205 token = G_TOKEN_INT;
206 if (gimp_scanner_parse_int (scanner, &file_version))
207 token = G_TOKEN_RIGHT_PAREN;
208 break;
209
210 case PLUG_IN_DEF:
211 g_scanner_set_scope (scanner, PLUG_IN_DEF);
212 token = plug_in_def_deserialize (gimp, scanner, &plug_in_defs);
213 g_scanner_set_scope (scanner, 0);
214 break;
215 default:
216 break;
217 }
218 break;
219
220 case G_TOKEN_RIGHT_PAREN:
221 token = G_TOKEN_LEFT_PAREN;
222 break;
223
224 default: /* do nothing */
225 break;
226 }
227 }
228
229 if (protocol_version != GIMP_PROTOCOL_VERSION ||
230 file_version != PLUG_IN_RC_FILE_VERSION ||
231 token != G_TOKEN_LEFT_PAREN)
232 {
233 if (protocol_version != GIMP_PROTOCOL_VERSION)
234 {
235 g_set_error (error,
236 GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_VERSION,
237 _("Skipping '%s': wrong GIMP protocol version."),
238 gimp_file_get_utf8_name (file));
239 }
240 else if (file_version != PLUG_IN_RC_FILE_VERSION)
241 {
242 g_set_error (error,
243 GIMP_CONFIG_ERROR, GIMP_CONFIG_ERROR_VERSION,
244 _("Skipping '%s': wrong pluginrc file format version."),
245 gimp_file_get_utf8_name (file));
246 }
247 else if (token != G_TOKEN_ERROR)
248 {
249 g_scanner_get_next_token (scanner);
250 g_scanner_unexp_token (scanner, token, NULL, NULL, NULL,
251 _("fatal parse error"), TRUE);
252 }
253
254 g_slist_free_full (plug_in_defs, (GDestroyNotify) g_object_unref);
255 plug_in_defs = NULL;
256 }
257
258 g_type_class_unref (enum_class);
259
260 gimp_scanner_destroy (scanner);
261
262 return g_slist_reverse (plug_in_defs);
263 }
264
265 static GTokenType
plug_in_def_deserialize(Gimp * gimp,GScanner * scanner,GSList ** plug_in_defs)266 plug_in_def_deserialize (Gimp *gimp,
267 GScanner *scanner,
268 GSList **plug_in_defs)
269 {
270 GimpPlugInDef *plug_in_def;
271 GimpPlugInProcedure *proc = NULL;
272 gchar *path;
273 GFile *file;
274 gint64 mtime;
275 GTokenType token;
276 GError *error = NULL;
277
278 if (! gimp_scanner_parse_string (scanner, &path))
279 return G_TOKEN_STRING;
280
281 if (! (path && *path))
282 {
283 g_scanner_error (scanner, "plug-in filename is empty");
284 return G_TOKEN_ERROR;
285 }
286
287 file = gimp_file_new_for_config_path (path, &error);
288 g_free (path);
289
290 if (! file)
291 {
292 g_scanner_error (scanner,
293 "unable to parse plug-in filename: %s",
294 error->message);
295 g_clear_error (&error);
296 return G_TOKEN_ERROR;
297 }
298
299 plug_in_def = gimp_plug_in_def_new (file);
300 g_object_unref (file);
301
302 if (! gimp_scanner_parse_int64 (scanner, &mtime))
303 {
304 g_object_unref (plug_in_def);
305 return G_TOKEN_INT;
306 }
307
308 plug_in_def->mtime = mtime;
309
310 token = G_TOKEN_LEFT_PAREN;
311
312 while (g_scanner_peek_next_token (scanner) == token)
313 {
314 token = g_scanner_get_next_token (scanner);
315
316 switch (token)
317 {
318 case G_TOKEN_LEFT_PAREN:
319 token = G_TOKEN_SYMBOL;
320 break;
321
322 case G_TOKEN_SYMBOL:
323 switch (GPOINTER_TO_INT (scanner->value.v_symbol))
324 {
325 case PROC_DEF:
326 token = plug_in_procedure_deserialize (scanner, gimp,
327 plug_in_def->file,
328 &proc);
329
330 if (token == G_TOKEN_LEFT_PAREN)
331 gimp_plug_in_def_add_procedure (plug_in_def, proc);
332
333 if (proc)
334 g_object_unref (proc);
335 break;
336
337 case LOCALE_DEF:
338 token = plug_in_locale_def_deserialize (scanner, plug_in_def);
339 break;
340
341 case HELP_DEF:
342 token = plug_in_help_def_deserialize (scanner, plug_in_def);
343 break;
344
345 case HAS_INIT:
346 token = plug_in_has_init_deserialize (scanner, plug_in_def);
347 break;
348
349 default:
350 break;
351 }
352 break;
353
354 case G_TOKEN_RIGHT_PAREN:
355 token = G_TOKEN_LEFT_PAREN;
356 break;
357
358 default:
359 break;
360 }
361 }
362
363 if (token == G_TOKEN_LEFT_PAREN)
364 {
365 token = G_TOKEN_RIGHT_PAREN;
366
367 if (gimp_scanner_parse_token (scanner, token))
368 {
369 *plug_in_defs = g_slist_prepend (*plug_in_defs, plug_in_def);
370 return G_TOKEN_LEFT_PAREN;
371 }
372 }
373
374 g_object_unref (plug_in_def);
375
376 return token;
377 }
378
379 static GTokenType
plug_in_procedure_deserialize(GScanner * scanner,Gimp * gimp,GFile * file,GimpPlugInProcedure ** proc)380 plug_in_procedure_deserialize (GScanner *scanner,
381 Gimp *gimp,
382 GFile *file,
383 GimpPlugInProcedure **proc)
384 {
385 GimpProcedure *procedure;
386 GTokenType token;
387 gchar *str;
388 gint proc_type;
389 gint n_args;
390 gint n_return_vals;
391 gint n_menu_paths;
392 gint i;
393
394 if (! gimp_scanner_parse_string (scanner, &str))
395 return G_TOKEN_STRING;
396
397 if (! (str && *str))
398 {
399 g_scanner_error (scanner, "procedure name is empty");
400 return G_TOKEN_ERROR;
401 }
402
403 if (! gimp_scanner_parse_int (scanner, &proc_type))
404 {
405 g_free (str);
406 return G_TOKEN_INT;
407 }
408
409 if (proc_type != GIMP_PLUGIN &&
410 proc_type != GIMP_EXTENSION)
411 {
412 g_free (str);
413 g_scanner_error (scanner, "procedure type %d is out of range",
414 proc_type);
415 return G_TOKEN_ERROR;
416 }
417
418 procedure = gimp_plug_in_procedure_new (proc_type, file);
419
420 *proc = GIMP_PLUG_IN_PROCEDURE (procedure);
421
422 gimp_object_take_name (GIMP_OBJECT (procedure),
423 gimp_canonicalize_identifier (str));
424
425 procedure->original_name = str;
426
427 if (! gimp_scanner_parse_string (scanner, &procedure->blurb))
428 return G_TOKEN_STRING;
429 if (! gimp_scanner_parse_string (scanner, &procedure->help))
430 return G_TOKEN_STRING;
431 if (! gimp_scanner_parse_string (scanner, &procedure->author))
432 return G_TOKEN_STRING;
433 if (! gimp_scanner_parse_string (scanner, &procedure->copyright))
434 return G_TOKEN_STRING;
435 if (! gimp_scanner_parse_string (scanner, &procedure->date))
436 return G_TOKEN_STRING;
437 if (! gimp_scanner_parse_string (scanner, &(*proc)->menu_label))
438 return G_TOKEN_STRING;
439
440 if (! gimp_scanner_parse_int (scanner, &n_menu_paths))
441 return G_TOKEN_INT;
442
443 for (i = 0; i < n_menu_paths; i++)
444 {
445 token = plug_in_menu_path_deserialize (scanner, *proc);
446 if (token != G_TOKEN_LEFT_PAREN)
447 return token;
448 }
449
450 token = plug_in_icon_deserialize (scanner, *proc);
451 if (token != G_TOKEN_LEFT_PAREN)
452 return token;
453
454 token = plug_in_file_proc_deserialize (scanner, *proc);
455 if (token != G_TOKEN_LEFT_PAREN)
456 return token;
457
458 if (! gimp_scanner_parse_string (scanner, &str))
459 return G_TOKEN_STRING;
460
461 gimp_plug_in_procedure_set_image_types (*proc, str);
462 g_free (str);
463
464 if (! gimp_scanner_parse_int (scanner, (gint *) &n_args))
465 return G_TOKEN_INT;
466 if (! gimp_scanner_parse_int (scanner, (gint *) &n_return_vals))
467 return G_TOKEN_INT;
468
469 for (i = 0; i < n_args; i++)
470 {
471 token = plug_in_proc_arg_deserialize (scanner, gimp, procedure, FALSE);
472 if (token != G_TOKEN_LEFT_PAREN)
473 return token;
474 }
475
476 for (i = 0; i < n_return_vals; i++)
477 {
478 token = plug_in_proc_arg_deserialize (scanner, gimp, procedure, TRUE);
479 if (token != G_TOKEN_LEFT_PAREN)
480 return token;
481 }
482
483 if (! gimp_scanner_parse_token (scanner, G_TOKEN_RIGHT_PAREN))
484 return G_TOKEN_RIGHT_PAREN;
485
486 return G_TOKEN_LEFT_PAREN;
487 }
488
489 static GTokenType
plug_in_menu_path_deserialize(GScanner * scanner,GimpPlugInProcedure * proc)490 plug_in_menu_path_deserialize (GScanner *scanner,
491 GimpPlugInProcedure *proc)
492 {
493 gchar *menu_path;
494
495 if (! gimp_scanner_parse_token (scanner, G_TOKEN_LEFT_PAREN))
496 return G_TOKEN_LEFT_PAREN;
497
498 if (! gimp_scanner_parse_token (scanner, G_TOKEN_SYMBOL) ||
499 GPOINTER_TO_INT (scanner->value.v_symbol) != MENU_PATH)
500 return G_TOKEN_SYMBOL;
501
502 if (! gimp_scanner_parse_string (scanner, &menu_path))
503 return G_TOKEN_STRING;
504
505 proc->menu_paths = g_list_append (proc->menu_paths, menu_path);
506
507 if (! gimp_scanner_parse_token (scanner, G_TOKEN_RIGHT_PAREN))
508 return G_TOKEN_RIGHT_PAREN;
509
510 return G_TOKEN_LEFT_PAREN;
511 }
512
513 static GTokenType
plug_in_icon_deserialize(GScanner * scanner,GimpPlugInProcedure * proc)514 plug_in_icon_deserialize (GScanner *scanner,
515 GimpPlugInProcedure *proc)
516 {
517 GEnumClass *enum_class;
518 GEnumValue *enum_value;
519 GimpIconType icon_type;
520 gint icon_data_length;
521 gchar *icon_name;
522 guint8 *icon_data;
523
524 if (! gimp_scanner_parse_token (scanner, G_TOKEN_LEFT_PAREN))
525 return G_TOKEN_LEFT_PAREN;
526
527 if (! gimp_scanner_parse_token (scanner, G_TOKEN_SYMBOL) ||
528 GPOINTER_TO_INT (scanner->value.v_symbol) != ICON)
529 return G_TOKEN_SYMBOL;
530
531 enum_class = g_type_class_peek (GIMP_TYPE_ICON_TYPE);
532
533 switch (g_scanner_peek_next_token (scanner))
534 {
535 case G_TOKEN_IDENTIFIER:
536 g_scanner_get_next_token (scanner);
537
538 enum_value = g_enum_get_value_by_nick (G_ENUM_CLASS (enum_class),
539 scanner->value.v_identifier);
540 if (!enum_value)
541 enum_value = g_enum_get_value_by_name (G_ENUM_CLASS (enum_class),
542 scanner->value.v_identifier);
543
544 if (!enum_value)
545 {
546 g_scanner_error (scanner,
547 _("invalid value '%s' for icon type"),
548 scanner->value.v_identifier);
549 return G_TOKEN_NONE;
550 }
551 break;
552
553 case G_TOKEN_INT:
554 g_scanner_get_next_token (scanner);
555
556 enum_value = g_enum_get_value (enum_class,
557 (gint) scanner->value.v_int64);
558
559 if (!enum_value)
560 {
561 g_scanner_error (scanner,
562 _("invalid value '%ld' for icon type"),
563 (glong) scanner->value.v_int64);
564 return G_TOKEN_NONE;
565 }
566 break;
567
568 default:
569 return G_TOKEN_IDENTIFIER;
570 }
571
572 icon_type = enum_value->value;
573
574 if (! gimp_scanner_parse_int (scanner, &icon_data_length))
575 return G_TOKEN_INT;
576
577 switch (icon_type)
578 {
579 case GIMP_ICON_TYPE_ICON_NAME:
580 case GIMP_ICON_TYPE_IMAGE_FILE:
581 icon_data_length = -1;
582
583 if (! gimp_scanner_parse_string_no_validate (scanner, &icon_name))
584 return G_TOKEN_STRING;
585
586 icon_data = (guint8 *) icon_name;
587 break;
588
589 case GIMP_ICON_TYPE_INLINE_PIXBUF:
590 if (icon_data_length < 0)
591 return G_TOKEN_STRING;
592
593 if (! gimp_scanner_parse_data (scanner, icon_data_length, &icon_data))
594 return G_TOKEN_STRING;
595 break;
596 }
597
598 gimp_plug_in_procedure_take_icon (proc, icon_type,
599 icon_data, icon_data_length);
600
601 if (! gimp_scanner_parse_token (scanner, G_TOKEN_RIGHT_PAREN))
602 return G_TOKEN_RIGHT_PAREN;
603
604 return G_TOKEN_LEFT_PAREN;
605 }
606
607 static GTokenType
plug_in_file_proc_deserialize(GScanner * scanner,GimpPlugInProcedure * proc)608 plug_in_file_proc_deserialize (GScanner *scanner,
609 GimpPlugInProcedure *proc)
610 {
611 GTokenType token;
612 gint symbol;
613
614 if (! gimp_scanner_parse_token (scanner, G_TOKEN_LEFT_PAREN))
615 return G_TOKEN_LEFT_PAREN;
616
617 if (! gimp_scanner_parse_token (scanner, G_TOKEN_SYMBOL))
618 return G_TOKEN_SYMBOL;
619
620 symbol = GPOINTER_TO_INT (scanner->value.v_symbol);
621 if (symbol != LOAD_PROC && symbol != SAVE_PROC)
622 return G_TOKEN_SYMBOL;
623
624 proc->file_proc = TRUE;
625
626 g_scanner_set_scope (scanner, symbol);
627
628 while (g_scanner_peek_next_token (scanner) == G_TOKEN_LEFT_PAREN)
629 {
630 token = g_scanner_get_next_token (scanner);
631
632 if (token != G_TOKEN_LEFT_PAREN)
633 return token;
634
635 if (! gimp_scanner_parse_token (scanner, G_TOKEN_SYMBOL))
636 return G_TOKEN_SYMBOL;
637
638 symbol = GPOINTER_TO_INT (scanner->value.v_symbol);
639
640 switch (symbol)
641 {
642 case EXTENSIONS:
643 {
644 gchar *extensions;
645
646 if (! gimp_scanner_parse_string (scanner, &extensions))
647 return G_TOKEN_STRING;
648
649 g_free (proc->extensions);
650 proc->extensions = extensions;
651 }
652 break;
653
654 case PREFIXES:
655 {
656 gchar *prefixes;
657
658 if (! gimp_scanner_parse_string (scanner, &prefixes))
659 return G_TOKEN_STRING;
660
661 g_free (proc->prefixes);
662 proc->prefixes = prefixes;
663 }
664 break;
665
666 case MAGICS:
667 {
668 gchar *magics;
669
670 if (! gimp_scanner_parse_string_no_validate (scanner, &magics))
671 return G_TOKEN_STRING;
672
673 g_free (proc->magics);
674 proc->magics = magics;
675 }
676 break;
677
678 case PRIORITY:
679 {
680 gint priority;
681
682 if (! gimp_scanner_parse_int (scanner, &priority))
683 return G_TOKEN_INT;
684
685 gimp_plug_in_procedure_set_priority (proc, priority);
686 }
687 break;
688
689 case MIME_TYPES:
690 {
691 gchar *mime_types;
692
693 if (! gimp_scanner_parse_string (scanner, &mime_types))
694 return G_TOKEN_STRING;
695
696 gimp_plug_in_procedure_set_mime_types (proc, mime_types);
697
698 g_free (mime_types);
699 }
700 break;
701
702 case HANDLES_URI:
703 gimp_plug_in_procedure_set_handles_uri (proc);
704 break;
705
706 case HANDLES_RAW:
707 gimp_plug_in_procedure_set_handles_raw (proc);
708 break;
709
710 case THUMB_LOADER:
711 {
712 gchar *thumb_loader;
713
714 if (! gimp_scanner_parse_string (scanner, &thumb_loader))
715 return G_TOKEN_STRING;
716
717 gimp_plug_in_procedure_set_thumb_loader (proc, thumb_loader);
718
719 g_free (thumb_loader);
720 }
721 break;
722
723 default:
724 return G_TOKEN_SYMBOL;
725 }
726 if (! gimp_scanner_parse_token (scanner, G_TOKEN_RIGHT_PAREN))
727 return G_TOKEN_RIGHT_PAREN;
728 }
729
730 if (! gimp_scanner_parse_token (scanner, G_TOKEN_RIGHT_PAREN))
731 return G_TOKEN_RIGHT_PAREN;
732
733 g_scanner_set_scope (scanner, PLUG_IN_DEF);
734
735 return G_TOKEN_LEFT_PAREN;
736 }
737
738 static GTokenType
plug_in_proc_arg_deserialize(GScanner * scanner,Gimp * gimp,GimpProcedure * procedure,gboolean return_value)739 plug_in_proc_arg_deserialize (GScanner *scanner,
740 Gimp *gimp,
741 GimpProcedure *procedure,
742 gboolean return_value)
743 {
744 GTokenType token;
745 gint arg_type;
746 gchar *name = NULL;
747 gchar *desc = NULL;
748 GParamSpec *pspec;
749
750 if (! gimp_scanner_parse_token (scanner, G_TOKEN_LEFT_PAREN))
751 {
752 token = G_TOKEN_LEFT_PAREN;
753 goto error;
754 }
755
756 if (! gimp_scanner_parse_token (scanner, G_TOKEN_SYMBOL) ||
757 GPOINTER_TO_INT (scanner->value.v_symbol) != PROC_ARG)
758 {
759 token = G_TOKEN_SYMBOL;
760 goto error;
761 }
762
763 if (! gimp_scanner_parse_int (scanner, (gint *) &arg_type))
764 {
765 token = G_TOKEN_INT;
766 goto error;
767 }
768 if (! gimp_scanner_parse_string (scanner, &name))
769 {
770 token = G_TOKEN_STRING;
771 goto error;
772 }
773 if (! gimp_scanner_parse_string (scanner, &desc))
774 {
775 token = G_TOKEN_STRING;
776 goto error;
777 }
778
779 if (! gimp_scanner_parse_token (scanner, G_TOKEN_RIGHT_PAREN))
780 {
781 token = G_TOKEN_RIGHT_PAREN;
782 goto error;
783 }
784
785 token = G_TOKEN_LEFT_PAREN;
786
787 pspec = gimp_pdb_compat_param_spec (gimp, arg_type, name, desc, NULL);
788
789 if (return_value)
790 gimp_procedure_add_return_value (procedure, pspec);
791 else
792 gimp_procedure_add_argument (procedure, pspec);
793
794 error:
795
796 g_free (name);
797 g_free (desc);
798
799 return token;
800 }
801
802 static GTokenType
plug_in_locale_def_deserialize(GScanner * scanner,GimpPlugInDef * plug_in_def)803 plug_in_locale_def_deserialize (GScanner *scanner,
804 GimpPlugInDef *plug_in_def)
805 {
806 gchar *domain_name;
807 gchar *domain_path = NULL;
808 gchar *expanded_path = NULL;
809
810 if (! gimp_scanner_parse_string (scanner, &domain_name))
811 return G_TOKEN_STRING;
812
813 if (gimp_scanner_parse_string (scanner, &domain_path))
814 expanded_path = gimp_config_path_expand (domain_path, TRUE, NULL);
815
816 gimp_plug_in_def_set_locale_domain (plug_in_def, domain_name, expanded_path);
817
818 g_free (domain_name);
819 g_free (domain_path);
820 g_free (expanded_path);
821
822 if (! gimp_scanner_parse_token (scanner, G_TOKEN_RIGHT_PAREN))
823 return G_TOKEN_RIGHT_PAREN;
824
825 return G_TOKEN_LEFT_PAREN;
826 }
827
828 static GTokenType
plug_in_help_def_deserialize(GScanner * scanner,GimpPlugInDef * plug_in_def)829 plug_in_help_def_deserialize (GScanner *scanner,
830 GimpPlugInDef *plug_in_def)
831 {
832 gchar *domain_name;
833 gchar *domain_uri;
834
835 if (! gimp_scanner_parse_string (scanner, &domain_name))
836 return G_TOKEN_STRING;
837
838 if (! gimp_scanner_parse_string (scanner, &domain_uri))
839 domain_uri = NULL;
840
841 gimp_plug_in_def_set_help_domain (plug_in_def, domain_name, domain_uri);
842
843 g_free (domain_name);
844 g_free (domain_uri);
845
846 if (! gimp_scanner_parse_token (scanner, G_TOKEN_RIGHT_PAREN))
847 return G_TOKEN_RIGHT_PAREN;
848
849 return G_TOKEN_LEFT_PAREN;
850 }
851
852 static GTokenType
plug_in_has_init_deserialize(GScanner * scanner,GimpPlugInDef * plug_in_def)853 plug_in_has_init_deserialize (GScanner *scanner,
854 GimpPlugInDef *plug_in_def)
855 {
856 gimp_plug_in_def_set_has_init (plug_in_def, TRUE);
857
858 if (! gimp_scanner_parse_token (scanner, G_TOKEN_RIGHT_PAREN))
859 return G_TOKEN_RIGHT_PAREN;
860
861 return G_TOKEN_LEFT_PAREN;
862 }
863
864
865 /* serialize functions */
866
867 gboolean
plug_in_rc_write(GSList * plug_in_defs,GFile * file,GError ** error)868 plug_in_rc_write (GSList *plug_in_defs,
869 GFile *file,
870 GError **error)
871 {
872 GimpConfigWriter *writer;
873 GEnumClass *enum_class;
874 GSList *list;
875
876 writer = gimp_config_writer_new_gfile (file,
877 FALSE,
878 "GIMP pluginrc\n\n"
879 "This file can safely be removed and "
880 "will be automatically regenerated by "
881 "querying the installed plug-ins.",
882 error);
883 if (!writer)
884 return FALSE;
885
886 enum_class = g_type_class_ref (GIMP_TYPE_ICON_TYPE);
887
888 gimp_config_writer_open (writer, "protocol-version");
889 gimp_config_writer_printf (writer, "%d", GIMP_PROTOCOL_VERSION);
890 gimp_config_writer_close (writer);
891
892 gimp_config_writer_open (writer, "file-version");
893 gimp_config_writer_printf (writer, "%d", PLUG_IN_RC_FILE_VERSION);
894 gimp_config_writer_close (writer);
895
896 gimp_config_writer_linefeed (writer);
897
898 for (list = plug_in_defs; list; list = list->next)
899 {
900 GimpPlugInDef *plug_in_def = list->data;
901
902 if (plug_in_def->procedures)
903 {
904 GSList *list2;
905 gchar *path;
906
907 path = gimp_file_get_config_path (plug_in_def->file, NULL);
908 if (! path)
909 continue;
910
911 gimp_config_writer_open (writer, "plug-in-def");
912 gimp_config_writer_string (writer, path);
913 gimp_config_writer_printf (writer, "%"G_GINT64_FORMAT,
914 plug_in_def->mtime);
915
916 g_free (path);
917
918 for (list2 = plug_in_def->procedures; list2; list2 = list2->next)
919 {
920 GimpPlugInProcedure *proc = list2->data;
921 GimpProcedure *procedure = GIMP_PROCEDURE (proc);
922 GEnumValue *enum_value;
923 GList *list3;
924 gint i;
925
926 if (proc->installed_during_init)
927 continue;
928
929 gimp_config_writer_open (writer, "proc-def");
930 gimp_config_writer_printf (writer, "\"%s\" %d",
931 procedure->original_name,
932 procedure->proc_type);
933 gimp_config_writer_linefeed (writer);
934 gimp_config_writer_string (writer, procedure->blurb);
935 gimp_config_writer_linefeed (writer);
936 gimp_config_writer_string (writer, procedure->help);
937 gimp_config_writer_linefeed (writer);
938 gimp_config_writer_string (writer, procedure->author);
939 gimp_config_writer_linefeed (writer);
940 gimp_config_writer_string (writer, procedure->copyright);
941 gimp_config_writer_linefeed (writer);
942 gimp_config_writer_string (writer, procedure->date);
943 gimp_config_writer_linefeed (writer);
944 gimp_config_writer_string (writer, proc->menu_label);
945 gimp_config_writer_linefeed (writer);
946
947 gimp_config_writer_printf (writer, "%d",
948 g_list_length (proc->menu_paths));
949 for (list3 = proc->menu_paths; list3; list3 = list3->next)
950 {
951 gimp_config_writer_open (writer, "menu-path");
952 gimp_config_writer_string (writer, list3->data);
953 gimp_config_writer_close (writer);
954 }
955
956 gimp_config_writer_open (writer, "icon");
957 enum_value = g_enum_get_value (enum_class, proc->icon_type);
958 gimp_config_writer_identifier (writer, enum_value->value_nick);
959 gimp_config_writer_printf (writer, "%d",
960 proc->icon_data_length);
961
962 switch (proc->icon_type)
963 {
964 case GIMP_ICON_TYPE_ICON_NAME:
965 case GIMP_ICON_TYPE_IMAGE_FILE:
966 gimp_config_writer_string (writer, (gchar *) proc->icon_data);
967 break;
968
969 case GIMP_ICON_TYPE_INLINE_PIXBUF:
970 gimp_config_writer_data (writer, proc->icon_data_length,
971 proc->icon_data);
972 break;
973 }
974
975 gimp_config_writer_close (writer);
976
977 if (proc->file_proc)
978 {
979 gimp_config_writer_open (writer,
980 proc->image_types ?
981 "save-proc" : "load-proc");
982
983 if (proc->extensions && *proc->extensions)
984 {
985 gimp_config_writer_open (writer, "extensions");
986 gimp_config_writer_string (writer, proc->extensions);
987 gimp_config_writer_close (writer);
988 }
989
990 if (proc->prefixes && *proc->prefixes)
991 {
992 gimp_config_writer_open (writer, "prefixes");
993 gimp_config_writer_string (writer, proc->prefixes);
994 gimp_config_writer_close (writer);
995 }
996
997 if (proc->magics && *proc->magics)
998 {
999 gimp_config_writer_open (writer, "magics");
1000 gimp_config_writer_string (writer, proc->magics);
1001 gimp_config_writer_close (writer);
1002 }
1003
1004 if (proc->priority)
1005 {
1006 gimp_config_writer_open (writer, "priority");
1007 gimp_config_writer_printf (writer, "%d", proc->priority);
1008 gimp_config_writer_close (writer);
1009 }
1010
1011 if (proc->mime_types && *proc->mime_types)
1012 {
1013 gimp_config_writer_open (writer, "mime-types");
1014 gimp_config_writer_string (writer, proc->mime_types);
1015 gimp_config_writer_close (writer);
1016 }
1017
1018 if (proc->priority)
1019 {
1020 gimp_config_writer_open (writer, "priority");
1021 gimp_config_writer_printf (writer, "%d", proc->priority);
1022 gimp_config_writer_close (writer);
1023 }
1024
1025 if (proc->handles_uri)
1026 {
1027 gimp_config_writer_open (writer, "handles-uri");
1028 gimp_config_writer_close (writer);
1029 }
1030
1031 if (proc->handles_raw && ! proc->image_types)
1032 {
1033 gimp_config_writer_open (writer, "handles-raw");
1034 gimp_config_writer_close (writer);
1035 }
1036
1037 if (proc->thumb_loader)
1038 {
1039 gimp_config_writer_open (writer, "thumb-loader");
1040 gimp_config_writer_string (writer, proc->thumb_loader);
1041 gimp_config_writer_close (writer);
1042 }
1043
1044 gimp_config_writer_close (writer);
1045 }
1046
1047 gimp_config_writer_linefeed (writer);
1048
1049 gimp_config_writer_string (writer, proc->image_types);
1050 gimp_config_writer_linefeed (writer);
1051
1052 gimp_config_writer_printf (writer, "%d %d",
1053 procedure->num_args,
1054 procedure->num_values);
1055
1056 for (i = 0; i < procedure->num_args; i++)
1057 {
1058 GParamSpec *pspec = procedure->args[i];
1059
1060 gimp_config_writer_open (writer, "proc-arg");
1061 gimp_config_writer_printf (writer, "%d",
1062 gimp_pdb_compat_arg_type_from_gtype (G_PARAM_SPEC_VALUE_TYPE (pspec)));
1063
1064 gimp_config_writer_string (writer,
1065 g_param_spec_get_name (pspec));
1066 gimp_config_writer_string (writer,
1067 g_param_spec_get_blurb (pspec));
1068
1069 gimp_config_writer_close (writer);
1070 }
1071
1072 for (i = 0; i < procedure->num_values; i++)
1073 {
1074 GParamSpec *pspec = procedure->values[i];
1075
1076 gimp_config_writer_open (writer, "proc-arg");
1077 gimp_config_writer_printf (writer, "%d",
1078 gimp_pdb_compat_arg_type_from_gtype (G_PARAM_SPEC_VALUE_TYPE (pspec)));
1079
1080 gimp_config_writer_string (writer,
1081 g_param_spec_get_name (pspec));
1082 gimp_config_writer_string (writer,
1083 g_param_spec_get_blurb (pspec));
1084
1085 gimp_config_writer_close (writer);
1086 }
1087
1088 gimp_config_writer_close (writer);
1089 }
1090
1091 if (plug_in_def->locale_domain_name)
1092 {
1093 gimp_config_writer_open (writer, "locale-def");
1094 gimp_config_writer_string (writer,
1095 plug_in_def->locale_domain_name);
1096
1097 if (plug_in_def->locale_domain_path)
1098 {
1099 path = gimp_config_path_unexpand (plug_in_def->locale_domain_path,
1100 TRUE, NULL);
1101 if (path)
1102 {
1103 gimp_config_writer_string (writer, path);
1104 g_free (path);
1105 }
1106 }
1107
1108 gimp_config_writer_close (writer);
1109 }
1110
1111 if (plug_in_def->help_domain_name)
1112 {
1113 gimp_config_writer_open (writer, "help-def");
1114 gimp_config_writer_string (writer,
1115 plug_in_def->help_domain_name);
1116
1117 if (plug_in_def->help_domain_uri)
1118 gimp_config_writer_string (writer,
1119 plug_in_def->help_domain_uri);
1120
1121 gimp_config_writer_close (writer);
1122 }
1123
1124 if (plug_in_def->has_init)
1125 {
1126 gimp_config_writer_open (writer, "has-init");
1127 gimp_config_writer_close (writer);
1128 }
1129
1130 gimp_config_writer_close (writer);
1131 }
1132 }
1133
1134 g_type_class_unref (enum_class);
1135
1136 return gimp_config_writer_finish (writer, "end of pluginrc", error);
1137 }
1138