/[gxemul]/trunk/src/settings.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Diff of /trunk/src/settings.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 28 by dpavlin, Mon Oct 8 16:20:26 2007 UTC revision 32 by dpavlin, Mon Oct 8 16:20:58 2007 UTC
# Line 25  Line 25 
25   *  SUCH DAMAGE.   *  SUCH DAMAGE.
26   *   *
27   *   *
28   *  $Id: settings.c,v 1.7 2006/07/15 10:06:11 debug Exp $   *  $Id: settings.c,v 1.14 2006/09/21 11:53:26 debug Exp $
29   *   *
30   *  A generic settings object. (This module should be 100% indepedent of GXemul   *  A generic settings object. (This module should be 100% indepedent of GXemul
31   *  and hence easily reusable.)  It is basically a tree structure of nodes,   *  and hence easily reusable.)  It is basically a tree structure of nodes,
# Line 34  Line 34 
34   *  or to a variable in memory.   *  or to a variable in memory.
35   *   *
36   *  Appart from the pointer, the other properties are a definition of the   *  Appart from the pointer, the other properties are a definition of the
37   *  type being pointed to (int, int32_t, int64_t, etc), how it should be   *  type being pointed to (int, int32_t, int64_t, char*, etc), how it should be
38   *  presented (e.g. it may be an int value in memory, but it should be   *  presented (e.g. it may be an int value in memory, but it should be
39   *  presented as a boolean "true/false" value), and a flag which tells us   *  presented as a boolean "true/false" value), and a flag which tells us
40   *  whether the setting is directly writable or not.   *  whether the setting is directly writable or not.
# Line 43  Line 43 
43   *  settings_destroy() is called if individual settings have not yet been   *  settings_destroy() is called if individual settings have not yet been
44   *  deleted. (This is to help making sure that code which uses the settings   *  deleted. (This is to help making sure that code which uses the settings
45   *  subsystem correctly un-initializes stuff.)   *  subsystem correctly un-initializes stuff.)
  *  
  *  
  *  TODO:  
  *      Remove a setting  
  *      Read/write settings  
