Attachment "0.diff" to
ticket [415689ffff]
added by
andreas_kupries
2001-04-12 22:27:08.
Index: ChangeLog
===================================================================
RCS file: /cvsroot/tcllib/tcllib/ChangeLog,v
retrieving revision 1.51
diff -u -r1.51 ChangeLog
--- ChangeLog 2001/03/31 13:44:17 1.51
+++ ChangeLog 2001/04/12 14:34:16
@@ -1,4 +1,8 @@
-2001-03-26 Tcl Project <[email protected]>
+2001-04-12 Andreas Kupries <[email protected]>
+
+ * Makefile.in (MODULES): Added module 'csv'.
+
+2001-03-26 Andreas Kupries <[email protected]>
* Makefile.in (install-libraries): [Bug #404917]
Added 'smtp' explictly to the list of modules for the full
Index: Makefile.in
===================================================================
RCS file: /cvsroot/tcllib/tcllib/Makefile.in,v
retrieving revision 1.42
diff -u -r1.42 Makefile.in
--- Makefile.in 2001/03/31 13:44:17 1.42
+++ Makefile.in 2001/04/12 14:34:17
@@ -20,6 +20,9 @@
# Option processing package (like opt)
CMDLINE=cmdline
+# CSV processing
+CSV=csv
+
# File utilities (grep, find, etc.)
FILEUTIL=fileutil
@@ -78,6 +81,7 @@
MODULES= \
$(BASE64) \
$(CMDLINE) \
+ $(CSV) \
$(COUNTER) \
$(STRUCT) \
$(FILEUTIL) \
Index: modules/csv/ChangeLog
===================================================================
RCS file: ChangeLog
diff -N ChangeLog
--- /dev/null Mon Dec 11 17:26:27 2000
+++ ChangeLog Thu Apr 12 07:34:17 2001
@@ -0,0 +1,3 @@
+2001-04-12 Andreas Kupries <[email protected]>
+
+ * New module for the processing of CSV lines and files.
Index: modules/csv/csv.n
===================================================================
RCS file: csv.n
diff -N csv.n
--- /dev/null Mon Dec 11 17:26:27 2000
+++ csv.n Thu Apr 12 07:34:17 2001
@@ -0,0 +1,67 @@
+'\"
+'\" Copyright (c) 2001 by ActiveState Tool Corp.
+'\" All rights reserved.
+'\"
+'\" RCS: @(#) $Id: log.n,v 1.1 2001/03/26 16:50:21 andreas_kupries Exp $
+'\"
+.so man.macros
+.TH csv n 1.0 Csv "CSV processing"
+.BS
+'\" Note: do not modify the .SH NAME line immediately below!
+.SH NAME
+::csv \- Procedures to handle CSV data
+.SH SYNOPSIS
+\fBpackage require csv ?0.1?\fR
+.sp
+\fB::csv::split\fR \fIline {sepChar ,}\fR
+.sp
+\fB::csv::join\fR \fIvalues {sepChar ,}\fR
+.sp
+.BE
+.SH DESCRIPTION
+.PP
+The \fB::csv\fR package provides commands to manipulate information in
+CSV format (CSV = Comma Separated Values).
+.SH FORMAT
+.PP
+Each record of a csv file (comma-separated values, as exported e.g. by
+Excel) is a set of ascii values separated by ",". For other languages
+it may be ";" however, although this is not important for this case
+(The functions provided here allow any separator character).
+.PP
+If a value contains itself the separator ",", then it (the value) is
+put between "".
+.PP
+If a value contains ", it is replaced by "".
+.PP
+The following commands are available:
+.TP
+\fB::csv::split\fR \fIline {sepChar ,}\fR
+converts a line in CSV format into a list of the values contained in
+the line. The separator character can be defined by the caller, but
+this is optional. The default is ",".
+.TP
+\fB::csv::join\fR \fIvalues {sepChar ,}\fR
+Takes a list of values and returns a string in CSV format containing
+these values. The separator character can be defined by the caller,
+but this is optional. The default is ",".
+.SH EXAMPLE
+.PP
+The record
+.TP
+*
+123,"123,521.2","Mary says ""Hello, I am Mary"""
+.PP
+is parsed as follows:
+.TP
+a)
+123
+.TP
+b)
+123,521.2
+.TP
+c)
+Mary says "Hello, I am Mary"
+.SH SEE ALSO
+.SH KEYWORDS
+csv
Index: modules/csv/csv.tcl
===================================================================
RCS file: csv.tcl
diff -N csv.tcl
--- /dev/null Mon Dec 11 17:26:27 2000
+++ csv.tcl Thu Apr 12 07:34:17 2001
@@ -0,0 +1,74 @@
+# csv.tcl --
+#
+# Tcl implementations of CSV reader and writer
+#
+# Copyright (c) 2001 ActiveState Tool Corp.
+#
+# See the file "license.terms" for information on usage and redistribution
+# of this file, and for a DISCLAIMER OF ALL WARRANTIES.
+#
+# RCS: @(#) $Id: csv.tcl,v 1.5 2001/03/26 16:50:21 andreas_kupries Exp $
+
+package provide csv 0.1
+
+namespace eval ::csv {
+ namespace export *
+}
+
+# ::csv::split --
+#
+# Split a string according to the rules for CSV processing.
+# This assumes that the string contains a single line of CSVs
+#
+# Arguments:
+# line The string to split
+# sepChar The separator character, defaults to comma
+#
+# Results:
+# results A list of the values in 'line'.
+
+proc ::csv::split {line {sepChar ,}} {
+ regsub -all {(\A\"|\"\Z)} $line \0 line
+ set line [string map [list $sepChar\"\"\" $sepChar\0\" \
+ \"\"\"$sepChar \"\0$sepChar \
+ \"\" \" \" \0 ] $line]
+ set end 0
+ while {[regexp -indices -start $end {(\0)[^\0]*(\0)} $line -> start end]} {
+ set start [lindex $start 0]
+ set end [lindex $end 0]
+ set range [string range $line $start $end]
+ set first [string first $sepChar $range]
+ if {$first >= 0} {
+ set line [string replace $line $start $end \
+ [string map [list $sepChar \1] $range]]
+ }
+ incr end
+ }
+ set line [string map [list $sepChar \0 \1 $sepChar \0 {} ] $line]
+ return [::split $line \0]
+}
+
+# ::csv::join --
+#
+# Takes a list of values and generates a string in CSV format.
+#
+# Arguments:
+# values A list of the values to join
+# sepChar The separator character, defaults to comma
+#
+# Results:
+# results A string containing the values in CSV format.
+
+proc ::csv::join {values {sepChar ,}} {
+ set out ""
+ set sep {}
+ foreach val $values {
+ if {[string match "*\[\"$sepChar\]*" $val]} {
+ append out $sep\"[string map [list \" \"\"] $val]\"
+ } else {
+ append out $sep$val
+ }
+ set sep $sepChar
+ }
+ return $out
+}
Index: modules/csv/csv.test
===================================================================
RCS file: csv.test
diff -N csv.test
--- /dev/null Mon Dec 11 17:26:27 2000
+++ csv.test Thu Apr 12 07:34:17 2001
@@ -0,0 +1,96 @@
+# -*- tcl -*-
+# Tests for the find function.
+#
+# Sourcing this file into Tcl runs the tests and generates output for errors.
+# No output means no errors were found.
+#
+# Copyright (c) 1998-2000 by Ajuba Solutions.
+# Copyright (c) 2001 by ActiveState Tool Corp.
+# All rights reserved.
+#
+# RCS: @(#) $Id: fileutil.test,v 1.4 2001/03/26 16:50:21 andreas_kupries Exp $
+
+if {[lsearch [namespace children] ::tcltest] == -1} {
+ package require tcltest
+ namespace import ::tcltest::*
+}
+
+if { [lsearch $auto_path [file dirname [info script]]] == -1 } {
+ set auto_path [linsert $auto_path 0 [file dirname [info script]]]
+}
+
+package require csv
+puts "csv [package present csv]"
+
+set str1 {"123","""a""",,hello}
+set str2 {1," o, ""a"" ,b ", 3}
+set str3 {"1"," o, "","" ,b ", 3}
+set str4 {1," foo,bar,baz", 3}
+set str5 {1,"""""a""""",b}
+set str6 {123,"123,521.2","Mary says ""Hello, I am Mary"""}
+
+set str1a {123,"""a""",,hello}
+set str3a {1," o, "","" ,b ", 3}
+
+
+test csv-1.1 {split} {
+ csv::split $str1
+} {123 {"a"} {} hello}
+
+test csv-1.2 {split} {
+ csv::split $str2
+} {1 { o, "a" ,b } { 3}}
+
+test csv-1.3 {split} {
+ csv::split $str3
+} {1 { o, "," ,b } { 3}}
+
+test csv-1.4 {split} {
+ csv::split $str4
+} {1 { foo,bar,baz} { 3}}
+
+test csv-1.5 {split} {
+ csv::split $str5
+} {1 {""a""} b}
+
+test csv-1.6 {split} {
+ csv::split $str6
+} {123 123,521.2 {Mary says "Hello, I am Mary"}}
+
+
+test csv-2.1 {join} {
+ csv::join {123 {"a"} {} hello}
+} $str1a
+
+test csv-2.2 {join} {
+ csv::join {1 { o, "a" ,b } { 3}}
+} $str2
+
+test csv-2.3 {join} {
+ csv::join {1 { o, "," ,b } { 3}}
+} $str3a
+
+test csv-2.4 {join} {
+ csv::join {1 { foo,bar,baz} { 3}}
+} $str4
+
+test csv-2.5 {join} {
+ csv::join {1 {""a""} b}
+} $str5
+
+test csv-2.6 {join} {
+ csv::join {123 123,521.2 {Mary says "Hello, I am Mary"}}
+} $str6
+
+# Malformed inputs
+
+test csv-3.1 {split} {
+ csv::split {abcd,abc",abc}
+} {abcd abc abc}
+
+test csv-3.2 {split} {
+ csv::split {abcd,abc"",abc}
+} {abcd abc\" abc}
+
+::tcltest::cleanupTests
+return
Index: modules/csv/pkgIndex.tcl
===================================================================
RCS file: pkgIndex.tcl
diff -N pkgIndex.tcl
--- /dev/null Mon Dec 11 17:26:27 2000
+++ pkgIndex.tcl Thu Apr 12 07:34:21 2001
@@ -0,0 +1,11 @@
+# Tcl package index file, version 1.1
+# This file is generated by the "pkg_mkIndex" command
+# and sourced either when an application starts up or
+# by a "package unknown" script. It invokes the
+# "package ifneeded" command to set up package-related
+# information so that packages will be loaded automatically
+# in response to "package require" commands. When this
+# script is sourced, the variable $dir must contain the
+# full path name of this file's directory.
+
+package ifneeded csv 0.1 [list source [file join $dir csv.tcl]]