gimprc.c 53.9 KB
Newer Older
Elliot Lee's avatar
Elliot Lee committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
/* The GIMP -- an image manipulation program
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
16
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Elliot Lee's avatar
Elliot Lee committed
17
 */
Sven Neumann's avatar
Sven Neumann committed
18

Tor Lillqvist's avatar
Tor Lillqvist committed
19 20
#include "config.h"

Elliot Lee's avatar
Elliot Lee committed
21 22
#include <stdlib.h>
#include <stdio.h>
Tor Lillqvist's avatar
Tor Lillqvist committed
23
#ifdef HAVE_UNISTD_H
Elliot Lee's avatar
Elliot Lee committed
24
#include <unistd.h>
Tor Lillqvist's avatar
Tor Lillqvist committed
25
#endif
Elliot Lee's avatar
Elliot Lee committed
26
#include <string.h>
27
#include <errno.h>
Asbjørn Pettersen's avatar
Asbjørn Pettersen committed
28
#include <sys/types.h>
Elliot Lee's avatar
Elliot Lee committed
29
#include <sys/stat.h>
Tor Lillqvist's avatar
Tor Lillqvist committed
30
#ifdef HAVE_SYS_PARAM_H
31
#include <sys/param.h>
Tor Lillqvist's avatar
Tor Lillqvist committed
32 33
#endif

Sven Neumann's avatar
Sven Neumann committed
34 35
#include <gtk/gtk.h>

36
#include "libgimpbase/gimpbase.h"
37 38
#include "libgimpcolor/gimpcolor.h"

39
#include "gui/gui-types.h"
Elliot Lee's avatar
Elliot Lee committed
40

41 42
#include "base/base-config.c"

43
#include "core/gimp.h"
Michael Natterer's avatar
Michael Natterer committed
44
#include "core/gimpcoreconfig.h"
Michael Natterer's avatar
Michael Natterer committed
45

46 47
#include "gui/menus.h"

48
#include "app_procs.h"
Elliot Lee's avatar
Elliot Lee committed
49 50 51
#include "general.h"
#include "gimprc.h"

52 53 54
#include "libgimp/gimpintl.h"


55 56 57
#define ERROR      0
#define DONE       1
#define OK         2
Elliot Lee's avatar
Elliot Lee committed
58

59

60 61 62
#define DEFAULT_IMAGE_TITLE_FORMAT  "%f-%p.%i (%t)"
#define DEFAULT_IMAGE_STATUS_FORMAT DEFAULT_IMAGE_TITLE_FORMAT
#define DEFAULT_COMMENT             "Created with The GIMP"
63 64


Sven Neumann's avatar
Sven Neumann committed
65 66
typedef enum
{
Elliot Lee's avatar
Elliot Lee committed
67 68 69
  TT_STRING,
  TT_PATH,
  TT_DOUBLE,
70
  TT_FLOAT,
Elliot Lee's avatar
Elliot Lee committed
71 72 73 74 75
  TT_INT,
  TT_BOOLEAN,
  TT_POSITION,
  TT_MEMSIZE,
  TT_IMAGETYPE,
76
  TT_INTERP,
Elliot Lee's avatar
Elliot Lee committed
77
  TT_XPREVSIZE,
78
  TT_XUNIT,
79
  TT_XNAVPREVSIZE,
80
  TT_XTHUMBSIZE,
81
  TT_XHELPBROWSER,
82
  TT_XCURSORMODE,
83
  TT_XCOMMENT
Elliot Lee's avatar
Elliot Lee committed
84 85
} TokenType;

86

Elliot Lee's avatar
Elliot Lee committed
87 88 89 90
typedef struct _ParseFunc ParseFunc;

struct _ParseFunc
{
Sven Neumann's avatar
Sven Neumann committed
91 92 93 94
  gchar     *name;
  TokenType  type;
  gpointer   val1p;
  gpointer   val2p;
Elliot Lee's avatar
Elliot Lee committed
95 96 97 98 99 100
};

typedef struct _UnknownToken UnknownToken;

struct _UnknownToken
{
Sven Neumann's avatar
Sven Neumann committed
101 102
  gchar *token;
  gchar *value;
Elliot Lee's avatar
Elliot Lee committed
103 104
};

105

106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121
static gint           get_next_token            (void);
static gint           peek_next_token           (void);
static gint           parse_statement           (void);

static gint           parse_string              (gpointer val1p, gpointer val2p);
static gint           parse_path                (gpointer val1p, gpointer val2p);
static gint           parse_double              (gpointer val1p, gpointer val2p);
static gint           parse_float               (gpointer val1p, gpointer val2p);
static gint           parse_int                 (gpointer val1p, gpointer val2p);
static gint           parse_boolean             (gpointer val1p, gpointer val2p);
static gint           parse_position            (gpointer val1p, gpointer val2p);
static gint           parse_mem_size            (gpointer val1p, gpointer val2p);
static gint           parse_image_type          (gpointer val1p, gpointer val2p);
static gint           parse_interpolation_type  (gpointer val1p, gpointer val2p);
static gint           parse_preview_size        (gpointer val1p, gpointer val2p);
static gint           parse_nav_preview_size    (gpointer val1p, gpointer val2p);
122
static gint           parse_thumbnail_size      (gpointer val1p, gpointer val2p);
123 124 125 126 127 128
static gint           parse_units               (gpointer val1p, gpointer val2p);
static gint           parse_help_browser        (gpointer val1p, gpointer val2p);
static gint           parse_cursor_mode         (gpointer val1p, gpointer val2p);

static gint           parse_unknown             (gchar          *token_sym);

