ziele_o2k 发表于 2022-7-5 16:45:05

使用lisp cha处理INI文件


 
在我的软件中,我使用ini文件。我编写了自己的例程来处理它们,因为我不喜欢使用acet/doslib。如果有人能编写类似于acet get ini/acet set ini或dos\u getini/dos\u setini或两者的函数,那就太好了。。。
 
这只是一个想法!不幸的是,我没有时间这样做,而且(也是更重要的)我不需要这些常规。虽然有这些东西会很棒
也许有人会把这个职位当成挑战?
 
编辑:
我可以发布有关在哪里可以找到acet/doslib函数文档的信息

BIGAL 发表于 2022-7-5 17:20:09

它(defun getini(filename key/)将您自己的版本写入规则INI文件只是一个文本文件。
 
我有一些库文本文件,其中一个有200多行,其格式可以让你找到一个已知“键”的值
 

eg use a comma seperated you can use TAB also
Key1,value1

or by position
12345678901234567890
key1 Value1 Colour Linetype

ziele_o2k 发表于 2022-7-5 17:25:49

好啊
基于李的代码,我写了这样的东西:
 
1) pz:INI读取
将ini文件读取到格式化列表-稍微修改了李Mac的XParseConfig。
分号(;)行开头的数字符号(#)表示注释。
(defun pz:INI-Read ( file / line sub lst i m )
(if (and (setq file (findfile file)) (setq file (open file "r")))
   (progn
   (while (setq line (read-line file))
       (cond
         ( (wcmatch line "`[*`]")
         (if sub (setq lst (cons (reverse sub) lst)))
         (setq sub (list (substr line 2 (- (strlen line) 2))))
         )
         ( (and (/= (substr line 1 1) ";") (/= (substr line 1 1) "#") (wcmatch line "*=*"))
         (setq i 0)
         (while (/= "=" (substr line (setq i (1+ i)) 1)))
         (setq sub (cons (list (substr line 1 (1- i)) (substr line (1+ i))) sub))
         )
         ( (setq sub (cons (list line) sub)) )
       )
   )
   (close file)
   (if sub (setq lst (cons (reverse sub) lst)))
   )
)
(reverse lst)
)
 
 
2) pz:INI获取
如果节为零,则返回节名称列表。
如果key为nil,则返回指定节的键列表。
如果未找到键,则返回默认值。
否则,将返回与键关联的字符串。
 
