File: cfgvar.c

package info (click to toggle)
csound 1%3A6.18.1%2Bdfsg-4
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 63,220 kB
  • sloc: ansic: 192,643; cpp: 14,149; javascript: 9,654; objc: 9,181; python: 3,376; java: 3,337; sh: 1,840; yacc: 1,255; xml: 985; perl: 635; lisp: 411; tcl: 341; lex: 217; makefile: 128
file content (567 lines) | stat: -rw-r--r-- 19,739 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
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
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
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
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
/*
    cfgvar.c:

    Copyright (C) 2005 Istvan Varga

    This file is part of Csound.

    The Csound Library is free software; you can redistribute it
    and/or modify it under the terms of the GNU Lesser General Public
    License as published by the Free Software Foundation; either
    version 2.1 of the License, or (at your option) any later version.

    Csound 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 Lesser General Public License for more details.

    You should have received a copy of the GNU Lesser General Public
    License along with Csound; if not, write to the Free Software
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
    02110-1301 USA
*/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <math.h>

#include "csoundCore.h"
#include "cfgvar.h"
#include "namedins.h"

/* the global database */

/* list of error messages */

static const char *errmsg_list[] = {
    Str_noop("(no error)"),
    Str_noop("invalid variable name"),
    Str_noop("invalid variable type"),
    Str_noop("invalid flags specified"),
    Str_noop("NULL pointer argument"),
    Str_noop("the specified value is too high"),
    Str_noop("the specified value is too low"),
    Str_noop("the specified value is not an integer power of two"),
    Str_noop("invalid boolean value; must be 0 or 1"),
    Str_noop("memory allocation failed"),
    Str_noop("string exceeds maximum allowed length"),
    Str_noop("(unknown error)")
};

/* check if the specified name, and type and flags values are valid */

static int check_name(const char *name)
{
    int i, c;

    if (UNLIKELY(name == NULL))
      return CSOUNDCFG_INVALID_NAME;
    if (UNLIKELY(name[0] == '\0'))
      return CSOUNDCFG_INVALID_NAME;
    i = -1;
    while (name[++i] != '\0') {
      c = (int) ((unsigned char) name[i]);
      if (UNLIKELY((c & 0x80) || !(c == '_' || isalpha(c) || isdigit(c))))
        return CSOUNDCFG_INVALID_NAME;
    }
    return CSOUNDCFG_SUCCESS;
}

static int check_type(int type)
{
    switch (type) {
      case CSOUNDCFG_INTEGER:
      case CSOUNDCFG_BOOLEAN:
      case CSOUNDCFG_FLOAT:
      case CSOUNDCFG_DOUBLE:
      case CSOUNDCFG_MYFLT:
      case CSOUNDCFG_STRING:
        break;
      default:
        return CSOUNDCFG_INVALID_TYPE;
    }
    return CSOUNDCFG_SUCCESS;
}

static int check_flags(int flags)
{
    if (UNLIKELY((flags & (~(CSOUNDCFG_POWOFTWO))) != 0))
      return CSOUNDCFG_INVALID_FLAG;
    return CSOUNDCFG_SUCCESS;
}

/**
 * Allocate configuration variable structure with the specified parameters:
 *   name:    name of the variable (may contain letters, digits, and _)
 *   p:       pointer to variable
 *   type:    type of variable, determines how 'p' is interpreted
 *              CSOUNDCFG_INTEGER:      int*
 *              CSOUNDCFG_BOOLEAN:      int* (value may be 0 or 1)
 *              CSOUNDCFG_FLOAT:        float*
 *              CSOUNDCFG_DOUBLE:       double*
 *              CSOUNDCFG_MYFLT:        MYFLT*
 *              CSOUNDCFG_STRING:       char* (should have enough space)
 *   flags:   bitwise OR of flag values, currently only CSOUNDCFG_POWOFTWO
 *            is available, which requests CSOUNDCFG_INTEGER values to be
 *            power of two
 *   min:     for CSOUNDCFG_INTEGER, CSOUNDCFG_FLOAT, CSOUNDCFG_DOUBLE, and
 *            CSOUNDCFG_MYFLT, a pointer to a variable of the type selected
 *            by 'type' that specifies the minimum allowed value.
 *            If 'min' is NULL, there is no minimum value.
 *   max:     similar to 'min', except it sets the maximum allowed value.
 *            For CSOUNDCFG_STRING, it is a pointer to an int variable
 *            that defines the maximum length of the string (including the
 *            null character at the end) in bytes. This value is limited
 *            to the range 8 to 16384, and if max is NULL, it defaults to 256.
 *   shortDesc: a short description of the variable (may be NULL or an empty
 *            string if a description is not available)
 *   longDesc: a long description of the variable (may be NULL or an empty
 *            string if a description is not available)
 * A pointer to the newly allocated structure is stored in (*ptr).
 * Return value is CSOUNDCFG_SUCCESS, or one of the error codes.
 */

