Сейчас мы сделаем lsp, который будет из s:\settings читать определенный текстовый файл и устанавливать значения каких-либо системных переменных. Сейчас придумаем общую систему хранения данных.
Логично предположить, что нам надо хранить, т.с., пары "переменная-значение". Самый простой и надежный способ - это использовать формат записи наподобие
НаименованиеПеременной=НеобходимоеЗначение
А уже код, который мы будем дальше разрабатывать, будет сам анализировать подставляемую строку и выполнять необходимые преобразования и вычисления.
В AutoCAD этих системных переменных тьма! Желающие могут посмотреть список (надеюсь, он более-менее полный). Но, что самое главное, типов значений не так уж и много: строка (правда, я не смог вспомнить навскидку системную переменную с типом значения строка), целое число, или список из чисел с десятичными разрядами. Отлично! Создаем текстовый файл с именем s:\settings\sysvars.txt:
; Если строка начинается с символа точки с запятой, то она считается комментарием ; и обработке не подлежит lunits=4 insunits=4 insunitsdefsource=4 insunitsdeftarget=4 blipmode=0 filedia=1 cmddia=1 attdia=1 attreq=1 insbase='(0. 0. 0.) luprec=2 auprec=4 measurement=1
Ну, пожалуй, хватит. Обратите внимание на переменную insbase: ее значение является списком из трех чисел. Фактически - координата точки. Учтем это при работе...
Теперь постепенно начнем разрабатывать нашу функцию firm-set-sysvar:
(defun firm-set-sysvar (/ file handle str lst)
;; Если найден файл из п.1...
(if ;; 1. Определяем имя файла, в котором у нас хранятся данные по системным переменным
(findfile (setq file "s:\\settings\\sysvar.txt"))
(progn
;; ... То можно и приступать к его чтению
)
) ;_ end of if
) ;_ end of defun
Ниже приведен работающий (насколько я смог его протестировать) вариант кода со всеми комментариями:
(defun firm-set-sysvar (/ file handle str lst pos name value cur)
;; Если найден файл из п.1...
(if ;; 1. Определяем имя файла, в котором у нас хранятся данные по системным переменным
(findfile (setq file "s:\\settings\\sysvar.txt"))
(progn
;; ... То можно и приступать к его чтению
(setq handle (open file "r"))
(while (setq str (read-line handle))
(if (and (not (wcmatch str ";*"))
(wcmatch str "*=*")
) ;_ end of and
;; Только если строка не начинается с символа ";"
;; и при этом содержит символ "="
;; тогда в общий список добавляем эту строку
;; В учебных целях код сделан неоптимальным
(setq lst (cons str lst))
) ;_ end of if
) ;_ end of while
;; "закрываем" файл
(close handle)
;; Теперь у нас в lst "болтается" перечень строк из txt-файла. Их необходимо
;; преобразовать: получить имя системной переменной и ее устанавливаемое значение
;; Мы точно знаем, что в строке может быть только один символ "=". Все, что слева
;; это имя системной переменной. Все, что справа - ее устанавливаемое значение
;; Пройдемся по всем элементам списка и сразу будем выполнять их преобразование.
(foreach item (reverse lst)
(setq pos (vl-string-search "=" item)
name (substr item 1 pos)
value (substr item (+ 2 pos))
;; Сейчас в name - имя переменной; в value - то значение, которое надо будет устанавливать
;; Обработаем и то, и другое, убрав возможные пробелы:
name (vl-string-trim " " name)
value (vl-string-trim " " value)
) ;_ end of setq
;; Дальнейшие движения имеют смысл только если имя переменной вбито верно, т.е.
;; можно получить ее значение:
(if (setq cur (getvar name))
;; Вот теперь самое интересное: проверяем тип значения, который есть в переменной
(cond
((= (type cur) 'str) ; строка
(setvar name value)
)
((= (type cur) 'int) ; целое
(setvar name (atoi value))
)
((= (type cur) 'real) ; число двойной точности
(setvar name (atof value))
)
((= (type cur) 'list) ; список
(setvar name (eval (read value)))
)
) ;_ end of cond
) ;_ end of if
) ;_ end of foreach
) ;_ end of progn
) ;_ end of if
) ;_ end of defun
А теперь он же, но написанный более компактно:
(defun firm-set-sysvar (/ file handle str lst pos cur)
(if (findfile (setq file "s:\\settings\\sysvar.txt"))
(progn
(setq handle (open file "r"))
(while (setq str (read-line handle))
(if (and (not (wcmatch str ";*"))
(wcmatch str "*=*")
(setq pos (vl-string-search "=" str))
(getvar (vl-string-trim " " (substr str 1 pos)))
) ;_ end of and
(setq lst (cons (vl-string-trim " " (substr str 1 pos))
(vl-string-trim " " (substr str (+ 2 pos)))
lst
) ;_ end of cons
) ;_ end of setq
) ;_ end of if
) ;_ end of while
(close handle)
(foreach item (reverse lst)
(if (setq cur (getvar (car item)))
(cond
((= (type cur) 'str)
(setvar (car item) (cdr item))
)
((= (type cur) 'int)
(setvar (car item) (atoi (cdr item)))
)
((= (type cur) 'real)
(setvar (car item) (atof (cdr item)))
)
((= (type cur) 'list)
(setvar (car item) (eval (read (cdr item))))
)
) ;_ end of cond
) ;_ end of if
) ;_ end of foreach
) ;_ end of progn
) ;_ end of if
) ;_ end of defun
Теперь можно при необходимости изменить путь к текстовому файлу (или вообще его имя) и, не заморачиваясь с правкой кода, при необходимости быстро внести дополнения в перечень устанавливаемых системных переменных.
"Более компактный" код можно забрать здесь.


Комментарии
Авторизоваться