# # patch "ChangeLog" # from [ff8c5b74caec143b53b946742bcf9738c2c840c2] # to [21a8e19ee3658d7856b3170f76c03790cb5a1aaa] # # patch "automate.cc" # from [004901821667adc38fe25860366b855c46af630d] # to [499b45688ed75fbfa45c9ab9d2551d48015ffdc6] # # patch "constants.cc" # from [3fd062ad419efedd4ec4fd0cd5452fbdd94d54c6] # to [6ea5ae0591af040ba8acbaf3cb826b8f2b5dac55] # # patch "constants.hh" # from [45cfb66d005ea786cc1852aedbb16d51e7d82db7] # to [4a4494bcaa97ec07c147fc066564519bb4d13481] # # patch "monotone.texi" # from [960f09d94f2b0189794b11c523426f755ef48f1c] # to [b06b56ffc15a3d9fcfd62aa90a6fc61ceab1beaa] # --- ChangeLog +++ ChangeLog @@ -1,3 +1,11 @@ +2005-05-23 Timothy Brownawell + + Fix "automate stdio" input/output format according to ML discussion + * automate.cc: changed: automate_stdio + added: print_some_output, class my_stringbuf + * constants.{cc,hh}: add constant for automate stdio block size + * monotone.texi: update documentation + 2005-05-14 Timothy Brownawell * contrib/monoprof.sh: Clean up variable definitions some. --- automate.cc +++ automate.cc @@ -9,10 +9,15 @@ #include #include #include +#include +#include +#include + #include "app_state.hh" #include "basic_io.hh" #include "commands.hh" +#include "constants.hh" #include "restrictions.hh" #include "revision.hh" #include "transforms.hh" @@ -800,51 +805,93 @@ // of monotone. // // Input format: The input is a series of lines of the form -// "command [args...]", where "command" is a valid "monotone automate" -// subcommand. Example: -// leaves -// parents 1f4ef73c3e056883c6a5ff66728dd764557db5e6 -// inventory +// [ ...] newline, where is +// colon . +// Example: +// 6:leaves +// 7:parents40:0e3171212f34839c2e3263e7282cdeea22fc5378 // -// Output format: The output consists of the output of each command given, -// preceeded by the line "###BEGIN ###" and followed by the line -// "###END ###", where is the command given. Example: -// ###BEGIN leaves### -// bdff75b3d1a58d5370d1b9aaeed1b5a4d0cba564 -// ed0306ed417d258d82716bee36841199d8bb7626 -// ee0f35591c79c9390baff5e0638b545963d1babf -// ###END leaves### -// ###BEGIN parents### -// 094a5075b4bd7fe379f810edeb5f03283b50e13a -// ###END parents### -// ###BEGIN inventory### -// "work.cc" -// "work.hh" -// "xdelta.cc" -// "xdelta.hh" -// ###END inventory### -// -// Error conditions: If an invalid command line is recieved, prints -// "###ERR usage###" to standard output, where is the name -// of the command that was given. -// If some other error condition occurrs during execution of a command -// received on input, prints "###ERR msg ###", where -// is the name of the command, and is the -// error message provided by that command, which would have been output on -// standard error if the command was invoked directly. -// This "###ERR
###" line replaces the "###END ###" line. +// Output format: :::: +// is a decimal number specifying which command +// this output is from. It is 0 for the first command, and increases +// by one each time. +// is 0 for success, 1 for a syntax error, and 2 for any +// other error. +// is 'l' if this is the last piece of output for this command, +// and 'm' if there is more output to come. +// is the number of bytes in the output. +// is the output of the command. // Example: -// (Input) -// inventor -// inventory -// (Output) -// ###BEGIN inventor### -// ###ERR inventor usage### -// ###BEGIN inventory### -// ###ERR inventory msg misuse: working copy directory required but not found### +// 0:0:l:205:0e3171212f34839c2e3263e7282cdeea22fc5378 +// 1f4ef73c3e056883c6a5ff66728dd764557db5e6 +// 2133c52680aa2492b18ed902bdef7e083464c0b8 +// 23501f8afd1f9ee037019765309b0f8428567f8a +// 2c295fcf5fe20301557b9b3a5b4d437b5ab8ec8c +// 1:0:l:41:7706a422ccad41621c958affa999b1a1dd644e79 // -// Errors do not affect the return value. +// Error conditions: Errors encountered by the commands run only set the error +// code in the output for that command. Malformed input results in exit with +// a non-zero return value and an error message. +//We use our own stringbuf class so we can put in a callback on write. +//This lets us dump output at a set length, rather than waiting until +//we have all of the output. +typedef std::basic_stringbuf, + std::allocator > char_stringbuf; +struct my_stringbuf : public char_stringbuf +{ +private: + std::streamsize written; + boost::function1 on_write; + std::streamsize last_call; + std::streamsize call_every; + bool clear; +public: + my_stringbuf() : char_stringbuf(), + written(0), + last_call(0), + call_every(constants::automate_stdio_size) + {} + virtual std::streamsize + xsputn(const char_stringbuf::char_type* __s, std::streamsize __n) + { + std::streamsize ret=char_stringbuf::xsputn(__s, __n); + written+=__n; + while(written>=last_call+call_every) + { + if(on_write) on_write(call_every); + last_call+=call_every; + } + return ret; + } + void set_on_write(boost::function1 x) + { + on_write = x; + } +}; + +void print_some_output(int cmdnum, + int err, + bool last, + std::string const & text, + std::ostream & s, + int & pos, + int size) +{ + s< args, std::string const & help_name, @@ -853,41 +900,81 @@ { if (args.size() != 0) throw usage(help_name); + int cmdnum = 0; while(!std::cin.eof()) { std::string x; utf8 cmd; args.clear(); bool first=true; - do + int toklen=0; + bool firstchar=true; + for(char c=std::cin.get();c != 'l' && !std::cin.eof();c=std::cin.get()) + ; + for(char c=std::cin.get();c != 'e' && !std::cin.eof(); c=std::cin.get()) { - std::cin>>x; - if(first) - cmd=utf8(x); + if(c<='9' && c>='0') + { + toklen=(toklen*10)+(c-'0'); + } + else if(c == ':') + { + char *tok=new char[toklen+1]; + std::cin.get(tok, toklen+1); + if(first) + cmd=utf8(std::string(tok, toklen)); + else + args.push_back(utf8(std::string(tok, toklen))); + toklen=0; + delete[] tok; + first=false; + } else - args.push_back(utf8(x)); - first=false; + { + N(false, F("Bad input to automate stdio")); + } + firstchar=false; } - while(!std::cin.eof() - && (std::cin.peek() != '\n') - && (std::cin.peek() != '\r')); if(cmd() != "") { - output<<(F("###BEGIN %s###") % cmd)< >::rdbuf(&sb); try { - automate_command(cmd, args, help_name, app, output); - output<<(F("###END %s###") % cmd)< [ ...] 'e', +where = colon . Characters between the ending 'e' +of one commad and the beginning 'l' of the next are ignored. @item Sample output: @verbatim -###BEGIN leaves### -bdff75b3d1a58d5370d1b9aaeed1b5a4d0cba564 -ed0306ed417d258d82716bee36841199d8bb7626 -ee0f35591c79c9390baff5e0638b545963d1babf -###END leaves### -###BEGIN parents### -094a5075b4bd7fe379f810edeb5f03283b50e13a -###END parents### -###BEGIN inventory### - "work.cc" - "work.hh" - "xdelta.cc" - "xdelta.hh" -###END inventory### +0:0:l:205:0e3171212f34839c2e3263e7282cdeea22fc5378 +1f4ef73c3e056883c6a5ff66728dd764557db5e6 +2133c52680aa2492b18ed902bdef7e083464c0b8 +23501f8afd1f9ee037019765309b0f8428567f8a +2c295fcf5fe20301557b9b3a5b4d437b5ab8ec8c +1:0:l:41:7706a422ccad41621c958affa999b1a1dd644e79 @end verbatim @item Output format: -The output consists of the output of each command given, preceeded by -the line "###BEGIN ###" and followed by the line -"###END ###", where is the name of the command. -If an error is encountered while running the command received, the -"###END ###" line is replaced with one of the -"###ERR name
###"lines shown below. +:::: address@hidden Error conditions: + is a decimal number specifying which command this output +is from. It is 0 for the first command, and increases by one each time. -If an invalid command line is recieved, prints "###ERR usage###" -to standard output, where is the name of the command that was -given. If some other error condition occurrs during execution of a command -received on input, prints "###ERR msg ###", where - is the name of the command, and is the error message -provided by that command, which would have been output on standard error -if the command was invoked directly. Output with errors looks like: + is 0 for success, 1 for a syntax error, and 2 for any other error. address@hidden -###BEGIN inventor### -###ERR inventor usage### -###BEGIN inventory### -###ERR inventory msg misuse: working copy directory required but not found### address@hidden verbatim + is 'l' if this is the last piece of output for this command, and 'm' +if there is more output to come. -Errors do not affect the return value. + is the number of bytes in the output. + is the output of the command. This will never exceed 1024 bytes. +If a command produces more than 1024 bytes of output, it will be split into +multiple peices, with all but the last having the field set to 'm'. + address@hidden Error conditions: + +If a badly formatted command is recieved, prints an error message to +standard error and exits with nonzero status. Errors in the commands run +through this interface do not affect the exit status. Instead, the +field in the output is set to 2, and the output of the command becomes +whatever error message would have been given. The output of an invalid +command line will have an error code of 1, and the output text will be a help +message. + @end table @end ftable