TIP 586: C String Parsing Support for binary scan

Login
Author:         Christian Werner <[email protected]>
State:          Final
Type:           Project
Vote:           Done
Created:        18-Sep-2020
Post-History:
Keywords:       binary
Tcl-Version:    8.7
Tcl-Branch:     tip-586-binary-scan-c-string
Vote-Summary:   Accepted 6/0/0
Votes-For:      DKF, FV, JN, KBK, KW, SL
Votes-Against:  none
Votes-Present:  none

Abstract

This TIP proposes to add another scan rule to the binary scan command in order to be able to deal with NUL terminated C strings.

Rationale

NUL terminated C strings are common place but currently not directly supported by the binary scan command. There's the scan format A which trims trailing space and NULs but it starts that trim process from the field's end backwards. In order to get C string semantics, that scan must be performed from the field's start and terminated upon detection of the first NUL.

The proposal of this TIP is therefore to add a binary scan format letter C which performs the aforementioned scan termination rule.

Implementation

This patch should be sufficient (line numbers most likely are different) for most current branches on http://core.tcl-lang.org/tcl:

--- tcl/generic/tclBinary.c
+++ tcl/generic/tclBinary.c
@@ -1315,11 +1315,12 @@
 	if (!GetFormatSpec(&format, &cmd, &count, &flags)) {
 	    goto done;
 	}
 	switch (cmd) {
 	case 'a':
-	case 'A': {
+	case 'A':
+	case 'C': {
 	    unsigned char *src;

 	    if (arg >= objc) {
 		DeleteScanNumberCache(numberCachePtr);
 		goto badIndex;
@@ -1337,14 +1338,22 @@

 	    src = buffer + offset;
 	    size = count;

 	    /*
-	     * Trim trailing nulls and spaces, if necessary.
+	     * Apply C string semantics or trim trailing
+	     * nulls and spaces, if necessary.
 	     */

-	    if (cmd == 'A') {
+	    if (cmd == 'C') {
+		for (i = 0; i < size; i++) {
+		    if (src[i] == '\0') {
+			size = i;
+			break;
+		    }
+		}
+	    } else if (cmd == 'A') {
 		while (size > 0) {
 		    if (src[size - 1] != '\0' && src[size - 1] != ' ') {
 			break;
 		    }
 		    size--;

Copyright

This document has been placed in the public domain.