├── deps.edn
├── .gitignore
├── .github
├── workflows
│ ├── test.yml
│ ├── snapshot.yml
│ ├── doc-build.yml
│ └── release.yml
└── PULL_REQUEST_TEMPLATE
├── CONTRIBUTING.md
├── pom.xml
├── src
├── test
│ └── clojure
│ │ └── clojure
│ │ └── data
│ │ └── csv_test.clj
└── main
│ └── clojure
│ └── clojure
│ └── data
│ └── csv.clj
├── README.md
└── LICENSE
/deps.edn:
--------------------------------------------------------------------------------
1 | {:paths ["src/main/clojure"]}
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | *~
2 | target/
3 | resources/
4 | lib/
5 | *.jar
6 | .cpcache/
7 |
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | name: Test
2 |
3 | on: [push]
4 |
5 | jobs:
6 | call-test:
7 | uses: clojure/build.ci/.github/workflows/test.yml@master
8 |
--------------------------------------------------------------------------------
/.github/workflows/snapshot.yml:
--------------------------------------------------------------------------------
1 | name: Snapshot on demand
2 |
3 | on: [workflow_dispatch]
4 |
5 | jobs:
6 | call-snapshot:
7 | uses: clojure/build.ci/.github/workflows/snapshot.yml@master
8 | secrets: inherit
9 |
--------------------------------------------------------------------------------
/.github/workflows/doc-build.yml:
--------------------------------------------------------------------------------
1 | name: Build API Docs
2 |
3 | on:
4 | workflow_dispatch:
5 |
6 | jobs:
7 | call-doc-build-workflow:
8 | uses: clojure/build.ci/.github/workflows/doc-build.yml@master
9 | with:
10 | project: clojure/data.csv
11 |
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | This is a [Clojure contrib] project.
2 |
3 | Under the Clojure contrib [guidelines], this project cannot accept
4 | pull requests. All patches must be submitted via [JIRA].
5 |
6 | See [Contributing] on the Clojure website for
7 | more information on how to contribute.
8 |
9 | [Clojure contrib]: https://clojure.org/community/contrib_libs
10 | [Contributing]: https://clojure.org/community/contributing
11 | [JIRA]: https://clojure.atlassian.net/browse/DCSV
12 | [guidelines]: https://clojure.org/community/contrib_howto
13 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: Release on demand
2 |
3 | on:
4 | workflow_dispatch:
5 | inputs:
6 | releaseVersion:
7 | description: "Version to release"
8 | required: true
9 | snapshotVersion:
10 | description: "Snapshot version after release"
11 | required: true
12 |
13 | jobs:
14 | call-release:
15 | uses: clojure/build.ci/.github/workflows/release.yml@master
16 | with:
17 | releaseVersion: ${{ github.event.inputs.releaseVersion }}
18 | snapshotVersion: ${{ github.event.inputs.snapshotVersion }}
19 | secrets: inherit
--------------------------------------------------------------------------------
/.github/PULL_REQUEST_TEMPLATE:
--------------------------------------------------------------------------------
1 | Hi! Thanks for your interest in contributing to this project.
2 |
3 | Clojure contrib projects do not use GitHub issues or pull requests, and
4 | require a signed Contributor Agreement. If you would like to contribute,
5 | please read more about the CA and sign that first (this can be done online).
6 |
7 | Then go to this project's issue tracker in JIRA to create tickets, update
8 | tickets, or submit patches. For help in creating tickets and patches,
9 | please see:
10 |
11 | - Contributing FAQ: https://clojure.org/dev
12 | - Signing the CA: https://clojure.org/dev/contributor_agreement
13 | - Creating Tickets: https://clojure.org/dev/creating_tickets
14 | - Developing Patches: https://clojure.org/dev/developing_patches
15 |
--------------------------------------------------------------------------------
/pom.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 | 4.0.0
4 | data.csv
5 | 1.1.1-SNAPSHOT
6 | data.csv
7 | A Clojure library for reading and writing comma separated value (csv) files
8 | https://github.com/clojure/data.csv
9 |
10 |
11 |
12 | Jonas Enlund
13 | jonas.enlund@gmail.com
14 | https://github.com/jonase
15 | +2
16 |
17 |
18 |
19 |
20 | org.clojure
21 | pom.contrib
22 | 1.3.0
23 |
24 |
25 |
26 | scm:git:git@github.com:clojure/data.csv
27 | scm:git:git@github.com:clojure/data.csv
28 | git@github.com:clojure/data.csv.git
29 | HEAD
30 |
31 |
32 |
--------------------------------------------------------------------------------
/src/test/clojure/clojure/data/csv_test.clj:
--------------------------------------------------------------------------------
1 | (ns clojure.data.csv-test
2 | (:use
3 | [clojure.test :only (deftest is)]
4 | [clojure.data.csv :only (read-csv write-csv)])
5 | (:import
6 | [java.io Reader StringReader StringWriter EOFException]))
7 |
8 | (def ^{:private true} simple
9 | "Year,Make,Model
10 | 1997,Ford,E350
11 | 2000,Mercury,Cougar
12 | ")
13 |
14 | (def ^{:private true} simple-alt-sep
15 | "Year;Make;Model
16 | 1997;Ford;E350
17 | 2000;Mercury;Cougar
18 | ")
19 |
20 | (def ^{:private true} complicated
21 | "1997,Ford,E350,\"ac, abs, moon\",3000.00
22 | 1999,Chevy,\"Venture \"\"Extended Edition\"\"\",\"\",4900.00
23 | 1999,Chevy,\"Venture \"\"Extended Edition, Very Large\"\"\",\"\",5000.00
24 | 1996,Jeep,Grand Cherokee,\"MUST SELL!
25 | air, moon roof, loaded\",4799.00")
26 |
27 | (deftest reading
28 | (let [csv (read-csv simple)]
29 | (is (= (count csv) 3))
30 | (is (= (count (first csv)) 3))
31 | (is (= (first csv) ["Year" "Make" "Model"]))
32 | (is (= (last csv) ["2000" "Mercury" "Cougar"])))
33 | (let [csv (read-csv simple-alt-sep :separator \;)]
34 | (is (= (count csv) 3))
35 | (is (= (count (first csv)) 3))
36 | (is (= (first csv) ["Year" "Make" "Model"]))
37 | (is (= (last csv) ["2000" "Mercury" "Cougar"])))
38 | (let [csv (read-csv complicated)]
39 | (is (= (count csv) 4))
40 | (is (= (count (first csv)) 5))
41 | (is (= (first csv)
42 | ["1997" "Ford" "E350" "ac, abs, moon" "3000.00"]))
43 | (is (= (last csv)
44 | ["1996" "Jeep" "Grand Cherokee", "MUST SELL!\nair, moon roof, loaded" "4799.00"]))))
45 |
46 |
47 | (deftest reading-and-writing
48 | (let [string-writer (StringWriter.)]
49 | (->> simple read-csv (write-csv string-writer))
50 | (is (= simple
51 | (str string-writer)))))
52 |
53 | (deftest throw-if-quoted-on-eof
54 | (let [s "ab,\"de,gh\nij,kl,mn"]
55 | (try
56 | (doall (read-csv s))
57 | (is false "No exception thrown")
58 | (catch Exception e
59 | (is (or (instance? java.io.EOFException e)
60 | (and (instance? RuntimeException e)
61 | (instance? java.io.EOFException (.getCause e)))))))))
62 |
63 | (deftest parse-line-endings
64 | (let [csv (read-csv "Year,Make,Model\n1997,Ford,E350")]
65 | (is (= 2 (count csv)))
66 | (is (= ["Year" "Make" "Model"] (first csv)))
67 | (is (= ["1997" "Ford" "E350"] (second csv))))
68 | (let [csv (read-csv "Year,Make,Model\r\n1997,Ford,E350")]
69 | (is (= 2 (count csv)))
70 | (is (= ["Year" "Make" "Model"] (first csv)))
71 | (is (= ["1997" "Ford" "E350"] (second csv))))
72 | (let [csv (read-csv "Year,Make,Model\r1997,Ford,E350")]
73 | (is (= 2 (count csv)))
74 | (is (= ["Year" "Make" "Model"] (first csv)))
75 | (is (= ["1997" "Ford" "E350"] (second csv))))
76 | (let [csv (read-csv "Year,Make,\"Model\"\r1997,Ford,E350")]
77 | (is (= 2 (count csv)))
78 | (is (= ["Year" "Make" "Model"] (first csv)))
79 | (is (= ["1997" "Ford" "E350"] (second csv)))))
80 |
--------------------------------------------------------------------------------
/src/main/clojure/clojure/data/csv.clj:
--------------------------------------------------------------------------------
1 | ;; Copyright (c) Jonas Enlund. All rights reserved. The use and
2 | ;; distribution terms for this software are covered by the Eclipse
3 | ;; Public License 1.0 (http://opensource.org/licenses/eclipse-1.0.php)
4 | ;; which can be found in the file epl-v10.html at the root of this
5 | ;; distribution. By using this software in any fashion, you are
6 | ;; agreeing to be bound by the terms of this license. You must not
7 | ;; remove this notice, or any other, from this software.
8 |
9 | (ns ^{:author "Jonas Enlund"
10 | :doc "Reading and writing comma separated values."}
11 | clojure.data.csv
12 | (:require (clojure [string :as str]))
13 | (:import (java.io PushbackReader Reader Writer StringReader EOFException)))
14 |
15 | ;(set! *warn-on-reflection* true)
16 |
17 | ;; Reading
18 |
19 | (def ^{:private true} lf (int \newline))
20 | (def ^{:private true} cr (int \return))
21 | (def ^{:private true} eof -1)
22 |
23 | (defn- read-quoted-cell [^PushbackReader reader ^StringBuilder sb sep quote]
24 | (loop [ch (.read reader)]
25 | (condp == ch
26 | quote (let [next-ch (.read reader)]
27 | (condp == next-ch
28 | quote (do (.append sb (char quote))
29 | (recur (.read reader)))
30 | sep :sep
31 | lf :eol
32 | cr (let [next-next-ch (.read reader)]
33 | (when (not= next-next-ch lf)
34 | (.unread reader next-next-ch))
35 | :eol)
36 | eof :eof
37 | (throw (Exception. ^String (format "CSV error (unexpected character: %c)" next-ch)))))
38 | eof (throw (EOFException. "CSV error (unexpected end of file)"))
39 | (do (.append sb (char ch))
40 | (recur (.read reader))))))
41 |
42 | (defn- read-cell [^PushbackReader reader ^StringBuilder sb sep quote]
43 | (let [first-ch (.read reader)]
44 | (if (== first-ch quote)
45 | (read-quoted-cell reader sb sep quote)
46 | (loop [ch first-ch]
47 | (condp == ch
48 | sep :sep
49 | lf :eol
50 | cr (let [next-ch (.read reader)]
51 | (when (not= next-ch lf)
52 | (.unread reader next-ch))
53 | :eol)
54 | eof :eof
55 | (do (.append sb (char ch))
56 | (recur (.read reader))))))))
57 |
58 | (defn- read-record [reader sep quote]
59 | (loop [record (transient [])]
60 | (let [cell (StringBuilder.)
61 | sentinel (read-cell reader cell sep quote)]
62 | (if (= sentinel :sep)
63 | (recur (conj! record (str cell)))
64 | [(persistent! (conj! record (str cell))) sentinel]))))
65 |
66 | (defprotocol Read-CSV-From
67 | (read-csv-from [input sep quote]))
68 |
69 | (extend-protocol Read-CSV-From
70 | String
71 | (read-csv-from [s sep quote]
72 | (read-csv-from (PushbackReader. (StringReader. s)) sep quote))
73 |
74 | Reader
75 | (read-csv-from [reader sep quote]
76 | (read-csv-from (PushbackReader. reader) sep quote))
77 |
78 | PushbackReader
79 | (read-csv-from [reader sep quote]
80 | (lazy-seq
81 | (let [[record sentinel] (read-record reader sep quote)]
82 | (case sentinel
83 | :eol (cons record (read-csv-from reader sep quote))
84 | :eof (when-not (= record [""])
85 | (cons record nil)))))))
86 |
87 | (defn read-csv
88 | "Reads CSV-data from input (String or java.io.Reader) into a lazy
89 | sequence of vectors.
90 |
91 | Valid options are
92 | :separator (default \\,)
93 | :quote (default \\\")"
94 | [input & options]
95 | (let [{:keys [separator quote] :or {separator \, quote \"}} options]
96 | (read-csv-from input (int separator) (int quote))))
97 |
98 |
99 | ;; Writing
100 |
101 | (defn- write-cell [^Writer writer obj sep quote quote?]
102 | (let [string (str obj)
103 | must-quote (quote? string)]
104 | (when must-quote (.write writer (int quote)))
105 | (.write writer (if must-quote
106 | (str/escape string
107 | {quote (str quote quote)})
108 | string))
109 | (when must-quote (.write writer (int quote)))))
110 |
111 | (defn- write-record [^Writer writer record sep quote quote?]
112 | (loop [record record]
113 | (when-first [cell record]
114 | (write-cell writer cell sep quote quote?)
115 | (when-let [more (next record)]
116 | (.write writer (int sep))
117 | (recur more)))))
118 |
119 | (defn- write-csv*
120 | [^Writer writer records sep quote quote? ^String newline]
121 | (loop [records records]
122 | (when-first [record records]
123 | (write-record writer record sep quote quote?)
124 | (.write writer newline)
125 | (recur (next records)))))
126 |
127 | (defn write-csv
128 | "Writes data to writer in CSV-format.
129 |
130 | Valid options are
131 | :separator (Default \\,)
132 | :quote (Default \\\")
133 | :quote? (A predicate function which determines if a string should be quoted. Defaults to quoting only when necessary.)
134 | :newline (:lf (default) or :cr+lf)"
135 | [writer data & options]
136 | (let [opts (apply hash-map options)
137 | separator (or (:separator opts) \,)
138 | quote (or (:quote opts) \")
139 | quote? (or (:quote? opts) (let [should-quote #{separator quote \return \newline}] #(some should-quote %)))
140 | newline (or (:newline opts) :lf)]
141 | (write-csv* writer
142 | data
143 | separator
144 | quote
145 | quote?
146 | ({:lf "\n" :cr+lf "\r\n"} newline))))
147 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | clojure.data.csv
2 | ========================================
3 |
4 | [*API documentation*](https://clojure.github.io/data.csv/)
5 |
6 | CSV reader/writer to/from Clojure data structures.
7 |
8 | Follows the [RFC4180](https://tools.ietf.org/html/rfc4180) specification but is more relaxed.
9 |
10 |
11 |
12 | Releases and Dependency Information
13 | ========================================
14 |
15 | This project follows the version scheme MAJOR.MINOR.PATCH where each component provides some relative indication of the size of the change, but does not follow semantic versioning. In general, all changes endeavor to be non-breaking (by moving to new names rather than by breaking existing names).
16 |
17 | Latest stable release: 1.1.0
18 |
19 | * [All Released Versions](https://search.maven.org/#search%7Cga%7C1%7Cg%3A%22org.clojure%22%20AND%20a%3A%22data.csv%22)
20 | * [Development Snapshot Versions](https://oss.sonatype.org/index.html#nexus-search;gav~org.clojure~data.csv~~~)
21 |
22 | [CLI/`deps.edn`](https://clojure.org/reference/deps_edn) dependency information:
23 | ```clojure
24 | org.clojure/data.csv {:mvn/version "1.1.0"}
25 | ```
26 |
27 | [Leiningen](https://github.com/technomancy/leiningen) dependency information:
28 |
29 | ```clojure
30 | [org.clojure/data.csv "1.1.0"]
31 | ```
32 |
33 | [Maven](https://maven.apache.org/) dependency information:
34 |
35 | ```xml
36 |
37 | org.clojure
38 | data.csv
39 | 1.1.0
40 |
41 | ```
42 |
43 |
44 | Example Usage
45 | ========================================
46 |
47 | ```clojure
48 | (require '[clojure.data.csv :as csv]
49 | '[clojure.java.io :as io])
50 |
51 | (with-open [reader (io/reader "in-file.csv")]
52 | (doall
53 | (csv/read-csv reader)))
54 |
55 | (with-open [writer (io/writer "out-file.csv")]
56 | (csv/write-csv writer
57 | [["abc" "def"]
58 | ["ghi" "jkl"]]))
59 | ```
60 |
61 | Refer to the [API documentation](https://clojure.github.io/data.csv/)
62 | for additional information.
63 |
64 | ## Working with data.csv
65 |
66 | This library is meant to remain small and focus on nothing but correctly parsing
67 | csv files. The following sections describes how to effectively use data.csv as a
68 | building block in larger programs as well as some hints on how to solve common
69 | problems.
70 |
71 | ### Laziness
72 |
73 | When parsing a csv file with data.csv the result is a lazy sequence of vectors
74 | of strings. With some care, laziness makes it possible to process very large csv
75 | files without excessive memory use. Here's an example of a program that copies
76 | one csv file to another but drops the first and last columns:
77 |
78 | ```clojure
79 | (defn copy-csv [from to]
80 | (with-open [reader (io/reader from)
81 | writer (io/writer to)]
82 | (->> (csv/read-csv reader)
83 | (map #(rest (butlast %)))
84 | (csv/write-csv writer))))
85 | ```
86 |
87 | This function will work even if the csv file is larger than would fit in memory
88 | because all the steps are lazy.
89 |
90 | There are a few things to look out for when dealing with lazy
91 | sequences. Especially with data.csv where the sequence is often created via a
92 | `clojure.java.io/reader` that could already be closed when the lazy sequence is
93 | consumed. For example
94 |
95 | ```clojure
96 | (defn read-column [filename column-index]
97 | (with-open [reader (io/reader filename)]
98 | (let [data (csv/read-csv reader)]
99 | (map #(nth % column-index) data))))
100 |
101 | (defn sum-second-column [filename]
102 | (->> (read-column filename 1)
103 | (drop 1) ;; Drop header column
104 | (map #(Double/parseDouble %))
105 | (reduce + 0)))
106 | ```
107 |
108 | This program will throw the exception "`java.io.Exception`: Stream Closed". The
109 | reason is that both `read-csv` and `map` are lazy, so `read-column` will
110 | immeditaly return a sequence without actually reading any bytes from the
111 | file. The reading (and parsing) will happen when data is needed by the calling
112 | code (`reduce` in this case). By the time `reduce` tries to add the first value
113 | `with-open` will already have closed the `io/reader` and the exception is
114 | thrown.
115 |
116 | There are two solutions to this problem:
117 |
118 | 1. Move the opening/closing of the reader up the callstack to the point where
119 | the content is consumed:
120 |
121 | ```clojure
122 | (defn read-column [reader column-index]
123 | (let [data (csv/read-csv reader)]
124 | (map #(nth % column-index) data)))
125 |
126 | (defn sum-second-column [filename]
127 | (with-open [reader (io/reader filename)]
128 | (->> (read-column reader 1)
129 | (drop 1)
130 | (map #(Double/parseDouble %))
131 | (reduce + 0))))
132 | ```
133 |
134 | 2. Don't return a lazy sequence
135 |
136 | ```clojure
137 | (defn read-column [filename column-index]
138 | (with-open [reader (io/reader filename)]
139 | (let [data (csv/read-csv reader)]
140 | ;; mapv is not lazy, so the csv data will be consumed at this point
141 | (mapv #(nth % column-index) data))))
142 |
143 | (defn sum-second-column [filename]
144 | (->> (read-column filename 1)
145 | (drop 1)
146 | (map #(Double/parseDouble %))
147 | (reduce + 0)))
148 | ```
149 |
150 | Which approach to choose depends on the application. If the csv file isn't huge
151 | the second approach will often work well. If you want to be careful not to read
152 | the csv file into memory the first approach is preferable.
153 |
154 | ### Parsing into maps
155 |
156 | Data.csv parses lines of a csv file into a vector of strings. This is often not
157 | the desired output where you might want the result to be a sequence of maps
158 | instead, such as
159 |
160 | ```text
161 | foo,bar,baz
162 | A,1,x
163 | B,2,y
164 | C,3,z
165 | ```
166 |
167 | ```clojure
168 | ({:foo "A"
169 | :bar "1"
170 | :baz "x"}
171 | {:foo "B"
172 | :bar "2"
173 | :baz "y"}
174 | {:foo "C"
175 | :bar "3"
176 | :baz "z"})
177 | ```
178 |
179 | One fairly elegant way to achieve this is the expression
180 |
181 | ```clojure
182 | (defn csv-data->maps [csv-data]
183 | (map zipmap
184 | (->> (first csv-data) ;; First row is the header
185 | (map keyword) ;; Drop if you want string keys instead
186 | repeat)
187 | (rest csv-data)))
188 |
189 | (csv-data->maps (csv/read-csv reader))
190 | ```
191 |
192 | This function is lazy so all the options described in the previous section are
193 | still valid. Now that the data is in a nice format it's easy to do any desired
194 | post-processing:
195 |
196 | ```clojure
197 | (->> (csv/read-csv reader)
198 | csv-data->maps
199 | (map (fn [csv-record]
200 | (update csv-record :bar #(Long/parseLong %)))))
201 |
202 | ({:foo "A"
203 | :bar 1
204 | :baz "x"}
205 | {:foo "B"
206 | :bar 2
207 | :baz "y"}
208 | {:foo "C"
209 | :bar 3
210 | :baz "z"})
211 | ```
212 |
213 | ### Byte Order Mark
214 |
215 | A [byte order mark (BOM)](https://en.wikipedia.org/wiki/Byte_order_mark) is a
216 | byte sequence that appears as the first couple of bytes in some CSV files (and
217 | other text files). Data.csv will not automatically remove these extra bytes so
218 | they can accidentally be interpreted as part of the first cells characters. If
219 | you want to avoid this you can either try to manually detect it by looking at
220 | the first byte(s) and calling `(.skip reader 1)` before you pass the reader to
221 | read-csv.
222 |
223 | Another option is to create the reader in such a way that the BOM will be
224 | automatically removed. One way to achieve this is to use
225 | [`org.apache.commons.io.input/BOMInputStream`](https://commons.apache.org/proper/commons-io/javadocs/api-release/org/apache/commons/io/input/BOMInputStream.html):
226 |
227 | ```clojure
228 | (with-open [reader (-> "data.csv"
229 | io/input-stream
230 | BOMInputStream.
231 | io/reader)]
232 | (doall (csv/read-csv reader)))
233 | ```
234 |
235 |
236 |
237 | Developer Information
238 | ========================================
239 |
240 | * [GitHub project](https://github.com/clojure/data.csv)
241 | * [Bug Tracker](https://clojure.atlassian.net/browse/DCSV)
242 | * [Continuous Integration](https://github.com/clojure/data.csv/actions/workflows/test.yml)
243 |
244 |
245 | Change Log
246 | ====================
247 |
248 | * Release 1.1.0 on 2024-02-19
249 | * Update parent pom version
250 | * Release 1.0.1 on 2022-04-04
251 | * Lift construction requiring quote out of the quote? function in write-csv
252 | * Release 1.0.0 on 2020-02-18
253 | * Release 0.1.4 on 2017-04-05
254 | * [DCSV-16](https://dev.clojure.org/jira/browse/DCSV-16) Resolve some reflection warnings
255 | * Release 0.1.3 on 2015-08-10
256 | * [DCSV-4](https://dev.clojure.org/jira/browse/DCSV-4) Allow carriage
257 | return by itself as a record separator
258 | * Release 0.1.2 on 2012-02-24
259 | * Fixed keyword params for `write-csv`
260 | * Release 0.1.1 on 2012-02-14
261 | * Added quote? keyword param to write-csv
262 | * Code cleanup
263 | * Release 0.1.0 on 2011-08-26
264 | * Initial release.
265 |
266 |
267 |
268 | Copyright and License
269 | ========================================
270 |
271 | Copyright (c) Jonas Enlund, Rich Hickey, and contributors.
272 | All rights reserved. The use and
273 | distribution terms for this software are covered by the Eclipse Public
274 | License 1.0 (https://opensource.org/license/epl-1-0/) which can
275 | be found in the file epl-v10.html at the root of this distribution.
276 | By using this software in any fashion, you are agreeing to be bound by
277 | the terms of this license. You must not remove this notice, or any
278 | other, from this software.
279 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Eclipse Public License - v 1.0
2 |
3 | THE ACCOMPANYING PROGRAM IS PROVIDED UNDER THE TERMS OF THIS ECLIPSE PUBLIC
4 | LICENSE ("AGREEMENT"). ANY USE, REPRODUCTION OR DISTRIBUTION OF THE PROGRAM
5 | CONSTITUTES RECIPIENT'S ACCEPTANCE OF THIS AGREEMENT.
6 |
7 | 1. DEFINITIONS
8 |
9 | "Contribution" means:
10 |
11 | a) in the case of the initial Contributor, the initial code and documentation
12 | distributed under this Agreement, and
13 | b) in the case of each subsequent Contributor:
14 | i) changes to the Program, and
15 | ii) additions to the Program;
16 |
17 | where such changes and/or additions to the Program originate from and are
18 | distributed by that particular Contributor. A Contribution 'originates'
19 | from a Contributor if it was added to the Program by such Contributor
20 | itself or anyone acting on such Contributor's behalf. Contributions do not
21 | include additions to the Program which: (i) are separate modules of
22 | software distributed in conjunction with the Program under their own
23 | license agreement, and (ii) are not derivative works of the Program.
24 |
25 | "Contributor" means any person or entity that distributes the Program.
26 |
27 | "Licensed Patents" mean patent claims licensable by a Contributor which are
28 | necessarily infringed by the use or sale of its Contribution alone or when
29 | combined with the Program.
30 |
31 | "Program" means the Contributions distributed in accordance with this
32 | Agreement.
33 |
34 | "Recipient" means anyone who receives the Program under this Agreement,
35 | including all Contributors.
36 |
37 | 2. GRANT OF RIGHTS
38 | a) Subject to the terms of this Agreement, each Contributor hereby grants
39 | Recipient a non-exclusive, worldwide, royalty-free copyright license to
40 | reproduce, prepare derivative works of, publicly display, publicly
41 | perform, distribute and sublicense the Contribution of such Contributor,
42 | if any, and such derivative works, in source code and object code form.
43 | b) Subject to the terms of this Agreement, each Contributor hereby grants
44 | Recipient a non-exclusive, worldwide, royalty-free patent license under
45 | Licensed Patents to make, use, sell, offer to sell, import and otherwise
46 | transfer the Contribution of such Contributor, if any, in source code and
47 | object code form. This patent license shall apply to the combination of
48 | the Contribution and the Program if, at the time the Contribution is
49 | added by the Contributor, such addition of the Contribution causes such
50 | combination to be covered by the Licensed Patents. The patent license
51 | shall not apply to any other combinations which include the Contribution.
52 | No hardware per se is licensed hereunder.
53 | c) Recipient understands that although each Contributor grants the licenses
54 | to its Contributions set forth herein, no assurances are provided by any
55 | Contributor that the Program does not infringe the patent or other
56 | intellectual property rights of any other entity. Each Contributor
57 | disclaims any liability to Recipient for claims brought by any other
58 | entity based on infringement of intellectual property rights or
59 | otherwise. As a condition to exercising the rights and licenses granted
60 | hereunder, each Recipient hereby assumes sole responsibility to secure
61 | any other intellectual property rights needed, if any. For example, if a
62 | third party patent license is required to allow Recipient to distribute
63 | the Program, it is Recipient's responsibility to acquire that license
64 | before distributing the Program.
65 | d) Each Contributor represents that to its knowledge it has sufficient
66 | copyright rights in its Contribution, if any, to grant the copyright
67 | license set forth in this Agreement.
68 |
69 | 3. REQUIREMENTS
70 |
71 | A Contributor may choose to distribute the Program in object code form under
72 | its own license agreement, provided that:
73 |
74 | a) it complies with the terms and conditions of this Agreement; and
75 | b) its license agreement:
76 | i) effectively disclaims on behalf of all Contributors all warranties
77 | and conditions, express and implied, including warranties or
78 | conditions of title and non-infringement, and implied warranties or
79 | conditions of merchantability and fitness for a particular purpose;
80 | ii) effectively excludes on behalf of all Contributors all liability for
81 | damages, including direct, indirect, special, incidental and
82 | consequential damages, such as lost profits;
83 | iii) states that any provisions which differ from this Agreement are
84 | offered by that Contributor alone and not by any other party; and
85 | iv) states that source code for the Program is available from such
86 | Contributor, and informs licensees how to obtain it in a reasonable
87 | manner on or through a medium customarily used for software exchange.
88 |
89 | When the Program is made available in source code form:
90 |
91 | a) it must be made available under this Agreement; and
92 | b) a copy of this Agreement must be included with each copy of the Program.
93 | Contributors may not remove or alter any copyright notices contained
94 | within the Program.
95 |
96 | Each Contributor must identify itself as the originator of its Contribution,
97 | if
98 | any, in a manner that reasonably allows subsequent Recipients to identify the
99 | originator of the Contribution.
100 |
101 | 4. COMMERCIAL DISTRIBUTION
102 |
103 | Commercial distributors of software may accept certain responsibilities with
104 | respect to end users, business partners and the like. While this license is
105 | intended to facilitate the commercial use of the Program, the Contributor who
106 | includes the Program in a commercial product offering should do so in a manner
107 | which does not create potential liability for other Contributors. Therefore,
108 | if a Contributor includes the Program in a commercial product offering, such
109 | Contributor ("Commercial Contributor") hereby agrees to defend and indemnify
110 | every other Contributor ("Indemnified Contributor") against any losses,
111 | damages and costs (collectively "Losses") arising from claims, lawsuits and
112 | other legal actions brought by a third party against the Indemnified
113 | Contributor to the extent caused by the acts or omissions of such Commercial
114 | Contributor in connection with its distribution of the Program in a commercial
115 | product offering. The obligations in this section do not apply to any claims
116 | or Losses relating to any actual or alleged intellectual property
117 | infringement. In order to qualify, an Indemnified Contributor must:
118 | a) promptly notify the Commercial Contributor in writing of such claim, and
119 | b) allow the Commercial Contributor to control, and cooperate with the
120 | Commercial Contributor in, the defense and any related settlement
121 | negotiations. The Indemnified Contributor may participate in any such claim at
122 | its own expense.
123 |
124 | For example, a Contributor might include the Program in a commercial product
125 | offering, Product X. That Contributor is then a Commercial Contributor. If
126 | that Commercial Contributor then makes performance claims, or offers
127 | warranties related to Product X, those performance claims and warranties are
128 | such Commercial Contributor's responsibility alone. Under this section, the
129 | Commercial Contributor would have to defend claims against the other
130 | Contributors related to those performance claims and warranties, and if a
131 | court requires any other Contributor to pay any damages as a result, the
132 | Commercial Contributor must pay those damages.
133 |
134 | 5. NO WARRANTY
135 |
136 | EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, THE PROGRAM IS PROVIDED ON AN
137 | "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR
138 | IMPLIED INCLUDING, WITHOUT LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE,
139 | NON-INFRINGEMENT, MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each
140 | Recipient is solely responsible for determining the appropriateness of using
141 | and distributing the Program and assumes all risks associated with its
142 | exercise of rights under this Agreement , including but not limited to the
143 | risks and costs of program errors, compliance with applicable laws, damage to
144 | or loss of data, programs or equipment, and unavailability or interruption of
145 | operations.
146 |
147 | 6. DISCLAIMER OF LIABILITY
148 |
149 | EXCEPT AS EXPRESSLY SET FORTH IN THIS AGREEMENT, NEITHER RECIPIENT NOR ANY
150 | CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY DIRECT, INDIRECT, INCIDENTAL,
151 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING WITHOUT LIMITATION
152 | LOST PROFITS), HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
153 | CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
154 | ARISING IN ANY WAY OUT OF THE USE OR DISTRIBUTION OF THE PROGRAM OR THE
155 | EXERCISE OF ANY RIGHTS GRANTED HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY
156 | OF SUCH DAMAGES.
157 |
158 | 7. GENERAL
159 |
160 | If any provision of this Agreement is invalid or unenforceable under
161 | applicable law, it shall not affect the validity or enforceability of the
162 | remainder of the terms of this Agreement, and without further action by the
163 | parties hereto, such provision shall be reformed to the minimum extent
164 | necessary to make such provision valid and enforceable.
165 |
166 | If Recipient institutes patent litigation against any entity (including a
167 | cross-claim or counterclaim in a lawsuit) alleging that the Program itself
168 | (excluding combinations of the Program with other software or hardware)
169 | infringes such Recipient's patent(s), then such Recipient's rights granted
170 | under Section 2(b) shall terminate as of the date such litigation is filed.
171 |
172 | All Recipient's rights under this Agreement shall terminate if it fails to
173 | comply with any of the material terms or conditions of this Agreement and does
174 | not cure such failure in a reasonable period of time after becoming aware of
175 | such noncompliance. If all Recipient's rights under this Agreement terminate,
176 | Recipient agrees to cease use and distribution of the Program as soon as
177 | reasonably practicable. However, Recipient's obligations under this Agreement
178 | and any licenses granted by Recipient relating to the Program shall continue
179 | and survive.
180 |
181 | Everyone is permitted to copy and distribute copies of this Agreement, but in
182 | order to avoid inconsistency the Agreement is copyrighted and may only be
183 | modified in the following manner. The Agreement Steward reserves the right to
184 | publish new versions (including revisions) of this Agreement from time to
185 | time. No one other than the Agreement Steward has the right to modify this
186 | Agreement. The Eclipse Foundation is the initial Agreement Steward. The
187 | Eclipse Foundation may assign the responsibility to serve as the Agreement
188 | Steward to a suitable separate entity. Each new version of the Agreement will
189 | be given a distinguishing version number. The Program (including
190 | Contributions) may always be distributed subject to the version of the
191 | Agreement under which it was received. In addition, after a new version of the
192 | Agreement is published, Contributor may elect to distribute the Program
193 | (including its Contributions) under the new version. Except as expressly
194 | stated in Sections 2(a) and 2(b) above, Recipient receives no rights or
195 | licenses to the intellectual property of any Contributor under this Agreement,
196 | whether expressly, by implication, estoppel or otherwise. All rights in the
197 | Program not expressly granted under this Agreement are reserved.
198 |
199 | This Agreement is governed by the laws of the State of New York and the
200 | intellectual property laws of the United States of America. No party to this
201 | Agreement will bring a legal action under this Agreement more than one year
202 | after the cause of action arose. Each party waives its rights to a jury trial in
203 | any resulting litigation.
204 |
205 |
206 |
--------------------------------------------------------------------------------