mgcp: Add new for_each_line macro that also returns empty lines

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
This commit is contained in:
Jacob Erlbeck
2013-11-29 13:43:44 +01:00
committed by Holger Hans Peter Freyther
parent a01bd60851
commit 2bee7f96ff
3 changed files with 80 additions and 0 deletions

View File

@@ -40,6 +40,38 @@
for (line = strtok_r(NULL, "\r\n", &save); line;\ for (line = strtok_r(NULL, "\r\n", &save); line;\
line = strtok_r(NULL, "\r\n", &save)) 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 */ /* Assume audio frame length of 20ms */
#define DEFAULT_RTP_AUDIO_FRAME_DUR_NUM 20 #define DEFAULT_RTP_AUDIO_FRAME_DUR_NUM 20
#define DEFAULT_RTP_AUDIO_FRAME_DUR_DEN 1000 #define DEFAULT_RTP_AUDIO_FRAME_DUR_DEN 1000

View File

@@ -25,6 +25,40 @@
#include <string.h> #include <string.h>
#include <limits.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@172.16.6.66 MGCP 1.0\r\n" #define AUEP1 "AUEP 158663169 ds/e1-1/2@172.16.6.66 MGCP 1.0\r\n"
#define AUEP1_RET "200 158663169 OK\r\n" #define AUEP1_RET "200 158663169 OK\r\n"
#define AUEP2 "AUEP 18983213 ds/e1-2/1@172.16.6.66 MGCP 1.0\r\n" #define AUEP2 "AUEP 18983213 ds/e1-2/1@172.16.6.66 MGCP 1.0\r\n"
@@ -463,6 +497,7 @@ int main(int argc, char **argv)
{ {
osmo_init_logging(&log_info); osmo_init_logging(&log_info);
test_strline();
test_messages(); test_messages();
test_retransmission(); test_retransmission();
test_packet_loss_calc(); test_packet_loss_calc();

View File

@@ -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 AUEP1
Testing AUEP2 Testing AUEP2
Testing MDCX1 Testing MDCX1