On Jun 23, 2009, at 8:46 AM, David Lutterkort wrote:

Hi Jeff,

On Sat, 2009-06-20 at 16:08 -0400, Jeff Johnson wrote:
This dinky patch permits an application (like RPM) to
capture fprintf output into a buffer without resorting
to memstream's.

Slightly better would be to add the (vector to struct aug
to permit per-instance overrides, but that is likely overkill,
and would be a bit more intrusive into your API.

Patch against current Augeas git afaik.

Yeah, aug_print wasn't the smartest thing to include in the API, since
its use is extremely limited.


Absoulutely agreed that aug_print isn't exactly essential to augtool
(but its is the only means atm to display paths for orientation to
a user).

And most definitely the patch I sent you is quick-n-dirty. It
was the minimal necessary change to accompish a highly peculier
and unusual task, i.e. embedding augtool within rpm. That isn't
what augtool was designed for, and better could/should be done
with augtool. Meanwhile, I needed to capture stdout into a
buffer "portably", which means no memstream's and libio etc etc.

The right way to address that shortcoming is to add a tree-walking API;
though I am not quite sure what the right callback mechanism is. I am
thinking that the callback should get an opaque, unique token, the label
and the value of the current node - the order of callbacks should be
'ENTER node foo', traverse all children, 'LEAVE node foo' - actually, we also need a separate indication for starting and ending the traversal of
a tree, since an XPath expression can match multiple disconnected
subtrees (e.g., '/augeas//error')


Capturing I/O and adding a tree walk with callbacks are ultimately
different goals. Both need to be done. Consider your foo.aug lens I/O, which is I/O
that cannot be handled by a tree walk, to see the difference.

But sure, a tree walk with callbacks could replace aug_print easily.

That would give us a signature for the callback like

       enum aug_iter_event {
         AUG_START,   /* start traversal of a new subtree */
AUG_ENTER, /* enter a node, used before traversing any children */ AUG_LEAVE, /* leave a node, used after traversing all children */
         AUG_END      /* finish traversal of a subtree */
       };
int (*aug_iter) (void *token, enum aug_iter_event event, const char *label, const char *value, void *user_data);

and an API function

       int aug_iter(augeas *aug, const char *pathx, aug_iter *iter);


As I suggested privately, I'd look to fts(3) as a solid and mature example of an API that is both consistent with what is in Augeas (both XPath and fts(3) have a means to collect sub-node or sub-directory "children", unlike nftw(3) from POSIX), and also has data structures and parameterization defined that is useful for any file system traversal. fts(3) is exactly the "guts" of *BSD find(1) for years and years,
even if one tends to prefer the POSIX nftw(3) on Linux.

I also mentioned that a very slight modification to fts(3) to add vectors like

        DIR * (*fts_opendir) (const char * path)
                /*...@globals fileSystem @*/
                /*...@modifies fileSystem @*/;
        struct dirent * (*fts_readdir) (DIR * dir)
                /*...@globals fileSystem @*/
                /*...@modifies *dir, fileSystem @*/;
        int (*fts_closedir) (/*...@only@*/ DIR * dir)
                /*...@globals fileSystem @*/
                /*...@modifies *dir, fileSystem @*/;
        int (*fts_stat) (const char * path, /*...@out@*/ struct stat * st)
                /*...@globals fileSystem @*/
                /*...@modifies *st, fileSystem @*/;
int (*fts_lstat) (const char * path, /*...@out@*/ struct stat * st)
                /*...@globals fileSystem @*/
                /*...@modifies *st, fileSystem @*/;

adds the ability to traverse non-file system trees if one can live
within some modest constraints, like populating a stat(2) structure
sufficiently to drive an fts(3) tree traversal, and populating
DIR and struct dirent structures compatibly with the existing OS structures.

RPM has been using this modified fts(3) for years to traverse remote
FTP/HTTP trees, XPath paths would be far far easier, mostly because
no network errors would ever be involved.

The reason for use a private fts(3) is not only for a public API that is largely documented and identical with "man 3 fts", but also to use the same fts(3) within Augeas
itself, which most certainly is doing file tree traversals, albeit by
assembling paths and using glob(3) to, say, load modules in aug_init().

But most certainly, any well defined file tree walk API across the Augeas XPath tree
will suffice for (and benefit) Augeas.

Maybe the stuff about subtree start/end should be split into a second
callback that gets the full path to the subtree's root passed in.

What do you think ? (Please post your reply to augeas-devel so others
can chime in),

Done.

73 de Jeff
David



Attachment: smime.p7s
Description: S/MIME cryptographic signature

_______________________________________________
augeas-devel mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/augeas-devel

Reply via email to