(defun pz:INI-Get ( file section key default / alist res )
(if
   (and
   (=(type file) 'STR)
   (setq alist (pz:INI-Read file))
   )
   (cond
   ( (not section)
       (foreach %1 alist
         (if (= (type (car %1)) 'STR)
         (setq res (cons (car %1) res))
         )
       )
       (reverse res)
   )
   ( (and (not key) (assoc section alist))
       (foreach %2 (cdr(assoc section alist))
         (if (= (length %2) 2)
         (setq res (cons (car %2) res))
         )
       )
       (reverse res)
   )
   ( (setq section (cdr (assoc section alist)))
       (if (setq res (assoc key section))
         (setq res (cadr res ))
         (setq res default)
       )
       res
   )
   )
   nil
)
)
 
3) pz:INI集
节:包含给定数据节名称的字符串。如果该节不存在,则将创建该节。
键:包含要与值关联的键的名称的字符串。如果给定部分中不存在密钥,
它将被创建。
(defun pz:INI-Set ( file section key value / alist sectionl i )
(if
   (and
   (=(type file) 'STR)
   (=(type section) 'STR)
   (=(type key) 'STR)
   (=(type value) 'STR)
   (setq alist (pz:INI-Read file))
   )
   (progn
   (if (setq sectionl (assoc section alist))
       (setq
         sectionl (cdr sectionl)
         sectionl
         (if (assoc key sectionl)
         (subst (list key value) (assoc key sectionl) sectionl)
         ;(reverse (append (list(list key value)) (reverse sectionl) ))
         (progn
             (setq i (1-(length sectionl)))
             (while (= (length(nth i sectionl)) 1)
               (setq i (1- i))
             )
             (cd:LST_InsertItem (1+ i) sectionl (list key value))
         )
         )
         alist (subst (cons section sectionl) (assoc section alist) alist)
       )
       (setq alist (reverse (append (list(list section (list key value))) (reverse alist) )))
   )
   (if (and (setq file (findfile file)) (setq file (open file "w")))
       (progn
         (foreach section alist
         (if (= (type (car section)) 'STR)
             (progn
               (write-line (strcat "[" (car section) "]") file)
               (foreach key (cdr section)
               (write-line (if (cadr key) (strcat (car key) "=" (cadr key)) (car key)) file)
               )
             )
             (foreach key section
               (write-line (if (cadr key) (strcat (car key) "=" (cadr key)) (car key)) file)
             )
         )
         )
         (not (close file))
       )
   )
   )
   nil
)
)
 
4) pz:INI Del
正在进行中
 
 
需要一个子例程
(defun cd:LST_InsertItem (Pos Lst New / res)
(if (< -1 Pos (1+ (length Lst)))
   (progn
   (repeat Pos
       (setq res (cons (car Lst) res)
             Lst (cdr Lst)
       )
   )
   (append (reverse res) (list New) Lst)
   )
   Lst
)
)

ziele_o2k 发表于 2022-7-5 17:55:39

好的,我希望这是最终结果
它应该如何工作:
-函数将保留ini文件格式(制表符/空格)
-节和kay名称不区分大小写
-评论可以从开始;或#
ini文件示例(要测试我的*ini*功能,请在cad搜索路径中创建文件Example.ini):
 
#I hope

#it will be


KEY1= VALUE 1_1
   ;useful
KEY2=
KEY3= VALUE 1_3

   
KEY1 = VALUE 2_1
KEY2    = VALUE 2_2
KEY3=VALUE 2_3

KEY1=VALUE 3_1
KEY2=VALUE 3_2
   
KEY3=VALUE 3_3
             
KEY1    =   VALUE 4_1
KEY2    =   VALUE 4_2
KEY3    =   VALUE 4_3
;for someone
 
My*ini*函数(基于第三篇文章中给出的源代码)
 
; =========================================================================================== ;
; (pz:INI-Get file section key value)                                                         ;
;file       - short or full path file name                                           ;
;section - name of section to read key                                          ;
;                      if nil then function will return all section names from .ini file      ;
;key    - name of key to read value                                              ;
;                      if nil then function will return all key names from section            ;
;                      if key value is "" then returns nil                                    ;
;value    - default value if section or key not found                              ;
; ------------------------------------------------------------------------------------------- ;
; (pz:INI-Get "example.ini" "SECTION1" "KEY2" nil)                                          ;
; =========================================================================================== ;
(defun pz:INI-Get ( file section key value / l res tmpl )
(if (and section (=(type section) 'STR))
   (setq section (strcat "[" section "]"))
)
(if (setq l (pz:INI-Read file))
   (cond
   ( (not section)
       (foreach %1 l
         (if (= (type (car %1)) 'STR)
         (setq res
             (cons
               (substr
               (pz:TrimStr (car %1))
               2
               (- (strlen (pz:TrimStr (car %1))) 2)
               )
               res
             )
         )
         )
       )
       (setq res (reverse res))
   )
   ( (and
         (not key)
         (setq tmpl (pz:AssocCI section l))
       )
       (foreach %1 (cdr tmpl)
         (if (= (length %1) 2)
         (setq res (cons (pz:TrimStr(car %1)) res))
         )
       )
       (setq res (reverse res))
   )
   ( (and
         key
         (setq section (cdr (pz:AssocCI section l)))
       )
       (if (setq res (pz:AssocCI key section))
         (if (= (setq res (pz:TrimStr(cadr res))) "")
         (setq res nil)
         )
         (setq res value)
       )
   )
   ( T (setq res value))
   )
   (setq res value)
)
res
)
; =========================================================================================== ;
; (pz:INI-Set file section key value)                                                         ;
;file    - short or full path file name                                             ;
;section - name of section to set key value                                           ;
;key    - name of key to set value                                                   ;
;value    - value to set                                                               ;
; ------------------------------------------------------------------------------------------- ;
; If section not found then function will create section with given key and value             ;
; If key in given section not found, function will create key with supplied value in section;
; ------------------------------------------------------------------------------------------- ;
; (pz:INI-Set "example.ini" "SECTION1" "KEY2" "Value 1_2")                                    ;
; =========================================================================================== ;
(defun pz:INI-Set ( file section key value / l sl fvalue i )
(if
   (and
   (=(type file) 'STR)
   (=(type section) 'STR)
   (=(type key) 'STR)
   (=(type value) 'STR)
   (setq section (strcat "[" section "]"))
   (setq l (pz:INI-Read file))
   )
   (progn
   (if (setq sl (pz:AssocCI section l))
       (setq
         sl (cdr sl)
         sl
         (if (pz:AssocCI key sl)
         (progn
             (setq
               fvalue (vl-string-subst value (pz:TrimStr(cadr(pz:AssocCI key sl))) (cadr(pz:AssocCI key sl)))
             )
             (subst
               (list (car(pz:AssocCI key sl)) fvalue)
               (pz:AssocCI key sl)
               sl
             )
         )
         (progn
             (setq i (1-(length sl)))
             (while (= (length(nth i sl)) 1)
               (setq i (1- i))
             )
             (cd:LST_InsertItem (1+ i) sl (list key value))
         )
         )
         l (subst (cons (car(pz:AssocCI section l)) sl) (pz:AssocCI section l) l)
       )
       (setq l (reverse (append (list(list (car(pz:AssocCI section l)) (list key value))) (reverse l) )))
   )
   (if (and (setq file (findfile file)) (setq file (open file "w")))
       (progn
         (foreach %1 l
         (if (= (type (car %1)) 'STR)
             (progn
               (write-line (car %1) file)
               (foreach key (cdr %1)
               (write-line (if (cadr key) (strcat (car key) "=" (cadr key)) (car key)) file)
               )
             )
             (foreach key %1
               (write-line (if (cadr key) (strcat (car key) "=" (cadr key)) (car key)) file)
             )
         )
         )
         (not (close file))
       )
   )
   )
   nil
)
)
; =========================================================================================== ;
; (pz:INI-Del file section key value)                                                         ;
;file       - short or full path file name                                           ;
;section    - name of section to delete key or key value                           ;
;key    - name of key to delete value or key                                     ;
;                      if nil then function will delete whole section with all it's keys      ;
;                      but will leave comments                                                ;
;value      - nil - delete key with value                                          ;
;                      T   - delete only value of given key                                 ;
; ------------------------------------------------------------------------------------------- ;
; (pz:INI-Del "example.ini" "SECTION4" "KEY2" nil)                                          ;
; =========================================================================================== ;

(defun pz:INI-Del ( file section key value / l sectionlst sectionl)
(if
   (and
   (=(type file) 'STR)
   (if (and section (=(type section) 'STR))
       (setq section (strcat "[" section "]"))
       nil
   )
   (setq l (pz:INI-Read file))
   )
   (cond
   ( (not key)
       (setq
         sectionlst (pz:AssocCI section l )
         sectionlst
         (vl-remove-if-not
         '(lambda (%1)
             (if (=(type %1) 'LIST)
               (=(length %1) 1)
               nil
             )
         )
         sectionlst
         )
         l (subst sectionlst (pz:AssocCI section l) l)
       )
   )
   ( (not value)
       (if
         (and
         (setq
             sectionl (cdr(pz:AssocCI section l ))
         )
         (pz:AssocCI key sectionl)
         )
         (setq
         sectionl (vl-remove (pz:AssocCI key sectionl) sectionl)
         l (subst (cons (car(pz:AssocCI section l)) sectionl) (pz:AssocCI section l) l)
         )
       )
   )
   ( T
       (if
         (and
         (setq
             sectionl (cdr(pz:AssocCI section l ))
         )
         (pz:AssocCI key sectionl)
         )
         (setq sectionl
         (subst
             (list (car(pz:AssocCI key sectionl)) "")
             (pz:AssocCI key sectionl)
             sectionl
         )
         l (subst (cons (car(pz:AssocCI section l)) sectionl) (pz:AssocCI section l) l)
         )
       )
   )
   )
)
(if (and (setq file (findfile file)) (setq file (open file "w")))
   (progn
   (foreach %1 l
       (if (= (type (car %1)) 'STR)
         (progn
         (write-line (car %1) file)
         (foreach key (cdr %1)
             (write-line (if (cadr key) (strcat (car key) "=" (cadr key)) (car key)) file)
         )
         )
         (foreach key %1
         (write-line (if (cadr key) (strcat (car key) "=" (cadr key)) (car key)) file)
         )
       )
   )
   (not (close file))
   )
)
)
要运行
pz:INI-Get/pz:INI-Set/pz:INI-Del
必须加载这些子程序
; =========================================================================================== ;
; Subroutines                                                                                 ;
; =========================================================================================== ;
(defun pz:TrimStr ( s )
(vl-string-trim " \t" s)
)
(defun pz:AssocCI (e l / )
(vl-some
   '(lambda (%1)
   (if
       (and
         (= (type (car %1)) 'STR)
         (= (strcase e) (strcase (pz:TrimStr(car %1) )) )
       )
       %1
   )
   )
   l
)
)
(defun pz:INI-Read ( f / l res sub i )
(if
   (and
   (setq l (cd:SYS_ReadFile nil f))
   (= (type l) 'LIST)
   )
   (progn
   (foreach %1 l
       (cond
         ( (and
             (/= (substr (pz:TrimStr %1) 1 1) ";")
             (/= (substr (pz:TrimStr %1) 1 1) "#")
             (wcmatch (pz:TrimStr %1) "`[*`]")
         )
         (if sub
             (setq res (cons (reverse sub) res))
         )
         (setq sub (list %1))
         )
         ( (and
             (/= (substr (pz:TrimStr %1) 1 1) ";")
             (/= (substr (pz:TrimStr %1) 1 1) "#")
             (wcmatch %1 "*=*")
         )
         (setq i 0)
         (while (/= "=" (substr %1 (setq i (1+ i)) 1)))
         (setq sub (cons (list (substr %1 1 (1- i)) (substr %1 (1+ i))) sub))
         )
         ((setq sub (cons (list %1) sub)))
       )
   )
   (if sub (setq res (cons (reverse sub) res)))
   )
)
(reverse res)
)

; =========================================================================================== ;
; Subroutines from:                                                                           ;
; CADPL-Pack-v1.lsp                                                                           ;
; =========================================================================================== ;

; =========================================================================================== ;
; Czyta plik tekstowy / Read a text file                                                      ;
;Line - INT = numer linii pliku / file line number                              ;
;                   nil = caly plik / all lines of file                                       ;
;File    - nazwa pliku (krotka lub ze sciezka) / short or full path file name      ;
; ------------------------------------------------------------------------------------------- ;
; Zwraca / Return:                                                                            ;
;   nil = gdy Line = INT wieksze niz ilosc linii w pliku lub plik jest pusty /                ;
;         when Line = INT is greater then number of lines in file or file is empty            ;
;   0 = brak dostepu do pliku / no access to file                                           ;
;    -1 = nie znaleziono pliku / file not found                                             ;
;   STR = gdy Line = INT / when Line = INT                                                    ;
;LIST = gdy Line = nil / when Line = nil                                                    ;
; ------------------------------------------------------------------------------------------- ;
; (cd:SYS_ReadFile nil "data.ini"), (cd:SYS_ReadFile 10 "acad.lin")                           ;
; =========================================================================================== ;
(defun cd:SYS_ReadFile (Line File / fn fd l res)
(if (setq fn (findfile File))
   (if (setq fd (open fn "r"))
   (progn
       (if Line
         (progn
         (repeat Line (read-line fd))
         (setq res (read-line fd))
         )
         (progn
         (setq l T)
         (while l
             (setq res
               (cons
               (setq l (read-line fd))
               res
               )
             )
         )
         (setq res (reverse (cdr res)))
         )
       )
       (close fd)
   )
   (setq res 0)
   )
   (setq res -1)
)
res
)
; =========================================================================================== ;
; Wstawia nowy element na liste / Inserts a new item in the list                              ;
;Pos - pozycja elementu / element position                                           ;
;Lst - lista wejsciowa / input list                                                ;
;New - nowy element / new item                                    ;
; ------------------------------------------------------------------------------------------- ;
; (cd:LST_InsertItem 3 (list 0 1 2 4 5) 3)                                                    ;
; =========================================================================================== ;
(defun cd:LST_InsertItem (Pos Lst New / res)
(if (< -1 Pos (1+ (length Lst)))
   (progn
   (repeat Pos
       (setq res (cons (car Lst) res)
             Lst (cdr Lst)
       )
   )
   (append (reverse res) (list New) Lst)
   )
   Lst
)
)
页: [1]
查看完整版本: 使用lisp cha处理INI文件