Home My Page Projects Code Snippets Project Openings SML/NJ
Summary Activity Forums Tracker Lists Tasks Docs Surveys News SCM Files

SCM Repository

[smlnj] Diff of /smlnj-lib/trunk/Dev/CSV/list-csv.sml
ViewVC logotype

Diff of /smlnj-lib/trunk/Dev/CSV/list-csv.sml

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 4056, Fri Mar 6 01:09:29 2015 UTC revision 4057, Fri Mar 6 02:00:10 2015 UTC
# Line 13  Line 13 
13    
14      type 'a seq = 'a list      type 'a seq = 'a list
15    
16        exception Error
17    
18      fun parse ln = let      fun parse ln = let
19            fun splitNext (start, ss) = let            fun splitNext start = let
20                  fun extract ss = SS.string(SS.trimr (SS.size ss) start)                  fun extract ss = SS.string(SS.trimr (SS.size ss) start)
21                  fun scan (ss, quoted) = (case (SS.getc ss, quoted)                  fun scan (ss, quoted) = (case (SS.getc ss, quoted)
22                         of (NONE, false) => extract ss                         of (NONE, false) => (extract ss, ss)
23                          | (NONE, true) => (* error *)                          | (NONE, true) => raise Error
24                          | (SOME(#",", ss'), false) => (* terminate *)                          | (SOME(#",", ss'), false) => (extract ss, ss')
25                          | (SOME(#"\"", ss'), true) => (* terminate *)                          | (SOME(#"\"", ss'), true) => (case SS.getc ss
26                          | (SOME(#"\"", ss'), false) => (* error? *)                               of NONE => (extract ss, ss')
27                          | (SOME(_, ss'), _) => splitNext (start, ss')                                | SOME(#",", ss') => (extract ss, ss')
28                                  | _ => raise Error
29                                (* end case *))
30                            | (SOME(#"\"", ss'), false) => scan(ss', quoted) (* error? *)
31                            | (SOME(_, ss'), _) => scan(ss', quoted)
32                        (* end case *))                        (* end case *))
33                  in                  in
34                    case getc ss                    case SS.getc start
35                     of SOME(#"\"", ss') =>                     of SOME(#"\"", ss') => scan(ss', true)
36                      | _ =>                      | _ => scan (start, false)
37                    (* end case *)                    (* end case *)
38                  end                  end
39              and scanLine (ss, fields) = if SS.isEmpty ss
40                    then List.rev fields
41                    else let
42                      val (fld, ss) = splitNext ss
43                      in
44                        scanLine (ss, fld::fields)
45                      end
46              in
47                SOME(scanLine (SS.full ln, []))
48                  handle Error => NONE
49              end
50    
51      (* convert a CSV line to a sequence of its fields; returns NONE on error *)
52        fun fromString s = parse s
53    
54        val hasComma = CharVector.exists (fn #"," => true | _ => false)
55    
56        fun cvtField s = if hasComma s
57              then concat["\"", s, "\""]  (* what if it has a quote? *)
58              else s
59    
60      (* convert a sequence to a string *)
61        fun toString flds = String.concatWith "," (List.map cvtField flds)
62    
63        fun fmt cvt = let
64              fun cvt' x = cvtField (cvt x)
65            in            in
66                fn flds => String.concatWith "," (List.map cvt' flds)
67            end            end
68    
69    end    end

Legend:
Removed from v.4056  
changed lines
  Added in v.4057

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0