Sven Neumann's avatar
Sven Neumann committed
129 130 131 132 133 134 135 136 137 138 139
static inline gchar * string_to_str             (gpointer val1p, gpointer val2p);
static inline gchar * path_to_str               (gpointer val1p, gpointer val2p);
static inline gchar * double_to_str             (gpointer val1p, gpointer val2p);
static inline gchar * int_to_str                (gpointer val1p, gpointer val2p);
static inline gchar * boolean_to_str            (gpointer val1p, gpointer val2p);
static inline gchar * position_to_str           (gpointer val1p, gpointer val2p);
static inline gchar * mem_size_to_str           (gpointer val1p, gpointer val2p);
static inline gchar * image_type_to_str         (gpointer val1p, gpointer val2p);
static inline gchar * interpolation_type_to_str (gpointer val1p, gpointer val2p);
static inline gchar * preview_size_to_str       (gpointer val1p, gpointer val2p);
static inline gchar * nav_preview_size_to_str   (gpointer val1p, gpointer val2p);
140
static inline gchar * thumbnail_size_to_str     (gpointer val1p, gpointer val2p);
Sven Neumann's avatar
Sven Neumann committed
141 142
static inline gchar * units_to_str              (gpointer val1p, gpointer val2p);
static inline gchar * help_browser_to_str       (gpointer val1p, gpointer val2p);
143
static inline gchar * cursor_mode_to_str        (gpointer val1p, gpointer val2p);
Sven Neumann's avatar
Sven Neumann committed
144 145
static inline gchar * comment_to_str            (gpointer val1p, gpointer val2p);

146 147
static gchar        * transform_path            (gchar        *path, 
						 gboolean      destroy);
148
static void           gimprc_set_token          (const gchar  *token,
149 150
						 gchar        *value);
static void           add_gimp_directory_token  (const gchar  *gimp_dir);
Asbjørn Pettersen's avatar
Asbjørn Pettersen committed
151
#ifdef __EMX__
152
static void           add_x11root_token         (gchar        *x11root);
Asbjørn Pettersen's avatar
Asbjørn Pettersen committed
153
#endif
154 155 156 157 158
static gchar        * open_backup_file          (gchar        *filename,
						 gchar        *secondary_filename,
						 gchar       **name_used,
						 FILE        **fp_new,
						 FILE        **fp_old);
Elliot Lee's avatar
Elliot Lee committed
159 160


161
/*  global gimprc variables  */
162 163
GimpRc gimprc =
{
164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193
  /* marching_speed            */  300,       /* 300 ms */
  /* last_opened_size          */  4,
  /* gamma_val                 */  1.0,
  /* transparency_type         */  1,     /* Mid-Tone Checks */
  /* perfectmouse              */  FALSE, /* off (fast and sloppy) */
  /* transparency_size         */  1,     /* Medium sized */
  /* min_colors                */  144,   /* 6*6*4 */
  /* install_cmap              */  FALSE,
  /* cycled_marching_ants      */  0,
  /* default_threshold         */  15,
  /* resize_windows_on_zoom    */  FALSE,
  /* resize_windows_on_resize  */  FALSE,
  /* no_cursor_updating        */  FALSE,
  /* preview_size              */  GIMP_PREVIEW_SIZE_SMALL,
  /* nav_preview_size          */  GIMP_PREVIEW_SIZE_HUGE,
  /* show_rulers               */  TRUE,
  /* show_statusbar            */  TRUE,
  /* auto_save                 */  TRUE,
  /* confirm_on_close          */  TRUE,
  /* default_dot_for_dot       */  TRUE,
  /* save_session_info         */  TRUE,
  /* save_device_status        */  FALSE,
  /* always_restore_session    */  TRUE,
  /* show_tips                 */  TRUE,
  /* last_tip                  */  -1,
  /* show_tool_tips            */  TRUE,
  /* monitor_xres              */  72.0,
  /* monitor_yres              */  72.0,
  /* using_xserver_resolution  */  FALSE,
  /* image_title_format        */  NULL,
194
  /* image_status_format       */  NULL,
195 196 197 198
  /* max_new_image_size        */  33554432,  /* 32 MB */
  /* trust_dirty_flag          */  FALSE,
  /* use_help                  */  TRUE,
  /* info_window_follows_mouse */  TRUE,
Michael Natterer's avatar
Michael Natterer committed
199
  /* help_browser              */  GIMP_HELP_BROWSER_GIMP,
200
  /* cursor_mode               */  GIMP_CURSOR_MODE_TOOL_ICON,
201 202 203
  /* disable_tearoff_menus     */  FALSE,
  /* theme_path                */  NULL,
  /* theme                     */  NULL
204
};
Elliot Lee's avatar
Elliot Lee committed
205

206 207 208
static GHashTable *parse_func_hash = NULL;


