[Commit] nickle ChangeLog, 1.34, 1.35 builtin.5c, 1.6, 1.7 string.5c, 1.3, 1.4

Bart Massey commit at keithp.com
Fri Apr 16 00:46:04 PDT 2004


Committed by: bart

Update of /local/src/CVS/nickle
In directory home.keithp.com:/tmp/cvs-serv19527

Modified Files:
	ChangeLog builtin.5c string.5c 
Log Message:
	* string.5c:
	Added new string functions _dequote(), dequote(), inchars(),
	readcsv(), and associated machinery.
	* builtin.5c:
	String depends on Ctype now, so reordered.




Index: ChangeLog
===================================================================
RCS file: /local/src/CVS/nickle/ChangeLog,v
retrieving revision 1.34
retrieving revision 1.35
diff -u -d -r1.34 -r1.35
--- a/ChangeLog	16 Apr 2004 06:06:01 -0000	1.34
+++ b/ChangeLog	16 Apr 2004 07:46:02 -0000	1.35
@@ -1,3 +1,11 @@
+2004-04-15  Bart Massey  <bart at cs.pdx.edu>
+
+	* string.5c:
+	Added new string functions _dequote(), dequote(), inchars(),
+	readcsv(), and associated machinery.
+	* builtin.5c:
+	String depends on Ctype now, so reordered.
+
 2004-04-15  Keith Packard  <keithp at keithp.com>
 
 	* array.c: (ArrayResize):

Index: builtin.5c
===================================================================
RCS file: /local/src/CVS/nickle/builtin.5c,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -d -r1.6 -r1.7
--- a/builtin.5c	16 Apr 2004 05:26:44 -0000	1.6
+++ b/builtin.5c	16 Apr 2004 07:46:02 -0000	1.7
@@ -77,8 +77,8 @@
 }
 
 # Load the prerequisites for the extra commands.
-library "string.5c";
 library "ctype.5c";
+library "string.5c";
 library "file.5c";
 library "printf.5c";
 library "history.5c";