static int cfg_alloc_structure(CSOUND* csound,
                               csCfgVariable_t **ptr,
                               const char *name,
                               void *p, int type, int flags,
                               void *min, void *max,
                               const char *shortDesc, const char *longDesc)
{
    int     structBytes = 0, nameBytes, sdBytes, ldBytes, totBytes;
    void    *pp;
    unsigned char *sdp = NULL, *ldp = NULL;

    (*ptr) = (csCfgVariable_t*) NULL;
    /* check for valid parameters */
    if (UNLIKELY(p == NULL))
      return CSOUNDCFG_NULL_POINTER;
    if (UNLIKELY(check_name(name) != CSOUNDCFG_SUCCESS))
      return CSOUNDCFG_INVALID_NAME;
    if (UNLIKELY(check_type(type) != CSOUNDCFG_SUCCESS))
      return CSOUNDCFG_INVALID_TYPE;
    if (UNLIKELY(check_flags(flags) != CSOUNDCFG_SUCCESS))
      return CSOUNDCFG_INVALID_FLAG;
    /* calculate the number of bytes to allocate */
    structBytes = ((int) sizeof(csCfgVariable_t) + 15) & (~15);
    nameBytes = (((int) strlen(name) + 1) + 15) & (~15);
    if (shortDesc != NULL)
      sdBytes = (shortDesc[0] == '\0' ? 0 : (int) strlen(shortDesc) + 1);
    else
      sdBytes = 0;
    sdBytes = (sdBytes + 15) & (~15);
    if (longDesc != NULL)
      ldBytes = (longDesc[0] == '\0' ? 0 : (int) strlen(longDesc) + 1);
    else
      ldBytes = 0;
    ldBytes = (ldBytes + 15) & (~15);
    totBytes = structBytes + nameBytes + sdBytes + ldBytes;
    /* allocate memory */
    pp = (void*) csound->Calloc(csound, (size_t) totBytes);
    if (UNLIKELY(pp == NULL))
      return CSOUNDCFG_MEMORY;
    //memset(pp, 0, (size_t) totBytes);
    (*ptr) = (csCfgVariable_t*) pp;
    /* copy name and descriptions */
    strcpy(((char*) pp + (int) structBytes), name);
    if (sdBytes > 0) {
      sdp = (unsigned char*) pp + (int) (structBytes + nameBytes);
      strcpy((char*) sdp, shortDesc);
    }
    else
      sdp = NULL;
    if (ldBytes > 0) {
      ldp = (unsigned char*) pp + (int) (structBytes + nameBytes + sdBytes);
      strcpy((char*) ldp, longDesc);
    }
    else
      ldp = NULL;
    /* set up structure */
    (*ptr)->h.nxt = (csCfgVariable_t*) NULL;
    (*ptr)->h.name = (unsigned char*) pp + (int) structBytes;
    (*ptr)->h.p = p;
    (*ptr)->h.type = type;
    (*ptr)->h.flags = flags;
    (*ptr)->h.shortDesc = sdp;
    (*ptr)->h.longDesc = ldp;
    /* depending on type */
    switch (type) {
      case CSOUNDCFG_INTEGER:                                   /* integer */
        (*ptr)->i.min = (min == NULL ? -0x7FFFFFFF : *((int*) min));
        (*ptr)->i.max = (max == NULL ? 0x7FFFFFFF : *((int*) max));
        break;
      case CSOUNDCFG_BOOLEAN:                                   /* boolean */
        (*ptr)->b.flags &= (~(CSOUNDCFG_POWOFTWO));
        break;
      case CSOUNDCFG_FLOAT:                                     /* float */
        (*ptr)->f.flags &= (~(CSOUNDCFG_POWOFTWO));
        (*ptr)->f.min = (min == NULL ? -1.0e30f : *((float*) min));
        (*ptr)->f.max = (max == NULL ? 1.0e30f : *((float*) max));
        break;
      case CSOUNDCFG_DOUBLE:                                    /* double */
        (*ptr)->d.flags &= (~(CSOUNDCFG_POWOFTWO));
        (*ptr)->d.min = (min == NULL ? -1.0e30 : *((double*) min));
        (*ptr)->d.max = (max == NULL ? 1.0e30 : *((double*) max));
        break;
      case CSOUNDCFG_MYFLT:                                     /* MYFLT */
        (*ptr)->m.flags &= (~(CSOUNDCFG_POWOFTWO));
        (*ptr)->m.min = (min == NULL ? (MYFLT) -1.0e30 : *((MYFLT*) min));
        (*ptr)->m.max = (max == NULL ? (MYFLT) 1.0e30 : *((MYFLT*) max));
        break;
      case CSOUNDCFG_STRING:                                    /* string */
        (*ptr)->s.flags &= (~(CSOUNDCFG_POWOFTWO));
        if (max != NULL) {
          (*ptr)->s.maxlen = *((int*) max);
          if ((*ptr)->s.maxlen < 8) (*ptr)->s.maxlen = 8;
          if ((*ptr)->s.maxlen > 16384) (*ptr)->s.maxlen = 16384;
        }
        else
          (*ptr)->s.maxlen = 256;   /* default maximum string length */
        break;
    }
    /* done */
    return CSOUNDCFG_SUCCESS;
}