Elliot Lee's avatar
Elliot Lee committed
209 210
static ParseFunc funcs[] =
{
Michael Natterer's avatar
Michael Natterer committed
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249
  { "gamma-correction",              TT_DOUBLE,        &gimprc.gamma_val, NULL                 },
  { "marching-ants-speed",           TT_INT,           &gimprc.marching_speed, NULL            },
  { "last-opened-size",              TT_INT,           &gimprc.last_opened_size, NULL          },
  { "transparency-type",             TT_INT,           &gimprc.transparency_type, NULL         },
  { "perfect-mouse",                 TT_BOOLEAN,       &gimprc.perfectmouse, NULL              },
  { "transparency-size",             TT_INT,           &gimprc.transparency_size, NULL         },
  { "min-colors",                    TT_INT,           &gimprc.min_colors, NULL                },
  { "install-colormap",              TT_BOOLEAN,       &gimprc.install_cmap, NULL              },
  { "colormap-cycling",              TT_BOOLEAN,       &gimprc.cycled_marching_ants, NULL      },
  { "default-threshold",             TT_INT,           &gimprc.default_threshold, NULL         },
  { "resize-windows-on-zoom",        TT_BOOLEAN,       &gimprc.resize_windows_on_zoom, NULL    },
  { "dont-resize-windows-on-zoom",   TT_BOOLEAN,       NULL, &gimprc.resize_windows_on_zoom    },
  { "resize-windows-on-resize",      TT_BOOLEAN,       &gimprc.resize_windows_on_resize, NULL  },
  { "dont-resize-windows-on-resize", TT_BOOLEAN,       NULL, &gimprc.resize_windows_on_resize  },
  { "cursor-updating",               TT_BOOLEAN,       NULL, &gimprc.no_cursor_updating        },
  { "no-cursor-updating",            TT_BOOLEAN,       &gimprc.no_cursor_updating, NULL        },
  { "preview-size",                  TT_XPREVSIZE,     &gimprc.preview_size, NULL              },
  { "nav-preview-size",              TT_XNAVPREVSIZE,  &gimprc.nav_preview_size, NULL          },
  { "show-rulers",                   TT_BOOLEAN,       &gimprc.show_rulers, NULL               },
  { "dont-show-rulers",              TT_BOOLEAN,       NULL, &gimprc.show_rulers               },
  { "show-statusbar",                TT_BOOLEAN,       &gimprc.show_statusbar, NULL            },
  { "dont-show-statusbar",           TT_BOOLEAN,       NULL, &gimprc.show_statusbar            },
  { "auto-save",                     TT_BOOLEAN,       &gimprc.auto_save, NULL                 },
  { "dont-auto-save",                TT_BOOLEAN,       NULL, &gimprc.auto_save                 },
  { "confirm-on-close",              TT_BOOLEAN,       &gimprc.confirm_on_close, NULL          },
  { "dont-confirm-on-close",         TT_BOOLEAN,       NULL, &gimprc.confirm_on_close          },
  { "save-session-info",             TT_BOOLEAN,       &gimprc.save_session_info, NULL         },
  { "dont-save-session-info",        TT_BOOLEAN,       NULL, &gimprc.save_session_info         },
  { "save-device-status",            TT_BOOLEAN,       &gimprc.save_device_status, NULL        },
  { "dont-save-device-status",       TT_BOOLEAN,       NULL, &gimprc.save_device_status        },
  { "always-restore-session",        TT_BOOLEAN,       &gimprc.always_restore_session , NULL   },
  { "show-tips",                     TT_BOOLEAN,       &gimprc.show_tips, NULL                 },
  { "dont-show-tips",                TT_BOOLEAN,       NULL, &gimprc.show_tips                 },
  { "show-tool-tips",                TT_BOOLEAN,       &gimprc.show_tool_tips, NULL            },
  { "dont-show-tool-tips",           TT_BOOLEAN,       NULL, &gimprc.show_tool_tips            },
  { "default-dot-for-dot",           TT_BOOLEAN,       &gimprc.default_dot_for_dot, NULL       },
  { "monitor-xresolution",           TT_DOUBLE,        &gimprc.monitor_xres, NULL              },
  { "monitor-yresolution",           TT_DOUBLE,        &gimprc.monitor_yres, NULL              },
  { "image-title-format",            TT_STRING,        &gimprc.image_title_format, NULL        },
250
  { "image-status-format",           TT_STRING,        &gimprc.image_status_format, NULL       },
Michael Natterer's avatar
Michael Natterer committed
251 252 253 254 255 256 257 258 259 260 261
  { "max-new-image-size",            TT_MEMSIZE,       &gimprc.max_new_image_size, NULL        },
  { "trust-dirty-flag",		     TT_BOOLEAN,       &gimprc.trust_dirty_flag, NULL          },
  { "dont-trust-dirty-flag",         TT_BOOLEAN,       NULL, &gimprc.trust_dirty_flag          },
  { "use-help",                      TT_BOOLEAN,       &gimprc.use_help, NULL                  },
  { "dont-use-help",                 TT_BOOLEAN,       NULL, &gimprc.use_help                  },
  { "info-window-follows-mouse",     TT_BOOLEAN,       &gimprc.info_window_follows_mouse, NULL },
  { "info-window-per-display",       TT_BOOLEAN,       NULL, &gimprc.info_window_follows_mouse },
  { "help-browser",                  TT_XHELPBROWSER,  &gimprc.help_browser, NULL              },
  { "cursor-mode",                   TT_XCURSORMODE,   &gimprc.cursor_mode, NULL               },
  { "disable-tearoff-menus",         TT_BOOLEAN,       &gimprc.disable_tearoff_menus, NULL     },
  { "theme-path",                    TT_PATH,          &gimprc.theme_path, NULL                },
262
  { "theme",                         TT_STRING,        &gimprc.theme, NULL                     }
Elliot Lee's avatar
Elliot Lee committed
263
};
264

Elliot Lee's avatar
Elliot Lee committed
265

Michael Natterer's avatar
Michael Natterer committed
266
static ParseInfo  parse_info = { NULL };
267

Michael Natterer's avatar
Michael Natterer committed
268
static GList     *unknown_tokens = NULL;
269

Michael Natterer's avatar
Michael Natterer committed
270 271
static gint       cur_token;
static gint       next_token;
272 273


274
static gchar *
275
gimp_system_rc_file (void)
Elliot Lee's avatar
Elliot Lee committed
276
{
277 278
  static gchar *value = NULL;

279 280
  if (! value)
    {
281
      value = g_build_filename (gimp_sysconf_directory (), "gimprc", NULL);
282
    }
Elliot Lee's avatar
Elliot Lee committed
283

Tor Lillqvist's avatar
Tor Lillqvist committed
284
  return value;
Elliot Lee's avatar
Elliot Lee committed
285 286
}

