From ebce0b8c751182f8adf6c0db76435e1298e8f8d7 Mon Sep 17 00:00:00 2001
From: Zbigniew Chyla <zbigniew.chyla@nsn.com>
Date: Fri, 16 Jan 2015 15:46:59 +0100
Subject: [PATCH 02/10] Add str_starts_with macro, use it instead of strncmp.

This change doesn't affect generated binary code.
---
 driver_nmea0183.c   |  3 ++-
 drivers.c           |  9 +++++----
 gps2udp.c           |  3 ++-
 gpsd.c              | 11 ++++++-----
 gpsmon.c            |  7 ++++---
 json.c              |  4 ++--
 libgps_sock.c       |  3 ++-
 libgpsd_core.c      |  9 +++++----
 monitor_sirf.c      |  4 ++--
 net_gnss_dispatch.c |  9 +++++----
 net_ntrip.c         | 14 ++++++--------
 packet.c            | 11 ++++++-----
 strfuncs.h          |  3 +++
 13 files changed, 50 insertions(+), 40 deletions(-)

diff --git a/driver_nmea0183.c b/driver_nmea0183.c
index 166ba36..653f2f8 100644
--- a/driver_nmea0183.c
+++ b/driver_nmea0183.c
@@ -11,6 +11,7 @@
 #include <time.h>
 
 #include "gpsd.h"
+#include "strfuncs.h"
 
 #ifdef NMEA_ENABLE
 /**************************************************************************
@@ -1339,7 +1340,7 @@ gps_mask_t nmea_parse(char *sentence, struct gps_device_t * session)
     }
 
     /* prevent overaccumulation of sat reports */
-    if (strncmp(session->nmea.field[0] + 2, "GSV", 3) !=0)
+    if (!str_starts_with(session->nmea.field[0] + 2, "GSV"))
 	session->nmea.last_gsv_talker = '\0';
 
     /* timestamp recording for fixes happens here */
diff --git a/drivers.c b/drivers.c
index 6030493..0003ad1 100644
--- a/drivers.c
+++ b/drivers.c
@@ -14,6 +14,7 @@
 
 #include "gpsd.h"
 #include "bits.h"		/* for getbeu16(), to extract big-endian words */
