Patchwork [04,of,55,RFC,c-hglib:level1] client: additional functions (hg_runcommand and hg_abort) used for model 2

login
register
mail settings
Submitter Iulian Stana
Date Sept. 14, 2013, 12:35 a.m.
Message ID <a48c610e5e6425f88530.1379118916@doppler>
Download mbox | patch
Permalink /patch/2449/
State Deferred, archived
Headers show

Comments

Iulian Stana - Sept. 14, 2013, 12:35 a.m.
# HG changeset patch
# User Iulian Stana <julian.stana@gmail.com>
# 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

Patch

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