/**
 * This function is similar to csoundCreateGlobalConfigurationVariable(),
 * except it creates a configuration variable specific to Csound instance
 * 'csound', and is suitable for calling from the Csound library
 * (in csoundPreCompile()) or plugins (in csoundModuleCreate()).
 * The other parameters and return value are the same as in the case of
 * csoundCreateGlobalConfigurationVariable().
 */

PUBLIC int
  csoundCreateConfigurationVariable(CSOUND *csound, const char *name,
                                    void *p, int type, int flags,
                                    void *min, void *max,
                                    const char *shortDesc,
                                    const char *longDesc)
{
    csCfgVariable_t *pp;
    int             retval;

    /* check if name is already in use */
    if (UNLIKELY(csoundQueryConfigurationVariable(csound, name) != NULL))
      return CSOUNDCFG_INVALID_NAME;
    /* if database is not allocated yet, create an empty one */
    if (csound->cfgVariableDB == NULL) {
      csound->cfgVariableDB = cs_hash_table_create(csound);
      if (UNLIKELY(csound->cfgVariableDB == NULL))
        return CSOUNDCFG_MEMORY;
    }
    /* allocate structure */
    retval =  cfg_alloc_structure(csound, &pp, name, p, type, flags, min, max,
                                  shortDesc, longDesc);
    if (UNLIKELY(retval != CSOUNDCFG_SUCCESS))
      return retval;
    /* link into database */

    cs_hash_table_put(csound, csound->cfgVariableDB, (char*)name, pp);

    /* report success */
    return CSOUNDCFG_SUCCESS;
}

/* set configuration variable to value (with error checking) */

static int set_cfgvariable_value(csCfgVariable_t *pp, void *value)
{
    double  dVal;
    MYFLT   mVal;
    float   fVal;
    int     iVal;
    /* set value depending on type */
    if (UNLIKELY(value == NULL))
      return CSOUNDCFG_NULL_POINTER;
    switch (pp->h.type) {
      case CSOUNDCFG_INTEGER:
        iVal = *((int*) value);
        if (UNLIKELY(iVal < pp->i.min)) return CSOUNDCFG_TOO_LOW;
        if (UNLIKELY(iVal > pp->i.max)) return CSOUNDCFG_TOO_HIGH;
        if (pp->i.flags & CSOUNDCFG_POWOFTWO)
          if (UNLIKELY(iVal < 1 || (iVal & (iVal - 1)) != 0))
            return CSOUNDCFG_NOT_POWOFTWO;
        *(pp->i.p) = iVal;
        break;
      case CSOUNDCFG_BOOLEAN:
        iVal = *((int*) value);
        if (UNLIKELY(iVal & (~1))) return CSOUNDCFG_INVALID_BOOLEAN;
        *(pp->b.p) = iVal;
        break;
      case CSOUNDCFG_FLOAT:
        fVal = *((float*) value);
        if (UNLIKELY(fVal < pp->f.min)) return CSOUNDCFG_TOO_LOW;
        if (UNLIKELY(fVal > pp->f.max)) return CSOUNDCFG_TOO_HIGH;
        *(pp->f.p) = fVal;
        break;
      case CSOUNDCFG_DOUBLE:
        dVal = *((double*) value);
        if (UNLIKELY(dVal < pp->d.min)) return CSOUNDCFG_TOO_LOW;
        if (UNLIKELY(dVal > pp->d.max)) return CSOUNDCFG_TOO_HIGH;
        *(pp->d.p) = dVal;
        break;
      case CSOUNDCFG_MYFLT:
        mVal = *((MYFLT*) value);
        if (UNLIKELY(mVal < pp->m.min)) return CSOUNDCFG_TOO_LOW;
        if (UNLIKELY(mVal > pp->m.max)) return CSOUNDCFG_TOO_HIGH;
        *(pp->m.p) = mVal;
        break;
      case CSOUNDCFG_STRING:
        if (UNLIKELY((int) strlen((char*) value) >= (pp->s.maxlen - 1)))
          return CSOUNDCFG_STRING_LENGTH;
        strcpy((char*) (pp->s.p), (char*) value);
        break;
      default:
        return CSOUNDCFG_INVALID_TYPE;
    }
    return CSOUNDCFG_SUCCESS;
}

