[PATCH 2/8] mgcp: Add new for_each_line macro that also returns empty lines

This is merely a historical archive of years 2008-2021, before the migration to mailman3.

A maintained and still updated list archive can be found at https://lists.osmocom.org/hyperkitty/list/OpenBSC@lists.osmocom.org/.

Jacob Erlbeck jerlbeck at sysmocom.de
Fri Nov 29 12:43:44 UTC 2013


This patch add the for_each_line macro based on a strline_r()
function (similar to strtok_r()), that is also part of this patch.
This strline_r() function is tolerant with respect to line endings,
it supports CR-only, CRLF, and LF-only and any combinations thereof
(note that a CRLF is always detected as a single line break).

Similar to for_each_non_empty_line (the former for_each_line) where
the 'save' pointer needed to be initialised by a call to strtok_r(),
the new for_each_line macro expects, that the 'save' pointer has been
initialised by a call to strline_r(). Also note, that
for_each_line/strline_r and for_each_non_empty_line/strtok_r may use
the 'save' pointer differently, so calls to them can not be mixed.

Sponsored-by: On-Waves ehf
---
 openbsc/src/libmgcp/mgcp_protocol.c |   32 ++++++++++++++++++++++++++++++++
 openbsc/tests/mgcp/mgcp_test.c      |   35 +++++++++++++++++++++++++++++++++++
 openbsc/tests/mgcp/mgcp_test.ok     |   13 +++++++++++++
 3 files changed, 80 insertions(+)

diff --git a/openbsc/src/libmgcp/mgcp_protocol.c b/openbsc/src/libmgcp/mgcp_protocol.c
index c040ab1..19a6f53 100644
--- a/openbsc/src/libmgcp/mgcp_protocol.c
+++ b/openbsc/src/libmgcp/mgcp_protocol.c
@@ -40,6 +40,38 @@
 	for (line = strtok_r(NULL, "\r\n", &save); line;\
 	     line = strtok_r(NULL, "\r\n", &save))
 
+#define for_each_line(line, save)			\
+	for (line = strline_r(NULL, &save); line;\
+	     line = strline_r(NULL, &save))
+
+char *strline_r(char *str, char **saveptr)
+{
+	char *result;
+
+	if (str)
+		*saveptr = str;
+
+	result = *saveptr;
+
+	if (*saveptr != NULL) {
+		*saveptr = strpbrk(*saveptr, "\r\n");
+
+		if (*saveptr != NULL) {
+			char *eos = *saveptr;
+
+			if ((*saveptr)[0] == '\r' && (*saveptr)[1] == '\n')
+				(*saveptr)++;
+			(*saveptr)++;
+			if ((*saveptr)[0] == '\0')
+				*saveptr = NULL;
+
+			*eos = '\0';
+		}
+	}
+
+	return result;
+}
+
 /* Assume audio frame length of 20ms */
 #define DEFAULT_RTP_AUDIO_FRAME_DUR_NUM 20
 #define DEFAULT_RTP_AUDIO_FRAME_DUR_DEN 1000
diff --git a/openbsc/tests/mgcp/mgcp_test.c b/openbsc/tests/mgcp/mgcp_test.c
index d36aaa8..362f029 100644
--- a/openbsc/tests/mgcp/mgcp_test.c
+++ b/openbsc/tests/mgcp/mgcp_test.c
@@ -25,6 +25,40 @@
 #include <string.h>
 #include <limits.h>
 
+char *strline_r(char *str, char **saveptr);
+
+const char *strline_test_data =
+    "one CR\r"
+    "two CR\r"
+    "\r"
+    "one CRLF\r\n"
+    "two CRLF\r\n"
+    "\r\n"
+    "one LF\n"
+    "two LF\n"
+    "\n"
+    "mixed (4 lines)\r\r\n\n\r\n";
+
+#define EXPECTED_NUMBER_OF_LINES 13
+
+static void test_strline(void)
+{
+	char *save = NULL;
+	char *line;
+	char buf[2048];
+	int counter = 0;
+
+	strncpy(buf, strline_test_data, sizeof(buf));
+
+	for (line = strline_r(buf, &save); line;
+	     line = strline_r(NULL, &save)) {
+		printf("line: '%s'\n", line);
+		counter++;
+	}
+
+	OSMO_ASSERT(counter == EXPECTED_NUMBER_OF_LINES);
+}
+
 #define AUEP1	"AUEP 158663169 ds/e1-1/2 at 172.16.6.66 MGCP 1.0\r\n"
 #define AUEP1_RET "200 158663169 OK\r\n"
 #define AUEP2	"AUEP 18983213 ds/e1-2/1 at 172.16.6.66 MGCP 1.0\r\n"
@@ -463,6 +497,7 @@ int main(int argc, char **argv)
 {
 	osmo_init_logging(&log_info);
 
+	test_strline();
 	test_messages();
 	test_retransmission();
 	test_packet_loss_calc();
diff --git a/openbsc/tests/mgcp/mgcp_test.ok b/openbsc/tests/mgcp/mgcp_test.ok
index 5666424..429e0df 100644
--- a/openbsc/tests/mgcp/mgcp_test.ok
+++ b/openbsc/tests/mgcp/mgcp_test.ok
@@ -1,3 +1,16 @@
+line: 'one CR'
+line: 'two CR'
+line: ''
+line: 'one CRLF'
+line: 'two CRLF'
+line: ''
+line: 'one LF'
+line: 'two LF'
+line: ''
+line: 'mixed (4 lines)'
+line: ''
+line: ''
+line: ''
 Testing AUEP1
 Testing AUEP2
 Testing MDCX1
-- 
1.7.9.5





More information about the OpenBSC mailing list