LISP : Comparing strings from 2 text files in a auto-updater for acad.pgp

LISP : Comparing strings from 2 text files in a auto-updater for acad.pgp

cyberflow
Advisor Advisor
1,335 Views
7 Replies
Message 1 of 8

LISP : Comparing strings from 2 text files in a auto-updater for acad.pgp

cyberflow
Advisor
Advisor

Hi,

I've done a little lisp that compares my custom shortcuts for PGP (PGP-ENU.txt and PGP-FRA.txt) and appends it to my acad.pgp.

Now it doesn't seem to compare correctly both depending on the language used (pulls out "enu" or "fra" in the path of acad.pgp) and appends to acad.pgp the correct PGP-*.txt file.

Now my code keeps always appending the PGP-*.txt files in acad.pgp even if both endings are identical

Is there anything specific thing that needs to be done to compare several text lines in a text file ?


Here's the source :

 

 

 

 

;; Script AutoLISP pour gérer les raccourcis acad.pgp et ajouter des lignes selon la langue
;; Variables pour les fichiers de langues
(setq file-fra "C:\\temp\\PGP-FRA.txt")  ;; Fichier pour le français
(setq file-enu "C:\\temp\\PGP-ENU.txt")  ;; Fichier pour l'anglais

(defun detect-language-and-setup-files ()
  (setq pgppath (findfile "acad.pgp"))  ;; Using pgppath consistently
  (if pgppath
      (progn
        (prompt (strcat "Fichier acad.pgp trouvé à : " pgppath "\n"))
        (prompt (strcat "Chemin converti en majuscules : " (strcase pgppath) "\n"))
        (cond ((vl-string-search "FRA" (strcase pgppath))
               (setq language-file file-fra)  ;; Fichier pour le français
               (prompt "Langue détectée : Français\n"))
              ((vl-string-search "ENU" (strcase pgppath))
               (setq language-file file-enu)  ;; Fichier pour l'anglais
               (prompt "Langue détectée : Anglais\n"))
              (t
               (setq language-file nil)
               (prompt "Langue inconnue : aucune action prise\n"))))
      (prompt "Fichier acad.pgp introuvable\n")))