Sven Neumann's avatar
Sven Neumann committed
287
gboolean
288
gimprc_init (Gimp *gimp)
Elliot Lee's avatar
Elliot Lee committed
289
{
290
  if (! parse_info.buffer)
Sven Neumann's avatar
Sven Neumann committed
291
    {
292 293 294 295 296 297 298 299
      gint i;

      static ParseFunc base_funcs[] =
      {
	{ "temp-path",          TT_PATH,    NULL, NULL },
	{ "swap-path",          TT_PATH,    NULL, NULL },
	{ "tile-cache-size",    TT_MEMSIZE, NULL, NULL },
	{ "stingy-memory-use",  TT_BOOLEAN, NULL, NULL },
Michael Natterer's avatar
Michael Natterer committed
300
	{ "num-processors",     TT_INT,     NULL, NULL }
301 302
      };

Michael Natterer's avatar
Michael Natterer committed
303 304
      static ParseFunc core_funcs[] =
      {
305
	{ "interpolation-type",       TT_INTERP,    NULL, NULL },
Michael Natterer's avatar
Michael Natterer committed
306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325
	{ "plug-in-path",             TT_PATH,      NULL, NULL },
	{ "module-path",              TT_PATH,      NULL, NULL },
	{ "brush-path",               TT_PATH,      NULL, NULL },
	{ "pattern-path",             TT_PATH,      NULL, NULL },
	{ "palette-path",             TT_PATH,      NULL, NULL },
	{ "gradient-path",            TT_PATH,      NULL, NULL },
	{ "default-brush",            TT_STRING,    NULL, NULL },
	{ "default-pattern",          TT_STRING,    NULL, NULL },
	{ "default-palette",          TT_STRING,    NULL, NULL },
	{ "default-gradient",         TT_STRING,    NULL, NULL },
	{ "default-comment",          TT_STRING,    NULL, NULL },
	{ "default-image-type",       TT_IMAGETYPE, NULL, NULL },
	{ "default-image-size",       TT_POSITION,  NULL, NULL },
	{ "default-units",            TT_XUNIT,     NULL, NULL },
	{ "default-xresolution",      TT_DOUBLE,    NULL, NULL },
	{ "default-yresolution",      TT_DOUBLE,    NULL, NULL },
	{ "default-resolution-units", TT_XUNIT,     NULL, NULL },
	{ "undo-levels",              TT_INT,       NULL, NULL },
	{ "pluginrc-path",            TT_PATH,      NULL, NULL },
	{ "module-load-inhibit",      TT_PATH,      NULL, NULL },
326
	{ "thumbnail-size",           TT_XTHUMBSIZE,NULL, NULL },
327 328
	{ "tool-plug-in-path",        TT_PATH,      NULL, NULL },
	{ "environ-path",             TT_PATH,      NULL, NULL }
Michael Natterer's avatar
Michael Natterer committed
329 330
      };

331
      /*  this hurts badly  */
Michael Natterer's avatar
Michael Natterer committed
332 333 334 335
      base_funcs[0].val1p  = &base_config->temp_path;
      base_funcs[1].val1p  = &base_config->swap_path;
      base_funcs[2].val1p  = &base_config->tile_cache_size;
      base_funcs[3].val1p  = &base_config->stingy_memory_use;
336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353
      base_funcs[4].val1p  = &base_config->num_processors;

      core_funcs[0].val1p  = &gimp->config->interpolation_type;
      core_funcs[1].val1p  = &gimp->config->plug_in_path;
      core_funcs[2].val1p  = &gimp->config->module_path;
      core_funcs[3].val1p  = &gimp->config->brush_path;
      core_funcs[4].val1p  = &gimp->config->pattern_path;
      core_funcs[5].val1p  = &gimp->config->palette_path;
      core_funcs[6].val1p  = &gimp->config->gradient_path;
      core_funcs[7].val1p  = &gimp->config->default_brush;
      core_funcs[8].val1p  = &gimp->config->default_pattern;
      core_funcs[9].val1p  = &gimp->config->default_palette;
      core_funcs[10].val1p = &gimp->config->default_gradient;
      core_funcs[11].val1p = &gimp->config->default_comment;
      core_funcs[12].val1p = &gimp->config->default_type;
      core_funcs[13].val1p = &gimp->config->default_width;
      core_funcs[13].val2p = &gimp->config->default_height;
      core_funcs[14].val1p = &gimp->config->default_units;
354
      core_funcs[15].val1p = &gimp->config->default_xresolution;
355 356 357 358 359
      core_funcs[16].val1p = &gimp->config->default_xresolution;
      core_funcs[17].val1p = &gimp->config->default_resolution_units;
      core_funcs[18].val1p = &gimp->config->levels_of_undo;
      core_funcs[19].val1p = &gimp->config->pluginrc_path;
      core_funcs[20].val1p = &gimp->config->module_db_load_inhibit;
360
      core_funcs[21].val1p = &gimp->config->thumbnail_size;
361
      core_funcs[22].val1p = &gimp->config->tool_plug_in_path;
362
      core_funcs[23].val1p = &gimp->config->environ_path;
363 364 365

      parse_func_hash = g_hash_table_new (g_str_hash, g_str_equal);

366
      for (i = 0; i < G_N_ELEMENTS (base_funcs); i++)
367 368 369 370
	g_hash_table_insert (parse_func_hash,
			     base_funcs[i].name,
			     &base_funcs[i]);

371
      for (i = 0; i < G_N_ELEMENTS (core_funcs); i++)
Michael Natterer's avatar
Michael Natterer committed
372 373 374 375
	g_hash_table_insert (parse_func_hash,
			     core_funcs[i].name,
			     &core_funcs[i]);

376
      for (i = 0; i < G_N_ELEMENTS (funcs); i++)
377 378 379 380
	g_hash_table_insert (parse_func_hash,
			     funcs[i].name,
			     &funcs[i]);

381
      parse_info.buffer        = g_new (gchar, 4096);
Sven Neumann's avatar
Sven Neumann committed
382 383 384 385 386 387
      parse_info.tokenbuf      = parse_info.buffer + 2048;
      parse_info.buffer_size   = 2048;
      parse_info.tokenbuf_size = 2048;

      return TRUE;
    }
388

Sven Neumann's avatar
Sven Neumann committed
389
  return FALSE;
390 391
}

392 393
static GList *
parse_add_directory_tokens (void)
394
{
395
  const gchar *gimp_dir;
Elliot Lee's avatar
Elliot Lee committed
396 397

  gimp_dir = gimp_directory ();
398

Elliot Lee's avatar
Elliot Lee committed
399
  add_gimp_directory_token (gimp_dir);
Asbjørn Pettersen's avatar
Asbjørn Pettersen committed
400
#ifdef __EMX__
401
  add_x11root_token (getenv ("X11ROOT"));
Asbjørn Pettersen's avatar
Asbjørn Pettersen committed
402
#endif
403

404
  /* the real output is unknown_tokens list !  */
405
  return unknown_tokens;
406 407 408
}

