home *** CD-ROM | disk | FTP | other *** search
/ Amiga MA Magazine 1998 #6 / amigamamagazinepolishissue1998.iso / coders / jËzyki_programowania / clisp / src / archive / clisp.faslsp.lha / user2.lsp < prev    next >
Lisp/Scheme  |  1996-07-05  |  55KB  |  1,460 lines

  1. ;;;; User-Interface, Teil 2
  2. ;;;; Funktionen fürs Debugging (Kapitel 25.3)
  3. ;;;; Apropos, Describe, Dribble, Ed
  4. ;;;; 27.6.1992
  5.  
  6. (in-package "LISP")
  7. (export '(*editor* editor-name editor-tempfile edit-file uncompile saveinitmem))
  8. #+(or UNIX OS/2 WIN32-DOS WIN32-UNIX) (export '(run-shell-command run-program))
  9. (in-package "SYSTEM")
  10.  
  11. ;-------------------------------------------------------------------------------
  12. ;; APROPOS
  13.  
  14. (defun apropos-list (string &optional (package nil))
  15.   (let* ((L nil)
  16.          (fun #'(lambda (sym)
  17.                   (when
  18.                       #| (search string (symbol-name sym) :test #'char-equal) |#
  19.                       (sys::search-string-equal string sym) ; 15 mal schneller!
  20.                     (push sym L)
  21.                 ) )
  22.         ))
  23.     (if package
  24.       (system::map-symbols fun package)
  25.       (system::map-all-symbols fun)
  26.     )
  27.     (stable-sort (delete-duplicates L :test #'eq :from-end t)
  28.                  #'string< :key #'symbol-name
  29.     )
  30. ) )
  31.  
  32. (defun fbound-string (sym) ; liefert den Typ eines Symbols sym mit (fboundp sym)
  33.   (cond ((special-form-p sym)
  34.          #L{
  35.          DEUTSCH "Spezialform"
  36.          ENGLISH "special form"
  37.          FRANCAIS "forme spéciale"
  38.          }
  39.         )
  40.         ((functionp (symbol-function sym))
  41.          #L{
  42.          DEUTSCH "Funktion"
  43.          ENGLISH "function"
  44.          FRANCAIS "fonction"
  45.          }
  46.         )
  47.         (t 
  48.          #L{
  49.          DEUTSCH "Macro"
  50.          ENGLISH "macro"
  51.          FRANCAIS "macro"
  52.          }
  53. ) )     )
  54.  
  55. (defun apropos (string &optional (package nil))
  56.   (dolist (sym (apropos-list string package))
  57.     (print sym)
  58.     (when (fboundp sym)
  59.       (write-string "   ")
  60.       (write-string (fbound-string sym))
  61.     )
  62.     (when (boundp sym)
  63.       (write-string "   ")
  64.       (if (constantp sym)
  65.         (write-string 
  66.          #L{
  67.          DEUTSCH "Konstante"
  68.          ENGLISH "constant"
  69.          FRANCAIS "constante"
  70.          }
  71.         )
  72.         (write-string 
  73.          #L{
  74.          DEUTSCH "Variable"
  75.          ENGLISH "variable"
  76.          FRANCAIS "variable"
  77.          }
  78.   ) ) ) )
  79.   (values)
  80. )
  81.  
  82. ;-------------------------------------------------------------------------------
  83. ;; DESCRIBE
  84.  
  85. (defun describe (obj &optional s &aux (more '()))
  86.   (cond ((eq s 'nil) (setq s *standard-output*))
  87.         ((eq s 't) (setq s *terminal-io*))
  88.   )
  89.   (format s 
  90.           #L{
  91.           DEUTSCH "~%Beschreibung von~%"
  92.           ENGLISH "~%Description of~%"
  93.           FRANCAIS "~%Description de~%"
  94.           }
  95.   )
  96.   (format s "~A" (write-to-short-string obj sys::*prin-linelength*))
  97.   (format s 
  98.           #L{
  99.           DEUTSCH "~%Das ist "
  100.           ENGLISH "~%This is "
  101.           FRANCAIS "~%Ceci est "
  102.           }
  103.   )
  104.   (let ((type (type-of obj)))
  105.     ; Dispatch nach den möglichen Resultaten von TYPE-OF:
  106.     (if (atom type)
  107.       (case type
  108.         (CONS
  109.           (flet ((list-length (list)  ; vgl. CLTL, S. 265
  110.                    (do ((n 0 (+ n 2))
  111.                         (fast list (cddr fast))
  112.                         (slow list (cdr slow))
  113.                        )
  114.                        (nil)
  115.                      (when (atom fast) (return n))
  116.                      (when (atom (cdr fast)) (return (1+ n)))
  117.                      (when (eq (cdr fast) slow) (return nil))
  118.                 )) )
  119.             (let ((len (list-length obj)))
  120.               (if len
  121.                 (if (null (nthcdr len obj))
  122.                   (format s 
  123.                           #L{
  124.                           DEUTSCH "eine Liste der Länge ~S."
  125.                           ENGLISH "a list of length ~S."
  126.                           FRANCAIS "une liste de longueur ~S."
  127.                           }
  128.                           len
  129.                   )
  130.                   (if (> len 1)
  131.                     (format s 
  132.                             #L{
  133.                             DEUTSCH "eine punktierte Liste der Länge ~S."
  134.                             ENGLISH "a dotted list of length ~S."
  135.                             FRANCAIS "une liste pointée de longueur ~S."
  136.                             }
  137.                             len
  138.                     )
  139.                     (format s 
  140.                             #L{
  141.                             DEUTSCH "ein Cons."
  142.                             ENGLISH "a cons."
  143.                             FRANCAIS "un «cons»."
  144.                             }
  145.                 ) ) )
  146.                 (format s 
  147.                         #L{
  148.                         DEUTSCH "eine zyklische Liste."
  149.                         ENGLISH "a cyclic list."
  150.                         FRANCAIS "une liste circulaire."
  151.                         }
  152.         ) ) ) ) )
  153.         ((SYMBOL NULL)
  154.           (when (null obj)
  155.             (format s 
  156.                     #L{
  157.                     DEUTSCH "die leere Liste, "
  158.                     ENGLISH "the empty list, "
  159.                     FRANCAIS "la liste vide, "
  160.                     }
  161.           ) )
  162.           (format s 
  163.                   #L{
  164.                   DEUTSCH "das Symbol ~S"
  165.                   ENGLISH "the symbol ~S"
  166.                   FRANCAIS "le symbole ~S"
  167.                   }
  168.                   obj
  169.           )
  170.           (when (keywordp obj)
  171.             (format s 
  172.                     #L{
  173.                     DEUTSCH ", ein Keyword"
  174.                     ENGLISH ", a keyword"
  175.                     FRANCAIS ", un mot-clé"
  176.                     }
  177.           ) )
  178.           (when (boundp obj)
  179.             (if (constantp obj)
  180.               (format s 
  181.                       #L{
  182.                       DEUTSCH ", eine Konstante"
  183.                       ENGLISH ", a constant"
  184.                       FRANCAIS ", une constante"
  185.                       }
  186.               )
  187.               (if (sys::special-variable-p obj)
  188.                 (format s 
  189.                         #L{
  190.                         DEUTSCH ", eine SPECIAL-deklarierte Variable"
  191.                         ENGLISH ", a variable declared SPECIAL"
  192.                         FRANCAIS ", une variable declarée SPECIAL"
  193.                         }
  194.                 )
  195.                 (format s 
  196.                         #L{
  197.                         DEUTSCH ", eine Variable"
  198.                         ENGLISH ", a variable"
  199.                         FRANCAIS ", une variable"
  200.                         }
  201.             ) ) )
  202.             (when (symbol-macro-expand obj)
  203.               (format s 
  204.                       #L{
  205.                       DEUTSCH " (Macro)"
  206.                       ENGLISH " (macro)"
  207.                       FRANCAIS " (macro)"
  208.                       }
  209.               )
  210.               (push `(MACROEXPAND-1 ',obj) more)
  211.             )
  212.             (push `,obj more)
  213.             (push `(SYMBOL-VALUE ',obj) more)
  214.           )
  215.           (when (fboundp obj)
  216.             (format s 
  217.                     #L{
  218.                     DEUTSCH ", benennt "
  219.                     ENGLISH ", names "
  220.                     FRANCAIS ", le nom "
  221.                     }
  222.             )
  223.             (cond ((special-form-p obj)
  224.                    (format s 
  225.                            #L{
  226.                            DEUTSCH "eine Special-Form"
  227.                            ENGLISH "a special form"
  228.                            FRANCAIS "d'une forme spéciale"
  229.                            }
  230.                    )
  231.                    (when (macro-function obj)
  232.                      (format s 
  233.                              #L{
  234.                              DEUTSCH " mit Macro-Definition"
  235.                              ENGLISH " with macro definition"
  236.                              FRANCAIS ", aussi d'un macro"
  237.                              }
  238.                   )) )
  239.                   ((functionp (symbol-function obj))
  240.                    (format s 
  241.                            #L{
  242.                            DEUTSCH "eine Funktion"
  243.                            ENGLISH "a function"
  244.                            FRANCAIS "d'une fonction"
  245.                            }
  246.                    )
  247.                    (push `#',obj more)
  248.                    (push `(SYMBOL-FUNCTION ',obj) more)
  249.                   )
  250.                   (t ; (macro-function obj)
  251.                    (format s 
  252.                            #L{
  253.                            DEUTSCH "einen Macro"
  254.                            ENGLISH "a macro"
  255.                            FRANCAIS "d'un macro"
  256.                            }
  257.                   ))
  258.           ) )
  259.           (when (symbol-plist obj)
  260.             (let ((properties
  261.                     (do ((l nil)
  262.                          (pl (symbol-plist obj) (cddr pl)))
  263.                         ((null pl) (nreverse l))
  264.                       (push (car pl) l)
  265.                  )) )
  266.               (format s 
  267.                       #L{
  268.                       DEUTSCH ", hat die Propert~@P ~{~S~^, ~}"
  269.                       ENGLISH ", has the propert~@P ~{~S~^, ~}"
  270.                       FRANCAIS ", a ~[~;la propriété~:;les propriétés~] ~{~S~^, ~}"
  271.                       }
  272.                       (length properties) properties
  273.             ) )
  274.             (push `(SYMBOL-PLIST ',obj) more)
  275.           )
  276.           (format s 
  277.                   #L{
  278.                   DEUTSCH "."
  279.                   ENGLISH "."
  280.                   FRANCAIS "."
  281.                   }
  282.           )
  283.           (format s 
  284.                   #L{
  285.                   DEUTSCH "~%Das Symbol "
  286.                   ENGLISH "~%The symbol "
  287.                   FRANCAIS "~%Le symbole "
  288.                   }
  289.           )
  290.           (let ((home (symbol-package obj)))
  291.             (if home
  292.               (format s 
  293.                       #L{
  294.                       DEUTSCH "liegt in ~S"
  295.                       ENGLISH "lies in ~S"
  296.                       FRANCAIS "est situé dans ~S"
  297.                       }
  298.                       home
  299.               )
  300.               (format s 
  301.                       #L{
  302.                       DEUTSCH "ist uninterniert"
  303.                       ENGLISH "is uninterned"
  304.                       FRANCAIS "n'appartient à aucun paquetage"
  305.                       }
  306.             ) )
  307.             (let ((accessible-packs nil))
  308.               (let ((*print-escape* t)
  309.                     (*print-readably* nil))
  310.                 (let ((normal-printout ; externe Repräsentation ohne Package-Marker
  311.                         (if home
  312.                           (let ((*package* home)) (prin1-to-string obj))
  313.                           (let ((*print-gensym* nil)) (prin1-to-string obj))
  314.                      )) )
  315.                   (dolist (pack (list-all-packages))
  316.                     (when ; obj in pack accessible?
  317.                           (string=
  318.                             (let ((*package* pack)) (prin1-to-string obj))
  319.                             normal-printout
  320.                           )
  321.                       (push pack accessible-packs)
  322.               ) ) ) )
  323.               (when accessible-packs
  324.                 (format s 
  325.                         #L{
  326.                         DEUTSCH " und ist in ~:[der Package~;den Packages~] ~{~A~^, ~} accessible"
  327.                         ENGLISH " and is accessible in the package~:[~;s~] ~{~A~^, ~}"
  328.                         FRANCAIS " et est visible dans le~:[ paquetage~;s paquetages~] ~{~A~^, ~}"
  329.                         }
  330.                         (cdr accessible-packs)
  331.                         (sort (mapcar #'package-name accessible-packs) #'string<)
  332.           ) ) ) )
  333.           (format s 
  334.                   #L{
  335.                   DEUTSCH "."
  336.                   ENGLISH "."
  337.                   FRANCAIS "."
  338.                   }
  339.         ) )
  340.         ((FIXNUM BIGNUM)
  341.           (format s 
  342.                   #L{
  343.                   DEUTSCH "eine ganze Zahl, belegt ~S Bits, ist als ~:(~A~) repräsentiert."
  344.                   ENGLISH "an integer, uses ~S bits, is represented as a ~(~A~)."
  345.                   FRANCAIS "un nombre entier, occupant ~S bits, est représenté comme ~(~A~)."
  346.                   }
  347.                   (integer-length obj) type
  348.         ) )
  349.         (RATIO
  350.           (format s 
  351.                   #L{
  352.                   DEUTSCH "eine rationale, nicht ganze Zahl."
  353.                   ENGLISH "a rational, not integral number."
  354.                   FRANCAIS "un nombre rationnel mais pas entier."
  355.                   }
  356.         ) )
  357.         ((SHORT-FLOAT SINGLE-FLOAT DOUBLE-FLOAT LONG-FLOAT)
  358.           (format s 
  359.                   #L{
  360.                   DEUTSCH "eine Fließkommazahl mit ~S Mantissenbits (~:(~A~))."
  361.                   ENGLISH "a float with ~S bits of mantissa (~(~A~))."
  362.                   FRANCAIS "un nombre à virgule flottante avec une précision de ~S bits (un ~(~A~))."
  363.                   }
  364.                   (float-digits obj) type
  365.         ) )
  366.         (COMPLEX
  367.           (format s 
  368.                   #L{
  369.                   DEUTSCH "eine komplexe Zahl "
  370.                   ENGLISH "a complex number "
  371.                   FRANCAIS "un nombre complexe "
  372.                   }
  373.           )
  374.           (let ((x (realpart obj))
  375.                 (y (imagpart obj)))
  376.             (if (zerop y)
  377.               (if (zerop x)
  378.                 (format s 
  379.                         #L{
  380.                         DEUTSCH "im Ursprung"
  381.                         ENGLISH "at the origin"
  382.                         FRANCAIS "à l'origine"
  383.                         }
  384.                 )
  385.                 (format s 
  386.                         #L{
  387.                         DEUTSCH "auf der ~:[posi~;nega~]tiven reellen Achse"
  388.                         ENGLISH "on the ~:[posi~;nega~]tive real axis"
  389.                         FRANCAIS "sur la partie ~:[posi~;nega~]tive de l'axe réelle"
  390.                         }
  391.                         (minusp x)
  392.               ) )
  393.               (if (zerop x)
  394.                 (format s 
  395.                         #L{
  396.                         DEUTSCH "auf der ~:[posi~;nega~]tiven imaginären Achse"
  397.                         ENGLISH "on the ~:[posi~;nega~]tive imaginary axis"
  398.                         FRANCAIS "sur la partie ~:[posi~;nega~]tive de l'axe imaginaire"
  399.                         }
  400.                         (minusp y)
  401.                 )
  402.                 (format s 
  403.                         #L{
  404.                         DEUTSCH "im ~:[~:[ers~;vier~]~;~:[zwei~;drit~]~]ten Quadranten"
  405.                         ENGLISH "in ~:[~:[first~;fourth~]~;~:[second~;third~]~] the quadrant"
  406.                         FRANCAIS "dans le ~:[~:[premier~;quatrième~]~;~:[deuxième~;troisième~]~] quartier"
  407.                         }
  408.                         (minusp x) (minusp y)
  409.           ) ) ) )
  410.           (format s 
  411.                   #L{
  412.                   DEUTSCH " der Gaußschen Zahlenebene."
  413.                   ENGLISH " of the Gaussian number plane."
  414.                   FRANCAIS " du plan Gaussien."
  415.                   }
  416.         ) )
  417.         (CHARACTER
  418.           (format s 
  419.                   #L{
  420.                   DEUTSCH "ein Zeichen"
  421.                   ENGLISH "a character"
  422.                   FRANCAIS "un caractère"
  423.                   }
  424.           )
  425.           (unless (zerop (char-bits obj))
  426.             (format s 
  427.                     #L{
  428.                     DEUTSCH " mit Zusatzbits"
  429.                     ENGLISH " with additional bits"
  430.                     FRANCAIS " avec des bits supplémentaires"
  431.                     }
  432.           ) )
  433.           (unless (zerop (char-font obj))
  434.             (format s 
  435.                     #L{
  436.                     DEUTSCH " aus Zeichensatz ~S"
  437.                     ENGLISH " from font ~S"
  438.                     FRANCAIS " de la police («font») ~S"
  439.                     }
  440.                     (char-font obj)
  441.           ) )
  442.           (format s 
  443.                   #L{
  444.                   DEUTSCH "."
  445.                   ENGLISH "."
  446.                   FRANCAIS "."
  447.                   }
  448.           )
  449.           (format s 
  450.                   #L{
  451.                   DEUTSCH "~%Es ist ein ~:[nicht ~;~]druckbares Zeichen."
  452.                   ENGLISH "~%It is a ~:[non-~;~]printable character."
  453.                   FRANCAIS "~%C'est un caractère ~:[non ~;~]imprimable."
  454.                   }
  455.                   (graphic-char-p obj)
  456.           )
  457.           (unless (standard-char-p obj)
  458.             (format s 
  459.                     #L{
  460.                     DEUTSCH "~%Seine Verwendung ist nicht portabel."
  461.                     ENGLISH "~%Its use is non-portable."
  462.                     FRANCAIS "~%Il n'est pas portable de l'utiliser."
  463.                     }
  464.           ) )
  465.         )
  466.         (FUNCTION ; (SYS::CLOSUREP obj) ist erfüllt
  467.           (let ((compiledp (compiled-function-p obj)))
  468.             (format s 
  469.                     #L{
  470.                     DEUTSCH "eine ~:[interpret~;compil~]ierte Funktion."
  471.                     ENGLISH "a~:[n interpret~; compil~]ed function."
  472.                     FRANCAIS "une fonction ~:[interprét~;compil~]ée."
  473.                     }
  474.                     compiledp
  475.             )
  476.             (if compiledp
  477.               (multiple-value-bind (req-anz opt-anz rest-p key-p keyword-list allow-other-keys-p)
  478.                   (sys::signature obj)
  479.                 (describe-signature s req-anz opt-anz rest-p key-p keyword-list allow-other-keys-p)
  480.                 (push `(DISASSEMBLE #',(sys::closure-name obj)) more)
  481.                 (push `(DISASSEMBLE ',obj) more)
  482.               )
  483.               (progn
  484.                 (format s 
  485.                         #L{
  486.                         DEUTSCH "~%Argumentliste: ~S"
  487.                         ENGLISH "~%argument list: ~S"
  488.                         FRANCAIS "~%Liste des arguments: ~S"
  489.                         }
  490.                         (car (sys::%record-ref obj 1))
  491.                 )
  492.                 (let ((doc (sys::%record-ref obj 2)))
  493.                   (when doc
  494.                     (format s 
  495.                             #L{
  496.                             DEUTSCH "~%Dokumentation: ~A"
  497.                             ENGLISH "~%documentation: ~A"
  498.                             FRANCAIS "~%Documentation: ~A"
  499.                             }
  500.                             doc
  501.               ) ) ) )
  502.         ) ) )
  503.         (COMPILED-FUNCTION ; nur SUBRs und FSUBRs
  504.           (if (functionp obj)
  505.             ; SUBR
  506.             (progn
  507.               (format s 
  508.                       #L{
  509.                       DEUTSCH "eine eingebaute System-Funktion."
  510.                       ENGLISH "a built-in system function."
  511.                       FRANCAIS "une fonction prédéfinie du système."
  512.                       }
  513.               )
  514.               (multiple-value-bind (name req-anz opt-anz rest-p keywords allow-other-keys)
  515.                   (sys::subr-info obj)
  516.                 (when name
  517.                   (describe-signature s req-anz opt-anz rest-p keywords keywords allow-other-keys)
  518.             ) ) )
  519.             ; FSUBR
  520.             (format s 
  521.                     #L{
  522.                     DEUTSCH "ein Special-Form-Handler."
  523.                     ENGLISH "a special form handler."
  524.                     FRANCAIS "un interpréteur de forme spéciale."
  525.                     }
  526.         ) ) )
  527.     #+(or AMIGA FFI)
  528.     (FOREIGN-POINTER
  529.           (format s 
  530.                   #L{
  531.                   DEUTSCH "ein Foreign-Pointer."
  532.                   ENGLISH "a foreign pointer"
  533.                   FRANCAIS "un pointeur étranger."
  534.                   }
  535.         ) )
  536.         #+FFI
  537.         (FOREIGN-ADDRESS
  538.           (format s 
  539.                   #L{
  540.                   DEUTSCH "eine Foreign-Adresse."
  541.                   ENGLISH "a foreign address"
  542.                   FRANCAIS "une addresse étrangère."
  543.                   }
  544.         ) )
  545.         #+FFI
  546.         (FOREIGN-VARIABLE
  547.           (format s 
  548.                   #L{
  549.                   DEUTSCH "eine Foreign-Variable vom Foreign-Typ ~S."
  550.                   ENGLISH "a foreign variable of foreign type ~S."
  551.                   FRANCAIS "une variable étrangère de type étranger ~S."
  552.                   }
  553.                   (deparse-c-type (sys::%record-ref obj 3))
  554.         ) )
  555.         #+FFI
  556.         (FOREIGN-FUNCTION
  557.           (format s 
  558.                   #L{
  559.                   DEUTSCH "eine Foreign-Funktion."
  560.                   ENGLISH "a foreign function."
  561.                   FRANCAIS "une fonction étrangère."
  562.                   }
  563.         ) )
  564.         ((STREAM FILE-STREAM SYNONYM-STREAM BROADCAST-STREAM
  565.           CONCATENATED-STREAM TWO-WAY-STREAM ECHO-STREAM STRING-STREAM
  566.          )
  567.           (format s 
  568.                   #L{
  569.                   DEUTSCH "ein ~:[~:[geschlossener ~;Output-~]~;~:[Input-~;bidirektionaler ~]~]Stream."
  570.                   ENGLISH "a~:[~:[ closed ~;n output-~]~;~:[n input-~;n input/output-~]~]stream."
  571.                   FRANCAIS "un «stream» ~:[~:[fermé~;de sortie~]~;~:[d'entrée~;d'entrée/sortie~]~]."
  572.                   }
  573.                   (input-stream-p obj) (output-stream-p obj)
  574.         ) )
  575.         (PACKAGE
  576.           (if (package-name obj)
  577.             (progn
  578.               (format s 
  579.                       #L{
  580.                       DEUTSCH "die Package mit Namen ~A"
  581.                       ENGLISH "the package named ~A"
  582.                       FRANCAIS "le paquetage de nom ~A"
  583.                       }
  584.                       (package-name obj)
  585.               )
  586.               (let ((nicknames (package-nicknames obj)))
  587.                 (when nicknames
  588.                   (format s 
  589.                           #L{
  590.                           DEUTSCH " und zusätzlichen Namen ~{~A~^, ~}"
  591.                           ENGLISH ". It has the nicknames ~{~A~^, ~}"
  592.                           FRANCAIS ". Il porte aussi les noms ~{~A~^, ~}"
  593.                           }
  594.                           nicknames
  595.               ) ) )
  596.               (format s 
  597.                       #L{
  598.                       DEUTSCH "."
  599.                       ENGLISH "."
  600.                       FRANCAIS "."
  601.                       }
  602.               )
  603.               (let ((use-list (package-use-list obj))
  604.                     (used-by-list (package-used-by-list obj)))
  605.                 (format s 
  606.                         #L{
  607.                         DEUTSCH "~%Sie "
  608.                         ENGLISH "~%It "
  609.                         FRANCAIS "~%Il "
  610.                         }
  611.                 )
  612.                 (when use-list
  613.                   (format s 
  614.                           #L{
  615.                           DEUTSCH "importiert die externen Symbole der Package~:[~;s~] ~{~A~^, ~} und "
  616.                           ENGLISH "imports the external symbols of the package~:[~;s~] ~{~A~^, ~} and "
  617.                           FRANCAIS "importe les symboles externes d~:[u paquetage~;es paquetages~] ~{~A~^, ~} et "
  618.                           }
  619.                           (cdr use-list) (mapcar #'package-name use-list)
  620.                 ) )
  621.                 (format s 
  622.                         #L{
  623.                         DEUTSCH "exportiert ~:[keine Symbole~;die Symbole~:*~{~<~%~:; ~S~>~^~}~]"
  624.                         ENGLISH "exports ~:[no symbols~;the symbols~:*~{~<~%~:; ~S~>~^~}~]"
  625.                         FRANCAIS "~:[n'exporte pas de symboles~;exporte les symboles~:*~{~<~%~:; ~S~>~^~}~]"
  626.                         }
  627.                         ;; Liste aller exportierten Symbole:
  628.                         (let ((L nil))
  629.                           (do-external-symbols (s obj) (push s L))
  630.                           (sort L #'string< :key #'symbol-name)
  631.                 )         )
  632.                 (when used-by-list
  633.                   (format s 
  634.                           #L{
  635.                           DEUTSCH " an die Package~:[~;s~] ~{~A~^, ~}"
  636.                           ENGLISH " to the package~:[~;s~] ~{~A~^, ~}"
  637.                           FRANCAIS " vers le~:[ paquetage~;s paquetages~] ~{~A~^, ~}"
  638.                           }
  639.                           (cdr used-by-list) (mapcar #'package-name used-by-list)
  640.                 ) )
  641.                 (format s 
  642.                         #L{
  643.                         DEUTSCH "."
  644.                         ENGLISH "."
  645.                         FRANCAIS "."
  646.                         }
  647.             ) ) )
  648.             (format s 
  649.                     #L{
  650.                     DEUTSCH "eine gelöschte Package."
  651.                     ENGLISH "a deleted package."
  652.                     FRANCAIS "un paquetage éliminé."
  653.                     }
  654.         ) ) )
  655.         (HASH-TABLE
  656.           (format s 
  657.                   #L{
  658.                   DEUTSCH "eine Hash-Tabelle mit ~S Eintr~:*~[ägen~;ag~:;ägen~]."
  659.                   ENGLISH "a hash table with ~S entr~:@P."
  660.                   FRANCAIS "un tableau de hachage avec ~S entrée~:*~[s~;~:;s~]."
  661.                   }
  662.                   (hash-table-count obj)
  663.         ) )
  664.         (READTABLE
  665.           (format s 
  666.                   #L{
  667.                   DEUTSCH "~:[eine ~;die Common-Lisp-~]Readtable."
  668.                   ENGLISH "~:[a~;the Common Lisp~] readtable."
  669.                   FRANCAIS "~:[un~;le~] tableau de lecture~:*~:[~; de Common Lisp~]."
  670.                   }
  671.                   (equalp obj (copy-readtable))
  672.         ) )
  673.         ((PATHNAME #+LOGICAL-PATHNAMES LOGICAL-PATHNAME)
  674.           (format s 
  675.                   #L{
  676.                   DEUTSCH "ein ~:[~;portabler ~]Pathname~:[.~;~:*, aufgebaut aus:~{~A~}~]"
  677.                   ENGLISH "a ~:[~;portable ~]pathname~:[.~;~:*, with the following components:~{~A~}~]"
  678.                   FRANCAIS "un «pathname»~:[~; portable~]~:[.~;~:*, composé de:~{~A~}~]"
  679.                   }
  680.                     (sys::logical-pathname-p obj)
  681.                     (mapcan #'(lambda (kw component)
  682.                                 (when component
  683.                                   (list (format nil "~%~A = ~A"
  684.                                                     (symbol-name kw)
  685.                                                     (make-pathname kw component)
  686.                               ) ) )     )
  687.                       '(:host :device :directory :name :type :version)
  688.                       (list
  689.                         (pathname-host obj)
  690.                         (pathname-device obj)
  691.                         (pathname-directory obj)
  692.                         (pathname-name obj)
  693.                         (pathname-type obj)
  694.                         (pathname-version obj)
  695.         ) )         ) )
  696.         (RANDOM-STATE
  697.           (format s 
  698.                   #L{
  699.                   DEUTSCH "ein Random-State."
  700.                   ENGLISH "a random-state."
  701.                   FRANCAIS "un «random-state»."
  702.                   }
  703.         ) )
  704.         (BYTE
  705.           (format s 
  706.                   #L{
  707.                   DEUTSCH "ein Byte-Specifier, bezeichnet die ~S Bits ab Bitposition ~S eines Integers."
  708.                   ENGLISH "a byte specifier, denoting the ~S bits starting at bit position ~S of an integer."
  709.                   FRANCAIS "un intervalle de bits, comportant ~S bits à partir de la position ~S d'un entier."
  710.                   }
  711.                   (byte-size obj) (byte-position obj)
  712.         ) )
  713.         (LOAD-TIME-EVAL
  714.           (format s 
  715.                   #L{
  716.                   DEUTSCH "eine Absicht der Evaluierung zur Ladezeit." ; ??
  717.                   ENGLISH "a load-time evaluation promise." ; ??
  718.                   FRANCAIS "une promesse d'évaluation au moment du chargement." ; ??
  719.                   }
  720.         ) )
  721.         (READ-LABEL
  722.           (format s 
  723.                   #L{
  724.                   DEUTSCH "eine Markierung zur Auflösung von #~D#-Verweisen bei READ."
  725.                   ENGLISH "a label used for resolving #~D# references during READ."
  726.                   FRANCAIS "une marque destinée à résoudre #~D# au cours de READ."
  727.                   }
  728.                   (logand (sys::address-of obj) '#,(ash most-positive-fixnum -1))
  729.         ) )
  730.         (FRAME-POINTER
  731.           (format s 
  732.                   #L{
  733.                   DEUTSCH "ein Pointer in den Stack. Er zeigt auf:"
  734.                   ENGLISH "a pointer into the stack. It points to:"
  735.                   FRANCAIS "un pointeur dans la pile. Il pointe vers :"
  736.                   }
  737.           )
  738.           (sys::describe-frame s obj)
  739.         )
  740.         (SYSTEM-INTERNAL
  741.           (format s 
  742.                   #L{
  743.                   DEUTSCH "ein Objekt mit besonderen Eigenschaften."
  744.                   ENGLISH "a special-purpose object."
  745.                   FRANCAIS "un objet distingué."
  746.                   }
  747.         ) )
  748.         (ADDRESS
  749.           (format s 
  750.                   #L{
  751.                   DEUTSCH "eine Maschinen-Adresse."
  752.                   ENGLISH "a machine address."
  753.                   FRANCAIS "une addresse au niveau de la machine."
  754.                   }
  755.         ) )
  756.         (t
  757.          (if (and (symbolp type) (sys::%structure-type-p type obj))
  758.            ; Structure
  759.            (progn
  760.              (format s 
  761.                      #L{
  762.                      DEUTSCH "eine Structure vom Typ ~S."
  763.                      ENGLISH "a structure of type ~S."
  764.                      FRANCAIS "une structure de type ~S."
  765.                      }
  766.                      type
  767.              )
  768.              (let ((type (sys::%record-ref obj 0)))
  769.                (when (cdr type)
  770.                  (format s 
  771.                          #L{
  772.                          DEUTSCH "~%Als solche ist sie auch eine Structure vom Typ ~{~S~^, ~}."
  773.                          ENGLISH "~%As such, it is also a structure of type ~{~S~^, ~}."
  774.                          FRANCAIS "~%En tant que telle, c'est aussi une structure de type ~{~S~^, ~}."
  775.                          }
  776.                          (cdr type)
  777.            ) ) ) )
  778.            ; CLOS-Instanz
  779.            (progn
  780.              (format s 
  781.                      #L{
  782.                      DEUTSCH "eine Instanz der CLOS-Klasse ~S."
  783.                      ENGLISH "an instance of the CLOS class ~S."
  784.                      FRANCAIS "un objet appartenant à la classe ~S de CLOS."
  785.                      }
  786.                      (clos:class-of obj)
  787.              )
  788.              (clos:describe-object obj s)
  789.          ) )
  790.       ) )
  791.       ; Array-Typen
  792.       (let ((rank (array-rank obj))
  793.             (eltype (array-element-type obj)))
  794.         (format s 
  795.                 #L{
  796.                 DEUTSCH "ein~:[~; einfacher~] ~A-dimensionaler Array"
  797.                 ENGLISH "a~:[~; simple~] ~A dimensional array"
  798.                 FRANCAIS "une matrice~:[~; simple~] à ~A dimension~:P"
  799.                 }
  800.                 (simple-array-p obj) rank
  801.         )
  802.         (when (eql rank 1)
  803.           (format s 
  804.                   #L{
  805.                   DEUTSCH " (Vektor)"
  806.                   ENGLISH " (vector)"
  807.                   FRANCAIS " (vecteur)"
  808.                   }
  809.         ) )
  810.         (unless (eq eltype 'T)
  811.           (format s 
  812.                   #L{
  813.                   DEUTSCH " von ~:(~A~)s"
  814.                   ENGLISH " of ~(~A~)s"
  815.                   FRANCAIS " de ~(~A~)s"
  816.                   }
  817.                   eltype
  818.         ) )
  819.         (when (adjustable-array-p obj)
  820.           (format s 
  821.                   #L{
  822.                   DEUTSCH ", adjustierbar"
  823.                   ENGLISH ", adjustable"
  824.                   FRANCAIS ", ajustable"
  825.                   }
  826.         ) )
  827.         (when (plusp rank)
  828.           (format s 
  829.                   #L{
  830.                   DEUTSCH ", der Größe ~{~S~^ x ~}"
  831.                   ENGLISH ", of size ~{~S~^ x ~}"
  832.                   FRANCAIS ", de grandeur ~{~S~^ x ~}"
  833.                   }
  834.                   (array-dimensions obj)
  835.           )
  836.           (when (array-has-fill-pointer-p obj)
  837.             (format s 
  838.                     #L{
  839.                     DEUTSCH " und der momentanen Länge (Fill-Pointer) ~S"
  840.                     ENGLISH " and current length (fill-pointer) ~S"
  841.                     FRANCAIS " et longueur courante (fill-pointer) ~S"
  842.                     }
  843.                     (fill-pointer obj)
  844.         ) ) )
  845.         (format s 
  846.                 #L{
  847.                 DEUTSCH "."
  848.                 ENGLISH "."
  849.                 FRANCAIS "."
  850.                 }
  851.       ) )
  852.   ) )
  853.   (when more
  854.     (format s 
  855.             #L{
  856.             DEUTSCH "~%Mehr Information durch Auswerten von ~{~S~^ oder ~}."
  857.             ENGLISH "~%For more information, evaluate ~{~S~^ or ~}."
  858.             FRANCAIS "~%Pour obtenir davantage d'information, évaluez ~{~S~^ ou ~}."
  859.             }
  860.             (nreverse more)
  861.   ) )
  862.   (values)
  863. )
  864.  
  865. ; Liefert die Signatur eines funktionalen Objekts, als Werte:
  866. ; 1. req-anz
  867. ; 2. opt-anz
  868. ; 3. rest-p
  869. ; 4. key-p
  870. ; 5. keyword-list
  871. ; 6. allow-other-keys-p
  872. (defun function-signature (obj)
  873.   (if (sys::closurep obj)
  874.     (if (compiled-function-p obj)
  875.       ; compilierte Closure
  876.       (multiple-value-bind (req-anz opt-anz rest-p key-p keyword-list allow-other-keys-p)
  877.           (sys::signature obj) ; siehe compiler.lsp
  878.         (values req-anz opt-anz rest-p key-p keyword-list allow-other-keys-p)
  879.       )
  880.       ; interpretierte Closure
  881.       (let ((clos_keywords (sys::%record-ref obj 16)))
  882.         (values (sys::%record-ref obj 12) ; req_anz
  883.                 (sys::%record-ref obj 13) ; opt_anz
  884.                 (sys::%record-ref obj 19) ; rest_flag
  885.                 (not (numberp clos_keywords))
  886.                 (if (not (numberp clos_keywords)) (copy-list clos_keywords))
  887.                 (sys::%record-ref obj 18) ; allow_flag
  888.       ) )
  889.     )
  890.     (cond #+FFI
  891.           ((eq (type-of obj) 'FOREIGN-FUNCTION)
  892.            (values (sys::foreign-function-signature obj) 0 nil nil nil nil)
  893.           )
  894.           (t
  895.            (multiple-value-bind (name req-anz opt-anz rest-p keywords allow-other-keys)
  896.                (sys::subr-info obj)
  897.              (if name
  898.                (values req-anz opt-anz rest-p keywords keywords allow-other-keys)
  899.                (error 
  900.                 #L{
  901.                 DEUTSCH "~S: ~S ist keine Funktion."
  902.                 ENGLISH "~S: ~S is not a function."
  903.                 FRANCAIS "~S : ~S n'est pas une fonction."
  904.                 }
  905.                 'function-signature obj
  906.                )
  907. ) ) )     )) )
  908.  
  909. (defun describe-signature (s req-anz opt-anz rest-p keyword-p keywords allow-other-keys)
  910.   (format s 
  911.           #L{
  912.           DEUTSCH "~%Argumentliste: "
  913.           ENGLISH "~%argument list: "
  914.           FRANCAIS "~%Liste des arguments : "
  915.           }
  916.   )
  917.   (format s "(~{~A~^ ~})"
  918.     (let ((args '()) (count 0))
  919.       (dotimes (i req-anz)
  920.         (incf count)
  921.         (push (format nil "ARG~D" count) args)
  922.       )
  923.       (when (plusp opt-anz)
  924.         (push '&OPTIONAL args)
  925.         (dotimes (i opt-anz)
  926.           (incf count)
  927.           (push (format nil "ARG~D" count) args)
  928.       ) )
  929.       (when rest-p
  930.         (push '&REST args)
  931.         (push "OTHER-ARGS" args)
  932.       )
  933.       (when keyword-p
  934.         (push '&KEY args)
  935.         (dolist (kw keywords) (push (prin1-to-string kw) args))
  936.         (when allow-other-keys (push '&ALLOW-OTHER-KEYS args))
  937.       )
  938.       (nreverse args)
  939. ) ) )
  940. ;; DOCUMENTATION mit abfragen und ausgeben??
  941. ;; function, variable, type, structure, setf
  942.  
  943. ; Gibt object in einen String aus, der nach Möglichkeit höchstens max Zeichen
  944. ; lang sein soll.
  945. (defun write-to-short-string (object max)
  946.   ; Methode: probiere
  947.   ; level = 0: length = 0,1,2
  948.   ; level = 1: length = 1,2,3,4
  949.   ; level = 2: length = 2,...,6
  950.   ; usw. bis maximal level = 16.
  951.   ; Dabei level möglichst groß, und bei festem level length möglichst groß.
  952.   (if (or (numberp object) (symbolp object)) ; von length und level unbeeinflußt?
  953.     (write-to-string object)
  954.     (macrolet ((minlength (level) `,level)
  955.                (maxlength (level) `(* 2 (+ ,level 1))))
  956.       ; Um level möglist groß zu bekommen, dabei length = minlength wählen.
  957.       (let* ((level ; Binärsuche nach dem richtigen level
  958.                (let ((level1 0) (level2 16))
  959.                  (loop
  960.                    (when (= (- level2 level1) 1) (return))
  961.                    (let ((levelm (floor (+ level1 level2) 2)))
  962.                      (if (<= (length (write-to-string object :level levelm :length (minlength levelm))) max)
  963.                        (setq level1 levelm) ; levelm paßt, probiere größere
  964.                        (setq level2 levelm) ; levelm paßt nicht, probiere kleinere
  965.                  ) ) )
  966.                  level1
  967.              ) )
  968.              (length ; Binärsuche nach dem richtigen length
  969.                (let ((length1 (minlength level)) (length2 (maxlength level)))
  970.                  (loop
  971.                    (when (= (- length2 length1) 1) (return))
  972.                    (let ((lengthm (floor (+ length1 length2) 2)))
  973.                      (if (<= (length (write-to-string object :level level :length lengthm)) max)
  974.                        (setq length1 lengthm) ; lengthm paßt, probiere größere
  975.                        (setq length2 lengthm) ; lengthm paßt nicht, probiere kleinere
  976.                  ) ) )
  977.                  length1
  978.             )) )
  979.         (write-to-string object :level level :length length)
  980. ) ) ) )
  981.  
  982. ;-------------------------------------------------------------------------------
  983. ;; DRIBBLE
  984.  
  985. (let ((dribble-file nil) (dribbled-input nil) (dribbled-output nil)
  986.       (dribbled-error-output nil) (dribbled-trace-output nil)
  987.       (dribbled-query-io nil) (dribbled-debug-io nil))
  988.   (defun dribble (&optional file)
  989.     (if file
  990.       (progn
  991.         (if dribble-file
  992.           (warn 
  993.            #L{
  994.            DEUTSCH "Es wird bereits auf ~S protokolliert."
  995.            ENGLISH "Already dribbling to ~S"
  996.            FRANCAIS "Le protocole est déjà écrit sur ~S."
  997.            }
  998.            dribble-file
  999.           )
  1000.           (flet ((goes-to-terminal (stream) ; this is a hack
  1001.                    (and (typep stream 'synonym-stream)
  1002.                         (eq (synonym-stream-symbol stream) '*terminal-io*)
  1003.                 )) )
  1004.             (setq dribble-file (open file :direction :output)
  1005.                   dribbled-input *standard-input*
  1006.                   dribbled-output *standard-output*
  1007.                   dribbled-error-output nil
  1008.                   dribbled-trace-output nil
  1009.                   dribbled-query-io nil
  1010.                   dribbled-debug-io nil
  1011.             )
  1012.             (setq *standard-input* (make-echo-stream *standard-input* dribble-file))
  1013.             (setq *standard-output* (make-broadcast-stream *standard-output* dribble-file))
  1014.             (when (goes-to-terminal *error-output*)
  1015.               (setq dribbled-error-output *error-output*)
  1016.               (setq *error-output* (make-broadcast-stream *error-output* dribble-file))
  1017.             )
  1018.             (when (goes-to-terminal *trace-output*)
  1019.               (setq dribbled-trace-output *trace-output*)
  1020.               (setq *trace-output* (make-broadcast-stream *trace-output* dribble-file))
  1021.             )
  1022.             (when (goes-to-terminal *query-io*)
  1023.               (setq dribbled-query-io *query-io*)
  1024.               (setq *query-io*
  1025.                     (make-two-way-stream
  1026.                           (make-echo-stream *query-io* dribble-file)
  1027.                           (make-broadcast-stream *query-io* dribble-file)
  1028.             ) )     )
  1029.             (when (goes-to-terminal *debug-io*)
  1030.               (setq dribbled-debug-io *debug-io*)
  1031.               (setq *debug-io*
  1032.                     (make-two-way-stream
  1033.                           (make-echo-stream *debug-io* dribble-file)
  1034.                           (make-broadcast-stream *debug-io* dribble-file)
  1035.             ) )     )
  1036.         ) )
  1037.         dribble-file
  1038.       )
  1039.       (if dribble-file
  1040.         (progn
  1041.           (setq *standard-input* dribbled-input)
  1042.           (setq *standard-output* dribbled-output)
  1043.           (when dribbled-error-output (setq *error-output* dribbled-error-output))
  1044.           (when dribbled-trace-output (setq *trace-output* dribbled-trace-output))
  1045.           (when dribbled-query-io (setq *query-io* dribbled-query-io))
  1046.           (when dribbled-debug-io (setq *query-io* dribbled-debug-io))
  1047.           (setq dribbled-input nil)
  1048.           (setq dribbled-output nil)
  1049.           (setq dribbled-error-output nil)
  1050.           (setq dribbled-trace-output nil)
  1051.           (setq dribbled-query-io nil)
  1052.           (setq dribbled-debug-io nil)
  1053.           (prog1
  1054.             dribble-file
  1055.             (close dribble-file)
  1056.             (setq dribble-file nil)
  1057.         ) )
  1058.         (warn 
  1059.          #L{
  1060.          DEUTSCH "Es wird zur Zeit nicht protokolliert."
  1061.          ENGLISH "Currently not dribbling."
  1062.          FRANCAIS "Aucun protocole n'est couramment écrit."
  1063.          }
  1064. ) ) ) ) )
  1065.  
  1066. ;-------------------------------------------------------------------------------
  1067. ;; ED
  1068.  
  1069. ;; *editor*, editor-name und editor-tempfile sind in CONFIG.LSP definiert.
  1070. ;; Hier stehen nur die Defaults.
  1071.  
  1072. ;; Der Name des Editors:
  1073. (defparameter *editor* nil)
  1074.  
  1075. ;; Liefert den Namen des Editors:
  1076. (defun editor-name () *editor*)
  1077.  
  1078. ;; Das temporäre File, das LISP beim Editieren anlegt:
  1079. (defun editor-tempfile ()
  1080.   #+DOS "LISPTEMP.LSP"
  1081.   #+OS/2 "lisptemp.lsp"
  1082.   #+WIN32-DOS "lisptemp.lsp"
  1083.   #+AMIGA "T:lisptemp.lsp"
  1084.   #+(or UNIX WIN32-UNIX) (merge-pathnames "lisptemp.lsp" (user-homedir-pathname))
  1085. )
  1086.  
  1087. ;; (edit-file file) editiert ein File.
  1088. (defun edit-file (file)
  1089.   (unless (editor-name)
  1090.     (error-of-type 'error
  1091.       #L{
  1092.       DEUTSCH "Kein externer Editor installiert."
  1093.       ENGLISH "No external editor installed."
  1094.       FRANCAIS "Un éditeur externe n'est pas installé."
  1095.       }
  1096.   ) )
  1097.   ; Damit TRUENAME keinen Fehler liefert, wenn das File noch nicht existiert,
  1098.   ; stellen wir sicher, daß das File existiert:
  1099.   #+(or UNIX AMIGA ACORN-RISCOS WIN32-UNIX)
  1100.   (unless (probe-file file)
  1101.     (close (open file :direction :output))
  1102.   )
  1103.   #+(or DOS OS/2 WIN32-DOS)
  1104.     (execute (editor-name) ; das ist der Name des Editors
  1105.              (namestring file t) ; file als String
  1106.     )
  1107.   #+(or UNIX WIN32-UNIX)
  1108.     (shell (format nil "~A ~A" (editor-name) (truename file)))
  1109.   #+AMIGA
  1110.     (shell (format nil "~A \"~A\"" (editor-name) (truename file)))
  1111.   #+ACORN-RISCOS
  1112.     (shell (format nil "filer_run ~A" (truename file)))
  1113. )
  1114.  
  1115. (defun ed (&optional arg &aux funname sym fun def)
  1116.   (if (null arg)
  1117.     (edit-file "")
  1118.     (if (or (pathnamep arg) (stringp arg))
  1119.       (edit-file arg)
  1120.       (if (and (cond ((function-name-p arg) (setq funname arg) t)
  1121.                      ((functionp arg) (function-name-p (setq funname (sys::%record-ref arg 0))))
  1122.                      (t nil)
  1123.                )
  1124.                (fboundp (setq sym (get-funname-symbol funname)))
  1125.                (or (setq fun (macro-function sym))
  1126.                    (setq fun (symbol-function sym))
  1127.                )
  1128.                (functionp fun)
  1129.                (or (function-name-p arg) (eql fun arg))
  1130.                (setq def (get sym 'sys::definition))
  1131.           )
  1132.         (let ((tempfile (editor-tempfile)))
  1133.           (with-open-file (f tempfile :direction :output)
  1134.             (pprint (car def) f)
  1135.             (terpri f) (terpri f)
  1136.           )
  1137.           (let ((date (file-write-date tempfile)))
  1138.             (edit-file tempfile)
  1139.             (when (> (file-write-date tempfile) date)
  1140.               (with-open-file (f tempfile :direction :input)
  1141.                 (let ((*package* *package*) ; *PACKAGE* binden
  1142.                       (end-of-file "EOF")) ; einmaliges Objekt
  1143.                   (loop
  1144.                     (let ((obj (read f nil end-of-file)))
  1145.                       (when (eql obj end-of-file) (return))
  1146.                       (print (evalhook obj nil nil (cdr def)))
  1147.               ) ) ) )
  1148.               (when (compiled-function-p fun) (compile funname))
  1149.           ) )
  1150.           funname
  1151.         )
  1152.         (error-of-type 'error
  1153.           #L{
  1154.           DEUTSCH "~S ist nicht editierbar."
  1155.           ENGLISH "~S cannot be edited."
  1156.           FRANCAIS "~S ne peut pas être édité."
  1157.           }
  1158.           arg
  1159. ) ) ) ) )
  1160.  
  1161. (defun uncompile (arg &aux funname sym fun def)
  1162.   (if (and (cond ((function-name-p arg) (setq funname arg) t)
  1163.                  ((functionp arg) (function-name-p (setq funname (sys::%record-ref arg 0))))
  1164.                  (t nil)
  1165.            )
  1166.            (fboundp (setq sym (get-funname-symbol funname)))
  1167.            (or (setq fun (macro-function sym))
  1168.                (setq fun (symbol-function sym))
  1169.            )
  1170.            (functionp fun)
  1171.            (or (function-name-p arg) (eql fun arg))
  1172.            (setq def (get sym 'sys::definition))
  1173.       )
  1174.     (evalhook (car def) nil nil (cdr def))
  1175.     (error-of-type 'error
  1176.       #L{
  1177.       DEUTSCH "~S: Quellcode zu ~S nicht verfügbar."
  1178.       ENGLISH "~S: source code for ~S not available."
  1179.       FRANCAIS "~S : Les sources de ~S ne sont pas présentes."
  1180.       }
  1181.       'uncompile funname
  1182.     )
  1183. ) )
  1184.  
  1185. ;-------------------------------------------------------------------------------
  1186.  
  1187. ; Speichert den momentanen Speicherinhalt unter Weglassen überflüssiger
  1188. ; Objekte ab als LISPIMAG.MEM.
  1189. ; Diese Funktion bekommt keine Argumente und hat keine lokalen Variablen, da
  1190. ; sonst in interpretiertem Zustand die Variablenwerte mit abgespeichert würden.
  1191. (defun %saveinitmem ()
  1192.   (do-all-symbols (sym) (remprop sym 'sys::definition))
  1193.   (when (fboundp 'clos::install-dispatch)
  1194.     (do-all-symbols (sym)
  1195.       (when (and (fboundp sym) (clos::generic-function-p (symbol-function sym)))
  1196.         (let ((gf (symbol-function sym)))
  1197.           (when (clos::gf-never-called-p gf)
  1198.             (clos::install-dispatch gf)
  1199.   ) ) ) ) )
  1200.   (setq - nil + nil ++ nil +++ nil * nil ** nil *** nil / nil // nil /// nil)
  1201.   (savemem "lispimag.mem")
  1202.   (room)
  1203. )
  1204.  
  1205. ; Speichert den momentanen Speicherinhalt ab.
  1206. ; Läuft nur in compiliertem Zustand!
  1207. (defun saveinitmem (&optional (filename "lispinit.mem")
  1208.                     &key ((:quiet *quiet*) nil) init-function)
  1209.   (setq - nil + nil ++ nil +++ nil * nil ** nil *** nil / nil // nil /// nil)
  1210.   (if init-function
  1211.     (let* ((old-driver *driver*)
  1212.            (*driver* #'(lambda ()
  1213.                          (setq *driver* old-driver)
  1214.                          (funcall init-function)
  1215.                          (funcall *driver*)
  1216.           ))           )
  1217.       (savemem filename)
  1218.     )
  1219.     (savemem filename)
  1220.   )
  1221.   (room)
  1222. )
  1223.  
  1224. ;-------------------------------------------------------------------------------
  1225.  
  1226. ; Vervollständigungs-Routine in Verbindung mit der GNU Readline-Library:
  1227. ; Input: string die Eingabezeile, (subseq string start end) das zu vervoll-
  1228. ; ständigende Textstück.
  1229. ; Output: eine Liste von Simple-Strings. Leer, falls keine sinnvolle Vervoll-
  1230. ; ständigung. Sonst CDR = Liste aller sinnvollen Vervollständigungen, CAR =
  1231. ; sofortige Ersetzung.
  1232. #+(or UNIX DOS OS/2 WIN32-DOS WIN32-UNIX)
  1233. (defun completion (string start end)
  1234.   ; quotiert vervollständigen?
  1235.   (let ((start1 start) (quoted nil))
  1236.     (when (and (>= start 1) (member (char string (- start 1)) '(#\" #\|)))
  1237.       (decf start1) (setq quoted t)
  1238.     )
  1239.     (let (; Hilfsvariablen beim Sammeln der Symbole:
  1240.           knownpart ; Anfangsstück
  1241.           knownlen  ; dessen Länge
  1242.           (L '())   ; sammelnde Liste
  1243.          )
  1244.       (let* ((functionalp1
  1245.                (and (>= start1 1)
  1246.                     (equal (subseq string (- start1 1) start1) "(")
  1247.              ) )
  1248.              (functionalp2
  1249.                (and (>= start1 2)
  1250.                     (equal (subseq string (- start1 2) start1) "#'")
  1251.              ) )
  1252.              (functionalp ; Vervollständigung in funktionaler Position?
  1253.                (or functionalp1 functionalp2)
  1254.              )
  1255.              (gatherer
  1256.                (if functionalp
  1257.                  #'(lambda (sym)
  1258.                      (when (fboundp sym)
  1259.                        (let ((name (symbol-name sym)))
  1260.                          (when (and (>= (length name) knownlen) (string-equal name knownpart :end1 knownlen))
  1261.                            (push name L)
  1262.                    ) ) ) )
  1263.                  #'(lambda (sym)
  1264.                      (let ((name (symbol-name sym)))
  1265.                        (when (and (>= (length name) knownlen) (string-equal name knownpart :end1 knownlen))
  1266.                          (push name L)
  1267.                    ) ) )
  1268.              ) )
  1269.              (package *package*)
  1270.              (mapfun #'sys::map-symbols)
  1271.              (prefix nil))
  1272.         ; Evtl. Packagenamen abspalten:
  1273.         (unless quoted
  1274.           (let ((colon (position #\: string :start start :end end)))
  1275.             (when colon
  1276.               (unless (setq package (find-package (string-upcase (subseq string start colon))))
  1277.                 (return-from completion nil)
  1278.               )
  1279.               (incf colon)
  1280.               (if (and (< colon end) (eql (char string colon) #\:))
  1281.                 (incf colon)
  1282.                 (setq mapfun #'sys::map-external-symbols)
  1283.               )
  1284.               (setq prefix (subseq string start colon))
  1285.               (setq start colon)
  1286.         ) ) )
  1287.         (setq knownpart (subseq string start end))
  1288.         (setq knownlen (length knownpart))
  1289.         (funcall mapfun gatherer package)
  1290.         (when (null L) (return-from completion nil))
  1291.         ; Bei einer Funktion ohne Argumente ergänze die schließende Klammer:
  1292.         (when (and functionalp1
  1293.                    (null (cdr L))
  1294.                    (let ((sym (find-symbol (car L) package)))
  1295.                      (and (fboundp sym)
  1296.                           (functionp (symbol-function sym))
  1297.                           (multiple-value-bind (req-anz opt-anz rest-p key-p)
  1298.                               (function-signature (symbol-function sym))
  1299.                             (and (eql req-anz 0) (eql opt-anz 0) (not rest-p) (not key-p))
  1300.               )    ) )    )
  1301.           (setf (car L) (string-concat (car L) ")"))
  1302.         )
  1303.         ; Kleinbuchstaben:
  1304.         (unless quoted
  1305.           (setq L (mapcar #'string-downcase L))
  1306.         )
  1307.         ; sortieren:
  1308.         (setq L (sort L #'string<))
  1309.         ; größtes gemeinsames Anfangsstück suchen:
  1310.         (let ((imax ; (reduce #'min (mapcar #'length L))
  1311.                 (let ((i (length (first L))))
  1312.                   (dolist (s (rest L)) (setq i (min i (length s))))
  1313.                   i
  1314.              )) )
  1315.           (do ((i 0 (1+ i)))
  1316.               ((or (eql i imax)
  1317.                    (let ((c (char (first L) i)))
  1318.                      (dolist (s (rest L) nil) (unless (eql (char s i) c) (return t)))
  1319.                )   )
  1320.                (push (subseq (first L) 0 i) L)
  1321.         ) )   )
  1322.         ; Präfix wieder ankleben:
  1323.         (when prefix
  1324.           (mapl #'(lambda (l)
  1325.                     (setf (car l) (string-concat prefix (car l)))
  1326.                   )
  1327.                 L
  1328.         ) )
  1329.         L
  1330. ) ) ) )
  1331.  
  1332. ;-------------------------------------------------------------------------------
  1333.  
  1334. #+(or UNIX OS/2 WIN32-DOS WIN32-UNIX)
  1335. ; Must quote the program name and arguments since Unix shells interpret
  1336. ; characters like #\Space, #\', #\<, #\>, #\$ etc. in a special way. This
  1337. ; kind of quoting should work unless the string contains #\Newline and we
  1338. ; call csh. But we are lucky: only /bin/sh will be used.
  1339. (flet (#+(or UNIX WIN32-UNIX)
  1340.        (shell-quote (string) ; surround a string by single quotes
  1341.          (let ((qchar nil) ; last quote character: nil or #\' or #\"
  1342.                (qstring (make-array 10 :element-type 'string-char
  1343.                                        :adjustable t :fill-pointer 0)))
  1344.            (map nil #'(lambda (c)
  1345.                         (let ((q (if (eql c #\') #\" #\')))
  1346.                           (unless (eql qchar q)
  1347.                             (when qchar (vector-push-extend qchar qstring))
  1348.                             (vector-push-extend (setq qchar q) qstring)
  1349.                           )
  1350.                           (vector-push-extend c qstring)))
  1351.                     string
  1352.            )
  1353.            (when qchar (vector-push-extend qchar qstring))
  1354.            qstring
  1355.        ) )
  1356.        #+(or DOS OS/2 WIN32-DOS)
  1357.        (shell-quote (string) ; surround a string by double quotes
  1358.          ; I have tested Turbo C compiled programs and EMX compiled programs.
  1359.          ; 1. Special characters (space, tab, <, >, ...) lose their effect if
  1360.          ;    they are inside double quotes. To get a double quote, write \".
  1361.          ; 2. Separate the strings by spaces. Turbo C compiled programs don't
  1362.          ;    require this, but EMX programs merge adjacent strings.
  1363.          ; 3. You cannot pass an empty string or a string terminated by \ to
  1364.          ;    Turbo C compiled programs. To pass an empty string to EMX
  1365.          ;    programs, write "". You shouldn't pass a string terminated by \
  1366.          ;    or containing \" to EMX programs.
  1367.          ; Quick and dirty: assume none of these cases occur.
  1368.          (let ((qstring (make-array 10 :element-type 'string-char
  1369.                                        :adjustable t :fill-pointer 0)))
  1370.            (vector-push-extend #\" qstring)
  1371.            (map nil #'(lambda (c)
  1372.                         (when (eql c #\") (vector-push-extend #\\ qstring))
  1373.                         (vector-push-extend c qstring)
  1374.                       )
  1375.                     string
  1376.            )
  1377.            (vector-push-extend #\" qstring)
  1378.            qstring
  1379.        ) )
  1380.        ; conversion to a string that works for a pathname as well
  1381.        (string (object)
  1382.          (if (pathnamep object) (namestring object t) (string object))
  1383.       ))
  1384.   (defun run-shell-command (command &key (input ':terminal) (output ':terminal)
  1385.                                          (if-output-exists ':overwrite)
  1386.                                          #+(or UNIX WIN32-UNIX) (may-exec nil))
  1387.     (case input
  1388.       ((:TERMINAL :STREAM) )
  1389.       (t (if (eq input 'NIL)
  1390.            (setq input
  1391.          #+(or UNIX WIN32-UNIX) "/dev/null" 
  1392.          #+(or DOS OS/2 WIN32-DOS) "nul")
  1393.            (setq input (string input))
  1394.          )
  1395.          (setq command (string-concat command " < " (shell-quote input)))
  1396.     ) )
  1397.     (case output
  1398.       ((:TERMINAL :STREAM) )
  1399.       (t (if (eq output 'NIL)
  1400.            (setq output
  1401.          #+(or UNIX WIN32-UNIX) "/dev/null"
  1402.          #+(or DOS OS/2 WIN32-DOS) "nul"
  1403.                  if-output-exists ':OVERWRITE
  1404.            )
  1405.            (progn
  1406.              (setq output (string output))
  1407.              (when (and (eq if-output-exists ':ERROR) (probe-file output))
  1408.                (setq output (pathname output))
  1409.                (error-of-type 'file-error
  1410.                  :pathname output
  1411.                  #L{
  1412.                  DEUTSCH "~S: Eine Datei ~S existiert bereits."
  1413.                  ENGLISH "~S: File ~S already exists"
  1414.                  FRANCAIS "~S : Le fichier ~S existe déjà."
  1415.                  }
  1416.                  'run-shell-command output
  1417.          ) ) ) )
  1418.          (setq command
  1419.                (string-concat command
  1420.                  (ecase if-output-exists
  1421.                    ((:OVERWRITE :ERROR) " > ")
  1422.                    (:APPEND " >> ")
  1423.                  )
  1424.                  (shell-quote output)
  1425.     ) )  )     )
  1426.     #+(or UNIX WIN32-UNIX)
  1427.     (when may-exec
  1428.       ; Wenn die ausführende Shell die "/bin/sh" ist und command eine
  1429.       ; "simple command" im Sinne von sh(1), können wir ein wenig optimieren:
  1430.       (setq command (string-concat "exec " command))
  1431.     )
  1432.     (if (eq input ':STREAM)
  1433.       (if (eq output ':STREAM)
  1434.         (make-pipe-io-stream command)
  1435.         (make-pipe-output-stream command)
  1436.       )
  1437.       (if (eq output ':STREAM)
  1438.         (make-pipe-input-stream command)
  1439.         (shell command) ; evtl. " &" anfügen, um Hintergrund-Prozeß zu bekommen
  1440.     ) )
  1441.   )
  1442.   (defun run-program (program &key (arguments '())
  1443.                                    (input ':terminal) (output ':terminal)
  1444.                                    (if-output-exists ':overwrite))
  1445.     (run-shell-command
  1446.       (apply #'string-concat
  1447.              #+(or UNIX WIN32-UNIX) (shell-quote (string program)) 
  1448.              #-(or UNIX WIN32-UNIX) (string program)
  1449.              (mapcan #'(lambda (argument)
  1450.                          (list " " (shell-quote (string argument)))
  1451.                        )
  1452.                      arguments
  1453.       )      )
  1454.       #+(or UNIX WIN32-UNIX) :may-exec
  1455.       #+(or UNIX WIN32-UNIX) t
  1456.       :input input :output output :if-output-exists if-output-exists
  1457.   ) )
  1458. )
  1459.  
  1460.