From 94c1bbb62e712f8999e3de6a7cfb998c56837847 Mon Sep 17 00:00:00 2001
From: Zbigniew Chyla <zbigniew@chyla.pl>
Date: Fri, 16 Jan 2015 15:46:59 +0100
Subject: [PATCH 05/10] Add str_rstrip_char, use it everywhere.

This change doesn't affect generated binary code.
---
 gpsd.c        |  12 +++----
 gpsd_json.c   | 102 ++++++++++++++++++++--------------------------------------
 libgps_sock.c |   6 ++--
 strfuncs.h    |   6 ++++
 4 files changed, 46 insertions(+), 80 deletions(-)

diff --git a/gpsd.c b/gpsd.c
index 0d68e15..14f877c 100644
--- a/gpsd.c
+++ b/gpsd.c
@@ -1069,8 +1069,7 @@ static void json_devicelist_dump(char *reply, size_t replylen)
 	    (void)strlcat(reply, ",", replylen);
 	}
 
-    if (reply[strlen(reply) - 1] == ',')
-	reply[strlen(reply) - 1] = '\0';
+    str_rstrip_char(reply, ',');
     (void)strlcat(reply, "]}\r\n", replylen);
 }
 #endif /* SOCKET_EXPORT_ENABLE */
@@ -1323,8 +1322,7 @@ static void handle_request(struct subscriber_t *sub,
 		}
 	    }
 	}
-	if (reply[strlen(reply) - 1] == ',')
-	    reply[strlen(reply) - 1] = '\0';	/* trim trailing comma */
+	str_rstrip_char(reply, ',');
 	(void)strlcat(reply, "],\"gst\":[", replylen);
 	for (devp = devices; devp < devices + MAXDEVICES; devp++) {
 	    if (allocated_device(devp) && subscribed(sub, devp)) {
@@ -1337,8 +1335,7 @@ static void handle_request(struct subscriber_t *sub,
 		}
 	    }
 	}
-	if (reply[strlen(reply) - 1] == ',')
-	    reply[strlen(reply) - 1] = '\0';	/* trim trailing comma */
+	str_rstrip_char(reply, ',');
 	(void)strlcat(reply, "],\"sky\":[", replylen);
 	for (devp = devices; devp < devices + MAXDEVICES; devp++) {
 	    if (allocated_device(devp) && subscribed(sub, devp)) {
@@ -1351,8 +1348,7 @@ static void handle_request(struct subscriber_t *sub,
 		}
 	    }
 	}
-	if (reply[strlen(reply) - 1] == ',')
-	    reply[strlen(reply) - 1] = '\0';	/* trim trailing comma */
+	str_rstrip_char(reply, ',');
 	(void)strlcat(reply, "]}\r\n", replylen);
     } else if (str_starts_with(buf, "VERSION;")) {
 	buf += 8;
diff --git a/gpsd_json.c b/gpsd_json.c
index 5ad699a..cb7e971 100644
--- a/gpsd_json.c
+++ b/gpsd_json.c
@@ -204,8 +204,7 @@ void json_tpv_dump(const struct gps_device_t *session,
 	}
 #endif /* TIMING_ENABLE */
     }
-    if (reply[strlen(reply) - 1] == ',')
-	reply[strlen(reply) - 1] = '\0';	/* trim trailing comma */
+    str_rstrip_char(reply, ',');
     (void)strlcat(reply, "}\r\n", replylen);
 }
 
@@ -236,8 +235,7 @@ void json_noise_dump(const struct gps_data_t *gpsdata,
 
 #undef ADD_GST_FIELD
 
-    if (reply[strlen(reply) - 1] == ',')
-	reply[strlen(reply) - 1] = '\0';	/* trim trailing comma */
+    str_rstrip_char(reply, ',');
     (void)strlcat(reply, "}\r\n", replylen);
 }
 
@@ -287,12 +285,10 @@ void json_sky_dump(const struct gps_data_t *datap,
 			       datap->skyview[i].used ? "true" : "false");
 	    }
 	}
-	if (reply[strlen(reply) - 1] == ',')
-	    reply[strlen(reply) - 1] = '\0';	/* trim trailing comma */
+	str_rstrip_char(reply, ',');
 	(void)strlcat(reply, "]", replylen);
     }
