Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
common/conf.c
Go to the documentation of this file.
1/*
2 This file is part of darktable,
3 Copyright (C) 2010-2011, 2014 Henrik Andersson.
4 Copyright (C) 2010-2013 johannes hanika.
5 Copyright (C) 2010, 2012-2017 Tobias Ellinghaus.
6 Copyright (C) 2012 Christian Tellefsen.
7 Copyright (C) 2012 Jérémy Rosen.
8 Copyright (C) 2012 Richard Wonka.
9 Copyright (C) 2012 Simon Spannagel.
10 Copyright (C) 2012, 2014 Ulrich Pegelow.
11 Copyright (C) 2013 Jean-Sébastien Pédron.
12 Copyright (C) 2013 Jesper Pedersen.
13 Copyright (C) 2014 parafin.
14 Copyright (C) 2014, 2020-2021 Pascal Obry.
15 Copyright (C) 2014, 2016 Roman Lebedev.
16 Copyright (C) 2016-2018 Peter Budai.
17 Copyright (C) 2019 jakubfi.
18 Copyright (C) 2019, 2021 luzpaz.
19 Copyright (C) 2020 Hubert Kowalski.
20 Copyright (C) 2020 Philippe Weyland.
21 Copyright (C) 2021 Aldric Renaudin.
22 Copyright (C) 2021 Marco Carrarini.
23 Copyright (C) 2021 Mark-64.
24 Copyright (C) 2021 Ralf Brown.
25 Copyright (C) 2022 Hanno Schwalm.
26 Copyright (C) 2022 Martin Bařinka.
27 Copyright (C) 2025 Aurélien PIERRE.
28
29 darktable is free software: you can redistribute it and/or modify
30 it under the terms of the GNU General Public License as published by
31 the Free Software Foundation, either version 3 of the License, or
32 (at your option) any later version.
33
34 darktable is distributed in the hope that it will be useful,
35 but WITHOUT ANY WARRANTY; without even the implied warranty of
36 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
37 GNU General Public License for more details.
38
39 You should have received a copy of the GNU General Public License
40 along with darktable. If not, see <http://www.gnu.org/licenses/>.
41*/
42
43#ifdef HAVE_CONFIG_H
44#include "config.h"
45#endif
46
47#include "math/calculator.h"
48#include "darktable.h"
50#include "math/math.h"
51#include "common/conf.h"
52
53#include <glib.h>
54#include <glib/gstdio.h>
55#include <glib/gprintf.h>
56#include <inttypes.h>
57#include <stdio.h>
58#include <stdlib.h>
59#include <strings.h>
60#include "common/utility.h"
61
62typedef struct dt_conf_dreggn_t
63{
65 const char *match;
67
68static void _free_confgen_value(void *value)
69{
71 dt_free(s->def);
72 dt_free(s->min);
73 dt_free(s->max);
76 dt_free(s->longdesc);
77 dt_free(s);
78}
79
86static inline char *_dt_conf_get_var_locked(const char *name)
87{
88 char *str;
89
91 if(!IS_NULL_PTR(str)) return str;
92
94 if(!IS_NULL_PTR(str)) return str;
95
96 // not found, try defaults
98 if(!IS_NULL_PTR(str))
99 {
100 char *str_new = g_strdup(str);
102 return str_new;
103 }
104
105 // FIXME: why insert garbage?
106 // still no luck? insert garbage:
107 str = (char *)g_malloc0(sizeof(int32_t));
109 return str;
110}
111
113static inline char *dt_conf_get_var(const char *name)
114{
118 return str;
119}
120
121/* set the value only if it hasn't been overridden from commandline
122 * return 1 if key/value is still the one passed on commandline. */
123static int dt_conf_set_if_not_overridden(const char *name, char *str)
124{
126
128 const int is_overridden = (over && !strcmp(str, over));
129 if(!is_overridden)
130 {
132 }
133
135
136 return is_overridden;
137}
138
139void dt_conf_set_int(const char *name, int val)
140{
141 char *str = g_strdup_printf("%d", val);
143 {
144 dt_free(str);
145 }
146}
147
148void dt_conf_set_int64(const char *name, int64_t val)
149{
150 char *str = g_strdup_printf("%" PRId64, val);
152 {
153 dt_free(str);
154 }
155}
156
157void dt_conf_set_float(const char *name, float val)
158{
159 char *str = (char *)g_malloc(G_ASCII_DTOSTR_BUF_SIZE);
162 {
163 dt_free(str);
164 }
165}
166
167void dt_conf_set_bool(const char *name, int val)
168{
169 char *str = g_strdup(val ? "TRUE" : "FALSE");
171 {
172 dt_free(str);
173 }
174}
175
176void dt_conf_set_string(const char *name, const char *val)
177{
178 char *str = g_strdup(val);
180 {
181 dt_free(str);
182 }
183}
184
186{
187
188#ifdef WIN32
189 // for Windows native file chooser, gtk_file_chooser_get_current_folder()
190 // does not work, so we workaround
192 {
194 if(pathname)
195 {
196 gchar *folder = g_path_get_dirname(pathname);
198 {
199 dt_free(folder);
200 }
202 }
203 return;
204 }
205#endif
206
209 {
210 dt_free(folder);
211 }
212}
213
215{
216 const char *str = dt_conf_get_var(name);
218 if(isnan(new_value))
219 {
220 //we've got garbage, check default
221 const char *def_val = dt_confgen_get(name, DT_DEFAULT);
222 if(!IS_NULL_PTR(def_val))
223 {
225 if(isnan(new_value))
226 new_value = 0.0;
227 else
228 {
229 char *fix_badval = g_strdup(def_val);
231 {
233 }
234 }
235 }
236 else
237 {
238 new_value = 0.0;
239 }
240 }
241
242 int val;
243 if(new_value > 0)
244 val = new_value + 0.5;
245 else
246 val = new_value - 0.5;
247 return val;
248}
249
250int dt_conf_get_int(const char *name)
251{
252 const int min = dt_confgen_get_int(name, DT_MIN);
253 const int max = dt_confgen_get_int(name, DT_MAX);
254 const int val = dt_conf_get_int_fast(name);
255 const int ret = CLAMP(val, min, max);
256 return ret;
257}
258
259int64_t dt_conf_get_int64_fast(const char *name)
260{
261 const char *str = dt_conf_get_var(name);
263 if(isnan(new_value))
264 {
265 //we've got garbage, check default
266 const char *def_val = dt_confgen_get(name, DT_DEFAULT);
267 if(!IS_NULL_PTR(def_val))
268 {
270 if(isnan(new_value))
271 new_value = 0.0;
272 else
273 {
274 char *fix_badval = g_strdup(def_val);
276 {
278 }
279 }
280 }
281 else
282 {
283 new_value = 0.0;
284 }
285 }
286
287 int64_t val;
288 if(new_value > 0)
289 val = new_value + 0.5;
290 else
291 val = new_value - 0.5;
292 return val;
293}
294
295int64_t dt_conf_get_int64(const char *name)
296{
297 const int64_t min = dt_confgen_get_int64(name, DT_MIN);
298 const int64_t max = dt_confgen_get_int64(name, DT_MAX);
299 const int64_t val = dt_conf_get_int64_fast(name);
300 const int64_t ret = CLAMP(val, min, max);
301 return ret;
302}
303
304float dt_conf_get_float_fast(const char *name)
305{
306 const char *str = dt_conf_get_var(name);
308 if(isnan(new_value))
309 {
310 //we've got garbage, check default
311 const char *def_val = dt_confgen_get(name, DT_DEFAULT);
312 if(!IS_NULL_PTR(def_val))
313 {
315 if(isnan(new_value))
316 new_value = 0.0;
317 else
318 {
319 char *fix_badval = g_strdup(def_val);
321 {
323 }
324 }
325 }
326 else
327 {
328 new_value = 0.0;
329 }
330 }
331 return new_value;
332}
333
334float dt_conf_get_float(const char *name)
335{
336 const float min = dt_confgen_get_float(name, DT_MIN);
337 const float max = dt_confgen_get_float(name, DT_MAX);
338 const float val = dt_conf_get_float_fast(name);
339 const float ret = CLAMP(val, min, max);
340 return ret;
341}
342
343int dt_conf_get_and_sanitize_int(const char *name, int min, int max)
344{
345 const int cmin = dt_confgen_get_int(name, DT_MIN);
346 const int cmax = dt_confgen_get_int(name, DT_MAX);
347 const int val = dt_conf_get_int_fast(name);
348 const int ret = CLAMPS(val, MAX(min, cmin), MIN(max, cmax));
349 dt_conf_set_int(name, ret);
350 return ret;
351}
352
353int64_t dt_conf_get_and_sanitize_int64(const char *name, int64_t min, int64_t max)
354{
355 const int64_t cmin = dt_confgen_get_int64(name, DT_MIN);
356 const int64_t cmax = dt_confgen_get_int64(name, DT_MAX);
357 const int64_t val = dt_conf_get_int64_fast(name);
358 const int64_t ret = CLAMPS(val, MAX(min, cmin), MIN(max, cmax));
360 return ret;
361}
362
363float dt_conf_get_and_sanitize_float(const char *name, float min, float max)
364{
365 const float cmin = dt_confgen_get_float(name, DT_MIN);
366 const float cmax = dt_confgen_get_float(name, DT_MAX);
367 const float val = dt_conf_get_float_fast(name);
368 const float ret = CLAMPS(val, MAX(min, cmin), MIN(max, cmax));
370 return ret;
371}
372
373int dt_conf_get_bool(const char *name)
374{
375 const char *str = dt_conf_get_var(name);
376 const int val = (str[0] == 'T') || (str[0] == 't');
377 return val;
378}
379
380gchar *dt_conf_get_string(const char *name)
381{
382 // Copy the value before releasing the lock: dt_conf_get_var() hands back a pointer straight
383 // into the conf hash table, and a concurrent dt_conf_set_*() on the same key can free it
384 // (g_hash_table_insert() destroys the value it replaces) the moment the lock is released --
385 // a caller strdup'ing that pointer afterwards races the free. This was the mechanism behind a
386 // "write_sidecar_files silently flips to FALSE" report: dt_image_get_xmp_mode() reads this key
387 // from many threads per image, and a torn read masqueraded as an unrecognized/disabled value.
389 const char *str = _dt_conf_get_var_locked(name);
390 gchar *result = g_strdup(str);
392 return result;
393}
394
395const char *dt_conf_get_string_const(const char *name)
396{
397 return dt_conf_get_var(name);
398}
399
400gboolean dt_conf_key_not_empty(const char *name)
401{
402 const char *val = dt_conf_get_string_const(name);
403 if(IS_NULL_PTR(val)) return FALSE;
404 if(strlen(val) == 0) return FALSE;
405 return TRUE;
406}
407
409{
410 const gchar *folder = dt_conf_get_string_const(name);
411 if (!IS_NULL_PTR(folder))
412 {
414 return TRUE;
415 }
416 return FALSE;
417}
418
419gboolean dt_conf_is_equal(const char *name, const char *value)
420{
421 const char *str = dt_conf_get_var(name);
422 return g_strcmp0(str, value) == 0;
423}
424
425static char *_sanitize_confgen(const char *name, const char *value)
426{
428
429 if(IS_NULL_PTR(item)) return g_strdup(value);
430
431 char *result = NULL;
432
433 switch(item->type)
434 {
435 case DT_INT:
436 {
437 float v = dt_calculator_solve(1, value);
438
439 const int min = item->min ? (int)dt_calculator_solve(1, item->min) : INT_MIN;
440 const int max = item->max ? (int)dt_calculator_solve(1, item->max) : INT_MAX;
441 // if garbage, use default
442 const int val = isnan(v) ? dt_confgen_get_int(name, DT_DEFAULT) : (int)v;
443 result = g_strdup_printf("%d", CLAMP(val, min, max));
444 }
445 break;
446 case DT_INT64:
447 {
448 float v = dt_calculator_solve(1, value);
449
450 const int64_t min = item->min ? (int64_t)dt_calculator_solve(1, item->min) : INT64_MIN;
451 const int64_t max = item->max ? (int64_t)dt_calculator_solve(1, item->max) : INT64_MAX;
452 // if garbage, use default
453 const int64_t val = isnan(v) ? dt_confgen_get_int64(name, DT_DEFAULT) : (int64_t)v;
454 result = g_strdup_printf("%"PRId64, CLAMP(val, min, max));
455 }
456 break;
457 case DT_FLOAT:
458 {
459 float v = dt_calculator_solve(1, value);
460
461 const float min = item->min ? (float)dt_calculator_solve(1, item->min) : -FLT_MAX;
462 const float max = item->max ? (float)dt_calculator_solve(1, item->max) : FLT_MAX;
463 // if garbage, use default
464 const float val = isnan(v) ? dt_confgen_get_float(name, DT_DEFAULT) : v;
465 result = g_strdup_printf("%f", CLAMP(val, min, max));
466 }
467 break;
468 case DT_BOOL:
469 {
470 if(strcasecmp(value, "true") && strcasecmp(value, "false"))
472 else
473 result = g_strdup(value);
474 }
475 break;
476 case DT_ENUM:
477 {
478 char *v = g_strdup_printf("[%s]", value);
479 if(!strstr(item->enum_values, v))
481 else
482 result = g_strdup(value);
483 dt_free(v);
484 }
485 break;
486 default:
487 result = g_strdup(value);
488 break;
489 }
490
491 return result;
492}
493
494void dt_conf_init(dt_conf_t *cf, const char *filename, GSList *override_entries)
495{
497
501
502 // init conf filename
503 g_strlcpy(darktable.conf->filename, filename, sizeof(darktable.conf->filename));
504
505#define LINE_SIZE 1023
506
507 char line[LINE_SIZE + 1];
508
509 FILE *f = NULL;
510
511 // check for user config
512 f = g_fopen(filename, "rb");
513
514 // if file has been found, parse it
515
516 if(!IS_NULL_PTR(f))
517 {
518 while(!feof(f))
519 {
520 const int read = fscanf(f, "%" STR(LINE_SIZE) "[^\r\n]\r\n", line);
521 if(read > 0)
522 {
523 char *c = line;
524 char *end = line + strlen(line);
525 // check for '=' which is separator between the conf name and value
526 while(*c != '=' && c < end) c++;
527
528 if(*c == '=')
529 {
530 *c = '\0';
531
532 char *name = g_strdup(line);
533 // ensure that numbers are properly clamped if min/max
534 // defined and if not and garbage is read then the default
535 // value is returned.
536 char *value = _sanitize_confgen(name, (const char *)(c + 1));
537
539 }
540 }
541 }
542 fclose(f);
543 }
544 else
545 {
546 // we initialize the conf table with default values
548 gpointer key, value;
549
551 while (g_hash_table_iter_next (&iter, &key, &value))
552 {
553 const char *name = (const char *)key;
556 }
557 }
558
559 if(!IS_NULL_PTR(override_entries))
560 {
561 for(GSList *p = override_entries; p; p = g_slist_next(p))
562 {
565 }
566 }
567
568#undef LINE_SIZE
569
570 return;
571}
572
582
583static void _conf_add(char *key, char *val, dt_conf_dreggn_t *d)
584{
585 if(strncmp(key, d->match, strlen(d->match)) == 0)
586 {
588 nv->key = g_strdup(key + strlen(d->match) + 1);
589 nv->value = g_strdup(val);
590 d->result = g_slist_append(d->result, nv);
591 }
592}
593
605
606void dt_conf_string_entry_free(gpointer data)
607{
609 dt_free(nv->key);
610 dt_free(nv->value);
611 nv->key = NULL;
612 nv->value = NULL;
613 dt_free(nv);
614}
615
616gboolean dt_confgen_exists(const char *name)
617{
619}
620
622{
624
625 if(!IS_NULL_PTR(item))
626 return item->type;
627 else
628 return DT_STRING;
629}
630
632{
634 if(IS_NULL_PTR(item))
635 return FALSE;
636
637 switch(kind)
638 {
639 case DT_DEFAULT:
640 return !IS_NULL_PTR(item->def);
641 case DT_MIN:
642 return !IS_NULL_PTR(item->min);
643 case DT_MAX:
644 return !IS_NULL_PTR(item->max);
645 case DT_VALUES:
646 return !IS_NULL_PTR(item->enum_values);
647 }
648 return FALSE;
649}
650
652{
654
655 if(!IS_NULL_PTR(item))
656 {
657 switch(kind)
658 {
659 case DT_DEFAULT:
660 return item->def;
661 case DT_MIN:
662 return item->min;
663 case DT_MAX:
664 return item->max;
665 case DT_VALUES:
666 return item->enum_values;
667 }
668 }
669
670 return "";
671}
672
673const char *dt_confgen_get_label(const char *name)
674{
676
677 if(!IS_NULL_PTR(item))
678 {
679 return item->shortdesc;
680 }
681
682 return "";
683}
684
685const char *dt_confgen_get_tooltip(const char *name)
686{
688
689 if(!IS_NULL_PTR(item))
690 {
691 return item->longdesc;
692 }
693
694 return "";
695}
696
698{
700 {
701 //early bail
702 switch (kind)
703 {
704 case DT_MIN:
705 return INT_MIN;
706 break;
707 case DT_MAX:
708 return INT_MAX;
709 break;
710 default:
711 return 0;
712 break;
713 }
714 }
715 const char *str = dt_confgen_get(name, kind);
716
717 //if str is NULL or empty, dt_calculator_solve will return NAN
718 const float value = dt_calculator_solve(1, str);
719
720 switch (kind)
721 {
722 case DT_MIN:
723 return isnan(value) ? INT_MIN : (value > 0 ? value + 0.5f : value - 0.5f);
724 break;
725 case DT_MAX:
726 return isnan(value) ? INT_MAX : (value > 0 ? value + 0.5f : value - 0.5f);
727 break;
728 default:
729 return isnan(value) ? 0.0f : (value > 0 ? value + 0.5f : value - 0.5f);
730 break;
731 }
732 return (int)value;
733}
734
736{
738 {
739 //early bail
740 switch (kind)
741 {
742 case DT_MIN:
743 return INT64_MIN;
744 break;
745 case DT_MAX:
746 return INT64_MAX;
747 break;
748 default:
749 return 0;
750 break;
751 }
752 }
753 const char *str = dt_confgen_get(name, kind);
754
755 //if str is NULL or empty, dt_calculator_solve will return NAN
756 const float value = dt_calculator_solve(1, str);
757
758 switch (kind)
759 {
760 case DT_MIN:
761 return isnan(value) ? INT64_MIN : (value > 0 ? value + 0.5f : value - 0.5f);
762 break;
763 case DT_MAX:
764 return isnan(value) ? INT64_MAX : (value > 0 ? value + 0.5f : value - 0.5f);
765 break;
766 default:
767 return isnan(value) ? 0.0f : (value > 0 ? value + 0.5f : value - 0.5f);
768 break;
769 }
770 return (int64_t)value;
771}
772
774{
775 const char *str = dt_confgen_get(name, kind);
776 return !strcmp(str, "true");
777}
778
780{
782 {
783 //early bail
784 switch (kind)
785 {
786 case DT_MIN:
787 return -FLT_MAX;
788 break;
789 case DT_MAX:
790 return FLT_MAX;
791 break;
792 default:
793 break;
794 }
795 return 0.0f;
796 }
797
798 const char *str = dt_confgen_get(name, kind);
799
800 //if str is NULL or empty, dt_calculator_solve will return NAN
801 const float value = dt_calculator_solve(1, str);
802
803 switch (kind)
804 {
805 case DT_MIN:
806 // to anyone askig FLT_MIN is superclose to 0, not furthest value from 0 possible in float
807 return isnan(value) ? -FLT_MAX : value;
808 break;
809 case DT_MAX:
810 return isnan(value) ? FLT_MAX : value;
811 break;
812 default:
813 break;
814 }
815 return isnan(value) ? 0.0f : value;
816}
817
818gboolean dt_conf_is_default(const char *name)
819{
821 return TRUE; // well if default doesn't know about it, it's default
822
823 switch(dt_confgen_type(name))
824 {
825 case DT_INT:
827 break;
828 case DT_INT64:
830 break;
831 case DT_FLOAT:
833 break;
834 case DT_BOOL:
836 break;
837 case DT_PATH:
838 case DT_STRING:
839 case DT_ENUM:
840 default:
841 {
842 const char *def_val = dt_confgen_get(name, DT_DEFAULT);
843 const char *cur_val = dt_conf_get_var(name);
844 return g_strcmp0(def_val, cur_val) == 0;
845 break;
846 }
847 }
848}
849
850gchar* dt_conf_expand_default_dir(const char *dir)
851{
852 // expand special dirs
853#define CONFIG_DIR "$(config)"
854#define HOME_DIR "$(home)"
855
856 gchar *path = NULL;
858 {
859 gchar configdir[PATH_MAX] = { 0 };
860 dt_loc_get_user_config_dir(configdir, sizeof(configdir));
861 path = g_strdup_printf("%s%s", configdir, dir + strlen(CONFIG_DIR));
862 }
863 else if(g_str_has_prefix(dir, HOME_DIR))
864 {
865 gchar *homedir = dt_loc_get_home_dir(NULL);
866 path = g_strdup_printf("%s%s", homedir, dir + strlen(HOME_DIR));
867 dt_free(homedir);
868 }
869 else path = g_strdup(dir);
870
872 dt_free(path);
873
874 return normalized_path;
875}
876
877static void dt_conf_print(const gchar *key, const gchar *val, FILE *f)
878{
879 fprintf(f, "%s=%s\n", key, val);
880}
881
883{
884 FILE *f = g_fopen(cf->filename, "wb");
885 if(!IS_NULL_PTR(f))
886 {
887 GList *keys = g_hash_table_get_keys(cf->table);
888 GList *sorted = g_list_sort(keys, (GCompareFunc)g_strcmp0);
889
890 for(GList *iter = sorted; iter; iter = g_list_next(iter))
891 {
892 const gchar *key = (const gchar *)iter->data;
893 const gchar *val = (const gchar *)g_hash_table_lookup(cf->table, key);
895 }
896
897 g_list_free(sorted);
898 sorted = NULL;
899 fclose(f);
900 }
901}
903{
905 g_hash_table_unref(cf->table);
906 g_hash_table_unref(cf->override_entries);
907 g_hash_table_unref(cf->x_confgen);
909}
910
911// clang-format off
912// modelines: These editor modelines have been set for all relevant files by tools/update_modelines.py
913// vim: shiftwidth=2 expandtab tabstop=2 cindent
914// kate: tab-indents: off; indent-width 2; replace-tabs on; indent-mode cstyle; remove-trailing-spaces modified;
915// clang-format on
#define TRUE
Definition ashift_lsd.c:162
#define FALSE
Definition ashift_lsd.c:158
float dt_calculator_solve(const float x, const char *formula)
Definition calculator.c:323
static const dt_adaptation_t kind
const float f
const float v
static const float const float const float min
const float max
void dt_conf_cleanup(dt_conf_t *cf)
void dt_conf_string_entry_free(gpointer data)
void dt_conf_set_bool(const char *name, int val)
int dt_conf_get_bool(const char *name)
#define HOME_DIR
int dt_conf_key_exists(const char *key)
float dt_confgen_get_float(const char *name, dt_confgen_value_kind_t kind)
int64_t dt_conf_get_int64_fast(const char *name)
static char * _sanitize_confgen(const char *name, const char *value)
void dt_conf_init(dt_conf_t *cf, const char *filename, GSList *override_entries)
void dt_conf_set_float(const char *name, float val)
float dt_conf_get_float(const char *name)
const char * dt_confgen_get_tooltip(const char *name)
static void _conf_add(char *key, char *val, dt_conf_dreggn_t *d)
static int dt_conf_set_if_not_overridden(const char *name, char *str)
gchar * dt_conf_get_string(const char *name)
int dt_conf_get_int_fast(const char *name)
int dt_conf_get_and_sanitize_int(const char *name, int min, int max)
static void _free_confgen_value(void *value)
Definition common/conf.c:68
void dt_conf_set_int(const char *name, int val)
gboolean dt_confgen_get_bool(const char *name, dt_confgen_value_kind_t kind)
void dt_conf_set_int64(const char *name, int64_t val)
gchar * dt_conf_expand_default_dir(const char *dir)
GSList * dt_conf_all_string_entries(const char *dir)
gboolean dt_conf_is_default(const char *name)
static char * _dt_conf_get_var_locked(const char *name)
Definition common/conf.c:86
int dt_conf_get_int(const char *name)
int64_t dt_conf_get_int64(const char *name)
gboolean dt_confgen_value_exists(const char *name, dt_confgen_value_kind_t kind)
int64_t dt_confgen_get_int64(const char *name, dt_confgen_value_kind_t kind)
gboolean dt_confgen_exists(const char *name)
int dt_confgen_get_int(const char *name, dt_confgen_value_kind_t kind)
#define LINE_SIZE
void dt_conf_set_string(const char *name, const char *val)
float dt_conf_get_float_fast(const char *name)
const char * dt_conf_get_string_const(const char *name)
static char * dt_conf_get_var(const char *name)
const char * dt_confgen_get(const char *name, dt_confgen_value_kind_t kind)
#define CONFIG_DIR
void dt_conf_save(dt_conf_t *cf)
int64_t dt_conf_get_and_sanitize_int64(const char *name, int64_t min, int64_t max)
void dt_conf_set_folder_from_file_chooser(const char *name, GtkFileChooser *chooser)
dt_confgen_type_t dt_confgen_type(const char *name)
static void dt_conf_print(const gchar *key, const gchar *val, FILE *f)
gboolean dt_conf_is_equal(const char *name, const char *value)
const char * dt_confgen_get_label(const char *name)
gboolean dt_conf_get_folder_to_file_chooser(const char *name, GtkFileChooser *chooser)
float dt_conf_get_and_sanitize_float(const char *name, float min, float max)
gboolean dt_conf_key_not_empty(const char *name)
dt_confgen_value_kind_t
Definition conf.h:96
@ DT_DEFAULT
Definition conf.h:97
@ DT_MAX
Definition conf.h:99
@ DT_MIN
Definition conf.h:98
@ DT_VALUES
Definition conf.h:100
dt_confgen_type_t
Definition conf.h:59
@ DT_BOOL
Definition conf.h:63
@ DT_STRING
Definition conf.h:65
@ DT_FLOAT
Definition conf.h:62
@ DT_INT64
Definition conf.h:61
@ DT_ENUM
Definition conf.h:66
@ DT_PATH
Definition conf.h:64
@ DT_INT
Definition conf.h:60
darktable_t darktable
Definition darktable.c:215
static int dt_pthread_mutex_unlock(dt_pthread_mutex_t *mutex) RELEASE(mutex) NO_THREAD_SAFETY_ANALYSIS
Definition dtpthread.h:385
static int dt_pthread_mutex_init(dt_pthread_mutex_t *mutex, const pthread_mutexattr_t *mutexattr)
Definition dtpthread.h:370
static int dt_pthread_mutex_destroy(dt_pthread_mutex_t *mutex)
Definition dtpthread.h:390
static int dt_pthread_mutex_lock(dt_pthread_mutex_t *mutex) ACQUIRE(mutex) NO_THREAD_SAFETY_ANALYSIS
Definition dtpthread.h:375
gchar * dt_loc_get_home_dir(const gchar *user)
void dt_loc_get_user_config_dir(char *configdir, size_t bufsize)
#define STR(x)
Definition macros.h:45
#define IS_NULL_PTR(p)
C is way too permissive with !=, == and if(var) checks, which can mean too many things depending on w...
Definition macros.h:65
#define CLAMPS(A, L, H)
Definition math.h:78
static void dt_free_gpointer(gpointer ptr)
Definition mem_alloc.h:104
#define dt_free(ptr)
Definition mem_alloc.h:97
char * key
#define PATH_MAX
Definition paths.h:45
const char * name
Definition pdf.h:90
static const dt_aligned_pixel_simd_t value
Definition simd.h:144
struct dt_conf_t * conf
Definition darktable.h:180
const char * match
Definition common/conf.c:65
Definition conf.h:90
char * key
Definition conf.h:91
char * value
Definition conf.h:92
GHashTable * override_entries
Definition conf.h:86
char filename[PATH_MAX]
Definition conf.h:83
dt_pthread_mutex_t mutex
Definition conf.h:82
GHashTable * x_confgen
Definition conf.h:85
GHashTable * table
Definition conf.h:84
char * enum_values
Definition conf.h:75
char * shortdesc
Definition conf.h:76
dt_confgen_type_t type
Definition conf.h:71
char * longdesc
Definition conf.h:77
#define MIN(a, b)
Definition thinplate.c:32
#define MAX(a, b)
Definition thinplate.c:29
gchar * dt_util_normalize_path(const gchar *_input)
Definition utility.c:682