guile-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: Module name mangling


From: Neil Jerram
Subject: Re: Module name mangling
Date: 30 Jan 2001 22:23:59 +0000

>>>>> "Marius" == Marius Vollmer <address@hidden> writes:

    Marius> Ok, we need to make some progress.  Since finding a list
    Marius> of safe or unsafe characters seems to be hard (harder than
    Marius> I thought), what about chickening out completely and not
    Marius> specifying a encoding at all.  We could just tell people
    Marius> to choose module names that make proper file names.

I'd be very sorry to decide this.  It sounds weak, and we'd
immediately have a backwards compatibility problem with and-let*.scm.

Here's my proposal, which doesn't require a comprehensive list of
unsafe or safe characters.

1. Address the problem in an OS-specific way.  => no encoding at all
   needed for Unices, no need to change and-let*.scm for the people for
   whom it already works.

2. For each OS, only address the known problems.  For DOS, we only need
   to solve the problem right now for `*', so let's only do that.

   Point (1) above means that the need-to-fix approach of point (2)
   will never invalidate a filename that used to work on a different
   platform.

3. For DOS: use _ as the escape character, encode `*' as `_star_' and
   `_' as `_underscore_'.

The only remaining problem is that of CVS and distributions.  Let's
assume that we don't want the DOS source distribution to differ from
the non-DOS one, and that we want to support CVS direct to/from DOS.
Solution: invent a shar-like format -- grokked by Guile, of course --
in which to hold .scm files with unsafe names, and unpack it at
build/install time.  `Files with unsafe names' is defined as { file :
filename encoded by any of the supported encoders != canonical
filename }.

In practice, this encapsulation may encourage developers to go for
`safe' names, but (i) it doesn't require it, and (ii) it provides a
compatible solution when a name previously believed to be safe (for
all supported platforms) becomes unsafe.

An extremely basic Guile archive implementation is attached.

Regards,
        Neil


(define-module (ossau archive)
  :use-module (ice-9 rdelim)
  :export (unpack-archive add-to-archive))

;;; unpack-archive archive-port file-name-proc
;;;
;;; ARCHIVE-PORT is the input port to read from.  FILE-NAME-PROC is a
;;; procedure that accepts one argument, a file name, and returns an
;;; output port to which the archive contents for that file name
;;; should be written.  Typically FILE-NAME-PROC would be
;;; `open-output-file'.
(define (unpack-archive archive-port file-name-proc)
  (let next-file ((file-name (read-line archive-port)))
    (or (eof-object? file-name)
        (let ((output-port (file-name-proc file-name)))
          (let next-line ((line (read-line archive-port)))
            (cond ((and (string? line)
                        (char=? (string-ref line 0) #\ ))
                   (write-line (substring line 1) output-port)
                   (next-line (read-line archive-port)))
                  (else
                   (close-output-port output-port)
                   (next-file line))))))))

;;; add-to-archive archive-port input-port [file-name]
;;;
;;; ARCHIVE-PORT is the archive port to add to.  INPUT-PORT is the
;;; port whose contents should be added to the archive.  Optional
;;; argument FILE-NAME is the file name to be written into the
;;; archive; if it is omitted, `(port-filename INPUT-PORT)' is used
;;; instead, so long as it returns a string.
(define (add-to-archive archive-port input-port . file-name)
  (set! file-name
        (cond ((null? file-name)
               (port-filename input-port))
              (else
               (car file-name))))
  (or (and (string? file-name)
           (> (string-length file-name) 0))
      (error "File name must be a non-empty string" file-name))
  (write-line file-name archive-port)
  (let next-line ((line (read-line input-port)))
    (or (eof-object? line)
        (begin
          (display " " archive-port)
          (write-line line archive-port)
          (next-line (read-line input-port))))))



reply via email to

[Prev in Thread] Current Thread [Next in Thread]