commit f14f23e8553b293cb69a6adcbd51e49dd7f8313f jose <jose@linux-q5ep.lan> 2018-11-12 07:55:33 -0800 Working but needs quoting.
src/csv-reader.lisp | 87 +++++++++++++++++++++++++++++++++++------------------ 1 file changed, 58 insertions(+), 29 deletions(-)
diff --git a/src/csv-reader.lisp b/src/csv-reader.lisp index 2cd9bdb..426401b 100644 --- a/src/csv-reader.lisp +++ b/src/csv-reader.lisp @@ -1,31 +1,60 @@ (defpackage :csv (:use :cl :utils) - (:import-from :utils :with-gensyms)) -(defun toggle (thing) - (setf thing (not thing))) -(defmacro make (external-var-pairs name args &body body) - `(let ,external-var-pairs - (setf (symbol-function ',name) #'(lambda ,args ,@body)))) -(defun push-on (elem array) - (let ((len (length array))) - (adjust-array array (1+ len)) - (setf (elt array len) elem) - array)) -(let ((in nil) - (str (make-array 0 :adjustable t :element-type 'character)) - (prev #\Nul)) - (make () reset () (setf in nil) (setf prev #\Nul)) - (make () close? (char) (and in (char= #\" char) (char/= #\Stx prev))) - (make () open! () (setf in t prev #\Stx)) - (make () close! () (push-on #\Nul str) (setf in nil)) - (make () open? (char) (and (not in) (char= #\" char))) - (make () wait? (char) (and (not in) (char= #\, char))) - (make () push! (char) (when (not (and (char= #\" char) (char= #\" prev))) (push-on char str)) (setf prev char)) - (make () str () (prog1 str (setf in nil str (make-array 0 :adjustable t :element-type 'character) prev #\Nul)))) -(defun read-csv-old (path) - (doread (char path) - (cond ((close? char) (close!)) - ((wait? char) nil) - ((open? char) (open!)) - (t (push! char)))) - (str)) + (:import-from :utils :push-on :with-gensyms :make) + (:export :read-csv)) +(in-package :csv) +(defun toggle (val) + (setf val (not val))) +(make ((line "") (pos 0)) read-char-fast (stream) + (if (string= "" line) + (let ((next (read-line stream nil nil))) + (when next (setf line next pos 0) #\Newline)) + (elt line (incf pos)))) +(defvar *in* nil) +(defun switches (prev curr str) + (format t "~A ~A ~A~%" *in* prev curr) + (let ((res (if (null curr) + (setf *in* nil) + (if *in* + (if (char= #\" prev curr) + #\" + (if #1=(char= #\" prev) + (progn (setf *in* nil) #\Nul) + prev)) + (if #1# + (setf *in* t)))))) + (if (characterp res) + (push-on res str) + str))) +(defun splice (str) + (when (not (string= "" str)) + (let ((res (search (string #\Nul) str))) + (cons (subseq str 0 res) (splice (subseq str (1+ res))))))) +(defmacro make-reader (name (stream-var dispatch-1 dispatch-2) &body body) + (with-gensyms (sub-char numarg) + `(progn (defun ,name (,stream-var ,sub-char ,numarg) + (declare (ignore ,sub-char ,numarg)) + ,@body) + (set-dispatch-macro-character ,dispatch-1 ,dispatch-2 #',name)))) +(make-reader my-csv (stream #\# #\,) + (do ((prev #1= (read-char stream nil nil) curr) + (curr #1# #1#) + (str (make-array 0 :adjustable t :element-type 'character) + (switches prev curr str))) + ((and (char= curr #\#) (char= prev #\,)) (splice (switches nil nil str))))) +;;; '#, "hi there","man!",# +(make-reader my-string (stream #\# #\>) + (do* ((prev #1=(read-char stream nil nil) curr) + (first prev) + (curr #1# #1#) + (str (make-array 0 :adjustable t :element-type 'character) + (push-on prev str))) + ((char= curr first) str))) + +;; (make-reader csv (stream #\#) +;; (do ((prev #1=(read-char-fast stream) curr) +;; (curr #1# #1#)) +;; ((not curr)))) +;; (defun read-csv (path) +;; (with-open-file (stream path) +;; (mapcar #'(lambda (x) (subseq x 1)) (read-string stream))))