/**
 * Set the value of a configuration variable of Csound instance 'csound'.
 * The 'name' and 'value' parameters, and return value are the same as
 * in the case of csoundSetGlobalConfigurationVariable().
 */

PUBLIC int
  csoundSetConfigurationVariable(CSOUND *csound, const char *name, void *value)
{
    csCfgVariable_t *pp;

    /* get pointer to variable */
    pp = csoundQueryConfigurationVariable(csound, name);
    if (UNLIKELY(pp == NULL))
      return CSOUNDCFG_INVALID_NAME;    /* not found */
    return (set_cfgvariable_value(pp, value));
}

/* parse string value for configuration variable */

static int parse_cfg_variable(csCfgVariable_t *pp, const char *value)
{
    double  dVal;
    MYFLT   mVal;
    float   fVal;
    int     iVal;

    if (UNLIKELY(value == NULL))
      return CSOUNDCFG_NULL_POINTER;
    switch (pp->h.type) {
      case CSOUNDCFG_INTEGER:
        iVal = (int) atoi(value);
        return set_cfgvariable_value(pp, (void*) (&iVal));
      case CSOUNDCFG_BOOLEAN:
        if (strcmp(value, "0") == 0   ||
            strcmp(value, "no") == 0  || strcmp(value, "No") == 0  ||
            strcmp(value, "NO") == 0  || strcmp(value, "off") == 0 ||
            strcmp(value, "Off") == 0 || strcmp(value, "OFF") == 0 ||
            strcmp(value, "false") == 0 || strcmp(value, "False") == 0 ||
            strcmp(value, "FALSE") == 0)
          *(pp->b.p) = 0;
        else if (strcmp(value, "1") == 0   ||
                 strcmp(value, "yes") == 0 || strcmp(value, "Yes") == 0 ||
                 strcmp(value, "YES") == 0 || strcmp(value, "on") == 0  ||
                 strcmp(value, "On") == 0  || strcmp(value, "ON") == 0  ||
                 strcmp(value, "true") == 0 || strcmp(value, "True") == 0 ||
                 strcmp(value, "TRUE") == 0)
          *(pp->b.p) = 1;
        else
          return CSOUNDCFG_INVALID_BOOLEAN;
        return CSOUNDCFG_SUCCESS;
      case CSOUNDCFG_FLOAT:
        fVal = (float) atof(value);
        return set_cfgvariable_value(pp, (void*) (&fVal));
      case CSOUNDCFG_DOUBLE:
        dVal = (double) atof(value);
        return set_cfgvariable_value(pp, (void*) (&dVal));
      case CSOUNDCFG_MYFLT:
        mVal = (MYFLT) atof(value);
        return set_cfgvariable_value(pp, (void*) (&mVal));
      case CSOUNDCFG_STRING:
        return set_cfgvariable_value(pp, (void*) value);
    }
    return CSOUNDCFG_INVALID_TYPE;
}

/**
 * Set the value of a configuration variable of Csound instance 'csound',
 * by parsing a string.
 * The 'name' and 'value' parameters, and return value are the same as
 * in the case of csoundParseGlobalConfigurationVariable().
 */

PUBLIC int
  csoundParseConfigurationVariable(CSOUND *csound, const char *name,
                                                    const char *value)
{
    csCfgVariable_t *pp;

    /* get pointer to variable */
    pp = csoundQueryConfigurationVariable(csound, name);
    if (UNLIKELY(pp == NULL))
      return CSOUNDCFG_INVALID_NAME;    /* not found */
    return (parse_cfg_variable(pp, value));
}

/**
 * Return pointer to the configuration variable of Csound instace 'csound'
 * with the specified name.
 * The return value may be NULL if the variable is not found in the database.
 */

PUBLIC csCfgVariable_t
    *csoundQueryConfigurationVariable(CSOUND *csound, const char *name)
{
    if (csound->cfgVariableDB == NULL) {
        return NULL;
    }
    return (csCfgVariable_t*) cs_hash_table_get(csound,
                                                csound->cfgVariableDB, (char*)name);
}

