From patchwork Sat Sep 14 00:35:16 2013 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: [04, of, 55, RFC, c-hglib:level1] client: additional functions (hg_runcommand and hg_abort) used for model 2 From: Iulian Stana X-Patchwork-Id: 2449 Message-Id: To: mercurial-devel@selenic.com Date: Sat, 14 Sep 2013 03:35:16 +0300 # HG changeset patch # User Iulian Stana # Date 1379108986 -10800 # Sat Sep 14 00:49:46 2013 +0300 # Node ID a48c610e5e6425f88530f8640910c658dd442a47 # Parent 25faae6c272acbdb530b7cefa5e16521f01851f9 client: additional functions (hg_runcommand and hg_abort) used for model 2 hg_runcommand: read or write data to the pipe hg_abort: will return a zero-length string diff --git a/client.c b/client.c --- a/client.c +++ b/client.c @@ -311,3 +311,59 @@ { return handle->out_data; } + +/* Will return a zero-length string. */ +char *hg_abort(const char *msg, size_t size) +{ + return ""; +} + +/* Read and add to some pointers the received data from cmdserver. */ +int hg_runcommand(hg_handle *handle, int (*callback)(const char *msg, size_t len), + char *(*prompt)(const char *msg, size_t len)) +{ + char buff[4096]; + int exitcode; + int nb; + char *err = "unexpected data on required channel"; + char *w_data; + hg_header *head; + while(head = hg_read_header(handle), head->channel != r){ + + if(head->channel == o){ + if(nb = hg_rawread(handle, buff, 4096), nb > 0){ + append_data(&handle->out_data, buff, + handle->out_data_size, nb); + handle->out_data_size += nb; + } + } + /* handle error data. */ + else if(head->channel == e){ + if(nb = hg_rawread(handle, buff, 4096), nb > 0) + if(callback) + callback(buff, strlen(buff)); + } + else if(head->channel == I || head->channel == L){ + if(prompt) + w_data = prompt(handle->out_data, + strlen(handle->out_data)); + else + w_data = hg_abort(NULL, 0); + hg_rawwrite(handle, w_data, strlen(w_data)); + } + else if(head->channel == r){ + break; + } + /* a channel that we don't know and can't ignore*/ + else { + if(callback) + callback(err, strlen(err)); + return 1; + } + } + if(head->channel == r){ + exitcode = hg_exitcode(handle); + } + return exitcode; +} + diff --git a/client.h b/client.h --- a/client.h +++ b/client.h @@ -213,4 +213,25 @@ **/ char *get_output_data(hg_handle *handle); +/** + * \brief Read or write data to the pipe. + * + * This function will handle all data from command server the output data will + * be append to handle->out_data filed and the error data will be handle by + * callback function or will be ingnored in case of using a NULL pointer in + * stead of a function. + * + * The input data will be also handled by a prompt function provide by user or + * will be "ignored"/"the abort function" will send no data to command server. + * + * \param handle The handle of the connection, wherewith I want to communicate + * \param callback A function that will handle error data. + * A NULL pointer will ignore error data. + * \param prompt A function that will handle prompts messages. + * A NULL pointer will use an abort function. + * \retval exitcode To indicate the end of runned commend. + **/ +int hg_runcommand(hg_handle *handle, int (*callback)(const char *msg, size_t len), + char *(*prompt)(const char *msg, size_t len)) + #endif