Как найти функции, определенные в fas/vlx/arx…

Тут возникла задачка - надо определить функции, определенные в загружаемом компилированном файле...

Вспомним про такую замечательную штуку, как atoms-family. Возвращает список всех определенных функций и переменных (как глобальных, так и локальных) на момент вызова.

То есть если будет функция, например, такая:

1
2
3
4
5
6
(defun test (/ a b c)
  (setq a (atoms-family 1)
        b 1
        c (atoms-family 1)
        ) ;_ end of setq
  ) ;_ end of defun

То, проанализировав во время выполнения значения a и c, можно будет найти, что в а присутствует определение функции TEST, а в с, помимо этого, еще и определение переменной А.

Следовательно, можно написать функцию, которая сначала получит список имеющихся фунций и переменных, потом загрузит файл, снова получит список функций и переменных, сравнит начальный и конечный списки и выдаст разницу. Естественно, что надо исключить локальные переменные, и имя функции. Ну, в качестве первой прикидки:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
(defun lispru-defuns (file / err start res)
                     ;|
*    Определение имен функций и переменных, загруженных fas- или vlx-файлом
*    Параметры вызова:
  file    полный путь к загружаемому файлу, с указанием расширения.
|;

  (if (and (findfile file)
           (not (vl-file-directory-p file))
           ) ;_ end of and
    (progn
      (setq start (mapcar (function strcase) (atoms-family 1)))
      (if (not (vl-catch-all-error-p
                 (setq err (vl-catch-all-apply
                             (function
                               (lambda ()
                                 (cond
                                   ((member (strcase (vl-filename-extension file) t)
                                            '(".lsp" ".fas" ".vlx")
                                            ) ;_ end of member
                                    (load file)
                                    )
                                   ((= (strcase (vl-filename-extension file) t) ".arx")
                                    (arxload file)
                                    )
                                   ((= (strcase (vl-filename-extension file) t) ".dll")
                                    (command "_.netload" file)
                                    )
                                   ) ;_ end of cond
                                 (foreach item (mapcar (function strcase) (atoms-family 1))
                                   (if (not (member item start))
                                     (setq res (cons item res))
                                     ) ;_ end of if
                                   ) ;_ end of foreach
                                 ) ;_ end of lambda
                               ) ;_ end of function
                             ) ;_ end of vl-catch-all-apply
                       ) ;_ end of setq
                 ) ;_ end of vl-catch-all-error-p
               ) ;_ end of not
        (progn
          (if (setq res (vl-sort (vl-remove-if
                                   (function
                                     (lambda (x)
                                       (member (strcase x) '("START" "FILE" "LISPRU-DEFUNS"))
                                       ) ;_ end of lambda
                                     ) ;_ end of function
                                   res
                                   ) ;_ end of vl-remove-if
                                 '>
                                 ) ;_ end of vl-sort
                    ) ;_ end of setq
            (princ (apply (function strcat)
                          (cons (car res)
                                (mapcar
                                  (function
                                    (lambda (x)
                                      (strcat "\n" x)
                                      ) ;_ end of lambda
                                    ) ;_ end of function
                                  (cdr res)
                                  ) ;_ end of mapcar
                                ) ;_ end of cons
                          ) ;_ end of apply
                   ) ;_ end of princ
            ) ;_ end of if
          ) ;_ end of progn
        (alert (strcat "Ошибка загрузки файла "
                       file
                       ":\n"
                       (vl-catch-all-error-message err)
                       ) ;_ end of strcat
               ) ;_ end of alert
        ) ;_ end of if
      ) ;_ end of progn
    ) ;_ end of if
  (princ)
  ) ;_ end of defun

Исходный код



Поделитесь своим мнением


Я не робот.