/* compare function for qsort() */

static int compare_func(const void *p1, const void *p2)
{
    return (int) strcmp((char*) ((*((csCfgVariable_t**) p1))->h.name),
                        (char*) ((*((csCfgVariable_t**) p2))->h.name));
}

/* create alphabetically sorted list of all entries in 'db' */

static csCfgVariable_t **list_db_entries(CSOUND* csound, CS_HASH_TABLE *db)
{
    csCfgVariable_t **lst;
    size_t          cnt;
    CONS_CELL*      values;

    values = cs_hash_table_values(csound, db);
    cnt = cs_cons_length(values);


    /* allocate memory for list */
    lst = (csCfgVariable_t**) csound->Malloc(csound, sizeof(csCfgVariable_t*)
                                             * (cnt + (size_t) 1));
    if (UNLIKELY(lst == NULL))
      return (csCfgVariable_t**) NULL;  /* not enough memory */
    /* create list */
    if (cnt) {
      cnt = 0;
        while (values != NULL) {
            lst[cnt++] = (csCfgVariable_t*)values->value;
            values = values->next;
        }
        qsort((void*) lst, cnt, sizeof(csCfgVariable_t*), compare_func);
    }

    lst[cnt] = (csCfgVariable_t*) NULL;
    /* return pointer to list */
    return lst;
}

/**
 * Create an alphabetically sorted list of all configuration variables
 * of Csound instance 'csound'.
 * Returns a pointer to a NULL terminated array of configuration variable
 * pointers, or NULL on error.
 * The caller is responsible for freeing the returned list with
 * csoundDeleteCfgVarList(), however, the variable pointers in the list
 * should not be freed.
 */

PUBLIC csCfgVariable_t **csoundListConfigurationVariables(CSOUND *csound)
{
    return (list_db_entries(csound, csound->cfgVariableDB));
}

/**
 * Release a configuration variable list previously returned
 * by csoundListGlobalConfigurationVariables() or
 * csoundListConfigurationVariables().
 */

PUBLIC void csoundDeleteCfgVarList(CSOUND* csound, csCfgVariable_t **lst)
{
    if (lst != NULL)
      csound->Free(csound, lst);
}

/* remove a configuration variable from 'db' */

static int remove_entry_from_db(CSOUND* csound, CS_HASH_TABLE *db, const char *name)
{
    csCfgVariable_t *pp = cs_hash_table_get(csound, db, (char*)name);

    if (UNLIKELY(pp == NULL))
        return CSOUNDCFG_INVALID_NAME;

    csound->Free(csound, pp);
    cs_hash_table_remove(csound, db, (char*)name);

    return CSOUNDCFG_SUCCESS;
}

/**
 * Remove the configuration variable of Csound instance 'csound' with the
 * specified name from the database. Plugins need not call this, as all
 * configuration variables are automatically deleted by csoundReset().
 * Return value is CSOUNDCFG_SUCCESS in case of success, or
 * CSOUNDCFG_INVALID_NAME if the variable was not found.
 */

PUBLIC int csoundDeleteConfigurationVariable(CSOUND *csound, const char *name)
{
    return remove_entry_from_db(csound, csound->cfgVariableDB, name);
}

static int destroy_entire_db(CSOUND *csound, CS_HASH_TABLE *db)
{
    CONS_CELL *head, *current;
    if (db == NULL)
      return CSOUNDCFG_SUCCESS;

    head = current = cs_hash_table_values(csound, db);

    while (current != NULL) {
        if (current->value != NULL) {
             csound->Free(csound, current->value);
        }
        current = current->next;
    }

    cs_cons_free(csound, head);
    cs_hash_table_free(csound, db);

    return CSOUNDCFG_SUCCESS;
}

/**
 * Remove all configuration variables of Csound instance 'csound'
 * and free database. This function is called by csoundReset().
 * Return value is CSOUNDCFG_SUCCESS in case of success.
 */

int csoundDeleteAllConfigurationVariables(CSOUND *csound)
{
    int retval;
    retval = destroy_entire_db(csound, csound->cfgVariableDB);
    csound->cfgVariableDB = NULL;
    return retval;
}

/**
 * Returns pointer to an error string constant for the specified
 * CSOUNDCFG error code. The string is not translated.
 */

PUBLIC const char *csoundCfgErrorCodeToString(int errcode)
{
    if (errcode > 0 || errcode < CSOUNDCFG_LASTERROR)
      return errmsg_list[1 - CSOUNDCFG_LASTERROR];      /* unknown */
    else
      return errmsg_list[(-errcode)];
}