-    if (reply[strlen(reply) - 1] == ',')
-	reply[strlen(reply) - 1] = '\0';	/* trim trailing comma */
+    str_rstrip_char(reply, ',');
     (void)strlcat(reply, "}\r\n", replylen);
 }
 
@@ -355,8 +351,7 @@ void json_device_dump(const struct gps_device_t *device,
 #endif /* RECONFIGURE_ENABLE */
 	}
     }
-    if (reply[strlen(reply) - 1] == ',')
-	reply[strlen(reply) - 1] = '\0';	/* trim trailing comma */
+    str_rstrip_char(reply, ',');
     (void)strlcat(reply, "}\r\n", replylen);
 }
 
@@ -375,8 +370,7 @@ void json_watch_dump(const struct policy_t *ccp,
 		   ccp->split24 ? "true" : "false");
     if (ccp->devpath[0] != '\0')
 	str_appendf(reply, replylen, "\"device\":\"%s\",", ccp->devpath);
-    if (reply[strlen(reply) - 1] == ',')
-	reply[strlen(reply) - 1] = '\0';
+    str_rstrip_char(reply, ',');
     (void)strlcat(reply, "}\r\n", replylen);
     /*@+compdef@*/
 }
@@ -715,8 +709,7 @@ void json_rtcm2_dump(const struct rtcm2_t *rtcm,
 			   rsp->udre, rsp->iod,
 			   rsp->prc, rsp->rrc);
 	}
-	if (buf[strlen(buf) - 1] == ',')
-	    buf[strlen(buf) - 1] = '\0';
+	str_rstrip_char(buf, ',');
 	(void)strlcat(buf, "]", buflen);
 	break;
 
@@ -762,8 +755,7 @@ void json_rtcm2_dump(const struct rtcm2_t *rtcm,
 			   JSON_BOOL(csp->new_data),
 			   JSON_BOOL(csp->los_warning), csp->tou);
 	}
-	if (buf[strlen(buf) - 1] == ',')
-	    buf[strlen(buf) - 1] = '\0';
+	str_rstrip_char(buf, ',');
 	(void)strlcat(buf, "]", buflen);
 	break;
 
@@ -782,8 +774,7 @@ void json_rtcm2_dump(const struct rtcm2_t *rtcm,
 			   ssp->frequency,
 			   ssp->health, ssp->station_id, ssp->bitrate);
 	}
-	if (buf[strlen(buf) - 1] == ',')
-	    buf[strlen(buf) - 1] = '\0';
+	str_rstrip_char(buf, ',');
 	(void)strlcat(buf, "]", buflen);
 	break;
 
@@ -825,8 +816,7 @@ void json_rtcm2_dump(const struct rtcm2_t *rtcm,
 			   rsp->tod,
 			   rsp->prc, rsp->rrc);
 	}
-	if (buf[strlen(buf) - 1] == ',')
-	    buf[strlen(buf) - 1] = '\0';
+	str_rstrip_char(buf, ',');
 	(void)strlcat(buf, "]", buflen);
 	break;
 
@@ -834,14 +824,12 @@ void json_rtcm2_dump(const struct rtcm2_t *rtcm,
 	(void)strlcat(buf, "\"data\":[", buflen);
 	for (n = 0; n < rtcm->length; n++)
 	    str_appendf(buf, buflen, "\"0x%08x\",", rtcm->words[n]);
-	if (buf[strlen(buf) - 1] == ',')
-	    buf[strlen(buf) - 1] = '\0';
+	str_rstrip_char(buf, ',');
 	(void)strlcat(buf, "]", buflen);
 	break;
     }
 
-    if (buf[strlen(buf) - 1] == ',')
-	buf[strlen(buf) - 1] = '\0';
+    str_rstrip_char(buf, ',');
     (void)strlcat(buf, "}\r\n", buflen);
     /*@+mustfreefresh@*/
 }
@@ -889,8 +877,7 @@ void json_rtcm3_dump(const struct rtcm3_t *rtcm,
 			   INT(R1001.L1.locktime));
 #undef R1001
 	}
