X-Git-Url: http://git.annexia.org/?p=libguestfs.git;a=blobdiff_plain;f=src%2Fgenerator.ml;h=c4f285119308fdb4ecd6911e77ac85086474f173;hp=067ac906b47d9f3ed1ba41cbaa2bdbda1fd7af88;hb=1e97e406c36031617a86a4fa6bb78a112848ee87;hpb=95de8eea73b6fc105de728aad7571cfd0042666f diff --git a/src/generator.ml b/src/generator.ml index 067ac90..c4f2851 100755 --- a/src/generator.ml +++ b/src/generator.ml @@ -18,8 +18,10 @@ *) (* This script generates a large amount of code and documentation for - * all the daemon actions. To add a new action there are only two - * files you need to change, this one to describe the interface, and + * all the daemon actions. + * + * To add a new action there are only two files you need to change, + * this one to describe the interface (see the big table below), and * daemon/.c to write the implementation. * * After editing this file, run it (./src/generator.ml) to regenerate @@ -31,6 +33,7 @@ *) #load "unix.cma";; +#load "str.cma";; open Printf @@ -41,9 +44,15 @@ and ret = *) | RErr (* "RInt" as a return value means an int which is -1 for error - * or any value >= 0 on success. + * or any value >= 0 on success. Only use this for smallish + * positive ints (0 <= i < 2^30). *) | RInt of string + (* "RInt64" is the same as RInt, but is guaranteed to be able + * to return a full 64 bit value, _except_ that -1 means error + * (so -1 cannot be a valid, non-error return value). + *) + | RInt64 of string (* "RBool" is a bool return value which can be true/false or * -1 for error. *) @@ -63,18 +72,189 @@ and ret = | RPVList of string | RVGList of string | RLVList of string + (* Stat buffers. *) + | RStat of string + | RStatVFS of string + (* Key-value pairs of untyped strings. Turns into a hashtable or + * dictionary in languages which support it. DON'T use this as a + * general "bucket" for results. Prefer a stronger typed return + * value if one is available, or write a custom struct. Don't use + * this if the list could potentially be very long, since it is + * inefficient. Keys should be unique. NULLs are not permitted. + *) + | RHashtable of string + and args = argt list (* Function parameters, guestfs handle is implicit. *) + + (* Note in future we should allow a "variable args" parameter as + * the final parameter, to allow commands like + * chmod mode file [file(s)...] + * This is not implemented yet, but many commands (such as chmod) + * are currently defined with the argument order keeping this future + * possibility in mind. + *) and argt = | String of string (* const char *name, cannot be NULL *) | OptString of string (* const char *name, may be NULL *) + | StringList of string(* list of strings (each string cannot be NULL) *) | Bool of string (* boolean *) | Int of string (* int (smallish ints, signed, <= 31 bits) *) + (* These are treated as filenames (simple string parameters) in + * the C API and bindings. But in the RPC protocol, we transfer + * the actual file content up to or down from the daemon. + * FileIn: local machine -> daemon (in request) + * FileOut: daemon -> local machine (in reply) + * In guestfish (only), the special name "-" means read from + * stdin or write to stdout. + *) + | FileIn of string + | FileOut of string type flags = | ProtocolLimitWarning (* display warning about protocol size limits *) + | DangerWillRobinson (* flags particularly dangerous commands *) | FishAlias of string (* provide an alias for this cmd in guestfish *) | FishAction of string (* call this function in guestfish *) | NotInFish (* do not export via guestfish *) + | NotInDocs (* do not add this function to documentation *) + +let protocol_limit_warning = + "Because of the message protocol, there is a transfer limit +of somewhere between 2MB and 4MB. To transfer large files you should use +FTP." + +let danger_will_robinson = + "B." + +(* You can supply zero or as many tests as you want per API call. + * + * Note that the test environment has 3 block devices, of size 500MB, + * 50MB and 10MB (respectively /dev/sda, /dev/sdb, /dev/sdc), and + * a fourth squashfs block device with some known files on it (/dev/sdd). + * + * Note for partitioning purposes, the 500MB device has 63 cylinders. + * + * The squashfs block device (/dev/sdd) comes from images/test.sqsh. + * + * To be able to run the tests in a reasonable amount of time, + * the virtual machine and block devices are reused between tests. + * So don't try testing kill_subprocess :-x + * + * Between each test we blockdev-setrw, umount-all, lvm-remove-all. + * + * If the appliance is running an older Linux kernel (eg. RHEL 5) then + * devices are named /dev/hda etc. To cope with this, the test suite + * adds some hairly logic to detect this case, and then automagically + * replaces all strings which match "/dev/sd.*" with "/dev/hd.*". + * When writing test cases you shouldn't have to worry about this + * difference. + * + * Don't assume anything about the previous contents of the block + * devices. Use 'Init*' to create some initial scenarios. + * + * You can add a prerequisite clause to any individual test. This + * is a run-time check, which, if it fails, causes the test to be + * skipped. Useful if testing a command which might not work on + * all variations of libguestfs builds. A test that has prerequisite + * of 'Always' is run unconditionally. + * + * In addition, packagers can skip individual tests by setting the + * environment variables: eg: + * SKIP_TEST__=1 SKIP_TEST_COMMAND_3=1 (skips test #3 of command) + * SKIP_TEST_=1 SKIP_TEST_ZEROFREE=1 (skips all zerofree tests) + *) +type tests = (test_init * test_prereq * test) list +and test = + (* Run the command sequence and just expect nothing to fail. *) + | TestRun of seq + (* Run the command sequence and expect the output of the final + * command to be the string. + *) + | TestOutput of seq * string + (* Run the command sequence and expect the output of the final + * command to be the list of strings. + *) + | TestOutputList of seq * string list + (* Run the command sequence and expect the output of the final + * command to be the list of block devices (could be either + * "/dev/sd.." or "/dev/hd.." form - we don't check the 5th + * character of each string). + *) + | TestOutputListOfDevices of seq * string list + (* Run the command sequence and expect the output of the final + * command to be the integer. + *) + | TestOutputInt of seq * int + (* Run the command sequence and expect the output of the final + * command to be a true value (!= 0 or != NULL). + *) + | TestOutputTrue of seq + (* Run the command sequence and expect the output of the final + * command to be a false value (== 0 or == NULL, but not an error). + *) + | TestOutputFalse of seq + (* Run the command sequence and expect the output of the final + * command to be a list of the given length (but don't care about + * content). + *) + | TestOutputLength of seq * int + (* Run the command sequence and expect the output of the final + * command to be a structure. + *) + | TestOutputStruct of seq * test_field_compare list + (* Run the command sequence and expect the final command (only) + * to fail. + *) + | TestLastFail of seq + +and test_field_compare = + | CompareWithInt of string * int + | CompareWithString of string * string + | CompareFieldsIntEq of string * string + | CompareFieldsStrEq of string * string + +(* Test prerequisites. *) +and test_prereq = + (* Test always runs. *) + | Always + (* Test is currently disabled - eg. it fails, or it tests some + * unimplemented feature. + *) + | Disabled + (* 'string' is some C code (a function body) that should return + * true or false. The test will run if the code returns true. + *) + | If of string + (* As for 'If' but the test runs _unless_ the code returns true. *) + | Unless of string + +(* Some initial scenarios for testing. *) +and test_init = + (* Do nothing, block devices could contain random stuff including + * LVM PVs, and some filesystems might be mounted. This is usually + * a bad idea. + *) + | InitNone + (* Block devices are empty and no filesystems are mounted. *) + | InitEmpty + (* /dev/sda contains a single partition /dev/sda1, which is formatted + * as ext2, empty [except for lost+found] and mounted on /. + * /dev/sdb and /dev/sdc may have random content. + * No LVM. + *) + | InitBasicFS + (* /dev/sda: + * /dev/sda1 (is a PV): + * /dev/VG/LV (size 8MB): + * formatted as ext2, empty [except for lost+found], mounted on / + * /dev/sdb and /dev/sdc may have random content. + *) + | InitBasicFSonLVM + +(* Sequence of commands for testing. *) +and seq = cmd list +and cmd = string list (* Note about long descriptions: When referring to another * action, use the format C (ie. the full name of @@ -84,8 +264,83 @@ type flags = * Apart from that, long descriptions are just perldoc paragraphs. *) -let non_daemon_functions = [ +(* These test functions are used in the language binding tests. *) + +let test_all_args = [ + String "str"; + OptString "optstr"; + StringList "strlist"; + Bool "b"; + Int "integer"; + FileIn "filein"; + FileOut "fileout"; +] + +let test_all_rets = [ + (* except for RErr, which is tested thoroughly elsewhere *) + "test0rint", RInt "valout"; + "test0rint64", RInt64 "valout"; + "test0rbool", RBool "valout"; + "test0rconststring", RConstString "valout"; + "test0rstring", RString "valout"; + "test0rstringlist", RStringList "valout"; + "test0rintbool", RIntBool ("valout", "valout"); + "test0rpvlist", RPVList "valout"; + "test0rvglist", RVGList "valout"; + "test0rlvlist", RLVList "valout"; + "test0rstat", RStat "valout"; + "test0rstatvfs", RStatVFS "valout"; + "test0rhashtable", RHashtable "valout"; +] + +let test_functions = [ + ("test0", (RErr, test_all_args), -1, [NotInFish; NotInDocs], + [], + "internal test function - do not use", + "\ +This is an internal test function which is used to test whether +the automatically generated bindings can handle every possible +parameter type correctly. + +It echos the contents of each parameter to stdout. + +You probably don't want to call this function."); +] @ List.flatten ( + List.map ( + fun (name, ret) -> + [(name, (ret, [String "val"]), -1, [NotInFish; NotInDocs], + [], + "internal test function - do not use", + "\ +This is an internal test function which is used to test whether +the automatically generated bindings can handle every possible +return type correctly. + +It converts string C to the return type. + +You probably don't want to call this function."); + (name ^ "err", (ret, []), -1, [NotInFish; NotInDocs], + [], + "internal test function - do not use", + "\ +This is an internal test function which is used to test whether +the automatically generated bindings can handle every possible +return type correctly. + +This function always returns an error. + +You probably don't want to call this function.")] + ) test_all_rets +) + +(* non_daemon_functions are any functions which don't get processed + * in the daemon, eg. functions for setting and getting local + * configuration values. + *) + +let non_daemon_functions = test_functions @ [ ("launch", (RErr, []), -1, [FishAlias "run"; FishAction "launch"], + [], "launch the qemu subprocess", "\ Internally libguestfs is implemented by running a virtual machine @@ -95,6 +350,7 @@ You should call this after configuring the handle (eg. adding drives) but before performing any actions."); ("wait_ready", (RErr, []), -1, [NotInFish], + [], "wait until the qemu subprocess launches", "\ Internally libguestfs is implemented by running a virtual machine @@ -104,11 +360,13 @@ You should call this after C to wait for the launch to complete."); ("kill_subprocess", (RErr, []), -1, [], + [], "kill the qemu subprocess", "\ This kills the qemu subprocess. You should never need to call this."); ("add_drive", (RErr, [String "filename"]), -1, [FishAlias "add"], + [], "add an image to examine or modify", "\ This function adds a virtual machine disk image C to the @@ -122,16 +380,49 @@ for whatever operations you want to perform (ie. read access if you just want to read the image or write access if you want to modify the image). -This is equivalent to the qemu parameter C<-drive file=filename>."); +This is equivalent to the qemu parameter C<-drive file=filename>. + +Note that this call checks for the existence of C. This +stops you from specifying other types of drive which are supported +by qemu such as C and C URLs. To specify those, use +the general C call instead."); ("add_cdrom", (RErr, [String "filename"]), -1, [FishAlias "cdrom"], + [], "add a CD-ROM disk image to examine", "\ This function adds a virtual CD-ROM disk image to the guest. -This is equivalent to the qemu parameter C<-cdrom filename>."); +This is equivalent to the qemu parameter C<-cdrom filename>. + +Note that this call checks for the existence of C. This +stops you from specifying other types of drive which are supported +by qemu such as C and C URLs. To specify those, use +the general C call instead."); + + ("add_drive_ro", (RErr, [String "filename"]), -1, [FishAlias "add-ro"], + [], + "add a drive in snapshot mode (read-only)", + "\ +This adds a drive in snapshot mode, making it effectively +read-only. + +Note that writes to the device are allowed, and will be seen for +the duration of the guestfs handle, but they are written +to a temporary file which is discarded as soon as the guestfs +handle is closed. We don't currently have any method to enable +changes to be committed, although qemu can support this. + +This is equivalent to the qemu parameter +C<-drive file=filename,snapshot=on>. + +Note that this call checks for the existence of C. This +stops you from specifying other types of drive which are supported +by qemu such as C and C URLs. To specify those, use +the general C call instead."); ("config", (RErr, [String "qemuparam"; OptString "qemuvalue"]), -1, [], + [], "add qemu parameters", "\ This can be used to add arbitrary qemu command line parameters @@ -143,7 +434,31 @@ The first character of C string must be a C<-> (dash). C can be NULL."); + ("set_qemu", (RErr, [String "qemu"]), -1, [FishAlias "qemu"], + [], + "set the qemu binary", + "\ +Set the qemu binary that we will use. + +The default is chosen when the library was compiled by the +configure script. + +You can also override this by setting the C +environment variable. + +Setting C to C restores the default qemu binary."); + + ("get_qemu", (RConstString "qemu", []), -1, [], + [], + "get the qemu binary", + "\ +Return the current qemu binary. + +This is always non-NULL. If it wasn't set already, then this will +return the default qemu binary name."); + ("set_path", (RErr, [String "path"]), -1, [FishAlias "path"], + [], "set the search path", "\ Set the path that libguestfs searches for kernel and initrd.img. @@ -151,12 +466,10 @@ Set the path that libguestfs searches for kernel and initrd.img. The default is C<$libdir/guestfs> unless overridden by setting C environment variable. -The string C is stashed in the libguestfs handle, so the caller -must make sure it remains valid for the lifetime of the handle. - Setting C to C restores the default path."); ("get_path", (RConstString "path", []), -1, [], + [], "get the search path", "\ Return the current search path. @@ -164,19 +477,48 @@ Return the current search path. This is always non-NULL. If it wasn't set already, then this will return the default path."); + ("set_append", (RErr, [String "append"]), -1, [FishAlias "append"], + [], + "add options to kernel command line", + "\ +This function is used to add additional options to the +guest kernel command line. + +The default is C unless overridden by setting +C environment variable. + +Setting C to C means I additional options +are passed (libguestfs always adds a few of its own)."); + + ("get_append", (RConstString "append", []), -1, [], + [], + "get the additional kernel options", + "\ +Return the additional kernel options which are added to the +guest kernel command line. + +If C then no options are added."); + ("set_autosync", (RErr, [Bool "autosync"]), -1, [FishAlias "autosync"], + [], "set autosync mode", "\ If C is true, this enables autosync. Libguestfs will make a -best effort attempt to run C when the handle is closed -(also if the program exits without closing handles)."); +best effort attempt to run C followed by +C when the handle is closed +(also if the program exits without closing handles). + +This is disabled by default (except in guestfish where it is +enabled by default)."); ("get_autosync", (RBool "autosync", []), -1, [], + [], "get autosync mode", "\ Get the autosync flag."); ("set_verbose", (RErr, [Bool "verbose"]), -1, [FishAlias "verbose"], + [], "set verbose mode", "\ If C is true, this turns on verbose messages (to C). @@ -185,13 +527,98 @@ Verbose messages are disabled unless the environment variable C is defined and set to C<1>."); ("get_verbose", (RBool "verbose", []), -1, [], + [], "get verbose mode", "\ -This returns the verbose messages flag.") +This returns the verbose messages flag."); + + ("is_ready", (RBool "ready", []), -1, [], + [], + "is ready to accept commands", + "\ +This returns true iff this handle is ready to accept commands +(in the C state). + +For more information on states, see L."); + + ("is_config", (RBool "config", []), -1, [], + [], + "is in configuration state", + "\ +This returns true iff this handle is being configured +(in the C state). + +For more information on states, see L."); + + ("is_launching", (RBool "launching", []), -1, [], + [], + "is launching subprocess", + "\ +This returns true iff this handle is launching the subprocess +(in the C state). + +For more information on states, see L."); + + ("is_busy", (RBool "busy", []), -1, [], + [], + "is busy processing a command", + "\ +This returns true iff this handle is busy processing a command +(in the C state). + +For more information on states, see L."); + + ("get_state", (RInt "state", []), -1, [], + [], + "get the current state", + "\ +This returns the current state as an opaque integer. This is +only useful for printing debug and internal error messages. + +For more information on states, see L."); + + ("set_busy", (RErr, []), -1, [NotInFish], + [], + "set state to busy", + "\ +This sets the state to C. This is only used when implementing +actions using the low-level API. + +For more information on states, see L."); + + ("set_ready", (RErr, []), -1, [NotInFish], + [], + "set state to ready", + "\ +This sets the state to C. This is only used when implementing +actions using the low-level API. + +For more information on states, see L."); + + ("end_busy", (RErr, []), -1, [NotInFish], + [], + "leave the busy state", + "\ +This sets the state to C, or if in C then it leaves the +state as is. This is only used when implementing +actions using the low-level API. + +For more information on states, see L."); + ] +(* daemon_functions are any functions which cause some action + * to take place in the daemon. + *) + let daemon_functions = [ ("mount", (RErr, [String "device"; String "mountpoint"]), 1, [], + [InitEmpty, Always, TestOutput ( + [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ","]; + ["mkfs"; "ext2"; "/dev/sda1"]; + ["mount"; "/dev/sda1"; "/"]; + ["write_file"; "/new"; "new file contents"; "0"]; + ["cat"; "/new"]], "new file contents")], "mount a guest disk at a position in the filesystem", "\ Mount a guest disk at a position in the filesystem. Block devices @@ -212,6 +639,7 @@ The filesystem options C and C are set with this call, in order to improve reliability."); ("sync", (RErr, []), 2, [], + [ InitEmpty, Always, TestRun [["sync"]]], "sync disks, writes are flushed through to the disk image", "\ This syncs the disk, so that any writes are flushed through to the @@ -221,6 +649,9 @@ You should always call this if you have modified a disk image, before closing the handle."); ("touch", (RErr, [String "path"]), 3, [], + [InitBasicFS, Always, TestOutputTrue ( + [["touch"; "/new"]; + ["exists"; "/new"]])], "update file timestamps or create a new file", "\ Touch acts like the L command. It can be used to @@ -228,16 +659,22 @@ update the timestamps on a file, or, if the file does not exist, to create a new zero-length file."); ("cat", (RString "content", [String "path"]), 4, [ProtocolLimitWarning], + [InitBasicFS, Always, TestOutput ( + [["write_file"; "/new"; "new file contents"; "0"]; + ["cat"; "/new"]], "new file contents")], "list the contents of a file", "\ Return the contents of the file named C. Note that this function cannot correctly handle binary files (specifically, files containing C<\\0> character which is treated -as end of string). For those you need to use the C +as end of string). For those you need to use the C function which has a more complex interface."); ("ll", (RString "listing", [String "directory"]), 5, [], + [], (* XXX Tricky to test because it depends on the exact format + * of the 'ls -l' command, which changes between F10 and F11. + *) "list the files in a directory (long format)", "\ List the files in C (relative to the root directory, @@ -247,6 +684,11 @@ This command is mostly useful for interactive sessions. It is I intended that you try to parse the output string."); ("ls", (RStringList "listing", [String "directory"]), 6, [], + [InitBasicFS, Always, TestOutputList ( + [["touch"; "/new"]; + ["touch"; "/newer"]; + ["touch"; "/newest"]; + ["ls"; "/"]], ["lost+found"; "new"; "newer"; "newest"])], "list the files in a directory", "\ List the files in C (relative to the root directory, @@ -257,6 +699,8 @@ This command is mostly useful for interactive sessions. Programs should probably use C instead."); ("list_devices", (RStringList "devices", []), 7, [], + [InitEmpty, Always, TestOutputListOfDevices ( + [["list_devices"]], ["/dev/sda"; "/dev/sdb"; "/dev/sdc"; "/dev/sdd"])], "list the block devices", "\ List all the block devices. @@ -264,6 +708,11 @@ List all the block devices. The full block device names are returned, eg. C"); ("list_partitions", (RStringList "partitions", []), 8, [], + [InitBasicFS, Always, TestOutputListOfDevices ( + [["list_partitions"]], ["/dev/sda1"]); + InitEmpty, Always, TestOutputListOfDevices ( + [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ",10 ,20 ,"]; + ["list_partitions"]], ["/dev/sda1"; "/dev/sda2"; "/dev/sda3"])], "list the partitions", "\ List all the partitions detected on all block devices. @@ -274,6 +723,14 @@ This does not return logical volumes. For that you will need to call C."); ("pvs", (RStringList "physvols", []), 9, [], + [InitBasicFSonLVM, Always, TestOutputListOfDevices ( + [["pvs"]], ["/dev/sda1"]); + InitEmpty, Always, TestOutputListOfDevices ( + [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ",10 ,20 ,"]; + ["pvcreate"; "/dev/sda1"]; + ["pvcreate"; "/dev/sda2"]; + ["pvcreate"; "/dev/sda3"]; + ["pvs"]], ["/dev/sda1"; "/dev/sda2"; "/dev/sda3"])], "list the LVM physical volumes (PVs)", "\ List all the physical volumes detected. This is the equivalent @@ -285,6 +742,16 @@ PVs (eg. C). See also C."); ("vgs", (RStringList "volgroups", []), 10, [], + [InitBasicFSonLVM, Always, TestOutputList ( + [["vgs"]], ["VG"]); + InitEmpty, Always, TestOutputList ( + [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ",10 ,20 ,"]; + ["pvcreate"; "/dev/sda1"]; + ["pvcreate"; "/dev/sda2"]; + ["pvcreate"; "/dev/sda3"]; + ["vgcreate"; "VG1"; "/dev/sda1 /dev/sda2"]; + ["vgcreate"; "VG2"; "/dev/sda3"]; + ["vgs"]], ["VG1"; "VG2"])], "list the LVM volume groups (VGs)", "\ List all the volumes groups detected. This is the equivalent @@ -296,6 +763,19 @@ detected (eg. C). See also C."); ("lvs", (RStringList "logvols", []), 11, [], + [InitBasicFSonLVM, Always, TestOutputList ( + [["lvs"]], ["/dev/VG/LV"]); + InitEmpty, Always, TestOutputList ( + [["sfdisk"; "/dev/sda"; "0"; "0"; "0"; ",10 ,20 ,"]; + ["pvcreate"; "/dev/sda1"]; + ["pvcreate"; "/dev/sda2"]; + ["pvcreate"; "/dev/sda3"]; + ["vgcreate"; "VG1"; "/dev/sda1 /dev/sda2"]; + ["vgcreate"; "VG2"; "/dev/sda3"]; + ["lvcreate"; "LV1"; "VG1"; "50"]; + ["lvcreate"; "LV2"; "VG1"; "50"]; + ["lvcreate"; "LV3"; "VG2"; "50"]; + ["lvs"]], ["/dev/VG1/LV1"; "/dev/VG1/LV2"; "/dev/VG2/LV3"])], "list the LVM logical volumes (LVs)", "\ List all the logical volumes detected. This is the equivalent @@ -307,24 +787,33 @@ This returns a list of the logical volume device names See also C."); ("pvs_full", (RPVList "physvols", []), 12, [], + [], (* XXX how to test? *) "list the LVM physical volumes (PVs)", "\ List all the physical volumes detected. This is the equivalent of the L command. The \"full\" version includes all fields."); ("vgs_full", (RVGList "volgroups", []), 13, [], + [], (* XXX how to test? *) "list the LVM volume groups (VGs)", "\ List all the volumes groups detected. This is the equivalent of the L command. The \"full\" version includes all fields."); ("lvs_full", (RLVList "logvols", []), 14, [], + [], (* XXX how to test? *) "list the LVM logical volumes (LVs)", "\ List all the logical volumes detected. This is the equivalent of the L command. The \"full\" version includes all fields."); ("read_lines", (RStringList "lines", [String "path"]), 15, [], + [InitBasicFS, Always, TestOutputList ( + [["write_file"; "/new"; "line1\r\nline2\nline3"; "0"]; + ["read_lines"; "/new"]], ["line1"; "line2"; "line3"]); + InitBasicFS, Always, TestOutputList ( + [["write_file"; "/new"; ""; "0"]; + ["read_lines"; "/new"]], [])], "read file as lines", "\ Return the contents of the file named C. @@ -338,6 +827,7 @@ as end of line). For those you need to use the C function which has a more complex interface."); ("aug_init", (RErr, [String "root"; Int "flags"]), 16, [], + [], (* XXX Augeas code needs tests. *) "create a new Augeas handle", "\ Create a new Augeas handle for editing configuration files. @@ -388,6 +878,7 @@ To close the handle, you can call C. To find out more about Augeas, see L."); ("aug_close", (RErr, []), 26, [], + [], (* XXX Augeas code needs tests. *) "close the current Augeas handle", "\ Close the current Augeas handle and free up any resources @@ -396,6 +887,7 @@ C again before you can use any other Augeas functions."); ("aug_defvar", (RInt "nrnodes", [String "name"; OptString "expr"]), 17, [], + [], (* XXX Augeas code needs tests. *) "define an Augeas variable", "\ Defines an Augeas variable C whose value is the result @@ -406,6 +898,7 @@ On success this returns the number of nodes in C, or C<0> if C evaluates to something which is not a nodeset."); ("aug_defnode", (RIntBool ("nrnodes", "created"), [String "name"; String "expr"; String "val"]), 18, [], + [], (* XXX Augeas code needs tests. *) "define an Augeas node", "\ Defines a variable C whose value is the result of @@ -420,17 +913,20 @@ number of nodes in the nodeset, and a boolean flag if a node was created."); ("aug_get", (RString "val", [String "path"]), 19, [], + [], (* XXX Augeas code needs tests. *) "look up the value of an Augeas path", "\ Look up the value associated with C. If C matches exactly one node, the C is returned."); ("aug_set", (RErr, [String "path"; String "val"]), 20, [], + [], (* XXX Augeas code needs tests. *) "set Augeas path to value", "\ Set the value associated with C to C."); ("aug_insert", (RErr, [String "path"; String "label"; Bool "before"]), 21, [], + [], (* XXX Augeas code needs tests. *) "insert a sibling Augeas node", "\ Create a new sibling C