Index: string.5c
===================================================================
RCS file: /local/src/CVS/nickle/string.5c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -d -r1.3 -r1.4
--- a/string.5c	11 Apr 2004 09:33:25 -0000	1.3
+++ b/string.5c	16 Apr 2004 07:46:02 -0000	1.4
@@ -1,5 +1,122 @@
 extend namespace String {
 
+    public string chomp(string s) {
+	if (s == "")
+	    return s;
+	int l = length(s);
+	int i = 0;
+	while(i < l && Ctype::isspace(s[i]))
+	    i++;
+	int j = l - 1;
+	while(j >= 0 && Ctype::isspace(s[j]))
+	    --j;
+	return substr(s, i, j - i + 1);
+    }
+
+    typedef enum {normal, openq, xq} qstate;
+
+    public bool inchars(int c, string s) {
+	return index(String::new(c), s) >= 0;
+    }
+
+    public typedef struct { 
+	string oq, cq, qq;
+    } quote_context;
+
+    public string _dequote(string s, quote_context q) {
+	string result = "";
+	qstate t = qstate.normal;
+	for (int cur = 0; cur < length(s); cur++) {
+	    int c = s[cur];
+	    switch(t) {
+	    case qstate.normal:
+		if (inchars(c, q.oq)) {
+		    t = qstate.openq;
+		    continue;
+		}
+		raise invalid_argument("_dequote: leading garbage", 0, s);
+		break;
+	    case qstate.openq:
+		if (inchars(c, q.qq)) {
+		    t = qstate.xq;
+		    continue;
+		}
+		if (inchars(c, q.cq)) {
+		    if (cur != length(s) - 1)
+			raise invalid_argument("_dequote: trailing garbage", 0, s);
+		    continue;
+		}
+		break;
+	    case qstate.xq:
+		t = qstate.openq;
+		break;
+	    }
+	    result = result + String::new(c);
+	}
+	if (q.qq == q.cq && t == qstate.xq)
+	    return result;
+	raise invalid_argument("_dequote: unexpected end of string", 0, s);
+    }
+
+    public quote_context default_quotes = {
+	oq = "\"", cq = "\"", qq = "\\"
+    };
+
+    public string dequote(string s) {
+	return _dequote(s, default_quotes);
+    }
+
+    public string[*] readcsv(string s) {
+	string[...] ss = {};
+	if (s == "" || s == "\n" || s == "\r\n")
+	    return ss;
+	quote_context q = default_quotes;
+	q.qq = "\"";
+	string curs = "";
+	qstate t = qstate.normal;
+	int cur = 0;
+	while (cur < length(s)) {
+	    int c = s[cur];
+#	    printf("%d: %c %v\n", cur, c, t);
+	    switch(t) {
+	    case qstate.normal:
+		if (c == ',') {
+		    string t = chomp(curs);
+		    if (t != "" && t[0] == '"')
+			t = _dequote(t, q);
+		    ss[dim(ss)] = t;
+		    curs = "";
+		    cur++;
+		    continue;
+		}
+		if (c == '"')
+		    t = qstate.openq;
+		break;
+	    case qstate.openq:
+		if (c == '"')
+		    t = qstate.xq;
+		break;
+	    case qstate.xq:
+		if (c == '"') {
+		    t = qstate.openq;
+		    break;
+		}
+		if (c == ',') {
+		    t = qstate.normal;
+		    continue;
+		}
+		t = qstate.normal;
+		break;
+	    }
+	    curs = curs + String::new(c);
+	    cur++;
+	}
+	if (t != qstate.normal)
+	    raise invalid_argument("readcsv: unexpected end of csv line", 0, s);
+	ss[dim(ss)] = curs;
+	return ss;
+    }
+
     public int rindex(string target, string pattern) {
 	int pl = length(pattern);
 	for (int i = length(target) - pl; i >= 0; --i) {
@@ -40,4 +157,121 @@
 	return ss;
     }
 
+    public string chomp(string s) {
+	if (s == "")
+	    return s;
+	int l = length(s);
+	int i = 0;
+	while(i < l && Ctype::isspace(s[i]))
+	    i++;
+	int j = l - 1;
+	while(j >= 0 && Ctype::isspace(s[j]))
+	    --j;
+	return substr(s, i, j - i + 1);
+    }
+
+    public bool inchars(int c, string s) {
+	return index(String::new(c), s) >= 0;
+    }
+
+    public typedef struct { 
+	string oq, cq, qq;
+    } quote_context;
+
+    typedef enum {normal, openq, xq} qstate;
+
+    public string _dequote(string s, quote_context q) {
+	string result = "";
+	qstate t = qstate.normal;
+	for (int cur = 0; cur < length(s); cur++) {
+	    int c = s[cur];
+	    switch(t) {
+	    case qstate.normal:
+		if (inchars(c, q.oq)) {
+		    t = qstate.openq;
+		    continue;
+		}
+		raise invalid_argument("_dequote: leading garbage", 0, s);
+		break;
+	    case qstate.openq:
+		if (inchars(c, q.qq)) {
+		    t = qstate.xq;
+		    continue;
+		}
+		if (inchars(c, q.cq)) {
+		    if (cur != length(s) - 1)
+			raise invalid_argument("_dequote: trailing garbage", 0, s);
+		    continue;
+		}
+		break;
+	    case qstate.xq:
+		t = qstate.openq;
+		break;
+	    }
+	    result = result + String::new(c);
+	}
+	if (q.qq == q.cq && t == qstate.xq)
+	    return result;
+	raise invalid_argument("_dequote: unexpected end of string", 0, s);
+    }
+
+    public quote_context default_quotes = {
+	oq = "\"", cq = "\"", qq = "\\"
+    };
+
+    public string dequote(string s) {
+	return _dequote(s, default_quotes);
+    }
+
+    public string[*] readcsv(string s) {
+	string[...] ss = {};
+	if (s == "" || s == "\n" || s == "\r\n")
+	    return ss;
+	quote_context q = default_quotes;
+	q.qq = "\"";
+	string curs = "";
+	qstate t = qstate.normal;
+	int cur = 0;
+	while (cur < length(s)) {
+	    int c = s[cur];
+#	    printf("%d: %c %v\n", cur, c, t);
+	    switch(t) {
+	    case qstate.normal:
+		if (c == ',') {
+		    string t = chomp(curs);
+		    if (t != "" && t[0] == '"')
+			t = _dequote(t, q);
+		    ss[dim(ss)] = t;
+		    curs = "";
+		    cur++;
+		    continue;
+		}
+		if (c == '"')
+		    t = qstate.openq;
+		break;
+	    case qstate.openq:
+		if (c == '"')
+		    t = qstate.xq;
+		break;
+	    case qstate.xq:
+		if (c == '"') {
+		    t = qstate.openq;
+		    break;
+		}
+		if (c == ',') {
+		    t = qstate.normal;
+		    continue;
+		}
+		t = qstate.normal;
+		break;
+	    }
+	    curs = curs + String::new(c);
+	    cur++;
+	}
+	if (t != qstate.normal)
+	    raise invalid_argument("readcsv: unexpected end of csv line", 0, s);
+	ss[dim(ss)] = curs;
+	return ss;
+    }
+
 }




More information about the Commit mailing list