X-Git-Url: http://git.annexia.org/?a=blobdiff_plain;f=src%2Fgenerator.ml;h=d3040d5fb88eb97ed7779923a87e9afb57ecf85b;hb=9af96c41f64567e6fbe0dd25f6ffa90385e9c49a;hp=7c0e566209a67c4157b489d1773165ecbca7d99f;hpb=ca75b55ec25f8ae3463702f16cdeb95ebde2916a;p=libguestfs.git diff --git a/src/generator.ml b/src/generator.ml index 7c0e566..d3040d5 100755 --- a/src/generator.ml +++ b/src/generator.ml @@ -24,8 +24,10 @@ * 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 - * all the output files. + * After editing this file, run it (./src/generator.ml) to regenerate all the + * output files. Note that if you are using a separate build directory you must + * run generator.ml from your top level build directory. You must also have run + * configure before generator.ml will run. * * IMPORTANT: This script should NOT print any warnings. If it prints * warnings, you should treat them as errors. @@ -84,6 +86,16 @@ and ret = * inefficient. Keys should be unique. NULLs are not permitted. *) | RHashtable of string +(* Not implemented: + (* "RBufferOut" is handled almost exactly like RString, but + * it allows the string to contain arbitrary 8 bit data including + * ASCII NUL. In the C API this causes an implicit extra parameter + * to be added of type . Other programming languages + * support strings with arbitrary 8 bit data. At the RPC layer + * we have to use the opaque<> type instead of string<>. + *) + | RBufferOut of string +*) and args = argt list (* Function parameters, guestfs handle is implicit. *) @@ -110,6 +122,18 @@ and argt = *) | FileIn of string | FileOut of string +(* Not implemented: + (* Opaque buffer which can contain arbitrary 8 bit data. + * In the C API, this is expressed as pair. + * Most other languages have a string type which can contain + * ASCII NUL. We use whatever type is appropriate for each + * language. + * Buffers are limited by the total message size. To transfer + * large blocks of data, use FileIn/FileOut parameters instead. + * To return an arbitrary buffer, use RBufferOut. + *) + | BufferIn of string +*) type flags = | ProtocolLimitWarning (* display warning about protocol size limits *) @@ -183,6 +207,10 @@ and test = *) | TestOutputInt of seq * int (* Run the command sequence and expect the output of the final + * command to be , eg. ">=", "1". + *) + | TestOutputIntOp of seq * string * int + (* Run the command sequence and expect the output of the final * command to be a true value (!= 0 or != NULL). *) | TestOutputTrue of seq @@ -206,6 +234,7 @@ and test = and test_field_compare = | CompareWithInt of string * int + | CompareWithIntOp of string * string * int | CompareWithString of string * string | CompareFieldsIntEq of string * string | CompareFieldsStrEq of string * string @@ -442,7 +471,8 @@ environment variable. Setting C to C restores the default qemu binary."); ("get_qemu", (RConstString "qemu", []), -1, [], - [], + [InitNone, Always, TestRun ( + [["get_qemu"]])], "get the qemu binary", "\ Return the current qemu binary. @@ -462,7 +492,8 @@ C environment variable. Setting C to C restores the default path."); ("get_path", (RConstString "path", []), -1, [], - [], + [InitNone, Always, TestRun ( + [["get_path"]])], "get the search path", "\ Return the current search path. @@ -484,6 +515,10 @@ Setting C to C means I additional options are passed (libguestfs always adds a few of its own)."); ("get_append", (RConstString "append", []), -1, [], + (* This cannot be tested with the current framework. The + * function can return NULL in normal operations, which the + * test framework interprets as an error. + *) [], "get the additional kernel options", "\ @@ -505,7 +540,8 @@ This is disabled by default (except in guestfish where it is enabled by default)."); ("get_autosync", (RBool "autosync", []), -1, [], - [], + [InitNone, Always, TestRun ( + [["get_autosync"]])], "get autosync mode", "\ Get the autosync flag."); @@ -526,7 +562,8 @@ C is defined and set to C<1>."); This returns the verbose messages flag."); ("is_ready", (RBool "ready", []), -1, [], - [], + [InitNone, Always, TestOutputTrue ( + [["is_ready"]])], "is ready to accept commands", "\ This returns true iff this handle is ready to accept commands @@ -535,7 +572,8 @@ This returns true iff this handle is ready to accept commands For more information on states, see L."); ("is_config", (RBool "config", []), -1, [], - [], + [InitNone, Always, TestOutputFalse ( + [["is_config"]])], "is in configuration state", "\ This returns true iff this handle is being configured @@ -544,7 +582,8 @@ This returns true iff this handle is being configured For more information on states, see L."); ("is_launching", (RBool "launching", []), -1, [], - [], + [InitNone, Always, TestOutputFalse ( + [["is_launching"]])], "is launching subprocess", "\ This returns true iff this handle is launching the subprocess @@ -553,7 +592,8 @@ This returns true iff this handle is launching the subprocess For more information on states, see L."); ("is_busy", (RBool "busy", []), -1, [], - [], + [InitNone, Always, TestOutputFalse ( + [["is_busy"]])], "is busy processing a command", "\ This returns true iff this handle is busy processing a command @@ -599,7 +639,9 @@ actions using the low-level API. For more information on states, see L."); ("set_memsize", (RErr, [Int "memsize"]), -1, [FishAlias "memsize"], - [], + [InitNone, Always, TestOutputInt ( + [["set_memsize"; "500"]; + ["get_memsize"]], 500)], "set memory allocated to the qemu subprocess", "\ This sets the memory size in megabytes allocated to the @@ -614,7 +656,8 @@ For more information on the architecture of libguestfs, see L."); ("get_memsize", (RInt "memsize", []), -1, [], - [], + [InitNone, Always, TestOutputIntOp ( + [["get_memsize"]], ">=", 256)], "get memory allocated to the qemu subprocess", "\ This gets the memory size in megabytes allocated to the @@ -628,7 +671,8 @@ For more information on the architecture of libguestfs, see L."); ("get_pid", (RInt "pid", []), -1, [FishAlias "pid"], - [], + [InitNone, Always, TestOutputIntOp ( + [["get_pid"]], ">=", 1)], "get PID of qemu subprocess", "\ Return the process ID of the qemu subprocess. If there is no @@ -636,6 +680,36 @@ qemu subprocess, then this will return an error. This is an internal call used for debugging and testing."); + ("version", (RStruct ("version", "version"), []), -1, [], + [InitNone, Always, TestOutputStruct ( + [["version"]], [CompareWithInt ("major", 1)])], + "get the library version number", + "\ +Return the libguestfs version number that the program is linked +against. + +Note that because of dynamic linking this is not necessarily +the version of libguestfs that you compiled against. You can +compile the program, and then at runtime dynamically link +against a completely different C library. + +This call was added in version C<1.0.58>. In previous +versions of libguestfs there was no way to get the version +number. From C code you can use ELF weak linking tricks to find out if +this symbol exists (if it doesn't, then it's an earlier version). + +The call returns a structure with four elements. The first +three (C, C and C) are numbers and +correspond to the usual version triplet. The fourth element +(C) is a string and is normally empty, but may be +used for distro-specific information. + +To construct the original version string: +C<$major.$minor.$release$extra> + +I Don't use this call to test for availability +of features. Distro backports makes this unreliable."); + ] (* daemon_functions are any functions which cause some action @@ -1644,8 +1718,8 @@ This uses the L command."); ("upload", (RErr, [FileIn "filename"; String "remotefilename"]), 66, [], [InitBasicFS, Always, TestOutput ( (* Pick a file from cwd which isn't likely to change. *) - [["upload"; "../COPYING.LIB"; "/COPYING.LIB"]; - ["checksum"; "md5"; "/COPYING.LIB"]], "e3eda01d9815f8d24aae2dbd89b68b06")], + [["upload"; "../COPYING.LIB"; "/COPYING.LIB"]; + ["checksum"; "md5"; "/COPYING.LIB"]], "e3eda01d9815f8d24aae2dbd89b68b06")], "upload a file from the local machine", "\ Upload local file C to C on the @@ -1658,10 +1732,10 @@ See also C."); ("download", (RErr, [String "remotefilename"; FileOut "filename"]), 67, [], [InitBasicFS, Always, TestOutput ( (* Pick a file from cwd which isn't likely to change. *) - [["upload"; "../COPYING.LIB"; "/COPYING.LIB"]; - ["download"; "/COPYING.LIB"; "testdownload.tmp"]; - ["upload"; "testdownload.tmp"; "/upload"]; - ["checksum"; "md5"; "/upload"]], "e3eda01d9815f8d24aae2dbd89b68b06")], + [["upload"; "../COPYING.LIB"; "/COPYING.LIB"]; + ["download"; "/COPYING.LIB"; "testdownload.tmp"]; + ["upload"; "testdownload.tmp"; "/upload"]; + ["checksum"; "md5"; "/upload"]], "e3eda01d9815f8d24aae2dbd89b68b06")], "download a file to the local machine", "\ Download file C and save it as C @@ -2283,19 +2357,19 @@ are activated or deactivated."); ("lvresize", (RErr, [String "device"; Int "mbytes"]), 105, [], [InitNone, Always, TestOutput ( - [["sfdiskM"; "/dev/sda"; ","]; - ["pvcreate"; "/dev/sda1"]; - ["vgcreate"; "VG"; "/dev/sda1"]; - ["lvcreate"; "LV"; "VG"; "10"]; - ["mkfs"; "ext2"; "/dev/VG/LV"]; - ["mount"; "/dev/VG/LV"; "/"]; - ["write_file"; "/new"; "test content"; "0"]; - ["umount"; "/"]; - ["lvresize"; "/dev/VG/LV"; "20"]; - ["e2fsck_f"; "/dev/VG/LV"]; - ["resize2fs"; "/dev/VG/LV"]; - ["mount"; "/dev/VG/LV"; "/"]; - ["cat"; "/new"]], "test content")], + [["sfdiskM"; "/dev/sda"; ","]; + ["pvcreate"; "/dev/sda1"]; + ["vgcreate"; "VG"; "/dev/sda1"]; + ["lvcreate"; "LV"; "VG"; "10"]; + ["mkfs"; "ext2"; "/dev/VG/LV"]; + ["mount"; "/dev/VG/LV"; "/"]; + ["write_file"; "/new"; "test content"; "0"]; + ["umount"; "/"]; + ["lvresize"; "/dev/VG/LV"; "20"]; + ["e2fsck_f"; "/dev/VG/LV"]; + ["resize2fs"; "/dev/VG/LV"]; + ["mount"; "/dev/VG/LV"; "/"]; + ["cat"; "/new"]], "test content")], "resize an LVM logical volume", "\ This resizes (expands or shrinks) an existing LVM logical @@ -2367,7 +2441,7 @@ This command is only needed because of C ("sleep", (RErr, [Int "secs"]), 109, [], [InitNone, Always, TestRun ( - [["sleep"; "1"]])], + [["sleep"; "1"]])], "sleep for some seconds", "\ Sleep for C seconds."); @@ -2783,6 +2857,17 @@ were rarely if ever used anyway. See also C and the L manpage."); + ("zfile", (RString "description", [String "method"; String "path"]), 140, [], + [], + "determine file type inside a compressed file", + "\ +This command runs C after first decompressing C +using C. + +C must be one of C, C or C. + +See also: C"); + ] let all_functions = non_daemon_functions @ daemon_functions @@ -2928,6 +3013,14 @@ let structs = [ "ftyp", FChar; "name", FString; ]; + + (* Version numbers. *) + "version", [ + "major", FInt64; + "minor", FInt64; + "release", FInt64; + "extra", FString; + ]; ] (* end of structs *) (* Ugh, Java has to be different .. @@ -2940,7 +3033,8 @@ let java_structs = [ "lvm_lv", "LV"; "stat", "Stat"; "statvfs", "StatVFS"; - "dirent", "Dirent" + "dirent", "Dirent"; + "version", "Version"; ] (* Used for testing language bindings. *) @@ -3091,7 +3185,8 @@ let cols_of_struct typ = let seq_of_test = function | TestRun s | TestOutput (s, _) | TestOutputList (s, _) | TestOutputListOfDevices (s, _) - | TestOutputInt (s, _) | TestOutputTrue s | TestOutputFalse s + | TestOutputInt (s, _) | TestOutputIntOp (s, _, _) + | TestOutputTrue s | TestOutputFalse s | TestOutputLength (s, _) | TestOutputStruct (s, _) | TestLastFail s -> s @@ -3642,7 +3737,7 @@ check_state (guestfs_h *g, const char *caller) { if (!guestfs_is_ready (g)) { if (guestfs_is_config (g)) - error (g, \"%%s: call launch() before using this function\", + error (g, \"%%s: call launch before using this function\\n(in guestfish, don't forget to use the 'run' command)\", caller); else if (guestfs_is_launching (g)) error (g, \"%%s: call wait_ready() before using this function\", @@ -4582,7 +4677,11 @@ static int %s (void) and generate_one_test_body name i test_name init test = (match init with - | InitNone + | InitNone (* XXX at some point, InitNone and InitEmpty became + * folded together as the same thing. Really we should + * make InitNone do nothing at all, but the tests may + * need to be checked to make sure this is OK. + *) | InitEmpty -> pr " /* InitNone|InitEmpty for %s */\n" test_name; List.iter (generate_test_command_call test_name) @@ -4708,6 +4807,19 @@ and generate_one_test_body name i test_name init test = in List.iter (generate_test_command_call test_name) seq; generate_test_command_call ~test test_name last + | TestOutputIntOp (seq, op, expected) -> + pr " /* TestOutputIntOp for %s (%d) */\n" name i; + let seq, last = get_seq_last seq in + let test () = + pr " if (! (r %s %d)) {\n" op expected; + pr " fprintf (stderr, \"%s: expected %s %d but got %%d\\n\"," + test_name op expected; + pr " (int) r);\n"; + pr " return -1;\n"; + pr " }\n" + in + List.iter (generate_test_command_call test_name) seq; + generate_test_command_call ~test test_name last | TestOutputTrue seq -> pr " /* TestOutputTrue for %s (%d) */\n" name i; let seq, last = get_seq_last seq in @@ -4766,6 +4878,13 @@ and generate_one_test_body name i test_name init test = pr " (int) r->%s);\n" field; pr " return -1;\n"; pr " }\n" + | CompareWithIntOp (field, op, expected) -> + pr " if (!(r->%s %s %d)) {\n" field op expected; + pr " fprintf (stderr, \"%s: %s was %%d, expected %s %d\\n\",\n" + test_name field op expected; + pr " (int) r->%s);\n" field; + pr " return -1;\n"; + pr " }\n" | CompareWithString (field, expected) -> pr " if (strcmp (r->%s, \"%s\") != 0) {\n" field expected; pr " fprintf (stderr, \"%s: %s was \"%%s\", expected \"%s\"\\n\",\n" @@ -8106,7 +8225,7 @@ let output_to filename = let () = check_functions (); - if not (Sys.file_exists "HACKING") then ( + if not (Sys.file_exists "config.status") then ( eprintf "\ You are probably running this from the wrong directory. Run it from the top source directory using the command @@ -8232,6 +8351,15 @@ Run it from the top source directory using the command close (); ) java_structs; + let close = output_to "java/Makefile.inc" in + pr "java_built_sources ="; + List.iter ( + fun (typ, jtyp) -> + pr " com/redhat/et/libguestfs/%s.java" jtyp; + ) java_structs; + pr " com/redhat/et/libguestfs/GuestFS.java\n"; + close (); + let close = output_to "java/com_redhat_et_libguestfs_GuestFS.c" in generate_java_c (); close ();