46   */   */
47    
48  #include <stdio.h>  #include <stdio.h>
# Line 62  Line 57 
57    
58    
59  struct settings {  struct settings {
60            struct settings         *parent;
61            char                    *name_in_parent;
62    
63          int                     n_settings;          int                     n_settings;
64    
65          /*          /*
# Line 108  struct settings *settings_new(void) Line 106  struct settings *settings_new(void)
106  /*  /*
107   *  settings_destroy():   *  settings_destroy():
108   *   *
109   *  Frees all resources occupied by a settings object.   *  Frees all resources occupied by a settings object. Also, if this settings
110     *  object has a parent, then remove it from the parent.
111   */   */
112  void settings_destroy(struct settings *settings)  void settings_destroy(struct settings *settings)
113  {  {
# Line 157  void settings_destroy(struct settings *s Line 156  void settings_destroy(struct settings *s
156          if (settings->ptr != NULL)          if (settings->ptr != NULL)
157                  free(settings->ptr);                  free(settings->ptr);
158    
159            if (settings->parent != NULL) {
160                    settings_remove(settings->parent, settings->name_in_parent);
161                    free(settings->name_in_parent);
162            }
163    
164          free(settings);          free(settings);
165  }  }
166    
167    
168  /*  /*
169     *  settings_read():
170     *
171     *  Used internally by settings_access() and settings_debugdump().
172     */
173    static int settings_read(struct settings *settings, int i, uint64_t *valuep)
174    {
175            *valuep = 0;
176    
177            switch (settings->storage_type[i]) {
178            case SETTINGS_TYPE_INT:
179                    *valuep = *((int *) settings->ptr[i]);
180                    break;
181            case SETTINGS_TYPE_INT8:
182                    *valuep = *((int8_t *) settings->ptr[i]);
183                    break;
184            case SETTINGS_TYPE_INT16:
185                    *valuep = *((int16_t *) settings->ptr[i]);
186                    break;
187            case SETTINGS_TYPE_INT32:
188                    *valuep = *((int32_t *) settings->ptr[i]);
189                    break;
190            case SETTINGS_TYPE_INT64:
191                    *valuep = *((int64_t *) settings->ptr[i]);
192                    break;
193            case SETTINGS_TYPE_UINT:
194                    *valuep = *((uint *) settings->ptr[i]);
195                    break;
196            case SETTINGS_TYPE_UINT8:
197                    *valuep = *((uint8_t *) settings->ptr[i]);
198                    break;
199            case SETTINGS_TYPE_UINT16:
200                    *valuep = *((uint16_t *) settings->ptr[i]);
201                    break;
202            case SETTINGS_TYPE_UINT32:
203                    *valuep = *((uint32_t *) settings->ptr[i]);
204                    break;
205            case SETTINGS_TYPE_UINT64:
206                    *valuep = *((uint64_t *) settings->ptr[i]);
207                    break;
208            case SETTINGS_TYPE_STRING:
209                    /*  Note: Strings cannot be read like this.  */
210                    break;
211            default:printf("settings_read(): FATAL ERROR! Unknown storage type"
212                        ": %i\n", settings->storage_type[i]);
213                    exit(1);
214            }
215    
216            return SETTINGS_OK;
217    }
218    
219    
220    /*
221     *  settings_write():
222     *
223     *  Used internally by settings_access().
224     */
225    static int settings_write(struct settings *settings, int i, uint64_t *valuep)
226    {
227            if (!settings->writable[i])
228                    return SETTINGS_READONLY;
229    
230            switch (settings->storage_type[i]) {
231            case SETTINGS_TYPE_INT:
232            case SETTINGS_TYPE_UINT:
233                    *((int *) settings->ptr[i]) = *valuep;
234                    break;
235            case SETTINGS_TYPE_INT8:
236            case SETTINGS_TYPE_UINT8:
237                    *((int8_t *) settings->ptr[i]) = *valuep;
238                    break;
239            case SETTINGS_TYPE_INT16:
240            case SETTINGS_TYPE_UINT16:
241                    *((int16_t *) settings->ptr[i]) = *valuep;
242                    break;
243            case SETTINGS_TYPE_INT32:
244            case SETTINGS_TYPE_UINT32:
245                    *((int32_t *) settings->ptr[i]) = *valuep;
246                    break;
247            case SETTINGS_TYPE_INT64:
248            case SETTINGS_TYPE_UINT64:
249                    *((int64_t *) settings->ptr[i]) = *valuep;
250                    break;
251            case SETTINGS_TYPE_STRING:
252                    /*  Note: Strings cannot be read like this.  */
253                    printf("settings_write(): ERROR! Strings cannot be "
254                        "written like this.\n");
255                    break;
256            default:printf("settings_read(): FATAL ERROR! Unknown storage type"
257                        ": %i\n", settings->storage_type[i]);
258                    exit(1);
259            }
260    
261            return SETTINGS_OK;
262    }
263    
264    
265    /*
266   *  settings_debugdump():   *  settings_debugdump():
267   *   *
268   *  Dump settings in a settings object to stdout.   *  Dump settings in a settings object to stdout.
# Line 173  void settings_debugdump(struct settings Line 274  void settings_debugdump(struct settings
274          size_t name_buflen = strlen(prefix) + 100;          size_t name_buflen = strlen(prefix) + 100;
275          char *name = malloc(name_buflen);          char *name = malloc(name_buflen);
276          int i;          int i;
277          uint64_t value;          uint64_t value = 0;
278    
279          for (i=0; i<settings->n_settings; i++) {          for (i=0; i<settings->n_settings; i++) {
280                  snprintf(name, name_buflen, "%s.%s", prefix, settings->name[i]);                  snprintf(name, name_buflen, "%s.%s", prefix, settings->name[i]);
# Line 186  void settings_debugdump(struct settings Line 287  void settings_debugdump(struct settings
287                          /*  Normal value:  */                          /*  Normal value:  */
288                          printf("%s = ", name);                          printf("%s = ", name);
289    
290                          switch (settings->storage_type[i]) {                          settings_read(settings, i, &value);
                         case SETTINGS_TYPE_INT:  
                                 value = *((int *) settings->ptr[i]);  
                                 break;  
                         case SETTINGS_TYPE_INT32:  
                                 value = *((int32_t *) settings->ptr[i]);  
                                 break;  
                         case SETTINGS_TYPE_INT64:  
                                 value = *((int64_t *) settings->ptr[i]);  
                                 break;  
                         default:printf("FATAL ERROR! Unknown storage type"  
                                     ": %i\n", settings->storage_type[i]);  
                                 exit(1);  
                         }  
291    
292                          switch (settings->presentation_format[i]) {                          switch (settings->presentation_format[i]) {
293                          case SETTINGS_FORMAT_DECIMAL:                          case SETTINGS_FORMAT_DECIMAL:
294                                  printf("%"PRIi64, value);                                  printf("%"PRIi64, value);
295                                  break;                                  break;
296                          case SETTINGS_FORMAT_HEX:                          case SETTINGS_FORMAT_HEX8:
297                                  printf("0x%"PRIx64, value);                                  printf("0x%02"PRIx8, (int8_t) value);
298                                    break;
299                            case SETTINGS_FORMAT_HEX16:
300                                    printf("0x%04"PRIx16, (int16_t) value);
301                                    break;
302                            case SETTINGS_FORMAT_HEX32:
303                                    printf("0x%08"PRIx32, (int32_t) value);
304                                    break;
305                            case SETTINGS_FORMAT_HEX64:
306                                    printf("0x%016"PRIx64, (int64_t) value);
307                                  break;                                  break;
308                          case SETTINGS_FORMAT_BOOL:                          case SETTINGS_FORMAT_BOOL:
309                                  printf(value? "true" : "false");                                  printf(value? "true" : "false");
# Line 214  void settings_debugdump(struct settings Line 311  void settings_debugdump(struct settings
311                          case SETTINGS_FORMAT_YESNO:                          case SETTINGS_FORMAT_YESNO:
312                                  printf(value? "yes" : "no");                                  printf(value? "yes" : "no");
313                                  break;                                  break;
314                            case SETTINGS_FORMAT_STRING:
315                                    printf("\"%s\"", *((char **)settings->ptr[i]));
316                                    break;
317                          default:printf("FATAL ERROR! Unknown presentation "                          default:printf("FATAL ERROR! Unknown presentation "
318                                      "format: %i\n",                                      "format: %i\n",
319                                      settings->presentation_format[i]);                                      settings->presentation_format[i]);
# Line 221  void settings_debugdump(struct settings Line 321  void settings_debugdump(struct settings
321                          }                          }
322    
323                          if (!settings->writable[i])                          if (!settings->writable[i])
324                                  printf("  (Read-only)");                                  printf("  (R/O)");
325    
326                          printf("\n");                          printf("\n");
327                  }                  }
# Line 239  void settings_debugdump(struct settings Line 339  void settings_debugdump(struct settings
339  void settings_add(struct settings *settings, const char *name, int writable,  void settings_add(struct settings *settings, const char *name, int writable,
340          int type, int format, void *ptr)          int type, int format, void *ptr)
341  {  {
342            int i;
343    
344            for (i=0; i<settings->n_settings; i++) {
345                    if (strcmp(settings->name[i], name) == 0)
346                            break;
347            }
348    
349            if (i < settings->n_settings) {
350                    fprintf(stderr, "settings_add(): name '%s' is already"
351                        " in use\n", name);
352                    exit(1);
353            }
354    
355          settings->n_settings ++;          settings->n_settings ++;
356    
357          if ((settings->name = realloc(settings->name, settings->n_settings          if ((settings->name = realloc(settings->name, settings->n_settings
# Line 258  void settings_add(struct settings *setti Line 371  void settings_add(struct settings *setti
371                  goto out_of_mem;                  goto out_of_mem;
372    
373          settings->name[settings->n_settings - 1] = strdup(name);          settings->name[settings->n_settings - 1] = strdup(name);
374            if (settings->name[settings->n_settings - 1] == NULL)
375                    goto out_of_mem;
376          settings->writable[settings->n_settings - 1] = writable;          settings->writable[settings->n_settings - 1] = writable;
377          settings->storage_type[settings->n_settings - 1] = type;          settings->storage_type[settings->n_settings - 1] = type;
378          settings->presentation_format[settings->n_settings - 1] = format;          settings->presentation_format[settings->n_settings - 1] = format;
379          settings->ptr[settings->n_settings - 1] = ptr;          settings->ptr[settings->n_settings - 1] = ptr;
380    
381            if (type == SETTINGS_TYPE_SUBSETTINGS) {
382                    ((struct settings *)ptr)->parent = settings;
383                    ((struct settings *)ptr)->name_in_parent = strdup(name);
384                    if (((struct settings *)ptr)->name_in_parent == NULL)
385                            goto out_of_mem;
386            }
387    
388          return;          return;
389    
390  out_of_mem:  out_of_mem:
# Line 271  out_of_mem: Line 393  out_of_mem:
393  }  }
394    
395    
396    /*
397     *  settings_remove():
398     *
399     *  Remove a setting from a settings object.
400     */
401    void settings_remove(struct settings *settings, const char *name)
402    {
403            int i, m;
404    
405            for (i=0; i<settings->n_settings; i++) {
406                    if (strcmp(settings->name[i], name) == 0)
407                            break;
408            }
409    
410            if (i >= settings->n_settings) {
411    #ifdef UNSTABLE_DEVEL
412                    fprintf(stderr, "settings_remove(): attempting to remove"
413                        " non-existant setting '%s'\n", name);
414    #endif
415                    return;
416            }
417    
418            /*  Check subsettings specifically:  */
419            if (settings->storage_type[i] == SETTINGS_TYPE_SUBSETTINGS &&
420                settings->ptr[i] != NULL) {
421                    struct settings *subsettings = settings->ptr[i];
422                    if (subsettings->n_settings != 0) {
423                            fprintf(stderr, "settings_remove(): attempting to "
424                                "remove non-emtpy setting '%s'\n", name);
425                            fprintf(stderr, "Remaining settings are:\n");
426                            for (i=0; i<subsettings->n_settings; i++)
427                                    fprintf(stderr, "\t%s\n", subsettings->name[i]);
428                            exit(1);
429                    }
430            }
431    
432            settings->n_settings --;
433            free(settings->name[i]);
434    
435            m = settings->n_settings - i;
436            if (m == 0)
437                    return;
438    
439            memmove(&settings->name[i], &settings->name[i+1],
440                m * sizeof(settings->name[0]));
441            memmove(&settings->writable[i], &settings->writable[i+1],
442                m * sizeof(settings->writable[0]));
443            memmove(&settings->storage_type[i], &settings->storage_type[i+1],
444                m * sizeof(settings->storage_type[0]));
445            memmove(&settings->presentation_format[i],
446                &settings->presentation_format[i+1],
447                m * sizeof(settings->presentation_format[0]));
448            memmove(&settings->ptr[i], &settings->ptr[i+1],
449                m * sizeof(settings->ptr[0]));
450    }
451    
452    
453    /*
454     *  settings_remove_all():
455     *
456     *  Remove all (level-1) settings from a settings object. By level-1, I mean
457     *  all settings that do not contain subsettings.
458     */
459    void settings_remove_all(struct settings *settings)
460    {
461            while (settings->n_settings > 0)
462                    settings_remove(settings, settings->name[0]);
463    }
464    
465    
466    /*
467     *  settings_access():
468     *
469     *  Read or write a setting. fullname may be something like "settings.x.y".
470     *  When writing a value, valuebuf should point to a uint64_t containing the
471     *  new value (note: always a uint64_t). When reading a value, valuebuf should
472     *  point to a uint64_t where the value will be stored.
473     *
474     *  The return value is one of the following:
475     *
476     *      SETTINGS_OK
477     *              The value was read or written.
478     *
479     *      SETTINGS_NAME_NOT_FOUND
480     *              The name was not found in the settings object.
481     *
482     *      SETTINGS_READONLY
483     *              The name was found, but it was marked as read-only, and
484     *              an attempt was made to write to it.
485     */
486    int settings_access(struct settings *settings, const char *fullname,
487            int writeflag, uint64_t *valuep)
488    {
489            int i;
490    
491            /*  printf("settings_access(fullname='%s')\n", fullname);  */
492    
493            if (strncmp(fullname, GLOBAL_SETTINGS_NAME".",
494                strlen(GLOBAL_SETTINGS_NAME) + 1) == 0)
495                    fullname += strlen(GLOBAL_SETTINGS_NAME) + 1;
496    
497            for (i=0; i<settings->n_settings; i++) {
498                    size_t settings_name_len = strlen(settings->name[i]);
499    
500                    if (strncmp(fullname, settings->name[i],
501                        settings_name_len) != 0)
502                            continue;
503    
504                    /*  Found the correct setting?  */
505                    if (fullname[settings_name_len] == '\0') {
506                            if (writeflag)
507                                    return settings_write(settings, i, valuep);
508                            else
509                                    return settings_read(settings, i, valuep);
510                    }
511    
512                    /*  Found a setting which has sub-settings?  */
513                    if (fullname[settings_name_len] == '.') {
514                            /*  Recursive search:  */
515                            return settings_access(
516                                (struct settings *)settings->ptr[i],
517                                fullname + settings_name_len + 1,
518                                writeflag, valuep);
519                    }
520            }
521    
522            return SETTINGS_NAME_NOT_FOUND;
523    }
524    

Legend:
Removed from v.28  
changed lines
  Added in v.32

  ViewVC Help
Powered by ViewVC 1.1.26