Сейчас мы сделаем 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
Теперь можно при необходимости изменить путь к текстовому файлу (или вообще его имя) и, не заморачиваясь с правкой кода, при необходимости быстро внести дополнения в перечень устанавливаемых системных переменных.
"Более компактный" код можно забрать здесь.
Комментарии
Авторизоваться