Jump to content

Handle INI files with lisp challenge (without acet)


ziele_o2k

Recommended Posts

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 ?:twisted:

 

EDIT:

I can post info about where to find documentation for acet / doslib functions

Link to comment
Share on other sites

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 by BIGAL
Link to comment
Share on other sites

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
 )
)

Link to comment
Share on other sites

  • 3 weeks later...

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 by ziele_o2k
Link to comment
Share on other sites

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.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...