;;;; -*- Mode: Lisp; Syntax: ANSI-Common-Lisp; Base: 10; Package: umlisp -*- ;;;; ************************************************************************* ;;;; FILE IDENTIFICATION ;;;; ;;;; Name: parse-macros.lisp ;;;; Purpose: Macros for UMLS file parsing ;;;; Author: Kevin M. Rosenberg ;;;; Created: Apr 2000 ;;;; ;;;; This file, part of UMLisp, is ;;;; Copyright (c) 2000-2010 by Kevin M. Rosenberg, M.D. ;;;; ;;;; UMLisp users are granted the rights to distribute and use this software ;;;; as governed by the terms of the GNU General Public License. ;;;; ************************************************************************* (in-package #:umlisp) (defun read-umls-line (strm &optional (eof 'eof)) "Read a line from a UMLS stream, split into fields" (let ((line (read-line strm nil eof))) (if (eq line eof) eof (delimited-string-to-list line #\| t)))) (defun source-files (path) (if (probe-file path) (list path) (sort (directory (make-pathname :defaults path :type :wild :name (concatenate 'string (pathname-name path) (aif (pathname-type path) (concatenate 'string "." it) "")))) #'(lambda (a b) (string-lessp (pathname-type a) (pathname-type b)))))) (defmacro with-buffered-reading-umls-file ((line path) &body body) "Opens a UMLS and processes each parsed line with (body) argument" (let ((ustream (gensym "STRM-")) (buffer (gensym "BUF-")) (eof (gensym "EOF-")) (files (gensym "FILES-"))) `(let ((,eof (gensym "EOFSYM-")) (,buffer (make-fields-buffer)) (,files (source-files ,path))) (with-open-file (,ustream (first ,files) :direction :input #+(and sbcl sb-unicode) :external-format #+(and sbcl sb-unicode) :UTF-8 #+(and allegro ics) :external-format #+(and allegro ics) :UTF-8 #+lispworks :external-format #+lispworks :UTF-8 #+(and clisp unicode) :external-format #+(and clisp unicode) charset:utf-8) (do ((,line (read-buffered-fields ,buffer ,ustream #\| ,eof) (read-buffered-fields ,buffer ,ustream #\| ,eof))) ((eq ,line ,eof) t) (setq ,line (coerce ,line 'list)) (print ,line) ,@body))))) (defmacro with-reading-umls-file ((line path) &body body) "Opens a UMLS and processes each parsed line with (body) argument" (let ((ustream (gensym "STRM-")) (eof (gensym "EOF-")) (files (gensym "FILES-"))) `(let ((,eof (gensym "EOFSYM-")) (,files (source-files ,path))) (unless ,files (error "Can't find files for ~A~%" (namestring ,path))) (with-open-file (,ustream (first ,files) :direction :input #+(and sbcl sb-unicode) :external-format #+(and sbcl sb-unicode) :UTF-8 #+(and allegro ics) :external-format #+(and allegro ics) :UTF-8 #+lispworks :external-format #+lispworks :UTF-8 #+(and clisp unicode) :external-format #+(and clisp unicode) charset:utf-8) (do ((,line (read-umls-line ,ustream ,eof) (read-umls-line ,ustream ,eof))) ((eq ,line ,eof) t) (locally (declare (type list ,line)) ,@body)))))) (defmacro with-umls-ufile ((line ufile) &body body) "Opens a UMLS and processes each parsed line with (body) argument" `(with-reading-umls-file (,line (ufile-pathname ,ufile)) ,@body)) (defmacro with-umls-file ((line ufile) &body body) "Opens a UMLS and processes each parsed line with (body) argument" `(with-reading-umls-file (,line (umls-pathname ,ufile)) ,@body)) (defmacro with-buffered-umls-file ((line filename) &body body) "Opens a UMLS and processes each parsed line with (body) argument" (let ((ustream (gensym "STRM-")) (buffer (gensym "BUF-")) (eof (gensym "EOF-"))) `(let ((,buffer (make-fields-buffer)) (,eof (gensym "EOFSYM-"))) (with-open-file (,ustream (umls-pathname ,filename) :direction :input #+(and sbcl sb-unicode) :external-format #+(and sbcl sb-unicode) :UTF-8 #+(and allegro ics) :external-format #+(and allegro ics) :UTF-8 #+lispworks :external-format #+lispworks :UTF-8 #+(and clisp unicode) :external-format #+(and clisp unicode) charset:utf-8) (do ((,line (read-buffered-fields ,buffer ,ustream #\| ,eof) (read-buffered-fields ,buffer ,ustream #\| ,eof))) ((eq ,line ,eof) t) ,@body)))))