[PATCH 5 of 6 RFC hglib] hg_fetch_cset_entry: will get, parse and pass changesets to user
Iulian Stana
julian.stana at gmail.com
Thu Sep 5 09:13:25 CDT 2013
# HG changeset patch
# User Iulian Stana <julian.stana at gmail.com>
# Date 1378389265 -10800
# Thu Sep 05 16:54:25 2013 +0300
# Node ID 45ab6314f20f386125e15e369cd1b719e3e7ebf2
# Parent 17d04670c65d6e6653a7a3c7875f2918abe073c3
hg_fetch_cset_entry: will get, parse and pass changesets to user
diff --git a/client.c b/client.c
--- a/client.c
+++ b/client.c
@@ -105,3 +105,60 @@
}
return exitcode;
}
+
+
+/* The cbuf next step. Getting the next changeset. */
+int hg_fetch_cset_entry(hg_csetstream_buffer *cbuf, hg_cset_entry *centry)
+{
+ hg_header head;
+ int exitcode, bc;
+ char *get_data;
+
+ /* Erase the first cset from cset pointer.
+ * This cset was already pass to user.*/
+ if(cbuf->buf_size){
+ cbuf->buf_size = erase_cset(&cbuf->buffer, cbuf->buf_size,
+ cbuf->first_cset_size);
+ }
+
+ while(!detect_null_byte(cbuf->buffer + 1, cbuf->buf_size, 1))
+ {
+ head = hg_head(cbuf->handle);
+ if(head.channel == 'r')
+ break;
+ /* if there is any error, read everything from pipe:
+ * pass error data to callback function
+ * trash the output data
+ * read the exticode
+ * return -1;
+ **/
+ else if(head.channel == 'e'){
+ trash_data(cbuf->handle, cbuf->callback);
+ return -1;
+ }
+
+ get_data = malloc(head.length + 1);
+ if(bc = hg_rawread(cbuf->handle, get_data, head.length), bc < 0)
+ return -1;
+ append_data(&cbuf->buffer, get_data, cbuf->buf_size, bc);
+ cbuf->buf_size += bc;
+ free(get_data);
+ }
+
+ if(bc = detect_null_byte(cbuf->buffer + 1, cbuf->buf_size, 0), bc > 0){
+ cbuf->first_cset_size = bc + 1;
+ parse_changeset(cbuf->buffer + 1, centry);
+ return 1;
+ /* Parse first cset from the remaining data. */
+ }
+
+ exitcode = hg_exitcode(cbuf->handle);
+ free(cbuf->command);
+ free(cbuf->buffer);
+ free(cbuf);
+ if(exitcode)
+ return -1;
+ return 0;
+
+}
+
diff --git a/client.h b/client.h
--- a/client.h
+++ b/client.h
@@ -49,4 +49,35 @@
hg_csetstream_buffer *hg_log(hg_handle *handle, int (*callback)(const char *msg,
size_t len), char *argument[]);
+/**
+ * \brief The iterator step. Getting the next changeset.
+ *
+ * The revision history could have a huge mass of data. You cannot pass the
+ * entire history in one call, so we use an iterator-like mechanism. Calling
+ * the hg_fetch_log_entry. The next changeset will be read from cmd-server,
+ * parse and pass to hg_cset_entry structure.
+ * The cset_entry structure will handle a changeset with the following string
+ * fields:
+ * - rev
+ * - node
+ * - tags (space delimited)
+ * - branch
+ * - author
+ * - desc
+ *
+ * \param hg_csetstream_buffer The buffer structure to store cset data.
+ * \param centry The hg_cset_entry structure where the changeset will be stored
+ * and pass
+ * \retval 1 Succesful operation, pass the first find cset to centry structure
+ * \retval 0 To indicate the end of log_command, everything works well.
+ * \retval -1 to indicate an error, with errno set appropriately.
+ *
+ * errno can be:
+ * - EINVAL - Invalid argument (handle it's set to a null pointer)
+ * - read(2) command errors
+ * - read_header error
+ * */
+int hg_fetch_cset_entry(hg_csetstream_buffer *cbuf, hg_cset_entry *centry);
+
+
#endif
More information about the Mercurial-devel
mailing list