(defun read-last-n-lines (filename n)
  (setq lines '())  ;; Initialize an empty list for lines
  (setq result '())  ;; Initialize an empty list for result
  (if (and filename (findfile filename))
      (progn
        (prompt (strcat "Ouverture du fichier : " filename "\n"))
        (setq file (open filename "r"))  ;; Open the file for reading
        (if file
            (progn
              (prompt "Lecture du fichier...\n")
              (while (setq line (read-line file))  ;; Ensure read-line is used correctly
                (setq lines (cons line lines)))  ;; Collect lines in reverse order
              (close file)  ;; Close the file after reading
              ;; Get the last n lines manually
              (setq lines (reverse lines))  ;; Reverse the list to get the correct order
              (setq result (if (<= n (length lines))
                               (mapcar (function (lambda (x) (nth x lines))) (iota n))  ;; Get last n lines
                               lines))  ;; If fewer than n lines, return all lines
              (prompt (strcat "Dernières lignes lues : " (apply 'strcat (mapcar 'strcat result)) "\n")))  ;; Debugging output
            (prompt "Erreur lors de l'ouverture du fichier.\n")))
      (prompt (strcat "Fichier introuvable : " filename "\n")))
  result)

;; Helper function to generate a list of numbers from 0 to n-1
(defun iota (n)
  (if (< n 1)
      nil
      (cons (- n 1) (iota (- n 1)))))

(defun clean-string (str)
  ;; Remove leading and trailing spaces, tabs, and newlines from the string
  (vl-string-trim "\n" (vl-string-trim "\t" (vl-string-trim " " str))))

(defun compare-last-n-lines (file1 file2 n)
  (let* ((lines1 (mapcar 'clean-string (read-last-n-lines file1 n)))
         (lines2 (mapcar 'clean-string (read-last-n-lines file2 n))))
    (prompt (strcat "Lignes de " file1 " : " (apply 'strcat (mapcar 'strcat lines1)) "\n"))
    (prompt (strcat "Lignes de " file2 " : " (apply 'strcat (mapcar 'strcat lines2)) "\n"))
    (equal lines1 lines2)))

(defun backup-and-append (source target)
  (if (and (findfile source) (findfile target))
      (progn
        (prompt (strcat "Fichier source trouvé : " source "\n"))
        (prompt (strcat "Fichier cible trouvé : " target "\n"))
        (setq timestamp (vl-string-right-trim "\n" (rtos (getvar "cdate") 2 0)))
        (setq backup-name (strcat (vl-filename-directory target) "\\" 
                                  (vl-filename-base target) "-" timestamp 
                                  (vl-filename-extension target)))
        ;; Créer une sauvegarde
        (vl-file-copy target backup-name)
        (prompt (strcat "Sauvegarde créée : " backup-name "\n"))
        ;; Ajouter le contenu
        (setq in (open source "r"))  ;; Open the source file for reading
        (setq out (open target "a"))  ;; Open the target file for appending
        (if (and in out)
            (progn
              (prompt "Ajout des lignes dans le fichier cible...\n")
              (while (not (eq (setq line (read-line in)) nil))
                (if (and line (not (null line)))
                    (write-line (strcat line) out)))  ;; Write each line from the source file to the target file
              (close in)
              (close out)
              (prompt "Contenu ajouté avec succès.\n"))
            (prompt "Erreur lors de l'ouverture des fichiers.\n")))
      (prompt "Un des fichiers est introuvable\n")))

(defun check-and-append ()
  (setq pgppath (findfile "acad.pgp"))  ;; Using pgppath consistently
  (if pgppath
      (progn
        (prompt (strcat "Fichier acad.pgp trouvé à : " pgppath "\n"))
        (if language-file
            (progn
              (setq pgp-lines (mapcar 'clean-string (read-last-n-lines pgppath 3)))
              (prompt (strcat "Dernières lignes de acad.pgp lues : " (apply 'strcat (mapcar 'strcat pgp-lines)) "\n"))
              (setq lang-lines (mapcar 'clean-string (read-last-n-lines language-file 3)))
              (prompt (strcat "Dernières lignes du fichier de langue lues : " (apply 'strcat (mapcar 'strcat lang-lines)) "\n"))
              (if (equal pgp-lines lang-lines)
                  (prompt "Les 3 dernières lignes sont identiques. Aucune modification nécessaire.\n")
                  (progn
                    (prompt "Les lignes diffèrent, ajout nécessaire.\n")
                    (backup-and-append language-file pgppath))))
            (prompt "Fichier de langue introuvable.\n")))
      (prompt "Fichier acad.pgp introuvable.\n")))

;; Exemple d'utilisation
(detect-language-and-setup-files)
(check-and-append)

(setvar "RE-INIT" 16)
(prompt "Mise a jour PGP effectue\n")

 

 

 

 

 We can see the last lines in both files are the same ... 

cyberflow_0-1737411776897.png

 



For the curious ones, i'm doing this cause i'm tired of going to do copy paste and updating this each time i reinstal Autocad.

LinkedIn  - Frank Freitas - CAE/CAD/BIM Coordinator & Support Specialist

Autodesk Civil 3D Certified Professional

0 Likes
Accepted solutions (2)
1,336 Views
7 Replies
Replies (7)
Message 2 of 8

Sea-Haven
Mentor
Mentor

There is an oldfashioned dos command "copy file1+file2 file3" this could be ran as a shell command from CAD, rename the acadpgp after making file3, then rename file3 to acadpgp. The pgp is in a known location. 

 

Like you I have a setup lisp that does lots of stuff after an upgrade. Is it easier the way I would approach to have a custom startup lisp with all the shorctuts defined in it and gets loaded via Appload, Startup suite. Mine has 37 defuns some programs, some 1 liner shortcuts. I try and leave anything to do with out the box alone.

Message 3 of 8

cyberflow
Advisor
Advisor

@Sea-Haven Hi there, really a nice approach to this but i'd have the same problem.

Is your script running at each time autocad is launched ?
If it's launched at each launch, how do you manage to prevent it to copy the file if it's already done ?


LinkedIn  - Frank Freitas - CAE/CAD/BIM Coordinator & Support Specialist

Autodesk Civil 3D Certified Professional

0 Likes
Message 4 of 8

Moshe-A
Mentor
Mentor

@cyberflow hi,

 

i do not use (equal) to compare strings, i think this is where the compare fails. replace it with '=' or (eq)

AutoLISP has not (let* ) function (on line #57) 😀

 

to get more help, post your txt + files

 

Moshe

 

0 Likes
Message 5 of 8

cyberflow
Advisor
Advisor
Accepted solution

Hi @Moshe-A !

I did found the error with some help from VovKa on TheSwamp forum !

 
Basicly i needed to remove this line : "(setq lines (reverse lines))"

It was always comparing two different list one was reversed and the other one not.

The code works correctly now.

LinkedIn  - Frank Freitas - CAE/CAD/BIM Coordinator & Support Specialist

Autodesk Civil 3D Certified Professional

0 Likes
Message 6 of 8

Sea-Haven
Mentor
Mentor

When you use Appload you save the lsp to the "Startup Suite" so it gets loaded every time you open a dwg. You would only have your custom shortcuts in the custom lsp file. 

Examples

(defun c:od () ;;opens new  dwg in current dwg  directory
(startapp "explorer" (getvar "dwgprefix"))
(princ)
)

(defun C:FD () (setvar "filedia" 1))

(defun C:j ()(command "Pedit" "J"))

 

 

Message 7 of 8

cyberflow
Advisor
Advisor

Thx for the tip @Sea-Haven 

LinkedIn  - Frank Freitas - CAE/CAD/BIM Coordinator & Support Specialist

Autodesk Civil 3D Certified Professional

0 Likes
Message 8 of 8

cyberflow
Advisor
Advisor
Accepted solution
;; Script AutoLISP pour gérer les raccourcis acad.pgp et ajouter des lignes selon la langue
;; Variables pour les fichiers de langues
(setq file-fra "C:\\temp\\PGP-FRA.txt")  ;; Fichier pour le français
(setq file-enu "C:\\temp\\PGP-ENU.txt")  ;; Fichier pour l'anglais

(defun detect-language-and-setup-files ()
  (setq pgppath (findfile "acad.pgp"))  ;; Using pgppath consistently
  (if pgppath
      (progn
        (prompt (strcat "Fichier acad.pgp trouvé à : " pgppath "\n"))
        (prompt (strcat "Chemin converti en majuscules : " (strcase pgppath) "\n"))
        (cond ((vl-string-search "FRA" (strcase pgppath))
               (setq language-file file-fra)  ;; Fichier pour le français
               (prompt "Langue détectée : Français\n"))
              ((vl-string-search "ENU" (strcase pgppath))
               (setq language-file file-enu)  ;; Fichier pour l'anglais
               (prompt "Langue détectée : Anglais\n"))
              (t
               (setq language-file nil)
               (prompt "Langue inconnue : aucune action prise\n"))))
      (prompt "Fichier acad.pgp introuvable\n")))

(defun read-last-n-lines (filename n)
  (setq lines '())  ;; Initialize an empty list for lines
  (setq result '())  ;; Initialize an empty list for result
  (if (and filename (findfile filename))
      (progn
        (prompt (strcat "Ouverture du fichier : " filename "\n"))
        (setq file (open filename "r"))  ;; Open the file for reading
        (if file
            (progn
              (prompt "Lecture du fichier...\n")
              (while (setq line (read-line file))  ;; Ensure read-line is used correctly
                (setq lines (cons line lines)))  ;; Collect lines in reverse order
              (close file)  ;; Close the file after reading
              ;; Get the last n lines manually
              (setq result (if (<= n (length lines))
                               (mapcar (function (lambda (x) (nth x lines))) (iota n))  ;; Get last n lines
                               lines))  ;; If fewer than n lines, return all lines
              (prompt (strcat "Dernières lignes lues : " (apply 'strcat (mapcar 'strcat result)) "\n")))  ;; Debugging output
            (prompt "Erreur lors de l'ouverture du fichier.\n")))
      (prompt (strcat "Fichier introuvable : " filename "\n")))
  result)

;; Helper function to generate a list of numbers from 0 to n-1
(defun iota (n)
  (if (< n 1)
      nil
      (cons (- n 1) (iota (- n 1)))))

(defun clean-string (str)
  ;; Remove leading and trailing spaces, tabs, and newlines from the string
  (vl-string-trim "\n" (vl-string-trim "\t" (vl-string-trim " " str))))

(defun compare-last-n-lines (file1 file2 n)
  (let* ((lines1 (mapcar 'clean-string (read-last-n-lines file1 n)))
         (lines2 (mapcar 'clean-string (read-last-n-lines file2 n))))
    (prompt (strcat "Lignes de " file1 " : " (apply 'strcat (mapcar 'strcat lines1)) "\n"))
    (prompt (strcat "Lignes de " file2 " : " (apply 'strcat (mapcar 'strcat lines2)) "\n"))
    (equal lines1 lines2)))

(defun backup-and-append (source target)
  (if (and (findfile source) (findfile target))
      (progn
        (prompt (strcat "Fichier source trouvé : " source "\n"))
        (prompt (strcat "Fichier cible trouvé : " target "\n"))
        (setq timestamp (vl-string-right-trim "\n" (rtos (getvar "cdate") 2 0)))
        (setq backup-name (strcat (vl-filename-directory target) "\\" 
                                  (vl-filename-base target) "-" timestamp 
                                  (vl-filename-extension target)))
        ;; Créer une sauvegarde
        (vl-file-copy target backup-name)
        (prompt (strcat "Sauvegarde créée : " backup-name "\n"))
        ;; Ajouter le contenu
        (setq in (open source "r"))  ;; Open the source file for reading
        (setq out (open target "a"))  ;; Open the target file for appending
        (if (and in out)
            (progn
              (prompt "Ajout des lignes dans le fichier cible...\n")
              (while (not (eq (setq line (read-line in)) nil))
                (if (and line (not (null line)))
                    (write-line (strcat line) out)))  ;; Write each line from the source file to the target file
              (close in)
              (close out)
              (prompt "Contenu ajouté avec succès.\n"))
            (prompt "Erreur lors de l'ouverture des fichiers.\n")))
      (prompt "Un des fichiers est introuvable\n")))

(defun check-and-append ()
  (setq pgppath (findfile "acad.pgp"))  ;; Using pgppath consistently
  (if pgppath
      (progn
        (prompt (strcat "Fichier acad.pgp trouvé à : " pgppath "\n"))
        (if language-file
            (progn
              (setq pgp-lines (mapcar 'clean-string (read-last-n-lines pgppath 3)))
              (prompt (strcat "Dernières lignes de acad.pgp lues : " (apply 'strcat (mapcar 'strcat pgp-lines)) "\n"))
              (setq lang-lines (mapcar 'clean-string (read-last-n-lines language-file 3)))
              (prompt (strcat "Dernières lignes du fichier de langue lues : " (apply 'strcat (mapcar 'strcat lang-lines)) "\n"))
              (if (equal pgp-lines lang-lines)
                  (prompt "Les 3 dernières lignes sont identiques. Aucune modification nécessaire.\n")
                  (progn
                    (prompt "Les lignes diffèrent, ajout nécessaire.\n")
                    (backup-and-append language-file pgppath))))
            (prompt "Fichier de langue introuvable.\n")))
      (prompt "Fichier acad.pgp introuvable.\n")))

;; Exemple d'utilisation
(detect-language-and-setup-files)
(check-and-append)

(setvar "RE-INIT" 16)
(prompt "Mise a jour PGP effectue\n")

The corrected code :

LinkedIn  - Frank Freitas - CAE/CAD/BIM Coordinator & Support Specialist

Autodesk Civil 3D Certified Professional

0 Likes