Subject: Re: format line wrap?
From: rpw3@rpw3.org (Rob Warnock)
Date: Thu, 06 Sep 2007 04:16:34 -0500
Newsgroups: comp.lang.lisp
Message-ID: <F-udnZ3s2r7vWELbnZ2dnUVZ_jydnZ2d@speakeasy.net>
Ken Tilton  <kentilton@gmail.com> wrote:
+---------------
| > I see, it's not very elegant, but doesn't it do what it's supposed to? 
| 
| Well, let me ask you this: in what real application besides Microsoft 
| Scrimshaw would your result be acceptable output?
| 
| I am sorry to interrupt the utter detachment from reality of this NG, 
| but when His Kennyness asks a question he is trying to get this NG to 
| work for his client for free on <gasp> real applications.
+---------------

O.k., here's a partial repost from what I wrote two weeks ago.
First a utility function from my standard personal toolbox:

  (defun \0x (stream arg colon-p at-sign-p &optional mincol padchar)
    "Hexadecimal numeric printing for use with the FORMAT ~/.../ directive.
    Outputs ARG to STREAM as \"~(0x~mincol,padX~)\" [default \"~(0x~8,'0X~)\"].
    If COLON-P, the entire output will be capitalized instead of lowercased.
    If AT-SIGN-P is true, the \"0x\" prefix will be suppressed."
    (let* ((fmt1 "~~~:[~;:@~](~:[0x~;~]~~~:[8~;~:*~a~],'~:[0~;~:*~a~]x~~)")
           (fmt2 (format nil fmt1 colon-p at-sign-p mincol padchar)))
      (format stream fmt2 arg)))

Then a use of that -- and the "~1,68:;" variant in "~<" -- that I
actually got paid for [not *this* code exactly, but something very,
very close]:

    I use it a lot when building data initialization tables in C code:

    > (let ((data (loop for i below 24 nconc (list (random 0x100000000)
                                                   (random 256))))
            (instance "georgey"))
        (format t "~%foo_t ~a_foos[~d] = {~
              ~%~{~<~%~1,68:;  {~/0x/, ~2/0x/}~>~^,~}~%};~%"
              instance (/ (length data) 2) data))

    foo_t georgey_foos[24] = {
      {0x21a41a5c, 0x87},  {0x1c63b86e, 0xb4},  {0x894c25d5, 0xa1},
      {0x9979b7fe, 0xbb},  {0xc2ad44aa, 0x4d},  {0xe2826239, 0x70},
      {0x053b537e, 0x05},  {0x6ac226e8, 0xbe},  {0x1252ea73, 0x20},
      {0xe3001d4a, 0x12},  {0x9a006313, 0x31},  {0x299d2f64, 0x54},
      {0x90feb745, 0xda},  {0xc7ed257b, 0xc1},  {0xa6e8e18a, 0x51},
      {0x0fdb8569, 0xed},  {0x713c27e0, 0xa8},  {0xd975dbac, 0x2d},
      {0xb4263772, 0x85},  {0xe6cdaaa9, 0x48},  {0x7db24d29, 0xf8},
      {0x87e5aa36, 0xa3},  {0xb56e3dd7, 0xe2},  {0x3cf23443, 0x4e}
    };
    NIL
    > 

Wrap the whole thing in (WITH-OPEN-FILE (S "xyz.c" :DIRECTION OUTPUT) ...)
and replace the (FORMAT T ...) with (FORMAT S ...) and now you're
writing nicely-formatted C code the easy way.  ;-}

[Note: The real code -- using data parsed from a flat-file
configuration database, not randomness as above -- built several
tables of "foo_t" and then an index table on top of all that...]


-Rob

p.s. And, no, I wasn't being paid to code Lisp per se; I was
being paid to get a piece of work done [a Linux kernel driver,
if you must know], and using Lisp to do parts of it was just
the fastest, simplest, least error-prone way I knew.  ;-}  ;-}

-----
Rob Warnock			<rpw3@rpw3.org>
627 26th Avenue			<URL:http://rpw3.org/>
San Mateo, CA 94403		(650)572-2607