ziele_o2k Posted January 7, 2017 Posted January 7, 2017 Hey, In my software I'm using ini files. I wrote my own routines to handle them, because I don't like tu use acet/doslib. It would be great if somone would wrote functions simillar to acet-get-ini / acet-set-ini or dos_getini / dos_setini or both... It's just an idea! Unfortunately I don't have time to do that, and (also and more important) i don't need those routines. Although it would be great to have that stuff Maybe some one will take this post as challenge ? EDIT: I can post info about where to find documentation for acet / doslib functions Quote
BIGAL Posted January 7, 2017 Posted January 7, 2017 (edited) Its (defun getini ( filename key / )) write your own version as a rule INI file is just a text file. I have some library text files one has 200+ lines in it and its formatted in a way that you can find the value of a known "Key" eg use a comma seperated you can use TAB also Key1,value1 or by position 12345678901234567890 key1 Value1 Colour Linetype Edited January 7, 2017 by BIGAL Quote
ziele_o2k Posted January 8, 2017 Author Posted January 8, 2017 Ok, based on this Lee Mac's code i wrote something like this: 1) pz:INI-Read Read ini file to formated list - slighty modified XParseConfig by Lee Mac. Semicolons ( ; ) and number signs ( # ) at the beginning of the line indicate a comment. (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-Get If section is nil, a list of section names is returned. If key is nil, a list of keys for the specified section is returned. If key is not found, default is returned. Otherwise, a string associated with key is returned. (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-Set section: A string containing the name of the section for the given data. If the section does not exist, it will be created. key: A string containing the name of the key to be associated with a value. If the key does not exist in the given section, it will be created. (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 In progress one subroutine needed (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 ) ) Quote
ziele_o2k Posted January 26, 2017 Author Posted January 26, 2017 (edited) Ok this is final i hope How should it work: - function will keep ini file formatting (tabs/spaces) - section and kay names are case insensitive - comments can start with ; or # Example of ini file (to test my *ini* functions please create file example.ini in cad search path) : #I hope #it will be [sECTION1] KEY1 = VALUE 1_1 ;useful KEY2 = KEY3 = VALUE 1_3 [sECTION2] KEY1 = VALUE 2_1 KEY2 = VALUE 2_2 KEY3=VALUE 2_3 [sECTION3] KEY1=VALUE 3_1 KEY2=VALUE 3_2 KEY3=VALUE 3_3 [sECTION4] KEY1 = VALUE 4_1 KEY2 = VALUE 4_2 KEY3 = VALUE 4_3 ;for someone My *ini* functions (based on source given in third post) ; =========================================================================================== ; ; (pz:INI-Get file section key value) ; ; file [sTR] - short or full path file name ; ; section [sTR/nil] - name of section to read key ; ; if nil then function will return all section names from .ini file ; ; key [sTR/nil] - 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 [sTR/nil] - 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 [sTR] - short or full path file name ; ; section [sTR] - name of section to set key value ; ; key [sTR] - name of key to set value ; ; value [sTR] - 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 [sTR] - short or full path file name ; ; section [sTR] - name of section to delete key or key value ; ; key [sTR/nil] - 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/T] - 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)) ) ) ) To run pz:INI-Get / pz:INI-Set / pz:INI-Del these Subroutines have to be loaded ; =========================================================================================== ; ; 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/nil] - INT = numer linii pliku / file line number ; ; nil = caly plik / all lines of file ; ; File [sTR] - 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 [iNT] - pozycja elementu / element position ; ; Lst [list] - lista wejsciowa / input list ; ; New [list/INT/REAL/STR/ENAME] - 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 ) ) Edited January 26, 2017 by ziele_o2k Quote
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.