-	if (buf[strlen(buf) - 1] == ',')
-	    buf[strlen(buf) - 1] = '\0';
+	str_rstrip_char(buf, ',');
 	(void)strlcat(buf, "]", buflen);
 	break;
 
@@ -919,8 +906,7 @@ void json_rtcm3_dump(const struct rtcm3_t *rtcm,
 			   R1002.L1.CNR);
 #undef R1002
 	}
-	if (buf[strlen(buf) - 1] == ',')
-	    buf[strlen(buf) - 1] = '\0';
+	str_rstrip_char(buf, ',');
 	(void)strlcat(buf, "]", buflen);
 	break;
 
@@ -954,8 +940,7 @@ void json_rtcm3_dump(const struct rtcm3_t *rtcm,
 			   INT(R1003.L2.locktime));
 #undef R1003
 	}
-	if (buf[strlen(buf) - 1] == ',')
-	    buf[strlen(buf) - 1] = '\0';
+	str_rstrip_char(buf, ',');
 	(void)strlcat(buf, "]", buflen);
 	break;
 
@@ -994,8 +979,7 @@ void json_rtcm3_dump(const struct rtcm3_t *rtcm,
 			   R1004.L2.CNR);
 #undef R1004
 	}
-	if (buf[strlen(buf) - 1] == ',')
-	    buf[strlen(buf) - 1] = '\0';
+	str_rstrip_char(buf, ',');
 	(void)strlcat(buf, "]", buflen);
 	break;
 
@@ -1009,8 +993,7 @@ void json_rtcm3_dump(const struct rtcm3_t *rtcm,
 	    (void)strlcat(buf, "\"GLONASS\",", buflen - strlen(buf));
 	if ((rtcm->rtcmtypes.rtcm3_1005.system & 0x01)!=0)
 	    (void)strlcat(buf, "\"GALILEO\",", buflen);
-	if (buf[strlen(buf)-1] == ',')
-	    buf[strlen(buf)-1] = '\0';
+	str_rstrip_char(buf, ',');
 	str_appendf(buf, buflen,
 		       "],\"refstation\":%s,\"sro\":%s,"
 		       "\"x\":%.4f,\"y\":%.4f,\"z\":%.4f,",
@@ -1031,8 +1014,7 @@ void json_rtcm3_dump(const struct rtcm3_t *rtcm,
 	    (void)strlcat(buf, "\"GLONASS\",", buflen);
 	if ((rtcm->rtcmtypes.rtcm3_1006.system & 0x01)!=0)
 	    (void)strlcat(buf, "\"GALILEO\",", buflen);
-	if (buf[strlen(buf)-1] == ',')
-	    buf[strlen(buf)-1] = '\0';
+	str_rstrip_char(buf, ',');
 	str_appendf(buf, buflen,
 		       "],\"refstation\":%s,\"sro\":%s,"
 		       "\"x\":%.4f,\"y\":%.4f,\"z\":%.4f,",
@@ -1089,8 +1071,7 @@ void json_rtcm3_dump(const struct rtcm3_t *rtcm,
 			   INT(R1009.L1.locktime));
 #undef R1009
 	}
-	if (buf[strlen(buf) - 1] == ',')
-	    buf[strlen(buf) - 1] = '\0';
+	str_rstrip_char(buf, ',');
 	(void)strlcat(buf, "]", buflen);
 	break;
 
@@ -1120,8 +1101,7 @@ void json_rtcm3_dump(const struct rtcm3_t *rtcm,
 			   R1010.L1.CNR);
 #undef R1010
 	}
-	if (buf[strlen(buf) - 1] == ',')
-	    buf[strlen(buf) - 1] = '\0';
+	str_rstrip_char(buf, ',');
 	(void)strlcat(buf, "]", buflen);
 	break;
 
@@ -1155,8 +1135,7 @@ void json_rtcm3_dump(const struct rtcm3_t *rtcm,
 			   INT(R1011.L2.locktime));
 #undef R1011
 	}
-	if (buf[strlen(buf) - 1] == ',')
-	    buf[strlen(buf) - 1] = '\0';
+	str_rstrip_char(buf, ',');
 	(void)strlcat(buf, "]", buflen);
 	break;
 
@@ -1196,8 +1175,7 @@ void json_rtcm3_dump(const struct rtcm3_t *rtcm,
 			   R1012.L2.CNR);
 #undef R1012
 	}
