Patchwork [3,of,3,RFC,-V3] model (2): c-hglib: hg_add() level 1 function

login
register
mail settings
Submitter Iulian Stana
Date Aug. 22, 2013, 2:20 p.m.
Message ID <3f9b35bb34df6f99e6a7.1377181202@doppler>
Download mbox | patch
Permalink /patch/2239/
State Deferred
Headers show

Comments

Iulian Stana - Aug. 22, 2013, 2:20 p.m.
# HG changeset patch
# User Iulian Stana <julian.stana@gmail.com>
# Date 1377180778 -10800
#      Thu Aug 22 17:12:58 2013 +0300
# Node ID 3f9b35bb34df6f99e6a7d8252a42375e8a73bf3b
# Parent  7fd664aa77f2cd8668510acf54c20c6474e5b5ce
model (2): c-hglib: hg_add() level 1 function

This mechanism could be called model (2):

(2) Wait for the commandserv to complete *all* his actions in response to
    the issued command, which is cache the commandserv response somewhere,
    and return the actual exitcode (channel 'r' from commandserv)
    as the result of the chglib API call"


The add command and more other mercurial commands, are not performing any kind
of parse data. The most important thing on those commands is the exitcode, if
everything works well or not.

More than that those commands will have a quickly exit. There is needed a short
time to process them.

But sometimes the command server could send some error or debug data, that
probably the user would like to know about, or to process it. For this thing I
created three pointers where the data will be stored. (This data is unparse!)

Patch

diff --git a/client.c b/client.c
--- a/client.c
+++ b/client.c
@@ -115,6 +115,66 @@ 
 	return new_cset_size;
 }
 
+/* return the output data. */
+char *get_output_data(hg_handle *handle)
+{
+	return handle->out_data;
+}
+
+/* return the error data. */
+char *get_error_data(hg_handle *handle)
+{
+	return handle->error_data;
+}
+
+/* return the debug data. */
+char *get_debug_data(hg_handle *handle)
+{
+	return handle->debug_data;
+}
+
+/* Read and add to some pointers the data */
+int runcommand(hg_handle *handle)
+{
+	char buff[4096];
+	int exitcode;
+	int ns;
+
+	while(hg_channel(handle) != 'r'){
+			if(hg_channel(handle) == 'o'){
+				adding_data(&handle->out_data, buff,
+					strlen(handle->out_data), strlen(buff));
+			}
+			else if(hg_channel(handle) == 'e'){
+				adding_data(&handle->error_data, buff,
+					strlen(handle->error_data), strlen(buff));
+			}
+			else{
+				adding_data(&handle->debug_data, buff,
+					strlen(handle->debug_data), strlen(buff));
+			}
+		}
+	}
+	exitcode = hg_exitcode(handle);
+
+	return exitcode;
+}
+
+/* The high level add command for hglib API.*/
+int hg_add(hg_handle *handle, char *argument[])
+{
+	int exitcode;
+	char **command = cmdbuilder("add", argument, NULL);
+
+	if(hg_rawcommand(handle, command) < 0){
+		return -1;
+	}
+	free(command);
+
+	exitcode = runcommand(handle);
+
+	return exitcode;
+}
 
 /* The high level log command for hglib API. */
 hg_cset_iterator *hg_log(hg_handle *handle, char *option[])
diff --git a/client.h b/client.h
--- a/client.h
+++ b/client.h
@@ -63,6 +63,10 @@ 
 	int p_read;
 	int p_write;
 	int protect;
+	
+	char *out_data;
+	char *error_data;
+	char *debug_data;
 } hg_handle;
 
 typedef struct hg_cset_iterator{
@@ -216,6 +220,50 @@ 
 int hg_exitcode(hg_handle *handle);
 
 /**
+ * \brief Getting the output data, received from the last command.
+ *
+ * \param handle The handle of the connection, wherewith I want to communicate
+ * \retval string Indicate the output data.
+ **/
+char *get_output_data(hg_handle *handle);
+
+/**
+ * \brief Getting the error data, received from the last command.
+ *
+ * \param handle The handle of the connection, wherewith I want to communicate
+ * \retval string Indicate the error data.
+ **/
+char *get_error_data(hg_handle *handle);
+
+/**
+ * \brief Getting the debug data, received from the last command.
+ *
+ * \param handle The handle of the connection, wherewith I want to communicate
+ * \retval string Indicate the debug data.
+ **/
+char *get_debug_data(hg_handle *handle);
+
+/**
+ * \brief hg_add command for hglib API.
+ *
+ * Add the specified files on the next commit.
+ * If no files are given, add all files to the repository.
+ *
+ *      dryrun - do no perform actions
+ *      subrepos - recurse into subrepositories
+ *      include - include names matching the given patterns
+ *      exclude - exclude names matching the given patterns
+ *
+ * \param handle The handle of the connection, wherewith I want to communicate
+ * \param option The option list for mercurial add command.
+ * \retval exitcode  To indicate the end of add_command.
+ *
+ * errno can be:
+ *      - hg_rawcommand errors
+ * */
+int hg_add(hg_handle *handle, char *argument[]);
+
+/**
  * \brief hg_log command for hglib API.
  *
  * It's an advance function to get revision history. It's more like the start 
diff --git a/main.c b/main.c
--- a/main.c
+++ b/main.c
@@ -89,6 +89,7 @@ 
 {
 	printf("Select test case to run:\n");
 	printf("1) log \n");
+	printf("2) add \n");
 	printf("\n");
 	printf("Your choice: ");
 }
@@ -105,7 +106,7 @@ 
 
 	print_select_case();
 	scanf("%d", &select_case);
-	if(select_case < 1 || select_case > 1){
+	if(select_case < 1 || select_case > 2){
 		printf("Your choice is not an option...\n");
 		return -1;
 	}
@@ -121,6 +122,23 @@ 
 			hg_close(&handle);
 			clean_tmp();
 			break;
+		case 2:
+			setup_tmp();
+			
+			system("touch 'foo_bar'");
+			system("hg st");
+
+			handle = hg_open(NULL, "");
+			char *arguments[] = {"foo_barr","--ff", NULL};
+			printf("exitcode %d\n", hg_add(handle, arguments));
+			printf("out_data = %s \n", get_output_data(handle));
+			printf("debug_data = %s \n", get_debug_data(handle));
+			
+			system("hg st");
+			
+			hg_close(&handle);
+			clean_tmp();
+			break;
 		default:
 			break;
 	}