pathnames.sl 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353
  1. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2. %
  3. % PathNames.SL
  4. %
  5. % Author: Alan Snyder
  6. % Hewlett-Packard/CRC
  7. % Date: 14 September 1982
  8. % Revised: 9 February 1983
  9. %
  10. % DEC-20 implementation of some Common Lisp pathname functions.
  11. %
  12. % 9-Feb-83 Alan Snyder
  13. % Revise conversion to string to omit the dot if there is no type or version.
  14. % Revise conversion from string to interpret trailing dot as specifying
  15. % an empty type or version. Change home-directory to specify PS:
  16. % Fix bug in make-pathname. Convert to using fast-strings stuff.
  17. %
  18. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  19. (CompileTime (load fast-int fast-vector fast-strings))
  20. (BothTimes (load objects))
  21. (when (funboundp 'string2integer)
  22. (de string2integer (s)
  23. (makestringintolispinteger s 10 1)
  24. ))
  25. % The following function is an NEXPR: be sure this module is loaded at
  26. % compile-time if you use this function in code to be compiled!
  27. (dn make-pathname (keyword-arg-list)
  28. (let ((pn (make-instance 'pathname)))
  29. (while (not (null keyword-arg-list))
  30. (let ((keyword (car keyword-arg-list)))
  31. (setf keyword-arg-list (cdr keyword-arg-list))
  32. (cond (keyword-arg-list
  33. (let ((value (car keyword-arg-list)))
  34. (setf keyword-arg-list (cdr keyword-arg-list))
  35. (selectq keyword
  36. (host (=> pn set-host value))
  37. (device (=> pn set-device value))
  38. (directory (=> pn set-directory value))
  39. (name (=> pn set-name value))
  40. (type (=> pn set-type value))
  41. (version (=> pn set-version value))
  42. ))))))
  43. pn
  44. ))
  45. (de pathname-host (pn)
  46. (=> (pathname pn) host))
  47. (de pathname-device (pn)
  48. (=> (pathname pn) device))
  49. (de pathname-directory (pn)
  50. (=> (pathname pn) directory))
  51. (de pathname-name (pn)
  52. (=> (pathname pn) name))
  53. (de pathname-type (pn)
  54. (=> (pathname pn) type))
  55. (de pathname-version (pn)
  56. (=> (pathname pn) version))
  57. (de PathnameP (x)
  58. (and (VectorP x) (eq (getv x 0) 'pathname)))
  59. (de StreamP (x)
  60. (and (VectorP x) (object-get-handler-quietly x 'file-name)))
  61. (de truename (x) (pathname x))
  62. (de pathname (x)
  63. (cond
  64. ((PathnameP x) x)
  65. ((StringP x) (string-to-pathname x))
  66. ((IdP x) (string-to-pathname (id2string x)))
  67. ((StreamP x) (string-to-pathname (=> x file-name)))
  68. (t (TypeError x "PathName" "convertible to a pathname"))
  69. ))
  70. (de namestring (x)
  71. (setf x (pathname x))
  72. (let ((dev (pathname-device x))
  73. (dir (pathname-directory x))
  74. (name (pathname-name x))
  75. (type (pathname-type x))
  76. (vers (pathname-version x))
  77. )
  78. (string-concat
  79. (if dev (string-concat (pathname-field-to-string dev) ":") "")
  80. (if dir (string-concat "<" (pathname-field-to-string dir) ">") "")
  81. (if name (pathname-field-to-string name) "")
  82. (if (or (not (pathname-empty-field? type))
  83. (not (pathname-empty-field? vers)))
  84. (string-concat "." (pathname-field-to-string type)) "")
  85. (if (not (pathname-empty-field? vers))
  86. (string-concat "." (pathname-field-to-string vers)) "")
  87. )))
  88. (de file-namestring (x)
  89. (setf x (pathname x))
  90. (let ((name (pathname-name x))
  91. (type (pathname-type x))
  92. (vers (pathname-version x))
  93. )
  94. (string-concat
  95. (if name (pathname-field-to-string name) "")
  96. (if type (string-concat "." (pathname-field-to-string type)) "")
  97. (if vers (string-concat "." (pathname-field-to-string vers)) "")
  98. )))
  99. (de directory-namestring (x)
  100. (setf x (pathname x))
  101. (let ((dir (pathname-directory x))
  102. )
  103. (if dir (string-concat "<" (pathname-field-to-string dir) ">") "")
  104. ))
  105. (de user-homedir-pathname ()
  106. (let ((pn (make-instance 'pathname))
  107. (user-number (Jsys1 0 0 0 0 (const jsGJINF)))
  108. (dir-name (MkString 100 (char space)))
  109. )
  110. (Jsys1 dir-name user-number 0 0 (const jsDIRST))
  111. (setf dir-name (recopystringtonull dir-name))
  112. (=> pn set-device "PS")
  113. (=> pn set-directory dir-name)
  114. pn
  115. ))
  116. (de init-file-pathname (program-name)
  117. (let ((pn (user-homedir-pathname)))
  118. (=> pn set-name program-name)
  119. (=> pn set-type "INIT")
  120. pn
  121. ))
  122. (de merge-pathname-defaults (pn defaults-pn default-type default-version)
  123. (setf pn (pathname pn))
  124. (setf defaults-pn (pathname defaults-pn))
  125. (setf pn (CopyVector pn))
  126. (if (not (=> pn host))
  127. (=> pn set-host (=> defaults-pn host)))
  128. (cond ((not (=> pn device))
  129. (=> pn set-device (=> defaults-pn device))
  130. (if (not (=> pn directory))
  131. (=> pn set-directory (=> defaults-pn directory)))
  132. ))
  133. (cond ((not (=> pn name))
  134. (=> pn set-name (=> defaults-pn name))
  135. (if (not (=> pn type)) (=> pn set-type (=> defaults-pn type)))
  136. (if (not (=> pn version)) (=> pn set-version (=> defaults-pn version)))
  137. ))
  138. (if (not (=> pn type))
  139. (=> pn set-type default-type))
  140. (if (not (=> pn version))
  141. (=> pn set-version default-version))
  142. pn
  143. )
  144. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  145. % Internal functions:
  146. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  147. (defflavor pathname
  148. ((host "LOCAL")
  149. (device NIL)
  150. (directory NIL)
  151. (name NIL)
  152. (type NIL)
  153. (version NIL)
  154. )
  155. ()
  156. gettable-instance-variables
  157. )
  158. (defmethod (pathname set-host) (new-host)
  159. (cond ((StringP new-host) (setf host (string-upcase new-host)))
  160. ((and (ListP new-host)
  161. (not (null new-host))
  162. (StringP (car new-host)))
  163. (setf host (string-upcase (car new-host))))
  164. (t (StdError "Invalid host specified for pathname."))
  165. ))
  166. (defmethod (pathname set-device) (new-device)
  167. (cond ((StringP new-device) (setf device (string-upcase new-device)))
  168. ((null new-device) (setf device NIL))
  169. ((and (ListP new-device)
  170. (StringP (car new-device)))
  171. (setf device (string-upcase (car new-device))))
  172. ((and (IdP new-device)
  173. (or (eq new-device 'unspecific)
  174. (eq new-device 'wild)))
  175. (setf device new-device))
  176. (t (StdError "Invalid device specified for pathname."))
  177. ))
  178. (defmethod (pathname set-directory) (new-directory)
  179. (cond ((StringP new-directory) (setf directory (string-upcase new-directory)))
  180. ((null new-directory) (setf directory NIL))
  181. ((and (ListP new-directory)
  182. (StringP (car new-directory)))
  183. (setf directory (string-upcase (car new-directory))))
  184. ((and (IdP new-directory)
  185. (or (eq new-directory 'unspecific)
  186. (eq new-directory 'wild)))
  187. (setf directory new-directory))
  188. (t (StdError "Invalid directory specified for pathname."))
  189. ))
  190. (defmethod (pathname set-name) (new-name)
  191. (cond ((StringP new-name) (setf name (string-upcase new-name)))
  192. ((null new-name) (setf name NIL))
  193. ((and (ListP new-name)
  194. (StringP (car new-name)))
  195. (setf name (string-upcase (car new-name))))
  196. ((and (IdP new-name)
  197. (or (eq new-name 'unspecific)
  198. (eq new-name 'wild)))
  199. (setf name new-name))
  200. (t (StdError "Invalid name specified for pathname."))
  201. ))
  202. (defmethod (pathname set-type) (new-type)
  203. (cond ((StringP new-type) (setf type (string-upcase new-type)))
  204. ((null new-type) (setf type NIL))
  205. ((and (IdP new-type)
  206. (or (eq new-type 'unspecific)
  207. (eq new-type 'wild)))
  208. (setf type new-type))
  209. (t (StdError "Invalid type specified for pathname."))
  210. ))
  211. (defmethod (pathname set-version) (new-version)
  212. (cond ((and (FixP new-version) (>= new-version 0))
  213. (setf version new-version))
  214. ((null new-version) (setf version NIL))
  215. ((and (IdP new-version)
  216. (or (eq new-version 'unspecific)
  217. (eq new-version 'wild)
  218. (eq new-version 'newest)
  219. (eq new-version 'oldest)
  220. ))
  221. (setf version new-version))
  222. (t (StdError "Invalid version specified for pathname."))
  223. ))
  224. (de string-to-pathname (s)
  225. (let ((pn (make-instance 'pathname))
  226. (i 0)
  227. j
  228. ch
  229. (len (string-length s))
  230. (name-count 0)
  231. field
  232. )
  233. (while (< i len)
  234. (setf j (pathname-bite s i))
  235. (selectq
  236. (string-fetch s (- j 1))
  237. (#\: (=> pn set-device (pathname-field-from-string
  238. (substring s i (- j 1)))))
  239. (#\> (=> pn set-directory (pathname-field-from-string
  240. (substring s (+ i 1) (- j 1)))))
  241. (#\. (setf name-count (+ name-count 1))
  242. (setf field (substring s i (- j 1)))
  243. (selectq
  244. name-count
  245. (1 (=> pn set-name (pathname-field-from-string field))
  246. (if (>= j len) (=> pn set-type 'UNSPECIFIC))
  247. )
  248. (2 (=> pn set-type (pathname-field-from-string field))
  249. (if (>= j len) (=> pn set-version 'UNSPECIFIC))
  250. )
  251. (3 (=> pn set-version (pathname-version-from-string field)))
  252. ))
  253. (t (setf name-count (+ name-count 1))
  254. (setf field (substring s i j))
  255. (selectq
  256. name-count
  257. (1 (=> pn set-name (pathname-field-from-string field)))
  258. (2 (=> pn set-type (pathname-field-from-string field)))
  259. (3 (=> pn set-version (pathname-version-from-string field)))
  260. )))
  261. (setf i j)
  262. )
  263. pn
  264. ))
  265. (de pathname-bite (pn i)
  266. (let* ((len (string-length pn))
  267. (ch (string-fetch pn i))
  268. )
  269. (cond ((= ch #\<)
  270. (setf i (+ i 1))
  271. (while (< i len)
  272. (setf ch (string-fetch pn i))
  273. (setf i (+ i 1))
  274. (if (= ch #\>) (exit))
  275. )
  276. )
  277. (t
  278. (while (< i len)
  279. (setf ch (string-fetch pn i))
  280. (setf i (+ i 1))
  281. (if (= ch #\:) (exit))
  282. (if (= ch #\.) (exit))
  283. )))
  284. i
  285. ))
  286. (de pathname-field-from-string (s)
  287. (cond ((StringP s)
  288. (cond ((string-empty? s) 'UNSPECIFIC)
  289. ((string= s "*") 'WILD)
  290. (t s)
  291. ))
  292. (t s)))
  293. (de pathname-version-from-string (s)
  294. (cond ((StringP s)
  295. (cond ((string-empty? s) NIL)
  296. ((string= s "-2") 'OLDEST)
  297. ((string= s "0") 'NEWEST)
  298. ((string= s "*") 'WILD)
  299. ((string-is-integer s) (string2integer s))
  300. (t s)
  301. ))
  302. (t s)))
  303. (de pathname-empty-field? (x)
  304. (string-empty? (pathname-field-to-string x))
  305. )
  306. (de pathname-field-to-string (x)
  307. (cond ((StringP x) x)
  308. ((eq x 'OLDEST) "-2")
  309. ((eq x 'NEWEST) "0")
  310. ((eq x 'UNSPECIFIC) "")
  311. ((eq x 'WILD) "*")
  312. ((null x) "")
  313. (t (BldMsg "%w" x))))
  314. (de string-is-integer (s)
  315. (for (from i 0 (string-upper-bound s))
  316. (always (DigitP (string-fetch s i)))
  317. ))