-	if (buf[strlen(buf) - 1] == ',')
-	    buf[strlen(buf) - 1] = '\0';
+	str_rstrip_char(buf, ',');
 	(void)strlcat(buf, "]", buflen);
 	break;
 
@@ -1284,14 +1262,12 @@ void json_rtcm3_dump(const struct rtcm3_t *rtcm,
 	for (n = 0; n < rtcm->length; n++)
 	    str_appendf(buf, buflen,
 			   "\"0x%02x\",",(unsigned int)rtcm->rtcmtypes.data[n]);
-	if (buf[strlen(buf) - 1] == ',')
-	    buf[strlen(buf) - 1] = '\0';
+	str_rstrip_char(buf, ',');
 	(void)strlcat(buf, "]", buflen);
 	break;
     }
 
-    if (buf[strlen(buf) - 1] == ',')
-	buf[strlen(buf) - 1] = '\0';
+    str_rstrip_char(buf, ',');
     (void)strlcat(buf, "}\r\n", buflen);
     /*@+mustfreefresh@*/
 #undef CODE
@@ -1908,8 +1884,7 @@ void json_aivdm_dump(const struct ais_t *ais,
 			       racon_status[ais->type6.dac235fid10.racon],
 			       ais->type6.dac235fid10.light,
 			       light_status[ais->type6.dac235fid10.light]);
-		if (buf[strlen(buf) - 1] == ',')
-		    buf[strlen(buf)-1] = '\0';
+		str_rstrip_char(buf, ',');
 		(void)strlcat(buf, "}\r\n", buflen);
 		break;
 	    }
@@ -2061,8 +2036,7 @@ void json_aivdm_dump(const struct ais_t *ais,
 
 				   ais->type6.dac1fid25.cargos[i].code,
 				   ais->type6.dac1fid25.cargos[i].subtype);
-		if (buf[strlen(buf) - 1] == ',')
-		    buf[strlen(buf) - 1] = '\0';
+		str_rstrip_char(buf, ',');
 		(void)strlcat(buf, "]}\r\n", buflen);
 		break;
 	    case 28:	/* IMO289 - Route info - addressed */
@@ -2093,8 +2067,7 @@ void json_aivdm_dump(const struct ais_t *ais,
 			    ais->type6.dac1fid28.waypoints[i].lon,
 			    ais->type6.dac1fid28.waypoints[i].lat);
 		}
-		if (buf[strlen(buf) - 1] == ',')
-		    buf[strlen(buf)-1] = '\0';
+		str_rstrip_char(buf, ',');
 		(void)strlcat(buf, "]}\r\n", buflen);
 		break;
 	    case 30:	/* IMO289 - Text description - addressed */
@@ -2138,8 +2111,7 @@ void json_aivdm_dump(const struct ais_t *ais,
 			  "\"cspeed\":%u},",
 			  tp->cspeed);
 	      }
-	      if (buf[strlen(buf) - 1] == ',')
-		  buf[strlen(buf)-1] = '\0';
+	      str_rstrip_char(buf, ',');
 	      (void)strlcat(buf, "]}\r\n", buflen);
 	      break;
 	    }
@@ -2400,8 +2372,7 @@ void json_aivdm_dump(const struct ais_t *ais,
 			ais->type8.dac1fid17.targets[i].second,
 			ais->type8.dac1fid17.targets[i].speed);
 		}
-		if (buf[strlen(buf) - 1] == ',')
-		    buf[strlen(buf) - 1] = '\0';
+		str_rstrip_char(buf, ',');
 		(void)strlcat(buf, "]}\r\n", buflen);
 		break;
 	    case 19:        /* IMO289 - Marine Traffic Signal */
@@ -2462,8 +2433,7 @@ void json_aivdm_dump(const struct ais_t *ais,
 			    ais->type8.dac1fid27.waypoints[i].lon,
 			    ais->type8.dac1fid27.waypoints[i].lat);
 		}
-		if (buf[strlen(buf) - 1] == ',')
-		    buf[strlen(buf) - 1] = '\0';
+		str_rstrip_char(buf, ',');
 		(void)strlcat(buf, "]}\r\n", buflen);
 		break;
 	    case 29:        /* IMO289 - Text Description - broadcast */