void
Michael Natterer's avatar
Michael Natterer committed
409 410 411
gimprc_parse (Gimp        *gimp,
              const gchar *cmdline_system_gimprc,
              const gchar *cmdline_gimprc)
412
{
413 414
  gchar *libfilename;
  gchar *filename;
415

416
  parse_add_directory_tokens ();
Elliot Lee's avatar
Elliot Lee committed
417

Michael Natterer's avatar
Michael Natterer committed
418 419
  if (cmdline_system_gimprc)
    libfilename = g_strdup (cmdline_system_gimprc);
420 421
  else
    libfilename = g_strdup (gimp_system_rc_file ());
422

423
  if (! gimprc_parse_file (libfilename))
Sven Neumann's avatar
Sven Neumann committed
424
    g_message ("Can't open '%s' for reading.", libfilename);
425

Michael Natterer's avatar
Michael Natterer committed
426 427
  if (cmdline_gimprc != NULL) 
    filename = g_strdup (cmdline_gimprc);
Tor Lillqvist's avatar
Tor Lillqvist committed
428
  else 
429
    filename = gimp_personal_rc_file ("gimprc");
Tor Lillqvist's avatar
Tor Lillqvist committed
430

431
  if (strcmp (filename, libfilename))
432
    gimprc_parse_file (filename);
433

434 435 436
  g_free (filename);
  g_free (libfilename);
 
Michael Natterer's avatar
Michael Natterer committed
437
  if (! gimprc.image_title_format)
438
    gimprc.image_title_format = g_strdup (DEFAULT_IMAGE_TITLE_FORMAT);
439 440 441 442

  if (! gimprc.image_status_format)
    gimprc.image_status_format = g_strdup (DEFAULT_IMAGE_STATUS_FORMAT);

443 444
  if (! gimp->config->default_comment)
    gimp->config->default_comment = g_strdup (DEFAULT_COMMENT);
Elliot Lee's avatar
Elliot Lee committed
445 446
}

447 448
static gboolean
parse_absolute_gimprc_file (const gchar *filename)
Elliot Lee's avatar
Elliot Lee committed
449
{
450
  gint status;
Elliot Lee's avatar
Elliot Lee committed
451

Asbjørn Pettersen's avatar
Asbjørn Pettersen committed
452
  parse_info.fp = fopen (filename, "rt");
Michael Natterer's avatar
Michael Natterer committed
453
  if (! parse_info.fp)
454
    return FALSE;
Elliot Lee's avatar
Elliot Lee committed
455

Michael Natterer's avatar
Michael Natterer committed
456
  if (the_gimp->be_verbose)
457
    g_print (_("parsing \"%s\"\n"), filename);
Elliot Lee's avatar
Elliot Lee committed
458

459
  cur_token  = -1;
Elliot Lee's avatar
Elliot Lee committed
460 461
  next_token = -1;

462 463 464
  parse_info.position    = -1;
  parse_info.linenum     = 1;
  parse_info.charnum     = 1;
Elliot Lee's avatar
Elliot Lee committed
465 466 467
  parse_info.inc_linenum = FALSE;
  parse_info.inc_charnum = FALSE;

468
  while ((status = parse_statement ()) == OK);
Elliot Lee's avatar
Elliot Lee committed
469 470 471 472 473

  fclose (parse_info.fp);

  if (status == ERROR)
    {
474 475 476
      g_print (_("error parsing: \"%s\"\n"), filename);
      g_print (_("  at line %d column %d\n"), parse_info.linenum, parse_info.charnum);
      g_print (_("  unexpected token: %s\n"), token_sym);
477 478

      return FALSE;
Elliot Lee's avatar
Elliot Lee committed
479
    }
480 481

  return TRUE;
Elliot Lee's avatar
Elliot Lee committed
482 483
}

484
gboolean
485
gimprc_parse_file (const gchar *filename)
486
{
Michael Natterer's avatar
Michael Natterer committed
487 488
  gchar    *rfilename;
  gboolean  parsed;
489

Michael Natterer's avatar
Michael Natterer committed
490
  if (! g_path_is_absolute (filename))
491
    {
492
      const gchar *home_dir = g_get_home_dir ();
493 494

      if (home_dir != NULL)
495
	{
496
	  rfilename = g_build_filename (home_dir, filename, NULL);
497 498 499
	  parsed = parse_absolute_gimprc_file (rfilename);
	  g_free (rfilename);
	  return parsed;
500 501 502
	}
    }

503 504
  parsed = parse_absolute_gimprc_file (filename);
  return parsed;
505 506
}

Elliot Lee's avatar
Elliot Lee committed
507
static GList *
508 509
g_list_findstr (GList       *list,
		const gchar *str)
Elliot Lee's avatar
Elliot Lee committed
510
{
511
  for (; list; list = g_list_next (list))
Elliot Lee's avatar
Elliot Lee committed
512
    {
513
      if (! strcmp ((gchar *) list->data, str))
Elliot Lee's avatar
Elliot Lee committed
514 515 516 517 518 519
        break;
    }

  return list;
}

520
void
521 522
save_gimprc_strings (const gchar *token,
		     const gchar *value)
