1
;;; edb-1int-to-single.el
3
;; Copyright (C) 2006,2007,2008 Thien-Thi Nguyen
5
;; This file is part of EDB.
7
;; EDB is free software; you can redistribute it and/or modify it under
8
;; the terms of the GNU General Public License as published by the Free
9
;; Software Foundation; either version 3, or (at your option) any later
12
;; EDB is distributed in the hope that it will be useful, but WITHOUT
13
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14
;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17
;; You should have received a copy of the GNU General Public License
18
;; along with EDB; see the file COPYING. If not, write to the Free
19
;; Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
20
;; MA 02110-1301, USA.
24
;; This file provides the single command `edb-1int-to-single',
25
;; as well as the feature by the same name. See info file.
29
(eval-when-compile (require 'cl))
32
(defun edb-1int-to-single (filename)
33
"Translate contents of FILENAME to a \"single\" schema-schema.
34
If the contents are not in EDB 1.x \"internal file layout, format 0.7\",
35
signal an error. Otherwise, leave the result of the translation in
36
a newly created output buffer named \":EDB (single) from FILENAME\".
38
The output buffer may have several \"<FIXME>\" tokens in it,
39
indicating places where further attention (a nice way to say
40
\"manual tweaking\") is required to complete the translation.
42
See info node `(edb)edb-1int-to-single' for the complete list
43
of possible <FIXME> occurances and suggested remedies."
44
(interactive "fTranslate EDB 1.x \"internal file layout\": ")
45
(let ((fixme "<FIXME>")
46
;; todo: for EDB 2.x, replace computation w/ (its) constant value
47
(mm-idx (let ((slots (mapcar (lambda (ent)
48
(intern (format ":%s" (car ent))))
49
(get 'edb--v1-monolithic-mess
51
(map 'list 'cons slots (number-sequence 0 (length slots)))))
52
mm extra records coding loc-block locals)
53
(flet ((elm () (let ((emacs-lisp-mode-hook nil))
55
(mref (slot) (aref mm (cdr (assq slot mm-idx))))
56
(cprop (prop &optional more) (insert (format "%s" prop)
61
(nlnl (&optional stuff) (insert (if stuff
66
(backslash-hat (c) (cond ((= ?\n c) (insert c))
67
((> 32 c) (insert "\\^" (+ c 64)))
71
(insert-file-contents filename)
72
(goto-char (point-min))
73
(unless (looking-at ";; Database file written by EDB; format 0.7")
74
(error "Not in \"internal file layout, format 0.7\": %s" filename))
76
(setq mm (read (current-buffer))
77
extra (read (current-buffer))
78
records (buffer-substring-no-properties
79
(progn (forward-line 1) (point))
81
coding coding-system-for-read))
84
(concat ":EDB (single) from " filename)))
86
(setq default-directory (file-name-directory filename))
88
(let ((standard-output (current-buffer))
90
(insert ":EDB (single) ;;; -*- mode:emacs-lisp; coding:")
91
(princ (or coding fixme))
94
(prin1 (or (mref :print-name) fixme))
97
(pp (map 'vector 'cons (mref :fieldnames) (mref :recordfieldspecs)))
99
(when (setq v (car (mref :field-priorities)))
102
(flet ((ok (x) (cond ((symbolp x)
105
(aref (mref :fieldnames) x))
107
(error "badness")))))
108
(mapcar (lambda (spec)
109
(cond ((and (consp spec)
110
(not (consp (cdr spec))))
113
(cons (ok (car spec)) (cdr spec)))
118
(let ((fsub (mref :sub-fieldsep-string))
119
(rsub (mref :sub-recordsep-string)))
121
(cprop :substitution-separators)
122
(let ((standard-output 'backslash-hat))
123
(pp (vector fsub rsub)))
125
(when (setq v (mref :substitutions))
126
(cprop :substitutions)
127
(let ((standard-output 'backslash-hat))
128
(pp (apply 'vector v)))
131
(flet ((yes (c) (when c
133
(setq limit (+ (cadr (insert-file-contents try))
135
(when (re-search-forward "\f*\nLocal Variables:\n"
138
(setq loc-block (buffer-substring-no-properties
139
(match-end 0) limit))
140
(delete-region (match-beginning 0) limit))
144
(cond ((yes (and (setq try (assq :format-file extra))
145
(setq try (expand-file-name
147
(file-name-directory filename)))
148
(file-readable-p try))))
149
((yes (setq try (db-locate-readable-file-prefer-cwd
150
(file-name-nondirectory
151
(file-name-sans-extension filename))
152
(cons (file-name-directory filename)
154
db-format-file-suffixes))))
156
(cprop :display (list (intern fixme)))
157
(insert fixme "\n"))))
159
(cprop :data '(:coding t :seqr read-line :EOTB ":EOTB"))
160
(insert records ":EOTB")
162
(goto-char (point-min))
164
(insert "\n;;; From primary format file's local variables block:\n")
165
(narrow-to-region (point) (point-max))
167
(delete-region (point) (progn (search-backward "\nEnd:")
169
(narrow-to-region (point-min) (point))
170
(goto-char (point-min))
171
(while (< (point) (point-max))
172
(cond ((looking-at "^eval:")
174
(let* ((opoint (point))
175
(form (read (current-buffer)))
176
(special (assq (car form)
177
'((database-set-fieldnames-to-list
179
(dbf-set-summary-format
180
:summary-format car)))))
182
(let* ((why (cadr special))
183
(blurb (if (stringp why)
188
"control property")))
189
(xlat (caddr special)))
190
(delete-region opoint (progn (forward-line 1)
192
(insert ";;*" blurb ":\n;; "
193
(format "(%s ...)" (car form))
199
(re-search-forward "^:data")
202
(let ((standard-output 'backslash-hat)
203
(v (funcall xlat (cdr form))))
209
(delete-horizontal-space)
211
(insert ";;*unhandled (" fixme "):\n")
212
(comment-region (point) (progn (forward-sexp 1)
216
(let* ((opoint (point))
217
(var (progn (looking-at "\\s-*\\([^:]+\\):\\s-*")
218
(prog1 (intern (match-string 1))
219
(goto-char (match-end 0)))))
220
(val (prog1 (read (current-buffer))
222
(form `(set (make-local-variable ',var)
223
,(if (or (stringp val)
226
(list 'quote val)))))
228
((db-new-record-function
229
dbf-first-change-function
230
dbf-every-change-function
231
dbf-before-display-record-function
232
dbf-format-name-spec-alist
234
(comment-region opoint (point))
237
(insert ";;*special variable (" fixme "):\n")))
239
(setq locals (acons var val locals))
240
(delete-region opoint (point))
241
(insert (format ";;*added to `:locals' %s: %s\n"
245
(delete-blank-lines))
246
(goto-char (point-min))
247
(when (setq locals (nconc (nreverse locals) (mref :locals)))
248
(re-search-forward "^:data")
251
(pp (apply 'vector (mapcar (lambda (pair)
252
(list (car pair) (cdr pair)))
255
(goto-char (point-min))))))
257
(provide 'edb-1int-to-single)
259
;;; edb-1int-to-single.el ends here