@@ -2805,8 +2775,7 @@ void json_aivdm_dump(const struct ais_t *ais,
 			ais->type8.dac200fid24.gauges[i].id,
 			ais->type8.dac200fid24.gauges[i].level);
 		}
-		if (buf[strlen(buf)-1] == ',')
-		    buf[strlen(buf)-1] = '\0';
+		str_rstrip_char(buf, ',');
 		(void)strlcat(buf, "]}\r\n", buflen - strlen(buf));
 		break;
 	    case 40:	/* Inland AIS Signal Strength */
@@ -3264,8 +3233,7 @@ void json_aivdm_dump(const struct ais_t *ais,
 			       ais->type24.dim.to_starboard);
 	    }
 	}
-	if (buf[strlen(buf)-1] == ',')
-	    buf[strlen(buf)-1] = '\0';
+	str_rstrip_char(buf, ',');
 	strlcat(buf, "}\r\n", buflen);
 	break;
     case 25:			/* Binary Message, Single Slot */
@@ -3324,8 +3292,7 @@ void json_aivdm_dump(const struct ais_t *ais,
 			   JSON_BOOL(ais->type27.gnss));
 	break;
     default:
-	if (buf[strlen(buf) - 1] == ',')
-	    buf[strlen(buf) - 1] = '\0';
+	str_rstrip_char(buf, ',');
 	(void)strlcat(buf, "}\r\n", buflen);
 	break;
     }
@@ -3426,8 +3393,7 @@ void json_att_dump(const struct gps_data_t *gpsdata,
 	str_appendf(reply, replylen,
 		       "\"depth\":%.3f,", gpsdata->attitude.depth);
 
-    if (reply[strlen(reply) - 1] == ',')
-	reply[strlen(reply) - 1] = '\0';	/* trim trailing comma */
+    str_rstrip_char(reply, ',');
     (void)strlcat(reply, "}\r\n", replylen);
 }
 #endif /* COMPASS_ENABLE */
diff --git a/libgps_sock.c b/libgps_sock.c
index 95f8b84..8d3a874 100644
--- a/libgps_sock.c
+++ b/libgps_sock.c
@@ -522,8 +522,7 @@ int gps_sock_stream(struct gps_data_t *gpsdata, unsigned int flags,
 		(void)strlcat(buf, "\"split24\":false,", sizeof(buf));
 	    if (flags & WATCH_PPS)
 		(void)strlcat(buf, "\"pps\":false,", sizeof(buf));
-	    if (buf[strlen(buf) - 1] == ',')
-		buf[strlen(buf) - 1] = '\0';
+	    str_rstrip_char(buf, ',');
 	    (void)strlcat(buf, "};", sizeof(buf));
 	}
 	libgps_debug_trace((DEBUG_CALLS, "gps_stream() disable command: %s\n", buf));
@@ -556,8 +555,7 @@ int gps_sock_stream(struct gps_data_t *gpsdata, unsigned int flags,
 	    if (flags & WATCH_DEVICE)
 		str_appendf(buf, sizeof(buf), "\"device\":\"%s\",", (char *)d);
 	    /*@+nullpass@*/
-	    if (buf[strlen(buf) - 1] == ',')
-		buf[strlen(buf) - 1] = '\0';
+	    str_rstrip_char(buf, ',');
 	    (void)strlcat(buf, "};", sizeof(buf));
 	}
 	libgps_debug_trace((DEBUG_CALLS, "gps_stream() enable command: %s\n", buf));
diff --git a/strfuncs.h b/strfuncs.h
index 657812d..b7911d9 100644
--- a/strfuncs.h
+++ b/strfuncs.h
@@ -19,4 +19,10 @@
 #define str_vappendf(str, alloc_size, format, ap) \
     ((void) vsnprintf((str) + strlen(str), (alloc_size) - strlen(str), (format), (ap)))
 
+#define str_rstrip_char(str, ch) \
+    do { \
+        if ((str)[strlen(str) - 1] == ch) \
+            (str)[strlen(str) - 1] = '\0'; \
+    } while (0)
+
 #endif /* _GPSD_STRFUNCS_H_ */
-- 
2.1.4

