Leo Bicknell writes:
 > On Fri, Aug 31, 2001 at 10:36:44AM +1000, Greg Black wrote:
 > > Why not do it the Unix way?  Create a new application, e.g.,
 > > url(1), to parse the URLs and use it like so:
 > 
 > Sometimes the solution is so obvious. :-)  Well, part of it.  I'm
 > thinking it's worth creating liburl, with parse routines, and then
 > a front end for the command line, url(1).
 > 
 > Some quick google work shows nothing quite like url(1) (save one
 > obscure reference to the MKS toolkit on Windows), and searching
 > for a lex/yacc grammar for parsing urls doesn't turn up anything
 > useful.
 > 
 > If only there were more hours in a day.

        OK, here's a Common Lisp function that works for some of the
common cases. One of my colleagues rewrote this to C++, for a total of
about 100 lines. If there's any interest, I can ask him if I can post
the code here. Alternatively, we could start rewriting FreeBSD in
Common Lisp :-)

        BTW: There are at least two IETF RFCs that deal exclusively
with URL/URI parsing, but I don't have the RFC numbers handy.

(defun split-url (url-string)
  "Splits the given URL into components representing the protocol,
user, password, host, port number, path and arguments."
  (flet ((split (sep string)
           (let ((pos (search sep string)))
             (if pos
                 (list (subseq string 0 pos)
                       (subseq string (+ pos (length sep))))
                 string))))
    (macrolet ((try-split (sep str (true-1-var true-2-var)
                               &optional false-var)
                 (let ((ressym (gensym)))
                   `(let ((,ressym (split ,sep ,str)))
                     (if (listp ,ressym)
                         (setf ,true-1-var (car ,ressym)
                               ,true-2-var (cadr ,ressym))
                         ,(when false-var
                                `(setf ,false-var ,ressym)))))))
      (let (proto user pass host port path args)
        (try-split "://" url-string (proto host) host)
        (try-split "/" host (host path))
        (try-split "@" host (user host))
        (when user
          (try-split ":" user (user pass)))
        (try-split ":" host (host port))
        (if path
          (let ((argstr nil))
            (try-split "?" path (path argstr))
            (when argstr
              (setq args
                    (let ((args '()) (end nil))
                      (loop (try-split "&" argstr (arg argstr) end)
                          (if end
                              (return-from nil
                                (nreverse (cons end args)))
                              (push arg args)))))))
          (setq path "/"))
        (values proto user pass host port path args)))))

To Unsubscribe: send mail to [EMAIL PROTECTED]
with "unsubscribe freebsd-hackers" in the body of the message

Reply via email to