使用lisp cha处理INI文件
嘿在我的软件中,我使用ini文件。我编写了自己的例程来处理它们,因为我不喜欢使用acet/doslib。如果有人能编写类似于acet get ini/acet set ini或dos\u getini/dos\u setini或两者的函数,那就太好了。。。
这只是一个想法!不幸的是,我没有时间这样做,而且(也是更重要的)我不需要这些常规。虽然有这些东西会很棒
也许有人会把这个职位当成挑战?
编辑:
我可以发布有关在哪里可以找到acet/doslib函数文档的信息 它(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
好啊
基于李的代码,我写了这样的东西:
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
)
) 好的,我希望这是最终结果
它应该如何工作:
-函数将保留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]