523
{
524 525 526 527 528 529 530 531 532 533 534
  gchar     timestamp[40];  /* variables for parsing and updating gimprc */
  gchar    *name;
  gchar     tokname[51];
  FILE     *fp_new;
  FILE     *fp_old;
  gchar    *cur_line;
  gchar    *prev_line;
  gchar    *error_msg;
  gboolean  found = FALSE;
  gchar    *personal_gimprc;
  gchar    *str;
Michael Natterer's avatar
Michael Natterer committed
535

536 537
  UnknownToken *ut;    /* variables to modify unknown_tokens */
  UnknownToken *tmp;
538
  GList        *list;
Michael Natterer's avatar
Michael Natterer committed
539

540 541
  g_assert (token != NULL);
  g_assert (value != NULL);
Michael Natterer's avatar
Michael Natterer committed
542

543
  /* get the name of the backup file, and the file pointers.  'name'
Michael Natterer's avatar
Michael Natterer committed
544 545
   * is reused in another context later, disregard it here
   */
Sven Neumann's avatar
Sven Neumann committed
546 547
  personal_gimprc = gimp_personal_rc_file ("gimprc");
  error_msg = open_backup_file (personal_gimprc,
548 549
				gimp_system_rc_file (),
				&name, &fp_new, &fp_old);
Sven Neumann's avatar
Sven Neumann committed
550
  g_free (personal_gimprc);
551 552 553 554

  if (error_msg != NULL)
    {
      g_message (error_msg);
Sven Neumann's avatar
Sven Neumann committed
555
      g_free (error_msg);
556 557 558 559 560 561 562 563
      return;
    }

  strcpy (timestamp, "by GIMP on ");
  iso_8601_date_format (timestamp + strlen (timestamp), FALSE);

  /* copy the old .gimprc into the new one, modifying it as needed */
  prev_line = NULL;
Michael Natterer's avatar
Michael Natterer committed
564 565 566
  cur_line  = g_new (char, 1024);

  while (! feof (fp_old))
567
    {
Michael Natterer's avatar
Michael Natterer committed
568
      if (! fgets (cur_line, 1024, fp_old))
569
	continue;
570

571 572
      /* special case: save lines starting with '#-' (added by GIMP) */
      if ((cur_line[0] == '#') && (cur_line[1] == '-'))
573 574
	{
	  if (prev_line != NULL)
575
	    {
576 577
	      fputs (prev_line, fp_new);
	      g_free (prev_line);
578
	    }
579 580 581
	  prev_line = g_strdup (cur_line);
	  continue;
	}
582 583

      /* see if the line contains something that we can use 
Michael Natterer's avatar
Michael Natterer committed
584 585
       * and place that into 'name' if its found
       */
GMT 1999 Andy Thomas's avatar
GMT 1999 Andy Thomas committed
586
      if (find_token (cur_line, tokname, 50))
587
	{
588
	  /* check if that entry should be updated */
589
	  if (! g_ascii_strcasecmp (token, tokname)) /* if they match */
590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605
	    {
	      if (prev_line == NULL)
		{
		  fprintf (fp_new, "#- Next line commented out %s\n",
			   timestamp);
		  fprintf (fp_new, "# %s\n", cur_line);
		  fprintf (fp_new, "#- Next line added %s\n",
			   timestamp);
		}
	      else
		{
		  g_free (prev_line);
		  prev_line = NULL;
		  fprintf (fp_new, "#- Next line modified %s\n",
			   timestamp);
		}
606
	      str = g_strescape (value, NULL);
607 608
              if (!found)
                {
Tor Lillqvist's avatar
Tor Lillqvist committed
609
		  fprintf (fp_new, "(%s \"%s\")\n", token, str);
610
		}
611
              else 
Tor Lillqvist's avatar
Tor Lillqvist committed
612 613
		fprintf (fp_new, "#- (%s \"%s\")\n", token, str);
	      g_free (str);
614 615
	      found = TRUE;
	      continue;
Michael Natterer's avatar
Michael Natterer committed
616 617
	    }
	}
618 619 620
    
      /* all lines that did not match the tests above are simply copied */
      if (prev_line != NULL)
621 622 623 624 625
	{
	  fputs (prev_line, fp_new);
	  g_free (prev_line);
	  prev_line = NULL;
	}
626 627 628 629
      fputs (cur_line, fp_new);
    } /* end of while(!feof) */

  g_free (cur_line);
Michael Natterer's avatar
Michael Natterer committed
630
  if (prev_line)
631
    g_free (prev_line);
Michael Natterer's avatar
Michael Natterer committed
632

633 634 635
  fclose (fp_old);

  /* append the options that were not in the old .gimprc */
Michael Natterer's avatar
Michael Natterer committed
636
  if (! found) 
637 638 639
    {
      fprintf (fp_new, "#- Next line added %s\n",
	       timestamp);
640
      str = g_strescape (value, NULL);
Tor Lillqvist's avatar
Tor Lillqvist committed
641 642
      fprintf (fp_new, "(%s \"%s\")\n\n", token, str);
      g_free (str);
643 644 645
    }

  /* update unknown_tokens to reflect new token value */
646 647 648
  ut = g_new (UnknownToken, 1);
  ut->token = g_strdup (token);
  ut->value = g_strdup (value);
649

650 651
  list = unknown_tokens;
  while (list)
652 653
    {
      tmp = (UnknownToken *) list->data;
654
      list = list->next;
655 656 657 658 659 660 661 662 663 664 665 666 667 668

      if (strcmp (tmp->token, ut->token) == 0)
	{
	  unknown_tokens = g_list_remove (unknown_tokens, tmp);
	  g_free (tmp->token);
	  g_free (tmp->value);
	  g_free (tmp);
	}
    }
  unknown_tokens = g_list_append (unknown_tokens, ut);

  fclose (fp_new);
}

