VetCAD

lisp установки системных переменных из стороннего файла

   1 оценка

размещено: 26 Января 2016
обновлено: 26 Января 2016

Сейчас мы сделаем 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

Теперь можно при необходимости изменить путь к текстовому файлу (или вообще его имя) и, не заморачиваясь с правкой кода, при необходимости быстро внести дополнения в перечень устанавливаемых системных переменных.

"Более компактный" код можно забрать здесь.

Комментарии

Комментарии могут оставлять только зарегистрированные участники
Авторизоваться
Комментарии 1-2 из 2
Кулик Алексей aka kpblc , 01 февраля 2016 в 14:23
#2
В каком месте "затык"? Я тут немного заболел, всю неделю сижу дома. Так что вариантов связаться - масса :)
lena.talkhina , 01 февраля 2016 в 13:30
#1
Что-то начала изменять подгрузку лиспа и у меня совсем перестал срабатывать - и старый, и новый :)