+#include "strfuncs.h"
 
 ssize_t generic_get(struct gps_device_t *session)
 {
@@ -47,7 +48,7 @@ gps_mask_t generic_parse_input(struct gps_device_t *session)
 	for (dp = gpsd_drivers; *dp; dp++) {
 	    char *trigger = (*dp)->trigger;
 
-	    if (trigger!=NULL && strncmp(sentence,trigger,strlen(trigger))==0) {
+	    if (trigger!=NULL && str_starts_with(sentence, trigger)) {
 		gpsd_report(&session->context->errout, LOG_PROG,
 			    "found trigger string %s.\n", trigger);
 		if (*dp != session->device_type) {
@@ -1240,7 +1241,7 @@ static bool aivdm_decode(const char *buf, size_t buflen,
 	 * which makes sense as they don't come in over radio.  This
 	 * is going to break if there's ever an AIVDO type 24, though.
 	 */
-	if (strncmp((const char *)field[0], "!AIVDO", 6) != 0)
+	if (!str_starts_with((const char *)field[0], "!AIVDO"))
 	    gpsd_report(&session->context->errout, LOG_INF,
 			"invalid empty AIS channel. Assuming 'A'\n");
 	ais_context = &session->driver.aivdm.context[0];
@@ -1426,7 +1427,7 @@ static void path_rewrite(struct gps_device_t *session, char *prefix)
     for (prefloc = (char *)session->lexer.outbuffer;
 	 prefloc < (char *)session->lexer.outbuffer+session->lexer.outbuflen;
 	 prefloc++)
-	if (strncmp(prefloc, prefix, strlen(prefix)) == 0) {
+	if (str_starts_with(prefloc, prefix)) {
 	    char copy[sizeof(session->lexer.outbuffer)+1];
 	    (void)strlcpy(copy,
 			  (char *)session->lexer.outbuffer,
@@ -1449,7 +1450,7 @@ static gps_mask_t json_pass_packet(struct gps_device_t *session)
     gpsd_report(&session->context->errout, LOG_IO,
 		"<= GPS: %s\n", (char *)session->lexer.outbuffer);
 
-    if (strncmp(session->gpsdata.dev.path, "gpsd://localhost:", 17) != 0) 
+    if (!str_starts_with(session->gpsdata.dev.path, "gpsd://localhost:"))
     {
 	/*@-nullpass@*/ /* required only because splint is buggy */
 	/* devices and paths need to be edited */
diff --git a/gps2udp.c b/gps2udp.c
index c39004d..7342dc0 100644
--- a/gps2udp.c
+++ b/gps2udp.c
@@ -33,6 +33,7 @@
 #include "gpsd.h"
 #include "gpsdclient.h"
 #include "revision.h"
+#include "strfuncs.h"
 
 #ifndef S_SPLINT_S
 #include <sys/socket.h>
@@ -462,7 +463,7 @@ int main(int argc, char **argv)
 		(void)fprintf (stdout,"---> [%s] -- %s",time2string(),buffer);
 
 		// Try to extract MMSI from AIS payload
-		if (strncmp (buffer,"!AIVDM",6) == 0)
+		if (str_starts_with(buffer, "!AIVDM"))
 		{
 #define MAX_INFO 6
 		    int  i,j;
diff --git a/gpsd.c b/gpsd.c
index e8d93b0..eaa2ebd 100644
--- a/gpsd.c
+++ b/gpsd.c
@@ -48,6 +48,7 @@
 #include "sockaddr.h"
 #include "gps_json.h"
 #include "revision.h"
+#include "strfuncs.h"
 
 #if defined(SYSTEMD_ENABLE)
 #include "sd_socket.h"
@@ -1107,10 +1108,10 @@ static void handle_request(struct subscriber_t *sub,
 
     if (buf[0] == '?')
 	++buf;
-    if (strncmp(buf, "DEVICES;", 8) == 0) {
+    if (str_starts_with(buf, "DEVICES;")) {
 	buf += 8;
 	json_devicelist_dump(reply, replylen);
-    } else if (strncmp(buf, "WATCH", 5) == 0
+    } else if (str_starts_with(buf, "WATCH")
 	       && (buf[5] == ';' || buf[5] == '=')) {
 	const char *start = buf;
 	buf += 5;
@@ -1173,7 +1174,7 @@ static void handle_request(struct subscriber_t *sub,
 	json_devicelist_dump(reply + strlen(reply), replylen - strlen(reply));
 	json_watch_dump(&sub->policy,
 			reply + strlen(reply), replylen - strlen(reply));
-    } else if (strncmp(buf, "DEVICE", 6) == 0
+    } else if (str_starts_with(buf, "DEVICE")
 	       && (buf[6] == ';' || buf[6] == '=')) {
 	struct devconfig_t devconf;
 	buf += 6;
@@ -1304,7 +1305,7 @@ static void handle_request(struct subscriber_t *sub,
 				 reply + strlen(reply),
 				 replylen - strlen(reply));
 	    }
-    } else if (strncmp(buf, "POLL;", 5) == 0) {
+    } else if (str_starts_with(buf, "POLL;")) {
 	char tbuf[JSON_DATE_MAX+1];
 	int active = 0;
 	buf += 5;
@@ -1357,7 +1358,7 @@ static void handle_request(struct subscriber_t *sub,
 	if (reply[strlen(reply) - 1] == ',')
 	    reply[strlen(reply) - 1] = '\0';	/* trim trailing comma */
 	(void)strlcat(reply, "]}\r\n", replylen);
-    } else if (strncmp(buf, "VERSION;", 8) == 0) {
+    } else if (str_starts_with(buf, "VERSION;")) {
 	buf += 8;
 	json_version_dump(reply, replylen);
     } else {
diff --git a/gpsmon.c b/gpsmon.c
index c2ab1aa..e10afc8 100644
--- a/gpsmon.c
+++ b/gpsmon.c
@@ -29,6 +29,7 @@
 #include "gpsmon.h"
 #include "gpsdclient.h"
 #include "revision.h"
+#include "strfuncs.h"
 
 #define BUFLEN		2048
 
@@ -661,7 +662,7 @@ static void gpsmon_hook(struct gps_device_t *device, gps_mask_t changed UNUSED)
 #endif /* NTPSHM_ENABLE */
 
 #if defined(PPS_ENABLE) && defined(CONTROL_SOCKET_ENABLE)
-    if (!serial && strncmp((char*)device->lexer.outbuffer, "{\"class\":\"PPS\",", 15) == 0)
+    if (!serial && str_starts_with((char*)device->lexer.outbuffer, "{\"class\":\"PPS\","))
     {
 	const char *end = NULL;
 	struct gps_data_t noclobber;
@@ -1127,7 +1128,7 @@ int main(int argc, char **argv)
         case 't':
 	    fallback = NULL;
 	    for (active = monitor_objects; *active; active++) {
-		if (strncmp((*active)->driver->type_name, optarg, strlen(optarg)) == 0)
+		if (str_starts_with((*active)->driver->type_name, optarg))
 		{
 		    fallback = (*active)->driver;
 		    matches++;
@@ -1163,7 +1164,7 @@ int main(int argc, char **argv)
 
     /* Grok the server, port, and device. */
     if (optind < argc) {
-	serial = (strncmp(argv[optind], "/dev", 4) == 0);
+	serial = str_starts_with(argv[optind], "/dev");
 	gpsd_source_spec(argv[optind], &source);
     } else {
 	serial = false;
diff --git a/json.c b/json.c
index f208e74..4ba5173 100644
--- a/json.c
+++ b/json.c
@@ -686,11 +686,11 @@ int json_read_array(const char *cp, const struct json_array_t *arr,
 #endif /* JSON_MINIMAL */
 	case t_boolean:
 #ifndef JSON_MINIMAL
-	    if (strncmp(cp, "true", 4) == 0) {
+	    if (str_starts_with(cp, "true")) {
 		arr->arr.booleans.store[offset] = true;
 		cp += 4;
 	    }
-	    else if (strncmp(cp, "false", 5) == 0) {
+	    else if (str_starts_with(cp, "false")) {
 		arr->arr.booleans.store[offset] = false;
 		cp += 5;
 	    }
diff --git a/libgps_sock.c b/libgps_sock.c
index 99b39b1..02164f6 100644
--- a/libgps_sock.c
+++ b/libgps_sock.c
@@ -33,6 +33,7 @@
 #include "gps.h"
 #include "gpsd.h"
 #include "libgps.h"
+#include "strfuncs.h"
 #ifdef SOCKET_EXPORT_ENABLE
 #include "gps_json.h"
 
@@ -272,7 +273,7 @@ int gps_unpack(char *buf, struct gps_data_t *gpsdata)
 #endif /* __UNUSED__ */
 
 	for (ns = buf; ns; ns = strstr(ns + 1, "GPSD")) {
-	    if ( /*@i1@*/ strncmp(ns, "GPSD", 4) == 0) {
+	    if (str_starts_with(ns, "GPSD")) {
 		/* the following should execute each time we have a good next sp */
 		for (sp = ns + 5; *sp != '\0'; sp = tp + 1) {
 		    bool eol;
diff --git a/libgpsd_core.c b/libgpsd_core.c
index e96cec6..bbcf674 100644
--- a/libgpsd_core.c
+++ b/libgpsd_core.c
@@ -33,6 +33,7 @@
 
 #include "gpsd.h"
 #include "matrix.h"
+#include "strfuncs.h"
 #if defined(NMEA2000_ENABLE)
 #include "driver_nmea2000.h"
 #endif /* defined(NMEA2000_ENABLE) */
@@ -407,7 +408,7 @@ int gpsd_open(struct gps_device_t *session)
 		    session->gpsdata.dev.path, session->gpsdata.gps_fd);
 	return session->gpsdata.gps_fd;
     /* otherwise, could be an TCP data feed */
-    } else if (strncmp(session->gpsdata.dev.path, "tcp://", 6) == 0) {
+    } else if (str_starts_with(session->gpsdata.dev.path, "tcp://")) {
 	char server[strlen(session->gpsdata.dev.path)+1], *port;
 	socket_t dsock;
 	(void)strlcpy(server, session->gpsdata.dev.path + 6, sizeof(server));
@@ -434,7 +435,7 @@ int gpsd_open(struct gps_device_t *session)
 	session->sourcetype = source_tcp;
 	return session->gpsdata.gps_fd;
     /* or could be UDP */
-    } else if (strncmp(session->gpsdata.dev.path, "udp://", 6) == 0) {
+    } else if (str_starts_with(session->gpsdata.dev.path, "udp://")) {
 	char server[strlen(session->gpsdata.dev.path)+1], *port;
 	socket_t dsock;
 	(void)strlcpy(server, session->gpsdata.dev.path + 6, sizeof(server));
@@ -463,7 +464,7 @@ int gpsd_open(struct gps_device_t *session)
     }
 #endif /* NETFEED_ENABLE */
 #ifdef PASSTHROUGH_ENABLE
-    if (strncmp(session->gpsdata.dev.path, "gpsd://", 7) == 0) {
+    if (str_starts_with(session->gpsdata.dev.path, "gpsd://")) {
 	/*@-branchstate -nullpass@*/
 	char server[strlen(session->gpsdata.dev.path)+1], *port;
 	socket_t dsock;
@@ -492,7 +493,7 @@ int gpsd_open(struct gps_device_t *session)
     }
 #endif /* PASSTHROUGH_ENABLE */
 #if defined(NMEA2000_ENABLE) && !defined(S_SPLINT_S)
-    if (strncmp(session->gpsdata.dev.path, "nmea2000://", 11) == 0) {
+    if (str_starts_with(session->gpsdata.dev.path, "nmea2000://")) {
         return nmea2000_open(session);
     }
 #endif /* defined(NMEA2000_ENABLE) && !defined(S_SPLINT_S) */
diff --git a/monitor_sirf.c b/monitor_sirf.c
index 3026e67..0a17691 100644
--- a/monitor_sirf.c
+++ b/monitor_sirf.c
@@ -16,6 +16,7 @@
 #include "gpsd.h"
 #include "bits.h"
 #include "gpsmon.h"
+#include "strfuncs.h"
 
 #if defined(SIRF_ENABLE) && defined(BINARY_ENABLE)
 extern const struct gps_type_t driver_sirf;
@@ -551,8 +552,7 @@ static void sirf_update(void)
 	buf[len] = '\0';
 	j = 1;
 	for (i = 0; verbpat[i] != NULL; i++)
-	    if (strncmp((char *)(buf + 1), verbpat[i], strlen(verbpat[i])) ==
-		0) {
+	    if (str_starts_with((char *)(buf + 1), verbpat[i])) {
 		j = 0;
 		break;
 	    }
diff --git a/net_gnss_dispatch.c b/net_gnss_dispatch.c
index 381e694..b3dfd80 100644
--- a/net_gnss_dispatch.c
+++ b/net_gnss_dispatch.c
@@ -14,6 +14,7 @@
 #endif /* S_SPLINT_S */
 
 #include "gpsd.h"
+#include "strfuncs.h"
 
 #define NETGNSS_DGPSIP	"dgpsip://"
 #define NETGNSS_NTRIP	"ntrip://"
@@ -22,8 +23,8 @@ bool netgnss_uri_check(char *name)
 /* is given string a valid URI for GNSS/DGPS service? */
 {
     return
-	strncmp(name, NETGNSS_NTRIP, strlen(NETGNSS_NTRIP)) == 0
-	|| strncmp(name, NETGNSS_DGPSIP, strlen(NETGNSS_DGPSIP)) == 0;
+	str_starts_with(name, NETGNSS_NTRIP)
+	|| str_starts_with(name, NETGNSS_DGPSIP);
 }
 
 
@@ -32,13 +33,13 @@ int netgnss_uri_open(struct gps_device_t *dev, char *netgnss_service)
 /* open a connection to a DGNSS service */
 {
 #ifdef NTRIP_ENABLE
-    if (strncmp(netgnss_service, NETGNSS_NTRIP, strlen(NETGNSS_NTRIP)) == 0) {
+    if (str_starts_with(netgnss_service, NETGNSS_NTRIP)) {
 	dev->ntrip.conn_state = ntrip_conn_init;
 	return ntrip_open(dev, netgnss_service + strlen(NETGNSS_NTRIP));
     }
 #endif
 
-    if (strncmp(netgnss_service, NETGNSS_DGPSIP, strlen(NETGNSS_DGPSIP)) == 0)
+    if (str_starts_with(netgnss_service, NETGNSS_DGPSIP))
 	return dgpsip_open(dev, netgnss_service + strlen(NETGNSS_DGPSIP));
 
 #ifndef REQUIRE_DGNSS_PROTO
diff --git a/net_ntrip.c b/net_ntrip.c
index 5d7617b..fb7266b 100644
--- a/net_ntrip.c
+++ b/net_ntrip.c
@@ -21,6 +21,7 @@
 
 #include "gpsd.h"
 #include "bsd_base64.h"
+#include "strfuncs.h"
 
 #define NTRIP_SOURCETABLE	"SOURCETABLE 200 OK\r\n"
 #define NTRIP_ENDSOURCETABLE	"ENDSOURCETABLE"
@@ -203,8 +204,7 @@ static int ntrip_sourcetable_parse(struct gps_device_t *device)
 	sourcetable = device->ntrip.sourcetable_parse;
 	if (!sourcetable) {
 	    /* parse SOURCETABLE */
-	    if (strncmp(line, NTRIP_SOURCETABLE, strlen(NTRIP_SOURCETABLE)) ==
-		    0) {
+	    if (str_starts_with(line, NTRIP_SOURCETABLE)) {
 		sourcetable = true;
 		device->ntrip.sourcetable_parse = true;
 		llen = (ssize_t) strlen(NTRIP_SOURCETABLE);
@@ -220,9 +220,7 @@ static int ntrip_sourcetable_parse(struct gps_device_t *device)
 
 	while (len > 0) {
 	    /* parse ENDSOURCETABLE */
-	    if (strncmp
-		    (line, NTRIP_ENDSOURCETABLE,
-		     strlen(NTRIP_ENDSOURCETABLE)) == 0)
+	    if (str_starts_with(line, NTRIP_ENDSOURCETABLE))
 		goto done;
 
 	    /* coverity[string_null] - nul-terminated by previous memset */
@@ -238,7 +236,7 @@ static int ntrip_sourcetable_parse(struct gps_device_t *device)
 	    /* todo: parse headers */
 
 	    /* parse STR */
-	    if (strncmp(line, NTRIP_STR, strlen(NTRIP_STR)) == 0) {
+	    if (str_starts_with(line, NTRIP_STR)) {
 		ntrip_str_parse(line + strlen(NTRIP_STR),
 				(size_t) (llen - strlen(NTRIP_STR)), 
 				&hold, &device->context->errout);
@@ -282,10 +280,10 @@ static int ntrip_sourcetable_parse(struct gps_device_t *device)
 		 * find nearest stream if user hasn't provided one */
 	    }
 	    /* todo: parse CAS */
-	    /* else if (strncmp(line, NTRIP_CAS, strlen(NTRIP_CAS))==0); */
+	    /* else if (str_starts_with(line, NTRIP_CAS)); */
 
 	    /* todo: parse NET */
-	    /* else if (strncmp(line, NTRIP_NET, strlen(NTRIP_NET))==0); */
+	    /* else if (str_starts_with(line, NTRIP_NET)); */
 
 	    llen += strlen(NTRIP_BR);
 	    line += llen;
diff --git a/packet.c b/packet.c
index 1cf2a5a..02b18e5 100644
--- a/packet.c
+++ b/packet.c
@@ -42,6 +42,7 @@ PERMISSIONS
 #include "bits.h"
 #include "gpsd.h"
 #include "crc24q.h"
+#include "strfuncs.h"
 
 /*
  * The packet-recognition state machine.  This takes an incoming byte stream
@@ -1503,7 +1504,7 @@ void packet_parse(struct gps_lexer_t *lexer)
 	     * $PASHR packets have no checksum. Avoid the possibility
 	     * that random garbage might make it look like they do.
 	     */
-	    if (strncmp((const char *)lexer->inbuffer, "$PASHR,", 7) != 0)
+	    if (!str_starts_with((const char *)lexer->inbuffer, "$PASHR,"))
 	    {
 		bool checksum_ok = true;
 		char csum[3] = { '0', '0', '0' };
@@ -1536,13 +1537,13 @@ void packet_parse(struct gps_lexer_t *lexer)
 	    }
 	    /* checksum passed or not present */
 #ifdef AIVDM_ENABLE
-	    if (strncmp((char *)lexer->inbuffer, "!AIVDM", 6) == 0)
+	    if (str_starts_with((char *)lexer->inbuffer, "!AIVDM"))
 		packet_accept(lexer, AIVDM_PACKET);
-	    else if (strncmp((char *)lexer->inbuffer, "!AIVDO", 6) == 0)
+	    else if (str_starts_with((char *)lexer->inbuffer, "!AIVDO"))
 		packet_accept(lexer, AIVDM_PACKET);
-	    else if (strncmp((char *)lexer->inbuffer, "!BSVDM", 6) == 0)
+	    else if (str_starts_with((char *)lexer->inbuffer, "!BSVDM"))
 		packet_accept(lexer, AIVDM_PACKET);
-	    else if (strncmp((char *)lexer->inbuffer, "!BSVDO", 6) == 0)
+	    else if (str_starts_with((char *)lexer->inbuffer, "!BSVDO"))
 		packet_accept(lexer, AIVDM_PACKET);
 	    else
 #endif /* AIVDM_ENABLE */
diff --git a/strfuncs.h b/strfuncs.h
index a196ef2..5937134 100644
--- a/strfuncs.h
+++ b/strfuncs.h
@@ -9,4 +9,7 @@
 
 #include <string.h>
 
+#define str_starts_with(str, prefix) \
+    (strncmp((str), (prefix), strlen(prefix)) == 0)
+
 #endif /* _GPSD_STRFUNCS_H_ */
-- 
2.1.4

