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 amthinking that the callback should get an opaque, unique token, the labeland 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 ofa 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 ultimatelydifferent 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
smime.p7s
Description: S/MIME cryptographic signature
_______________________________________________ augeas-devel mailing list [email protected] https://www.redhat.com/mailman/listinfo/augeas-devel