Elliot Lee's avatar
Elliot Lee committed
669
void
670
gimprc_save (GList **updated_options,
Elliot Lee's avatar
Elliot Lee committed
671 672
	     GList **conflicting_options)
{
673 674 675 676 677
  gchar  timestamp[40];
  gchar *name;
  gchar  tokname[51];
  FILE  *fp_new;
  FILE  *fp_old;
Elliot Lee's avatar
Elliot Lee committed
678
  GList *option;
679 680 681
  gchar *cur_line;
  gchar *prev_line;
  gchar *str;
Sven Neumann's avatar
Sven Neumann committed
682 683
  gchar *error_msg;
  gchar *personal_gimprc;
Elliot Lee's avatar
Elliot Lee committed
684

685 686
  g_assert (updated_options != NULL);
  g_assert (conflicting_options != NULL);
Elliot Lee's avatar
Elliot Lee committed
687

Sven Neumann's avatar
Sven Neumann committed
688 689
  personal_gimprc = gimp_personal_rc_file ("gimprc");
  error_msg = open_backup_file (personal_gimprc,
Tor Lillqvist's avatar
Tor Lillqvist committed
690 691
				gimp_system_rc_file (),
				&name, &fp_new, &fp_old);
Sven Neumann's avatar
Sven Neumann committed
692
  g_free (personal_gimprc);
Elliot Lee's avatar
Elliot Lee committed
693

694
  if (error_msg != NULL)
Elliot Lee's avatar
Elliot Lee committed
695
    {
696
      g_message (error_msg);
Sven Neumann's avatar
Sven Neumann committed
697
      g_free (error_msg);
Elliot Lee's avatar
Elliot Lee committed
698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724
      return;
    }

  strcpy (timestamp, "by GIMP on ");
  iso_8601_date_format (timestamp + strlen (timestamp), FALSE);

  /* copy the old .gimprc into the new one, modifying it as needed */
  prev_line = NULL;
  cur_line = g_new (char, 1024);
  while (!feof (fp_old))
    {
      if (!fgets (cur_line, 1024, fp_old))
	continue;
      
      /* special case: save lines starting with '#-' (added by GIMP) */
      if ((cur_line[0] == '#') && (cur_line[1] == '-'))
	{
	  if (prev_line != NULL)
	    {
	      fputs (prev_line, fp_new);
	      g_free (prev_line);
	    }
	  prev_line = g_strdup (cur_line);
	  continue;
	}

      /* see if the line contains something that we can use */
GMT 1999 Andy Thomas's avatar
GMT 1999 Andy Thomas committed
725
      if (find_token (cur_line, tokname, 50))
Elliot Lee's avatar
Elliot Lee committed
726 727
	{
	  /* check if that entry should be updated */
GMT 1999 Andy Thomas's avatar
GMT 1999 Andy Thomas committed
728
	  option = g_list_findstr (*updated_options, tokname);
Elliot Lee's avatar
Elliot Lee committed
729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745
	  if (option != NULL)
	    {
	      if (prev_line == NULL)
		{
		  fprintf (fp_new, "#- Next line commented out %s\n",
			   timestamp);
		  fprintf (fp_new, "# %s\n", cur_line);
		  fprintf (fp_new, "#- Next line added %s\n",
			   timestamp);
		}
	      else
		{
		  g_free (prev_line);
		  prev_line = NULL;
		  fprintf (fp_new, "#- Next line modified %s\n",
			   timestamp);
		}
746
	      str = gimprc_value_to_str (tokname);
GMT 1999 Andy Thomas's avatar
GMT 1999 Andy Thomas committed
747
	      fprintf (fp_new, "(%s %s)\n", tokname, str);
Elliot Lee's avatar
Elliot Lee committed
748 749 750
	      g_free (str);

	      *updated_options = g_list_remove_link (*updated_options, option);
751 752
	      *conflicting_options = g_list_concat (*conflicting_options,
						    option);
Elliot Lee's avatar
Elliot Lee committed
753 754 755 756
	      continue;
	    }

	  /* check if that entry should be commented out */
GMT 1999 Andy Thomas's avatar
GMT 1999 Andy Thomas committed
757
	  option = g_list_findstr (*conflicting_options, tokname);
Elliot Lee's avatar
Elliot Lee committed
758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793
	  if (option != NULL)
	    {
	      if (prev_line != NULL)
		{
		  g_free (prev_line);
		  prev_line = NULL;
		}
	      fprintf (fp_new, "#- Next line commented out %s\n",
		       timestamp);
	      fprintf (fp_new, "# %s\n", cur_line);
	      continue;
	    }
	}

      /* all lines that did not match the tests above are simply copied */
      if (prev_line != NULL)
	{
	  fputs (prev_line, fp_new);
	  g_free (prev_line);
	  prev_line = NULL;
	}
      fputs (cur_line, fp_new);

    }

  g_free (cur_line);
  if (prev_line != NULL)
    g_free (prev_line);
  fclose (fp_old);

  /* append the options that were not in the old .gimprc */
  option = *updated_options;
  while (option)
    {
      fprintf (fp_new, "#- Next line added %s\n",
	       timestamp);
794
      str = gimprc_value_to_str ((const gchar *) option->data);
Elliot Lee's avatar
Elliot Lee committed
795 796 797 798 799 800 801
      fprintf (fp_new, "(%s %s)\n\n", (char *) option->data, str);
      g_free (str);
      option = option->next;
    }
  fclose (fp_new);
}

802
static gint
803
get_next_token (void)
Elliot Lee's avatar
Elliot Lee committed
804 805 806 807 808 809 810 811 812 813 814 815 816 817
{
  if (next_token != -1)
    {
      cur_token = next_token;
      next_token = -1;
    }
  else
    {
      cur_token = get_token (&parse_info);
    }

  return cur_token;
}

818
static gint
819
peek_next_token (void)
Elliot Lee's avatar
Elliot Lee committed
820 821 822 823 824 825 826
{
  if (next_token == -1)
    next_token = get_token (&parse_info);

  return next_token;
}

