Imported Upstream version 1.12.0
[platform/upstream/augeas.git] / src / internal.h
1 /*
2  * internal.h: Useful definitions
3  *
4  * Copyright (C) 2007-2017 David Lutterkort
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
19  *
20  * Author: David Lutterkort <dlutter@redhat.com>
21  */
22
23 #ifndef INTERNAL_H_
24 #define INTERNAL_H_
25
26 #include "list.h"
27 #include "datadir.h"
28 #include "augeas.h"
29
30 #include <stdio.h>
31 #include <string.h>
32 #include <strings.h>
33 #include <stdlib.h>
34 #include <stdbool.h>
35 #include <unistd.h>
36 #include <errno.h>
37 #include <assert.h>
38 #include <locale.h>
39 #include <stdint.h>
40
41 /*
42  * Various parameters about env vars, special tree nodes etc.
43  */
44
45 /* Define: AUGEAS_LENS_DIR
46  * The default location for lens definitions */
47 #define AUGEAS_LENS_DIR DATADIR "/augeas/lenses"
48
49 /* The directory where we install lenses distribute with Augeas */
50 #define AUGEAS_LENS_DIST_DIR DATADIR "/augeas/lenses/dist"
51
52 /* Define: AUGEAS_ROOT_ENV
53  * The env var that points to the chroot holding files we may modify.
54  * Mostly useful for testing */
55 #define AUGEAS_ROOT_ENV "AUGEAS_ROOT"
56
57 /* Define: AUGEAS_FILES_TREE
58  * The root for actual file contents */
59 #define AUGEAS_FILES_TREE "/files"
60
61 /* Define: AUGEAS_META_TREE
62  * Augeas reports some information in this subtree */
63 #define AUGEAS_META_TREE "/augeas"
64
65 /* Define: AUGEAS_META_FILES
66  * Information about files */
67 #define AUGEAS_META_FILES AUGEAS_META_TREE AUGEAS_FILES_TREE
68
69 /* Define: AUGEAS_META_TEXT
70  * Information about text (see aug_text_store and aug_text_retrieve) */
71 #define AUGEAS_META_TEXT AUGEAS_META_TREE "/text"
72
73 /* Define: AUGEAS_META_ROOT
74  * The root directory */
75 #define AUGEAS_META_ROOT AUGEAS_META_TREE "/root"
76
77 /* Define: AUGEAS_META_SAVE_MODE
78  * How we save files. One of 'backup', 'overwrite' or 'newfile' */
79 #define AUGEAS_META_SAVE_MODE AUGEAS_META_TREE "/save"
80
81 /* Define: AUGEAS_CLONE_IF_RENAME_FAILS
82  * Control what save does when renaming the temporary file to its final
83  * destination fails with EXDEV or EBUSY: when this tree node exists, copy
84  * the file contents. If it is not present, simply give up and report an
85  * error.  */
86 #define AUGEAS_COPY_IF_RENAME_FAILS \
87     AUGEAS_META_SAVE_MODE "/copy_if_rename_fails"
88
89 /* Define: AUGEAS_CONTEXT
90  * Context prepended to all non-absolute paths */
91 #define AUGEAS_CONTEXT AUGEAS_META_TREE "/context"
92
93 /* A hierarchy where we record certain 'events', e.g. which tree
94  * nodes actually gotsaved into files */
95 #define AUGEAS_EVENTS AUGEAS_META_TREE "/events"
96
97 #define AUGEAS_EVENTS_SAVED AUGEAS_EVENTS "/saved"
98
99 /* Where to put information about parsing of path expressions */
100 #define AUGEAS_META_PATHX AUGEAS_META_TREE "/pathx"
101
102 /* Define: AUGEAS_SPAN_OPTION
103  * Enable or disable node indexes */
104 #define AUGEAS_SPAN_OPTION AUGEAS_META_TREE "/span"
105
106 /* Define: AUGEAS_LENS_ENV
107  * Name of env var that contains list of paths to search for additional
108    spec files */
109 #define AUGEAS_LENS_ENV "AUGEAS_LENS_LIB"
110
111 /* Define: MAX_ENV_SIZE
112  * Fairly arbitrary bound on the length of the path we
113  *  accept from AUGEAS_SPEC_ENV */
114 #define MAX_ENV_SIZE 4096
115
116 /* Define: PATH_SEP_CHAR
117  * Character separating paths in a list of paths */
118 #define PATH_SEP_CHAR ':'
119
120 /* Constants for setting the save mode via the augeas path at
121  * AUGEAS_META_SAVE_MODE */
122 #define AUG_SAVE_BACKUP_TEXT "backup"
123 #define AUG_SAVE_NEWFILE_TEXT "newfile"
124 #define AUG_SAVE_NOOP_TEXT "noop"
125 #define AUG_SAVE_OVERWRITE_TEXT "overwrite"
126
127 /* constants for options in the tree */
128 #define AUG_ENABLE "enable"
129 #define AUG_DISABLE "disable"
130
131 /* default value for the relative path context */
132 #define AUG_CONTEXT_DEFAULT "/files"
133
134 #ifdef __GNUC__
135
136 #ifndef __GNUC_PREREQ
137 #define __GNUC_PREREQ(maj,min) 0
138 #endif
139
140 /**
141 * AUGEAS_LIKELY:
142 *
143 * Macro to flag a code branch as a likely branch
144 *
145 * AUGEAS_UNLIKELY:
146 *
147 * Macro to flag a code branch as an unlikely branch
148 */
149 #ifndef __has_builtin
150 #   define __has_builtin(x) (0)
151 #endif
152 #if defined(__builtin_expect) || __has_builtin(__builtin_expect)
153 #   define AUGEAS_LIKELY(x)        (__builtin_expect(!!(x), 1))
154 #   define AUGEAS_UNLIKELY(x)      (__builtin_expect(!!(x), 0))
155 #else
156 #   define AUGEAS_LIKELY(x)        (x)
157 #   define AUGEAS_UNLIKELY(x)      (x)
158 #endif
159
160 /**
161  * ATTRIBUTE_UNUSED:
162  *
163  * Macro to flag conciously unused parameters to functions
164  */
165 #ifndef ATTRIBUTE_UNUSED
166 #define ATTRIBUTE_UNUSED __attribute__((__unused__))
167 #endif
168
169 /**
170  * ATTRIBUTE_FORMAT
171  *
172  * Macro used to check printf/scanf-like functions, if compiling
173  * with gcc.
174  */
175 #ifndef ATTRIBUTE_FORMAT
176 #define ATTRIBUTE_FORMAT(args...) __attribute__((__format__ (args)))
177 #endif
178
179 #ifndef ATTRIBUTE_PURE
180 #define ATTRIBUTE_PURE __attribute__((pure))
181 #endif
182
183 #ifndef ATTRIBUTE_RETURN_CHECK
184 #if __GNUC_PREREQ (3, 4)
185 #define ATTRIBUTE_RETURN_CHECK __attribute__((__warn_unused_result__))
186 #else
187 #define ATTRIBUTE_RETURN_CHECK
188 #endif
189 #endif
190
191 /* Allow falling through in switch statements for the few cases where that
192    is needed */
193 #ifndef ATTRIBUTE_FALLTHROUGH
194 #  if __GNUC_PREREQ (7, 0)
195 #    define ATTRIBUTE_FALLTHROUGH __attribute__ ((fallthrough))
196 #  else
197 #    define ATTRIBUTE_FALLTHROUGH
198 #  endif
199 #endif
200
201 /* A poor man's macro to get some move semantics: return the value of P but
202    set P itself to NULL. This has the effect that if you say 'x = move(y)'
203    that there is still only one pointer pointing to the memory Y pointed to
204    initially.
205  */
206 #define move(p) ({ typeof(p) _tmp = (p); (p) = NULL; _tmp; })
207
208 #else
209 #define ATTRIBUTE_UNUSED
210 #define ATTRIBUTE_FORMAT(...)
211 #define ATTRIBUTE_PURE
212 #define ATTRIBUTE_RETURN_CHECK
213 #define ATTRIBUTE_FALLTHROUGH
214 #define move(p) p
215 #endif                                   /* __GNUC__ */
216
217 #define ARRAY_CARDINALITY(array) (sizeof (array) / sizeof *(array))
218
219 /* String equality tests, suggested by Jim Meyering. */
220 #define STREQ(a,b) (strcmp((a),(b)) == 0)
221 #define STRCASEEQ(a,b) (strcasecmp((a),(b)) == 0)
222 #define STRCASEEQLEN(a,b,n) (strncasecmp((a),(b),(n)) == 0)
223 #define STRNEQ(a,b) (strcmp((a),(b)) != 0)
224 #define STRCASENEQ(a,b) (strcasecmp((a),(b)) != 0)
225 #define STREQLEN(a,b,n) (strncmp((a),(b),(n)) == 0)
226 #define STRNEQLEN(a,b,n) (strncmp((a),(b),(n)) != 0)
227
228 ATTRIBUTE_PURE
229 static inline int streqv(const char *a, const char *b) {
230     if (a == NULL || b == NULL)
231         return a == b;
232     return STREQ(a,b);
233 }
234
235 /* Path length and comparison */
236
237 #define SEP '/'
238
239 /* Length of PATH without any trailing '/' */
240 ATTRIBUTE_PURE
241 static inline int pathlen(const char *path) {
242     int len = strlen(path);
243
244     if (len > 0 && path[len-1] == SEP)
245         len--;
246
247     return len;
248 }
249
250 /* Return 1 if P1 is a prefix of P2. P1 as a string must have length <= P2 */
251 ATTRIBUTE_PURE
252 static inline int pathprefix(const char *p1, const char *p2) {
253     if (p1 == NULL || p2 == NULL)
254         return 0;
255     int l1 = pathlen(p1);
256
257     return STREQLEN(p1, p2, l1) && (p2[l1] == '\0' || p2[l1] == SEP);
258 }
259
260 static inline int pathendswith(const char *path, const char *basenam) {
261     const char *p = strrchr(path, SEP);
262     if (p == NULL)
263         return 0;
264     return streqv(p+1, basenam);
265 }
266
267 /* Join NSEG path components (passed as const char *) into one PATH.
268    Allocate as needed. Return 0 on success, -1 on failure */
269 int pathjoin(char **path, int nseg, ...);
270
271 #define MEMZERO(ptr, n) memset((ptr), 0, (n) * sizeof(*(ptr)));
272
273 #define MEMMOVE(dest, src, n) memmove((dest), (src), (n) * sizeof(*(src)))
274
275 /**
276  * TODO:
277  *
278  * macro to flag unimplemented blocks
279  */
280 #define TODO                                                            \
281     fprintf(stderr, "%s:%d Unimplemented block\n",                      \
282             __FILE__, __LINE__);
283
284 #define FIXME(msg, args ...)                            \
285     do {                                                \
286         fprintf(stderr, "%s:%d Fixme: ",                \
287                 __FILE__, __LINE__);                    \
288       fprintf(stderr, msg, ## args);                    \
289       fputc('\n', stderr);                              \
290     } while(0)
291
292 /*
293  * Internal data structures
294  */
295
296 // internal.c
297
298 /* Function: escape
299  * Escape nonprintable characters within TEXT, similar to how it's done in
300  * C string literals. Caller must free the returned string.
301  */
302 char *escape(const char *text, int cnt, const char *extra);
303
304 /* Function: unescape */
305 char *unescape(const char *s, int len, const char *extra);
306
307 /* Extra characters to be escaped in strings and regexps respectively */
308 #define STR_ESCAPES "\"\\"
309 #define RX_ESCAPES  "/\\"
310
311 /* Function: print_chars */
312 int print_chars(FILE *out, const char *text, int cnt);
313
314 /* Function: print_pos
315  * Print a pretty representation of being at position POS within TEXT */
316 void print_pos(FILE *out, const char *text, int pos);
317 char *format_pos(const char *text, int pos);
318
319 /* Function: xread_file
320  * Read the contents of file PATH and return them as one long string. The
321  * caller must free the result. Return NULL if any error occurs.
322  */
323 char* xread_file(const char *path);
324
325 /* Like xread_file, but caller supplies a file pointer */
326 char* xfread_file(FILE *fp);
327
328 /* Get the error message for ERRNUM in a threadsafe way. Based on libvirt's
329  * virStrError
330  */
331 const char *xstrerror(int errnum, char *buf, size_t len);
332
333 /* Like asprintf, but set *STRP to NULL on error */
334 int xasprintf(char **strp, const char *format, ...);
335
336 /* Convert S to RESULT with error checking */
337 int xstrtoint64(char const *s, int base, int64_t *result);
338
339 /* Calculate line and column number of character POS in TEXT */
340 void calc_line_ofs(const char *text, size_t pos, size_t *line, size_t *ofs);
341
342 /* Cleans path from user, removing trailing slashes and whitespace */
343 char *cleanpath(char *path);
344
345 /* Take the first LEN characters from the regexp *U and expand any
346  * character ranges in it. The expanded regexp, if expansion is necessary,
347  * is in U, and the old string is freed. If expansion is not needed or an
348  * error happens, U will be unchanged.
349  *
350  * Return 0 if expansion is not necessary, -1 if an error occurs, and 1 if
351  * expansion was needed.
352  */
353 int regexp_c_locale(char **u, size_t *len);
354
355 /* Struct: augeas
356  * The data structure representing a connection to Augeas. */
357 struct augeas {
358     struct tree      *origin;     /* Actual tree root is origin->children */
359     const char       *root;       /* Filesystem root for all files */
360                                   /* always ends with '/' */
361     unsigned int      flags;      /* Flags passed to AUG_INIT */
362     struct module    *modules;    /* Loaded modules */
363     size_t            nmodpath;
364     char             *modpathz;   /* The search path for modules as a
365                                      glibc argz vector */
366     struct pathx_symtab *symtab;
367     struct error        *error;
368     uint                api_entries;  /* Number of entries through a public
369                                        * API, 0 when called from outside */
370 #if HAVE_USELOCALE
371     /* On systems that have a uselocale call, we switch to the C locale
372      * on entry into API functions, and back to the old user locale
373      * on exit.
374      * FIXME: We need some solution for systems without uselocale, like
375      * setlocale + critical section, though that is very heavy-handed
376      */
377     locale_t            c_locale;
378     locale_t            user_locale;
379 #endif
380 };
381
382 static inline struct error *err_of_aug(const struct augeas *aug) {
383     return ((struct augeas *) aug)->error;
384 }
385
386 /* Used by augparse for loading tests */
387 int __aug_load_module_file(struct augeas *aug, const char *filename);
388
389 /* Called at beginning and end of every _public_ API function */
390 void api_entry(const struct augeas *aug);
391 void api_exit(const struct augeas *aug);
392
393 /* Struct: tree
394  * An entry in the global config tree. The data structure allows associating
395  * values with interior nodes, but the API currently marks that as an error.
396  *
397  * To make dealing with parents uniform, even for the root, we create
398  * standalone trees with a fake root, called origin. That root is generally
399  * not referenced from anywhere. Standalone trees should be created with
400  * MAKE_TREE_ORIGIN.
401  *
402  * The DIRTY flag is used to track which parts of the tree might need to be
403  * saved. For any node that is marked dirty, all of its ancestors must be
404  * marked dirty, too. Instead of setting this flag directly, the function
405  * TREE_MARK_DIRTY in augeas.c should be used (and only functions in that
406  * file should have a need to mark nodes as dirty)
407  *
408  * The FILE flag is set for entries underneath /augeas/files that hold the
409  * metadata for a file by ADD_FILE_INFO. The FILE flag is set for entries
410  * underneath /files for the toplevel node corresponding to a file by
411  * TREE_FREPLACE and is used by AUG_SOURCE to find the file to which a node
412  * belongs.
413  */
414 struct tree {
415     struct tree *next;
416     struct tree *parent;     /* Points to self for root */
417     char        *label;      /* Last component of PATH */
418     struct tree *children;   /* List of children through NEXT */
419     char        *value;
420     struct span *span;
421
422     /* Flags */
423     bool         dirty;
424     bool         file;
425     bool         added;      /* only used by ns_add and tree_rm to dedupe
426                                 nodesets */
427 };
428
429 /* The opaque structure used to represent path expressions. API's
430  * using STRUCT PATHX are declared farther below
431  */
432 struct pathx;
433
434 #define ROOT_P(t) ((t) != NULL && (t)->parent == (t)->parent->parent)
435
436 #define TREE_HIDDEN(tree) ((tree)->label == NULL)
437
438 /* Function: make_tree
439  * Allocate a new tree node with the given LABEL, VALUE, and CHILDREN,
440  * which are not copied. The new tree is marked as dirty
441  */
442 struct tree *make_tree(char *label, char *value,
443                        struct tree *parent, struct tree *children);
444
445 /* Mark a tree as a standalone tree; this creates a fake parent for ROOT,
446  * so that even ROOT has a parent. A new node with only child ROOT is
447  * returned on success, and NULL on failure.
448  */
449 struct tree  *make_tree_origin(struct tree *root);
450
451 /* Make a new tree node and append it to parent's children */
452 struct tree *tree_append(struct tree *parent, char *label, char *value);
453
454 int tree_rm(struct pathx *p);
455 int tree_unlink(struct augeas *aug, struct tree *tree);
456 struct tree *tree_set(struct pathx *p, const char *value);
457 int tree_insert(struct pathx *p, const char *label, int before);
458 int free_tree(struct tree *tree);
459 int dump_tree(FILE *out, struct tree *tree);
460 int tree_equal(const struct tree *t1, const struct tree *t2);
461 /* Return the 1-based index of TREE amongst its siblings with the same
462  * label or 0 if none of TREE's siblings have the same label */
463 int tree_sibling_index(struct tree *tree);
464 char *path_expand(struct tree *tree, const char *ppath);
465 char *path_of_tree(struct tree *tree);
466 /* Clear the dirty flag in the whole TREE */
467 void tree_clean(struct tree *tree);
468 /* Return first child with label LABEL or NULL */
469 struct tree *tree_child(struct tree *tree, const char *label);
470 /* Return first existing child with label LABEL or create one. Return NULL
471  * when allocation fails */
472 struct tree *tree_child_cr(struct tree *tree, const char *label);
473 /* Create a path in the tree; nodes along the path are looked up with
474  * tree_child_cr */
475 struct tree *tree_path_cr(struct tree *tree, int n, ...);
476 /* Store VALUE directly as the value of TREE and set VALUE to NULL.
477  * Update dirty flags */
478 void tree_store_value(struct tree *tree, char **value);
479 /* Set the value of TREE to a copy of VALUE and update dirty flags */
480 int tree_set_value(struct tree *tree, const char *value);
481 /* Cleanly remove all children of TREE, but leave TREE itself unchanged */
482 void tree_unlink_children(struct augeas *aug, struct tree *tree);
483 /* Find a node in the tree at path FPATH; FPATH is a file path, i.e.
484  * not interpreted as a path expression. If no such node exists, return NULL
485  */
486 struct tree *tree_fpath(struct augeas *aug, const char *fpath);
487 /* Find a node in the tree at path FPATH; FPATH is a file path, i.e.
488  * not interpreted as a path expression. If no such node exists, create
489  * it and all its missing ancestors.
490  */
491 struct tree *tree_fpath_cr(struct augeas *aug, const char *fpath);
492 /* Find the node matching PATH.
493  * Returns the node or NULL on error
494  * Errors: EMMATCH - more than one node matches PATH
495  *         ENOMEM  - allocation error
496  */
497 struct tree *tree_find(struct augeas *aug, const char *path);
498 /* Find the node matching PATH. Expand the tree to contain such a node if
499  * none exists.
500  * Returns the node or NULL on error
501  */
502 struct tree *tree_find_cr(struct augeas *aug, const char *path);
503 /* Find the node at the path stored in AUGEAS_CONTEXT, i.e. the root context
504  * node for relative paths.
505  * Errors: EMMATCH - more than one node matches PATH
506  *         ENOMEM  - allocation error
507  */
508 struct tree *tree_root_ctx(const struct augeas *aug);
509
510 /* Struct: memstream
511  * Wrappers to simulate OPEN_MEMSTREAM where that's not available. The
512  * STREAM member is opened by INIT_MEMSTREAM and closed by
513  * CLOSE_MEMSTREAM. The BUF is allocated automatically, but can not be used
514  * until after CLOSE_MEMSTREAM has been called. It is the callers
515  * responsibility to free up BUF.
516  */
517 struct memstream {
518     FILE   *stream;
519     char   *buf;
520     size_t size;
521 };
522
523 /* Function: init_memstream
524  * Initialize a memstream. On systems that have OPEN_MEMSTREAM, it is used
525  * to open MS->STREAM. On systems without OPEN_MEMSTREAM, MS->STREAM is
526  * backed by a temporary file.
527  *
528  * MS must be allocated in advance; INIT_MEMSTREAM initializes it.
529  */
530 int __aug_init_memstream(struct memstream *ms);
531 #define init_memstream(ms) __aug_init_memstream(ms);
532
533 /* Function: close_memstream
534  * Close a memstream. After calling this, MS->STREAM can not be used
535  * anymore and a string representing whatever was written to it is
536  * available in MS->BUF. The caller must free MS->BUF.
537  *
538  * The caller must free the MEMSTREAM structure.
539  */
540 int __aug_close_memstream(struct memstream *ms);
541 #define close_memstream(ms) __aug_close_memstream(ms)
542
543 /*
544  * Path expressions
545  */
546
547 typedef enum {
548     PATHX_NOERROR = 0,
549     PATHX_ENAME,
550     PATHX_ESTRING,
551     PATHX_ENUMBER,
552     PATHX_EDELIM,
553     PATHX_ENOEQUAL,
554     PATHX_ENOMEM,
555     PATHX_EPRED,
556     PATHX_EPAREN,
557     PATHX_ESLASH,
558     PATHX_EINTERNAL,
559     PATHX_ETYPE,
560     PATHX_ENOVAR,
561     PATHX_EEND,
562     PATHX_ENOMATCH,
563     PATHX_EARITY,
564     PATHX_EREGEXP,
565     PATHX_EMMATCH,
566     PATHX_EREGEXPFLAG
567 } pathx_errcode_t;
568
569 struct pathx;
570 struct pathx_symtab;
571
572 const char *pathx_error(struct pathx *pathx, const char **txt, int *pos);
573
574 /* Parse a path expression PATH rooted at TREE, which is a node somewhere
575  * in AUG->ORIGIN. If TREE is NULL, AUG->ORIGIN is used. If ROOT_CTX is not
576  * NULL and the PATH isn't absolute then it will be rooted at ROOT_CTX.
577  *
578  * Use this function rather than PATHX_PARSE for path expressions inside
579  * the tree in AUG->ORIGIN.
580  *
581  * If NEED_NODESET is true, the resulting path expression must evaluate toa
582  * nodeset, otherwise it can evaluate to a value of any type.
583  *
584  * Return the resulting path expression, or NULL on error. If an error
585  * occurs, the error struct in AUG contains details.
586  */
587 struct pathx *pathx_aug_parse(const struct augeas *aug,
588                               struct tree *tree,
589                               struct tree *root_ctx,
590                               const char *path, bool need_nodeset);
591
592 /* Parse the string PATH into a path expression PX that will be evaluated
593  * against the tree ORIGIN.
594  *
595  * If NEED_NODESET is true, the resulting path expression must evaluate toa
596  * nodeset, otherwise it can evaluate to a value of any type.
597  *
598  * Returns 0 on success, and -1 on error
599  */
600 int pathx_parse(const struct tree *origin,
601                 struct error *err,
602                 const char *path,
603                 bool need_nodeset,
604                 struct pathx_symtab *symtab,
605                 struct tree *root_ctx,
606                 struct pathx **px);
607 /* Return the error struct that was passed into pathx_parse */
608 struct error *err_of_pathx(struct pathx *px);
609 struct tree *pathx_first(struct pathx *path);
610 struct tree *pathx_next(struct pathx *path);
611 /* Return -1 if evaluating PATH runs into trouble, otherwise return the
612  * number of nodes matching PATH and set MATCH to the first matching
613  * node */
614 int pathx_find_one(struct pathx *path, struct tree **match);
615 int pathx_expand_tree(struct pathx *path, struct tree **tree);
616 void free_pathx(struct pathx *path);
617
618 struct pathx_symtab *pathx_get_symtab(struct pathx *pathx);
619 int pathx_symtab_define(struct pathx_symtab **symtab,
620                         const char *name, struct pathx *px);
621 /* Returns 1 on success, and -1 when out of memory */
622 int pathx_symtab_assign_tree(struct pathx_symtab **symtab, const char *name,
623                              struct tree *tree);
624 int pathx_symtab_undefine(struct pathx_symtab **symtab, const char *name);
625 void pathx_symtab_remove_descendants(struct pathx_symtab *symtab,
626                                      const struct tree *tree);
627
628 /* Return the number of nodes in the nodeset NAME. If the variable NAME
629  * does not exist, or is not a nodeset, return -1 */
630 int pathx_symtab_count(const struct pathx_symtab *symtab, const char *name);
631
632 /* Return the tree stored in the variable NAME at position I, which is the
633    same as evaluating the path expression '$NAME[I]'. If the variable NAME
634    does not exist, or does not contain a nodeset, or if I is bigger than
635    the size of the nodeset, return NULL */
636 struct tree *pathx_symtab_get_tree(struct pathx_symtab *symtab,
637                                    const char *name, int i);
638 void free_symtab(struct pathx_symtab *symtab);
639
640 /* Escape a name so that it is safe to pass to parse_name and have it
641  * interpreted as the literal name of a path component.
642  *
643  * On return, *OUT will be NULL if IN does not need escaping, otherwise it
644  * will contain an escaped copy of IN which the caller must free.
645  *
646  * Returns -1 if it failed to allocate memory for *OUT, 0 on success
647  */
648 int pathx_escape_name(const char *in, char **out);
649
650 /* Debug helpers, all defined in internal.c. When ENABLE_DEBUG is not
651  * set, they compile to nothing.
652  */
653 #  if ENABLE_DEBUG
654   /* Return true if debugging for CATEGORY is turned on */
655   bool debugging(const char *category);
656   /* Format the arguments into a file name, prepend it with the directory
657    * from the environment variable AUGEAS_DEBUG_DIR, and open the file for
658    * writing.
659   */
660   FILE *debug_fopen(const char *format, ...)
661     ATTRIBUTE_FORMAT(printf, 1, 2);
662 #  else
663 #    define debugging(facility) (0)
664 #    define debug_fopen(format ...) (NULL)
665 #  endif
666 #endif
667
668
669 /*
670  * Local variables:
671  *  indent-tabs-mode: nil
672  *  c-indent-level: 4
673  *  c-basic-offset: 4
674  *  tab-width: 4
675  * End:
676  */