827
static gint
828
parse_statement (void)
Elliot Lee's avatar
Elliot Lee committed
829
{
830 831
  ParseFunc *func;
  gint       token;
Elliot Lee's avatar
Elliot Lee committed
832 833 834 835 836 837 838 839 840 841 842 843 844

  token = peek_next_token ();
  if (!token)
    return DONE;
  if (token != TOKEN_LEFT_PAREN)
    return ERROR;
  token = get_next_token ();

  token = peek_next_token ();
  if (!token || (token != TOKEN_SYMBOL))
    return ERROR;
  token = get_next_token ();

845 846 847 848 849
  func = g_hash_table_lookup (parse_func_hash, token_sym);

  if (func)
    {
      switch (func->type)
Elliot Lee's avatar
Elliot Lee committed
850 851
	{
	case TT_STRING:
852
	  return parse_string (func->val1p, func->val2p);
Elliot Lee's avatar
Elliot Lee committed
853
	case TT_PATH:
854
	  return parse_path (func->val1p, func->val2p);
Elliot Lee's avatar
Elliot Lee committed
855
	case TT_DOUBLE:
856
	  return parse_double (func->val1p, func->val2p);
857
	case TT_FLOAT:
858
	  return parse_float (func->val1p, func->val2p);
Elliot Lee's avatar
Elliot Lee committed
859
	case TT_INT:
860
	  return parse_int (func->val1p, func->val2p);
Elliot Lee's avatar
Elliot Lee committed
861
	case TT_BOOLEAN:
862
	  return parse_boolean (func->val1p, func->val2p);
Elliot Lee's avatar
Elliot Lee committed
863
	case TT_POSITION:
864
	  return parse_position (func->val1p, func->val2p);
Elliot Lee's avatar
Elliot Lee committed
865
	case TT_MEMSIZE:
866
	  return parse_mem_size (func->val1p, func->val2p);
Elliot Lee's avatar
Elliot Lee committed
867
	case TT_IMAGETYPE:
868
	  return parse_image_type (func->val1p, func->val2p);
869
	case TT_INTERP:
870
	  return parse_interpolation_type (func->val1p, func->val2p);
Elliot Lee's avatar
Elliot Lee committed
871
	case TT_XPREVSIZE:
872
	  return parse_preview_size (func->val1p, func->val2p);
873
	case TT_XNAVPREVSIZE:
874
	  return parse_nav_preview_size (func->val1p, func->val2p);
875 876
	case TT_XTHUMBSIZE:
	  return parse_thumbnail_size (func->val1p, func->val2p);
877
	case TT_XUNIT:
878
	  return parse_units (func->val1p, func->val2p);
879
	case TT_XHELPBROWSER:
880
	  return parse_help_browser (func->val1p, func->val2p);
881
	case TT_XCURSORMODE:
882
	  return parse_cursor_mode (func->val1p, func->val2p);
883
	case TT_XCOMMENT:
884
	  return parse_string (func->val1p, func->val2p);
Elliot Lee's avatar
Elliot Lee committed
885
	}
886
    }
Elliot Lee's avatar
Elliot Lee committed
887 888 889 890

  return parse_unknown (token_sym);
}

891
static gint
Elliot Lee's avatar
Elliot Lee committed
892 893 894
parse_path (gpointer val1p,
	    gpointer val2p)
{
895 896
  gint    token;
  gchar **pathp;
Elliot Lee's avatar
Elliot Lee committed
897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923

  g_assert (val1p != NULL);
  pathp = (char **)val1p;

  token = peek_next_token ();
  if (!token || (token != TOKEN_STRING))
    return ERROR;
  token = get_next_token ();

  if (*pathp)
    g_free (*pathp);
  *pathp = g_strdup (token_str);

  token = peek_next_token ();
  if (!token || (token != TOKEN_RIGHT_PAREN))
    {
      g_free (*pathp);
      *pathp = NULL;
      return ERROR;
    }
  token = get_next_token ();

  *pathp = transform_path (*pathp, TRUE);

  return OK;
}

924
static gint
Elliot Lee's avatar
Elliot Lee committed
925 926 927
parse_string (gpointer val1p,
	      gpointer val2p)
{
928 929
  gint    token;
  gchar **strp;
Elliot Lee's avatar
Elliot Lee committed
930 931

  g_assert (val1p != NULL);
932
  strp = (gchar **)val1p;
Elliot Lee's avatar
Elliot Lee committed
933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954

  token = peek_next_token ();
  if (!token || (token != TOKEN_STRING))
    return ERROR;
  token = get_next_token ();

  if (*strp)
    g_free (*strp);
  *strp = g_strdup (token_str);

  token = peek_next_token ();
  if (!token || (token != TOKEN_RIGHT_PAREN))
    {
      g_free (*strp);
      *strp = NULL;
      return ERROR;
    }
  token = get_next_token ();

  return OK;
}

955
static gint
Elliot Lee's avatar
Elliot Lee committed
956 957 958
parse_double (gpointer val1p,
	      gpointer val2p)
{
959 960
  gint     token;
  gdouble *nump;
Elliot Lee's avatar
Elliot Lee committed
961 962

  g_assert (val1p != NULL);
963
  nump = (gdouble *) val1p;
Elliot Lee's avatar
Elliot Lee committed
964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979

  token = peek_next_token ();
  if (!token || (token != TOKEN_NUMBER))
    return ERROR;
  token = get_next_token ();

  *nump = token_num;

  token = peek_next_token ();
  if (!token || (token != TOKEN_RIGHT_PAREN))
    return ERROR;
  token = get_next_token ();

  return OK;
}

980
static gint
981 982 983
parse_float (gpointer val1p,
	     gpointer val2p)
{
984 985
  gint    token;
  gfloat *nump;
986 987

  g_assert (val1p != NULL);
988
  nump = (gfloat *) val1p;
989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004

  token = peek_next_token ();
  if (!token || (token != TOKEN_NUMBER))
    return ERROR;
  token = get_next_token ();

  *nump = token_num;

  token = peek_next_token ();
  if (!token || (token != TOKEN_RIGHT_PAREN))
    return ERROR;
  token = get_next_token ();

  return OK;
}

1005
static gint
Elliot Lee's avatar
Elliot Lee committed
1006 1007 1008
parse_int (gpointer val1p,
	   gpointer val2p)
{
1009 1010
  gint token;
  gint *nump;
Elliot Lee's avatar
Elliot Lee committed
1011 1012

  g_assert (val1p != NULL);
1013
  nump = (gint *) val1p;
Elliot Lee's avatar
Elliot Lee committed
1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029

  token = peek_next_token ();
  if (!token || (token != TOKEN_NUMBER))
    return ERROR;
  token = get_next_token ();

  *nump = token_num;

  token = peek_next_token ();
  if (!token || (token != TOKEN_RIGHT_PAREN))
    return ERROR;
  token = get_next_token ();

  return OK;
}