Jump to content

Recommended Posts

Posted (edited)

Hello everyone, I need advice why is something happening that I can't explain. So, I have multiple of lisps (55), that I usually add to one VLX app for faster loading, but I can't add lisps that create dcl files from inside lisp, cause they aren't found when in runtime. I even added pause (while (not (findfile dclfile))) at the end of function that writes dcl file. It all works normal when loading only one lisp with dcl creation or even vlx from just one lisp, but when combined multiple of lisps, then it doesn't.

Edited by Tomislav
Posted

Why not use "dcl2lsp.lsp" to convert *.dcl to *.lsp which you can add to your main *.lsp that is to be compiled into *.VLX... Here is what I suggest (c:dcl2lsp)...

 

(defun c:dcl2lsp ( / fname1 fn1 fname2 fn2 k fn1l fn2l )
  (setq fname1 (getfiled "Select DCL file" "" "dcl" 16))
  (setq fn1 (open fname1 "r"))
  (setq fname2 (getfiled "File to save" "" "lsp" 1))
  (setq fn2 (open fname2 "w"))
  (while (setq fn1l (read-line fn1))
    (setq fn2l fn1l)
    (setq k 0)
    (while (setq k (vl-string-search "\\" fn2l k))
      (setq fn2l (vl-string-subst "\\\\" "\\" fn2l k)) 
      (setq k (+ k 2))
    )
    (setq k 0)
    (while (setq k (vl-string-search "\"" fn2l k))
      (setq fn2l (vl-string-subst "\\\"" "\"" fn2l k)) 
      (setq k (+ k 2))
    )
    (setq fn2l (strcat "(write-line \"" fn2l "\" fn)"))
    (write-line fn2l fn2)
  )
  (close fn1)
  (close fn2)
  (princ)
)

(defun c:lsp2dcl ( / fname1 fn1 fname2 fn2 k fn1l fn2l )
  (setq fname1 (getfiled "Select LSP file" "" "lsp" 16))
  (setq fn1 (open fname1 "r"))
  (setq fname2 (getfiled "File to save" "" "dcl" 1))
  (setq fn2 (open fname2 "w"))
  (while (setq fn1l (read-line fn1))
    (setq fn2l fn1l)
    (setq fn2l (substr fn2l (+ (vl-string-search "\"" fn2l) 2) (- (vl-string-position (ascii "\"") fn2l nil T) (+ (vl-string-search "\"" fn2l) 1)))) 
    (setq k 0)
    (while (setq k (vl-string-search "\\\"" fn2l k))
      (setq fn2l (vl-string-subst "\"" "\\\"" fn2l k)) 
      (setq k (+ k 1))
    )
    (setq k 0)
    (while (setq k (vl-string-search "\\\\" fn2l k))
      (setq fn2l (vl-string-subst "\\" "\\\\" fn2l k)) 
      (setq k (+ k 1))
    )
    (write-line fn2l fn2)
  )
  (close fn1)
  (close fn2)
  (princ)
)

(defun c:viewdcl ( / dclid return# filen fn lin )
  (setq dclid (load_dialog (setq filen (getfiled "" "" "dcl" 16))))
  (setq fn (open filen "r"))
  (while (or (eq (substr (setq lin (read-line fn)) 1 2) "//") (eq (substr lin 1 (vl-string-search " " lin)) "") (not (eq (substr lin (+ (vl-string-search " " lin) 1) 9) " : dialog"))))
  (new_dialog (substr lin 1 (vl-string-search " " lin)) dclid)
  (action_tile "accept" "(done_dialog 1)")
  (action_tile "cancel" "(done_dialog 0)")
  (setq return# (start_dialog))
  (princ return#)
  (unload_dialog dclid)
  (princ)
)

 

  • Like 1
Posted

Like @marko_ribar I use a convert to lisp by RLX. I use it to make custom dcl's, taking advantage of my Multi xxx lisps to write a dcl. Then convert it to lisp. Then just use notepad etc to add the dcl to your code. Speaking of that did you know you can have one dcl with multiple dcl's inside of it, You just load the master and call the sub dcl.

 

Just a comment if you bomb a lisp with a dcl made using Mktemp it will leave the temporary dcl behind, just check your temp directory you may be horrified to see how many are there along with SV$, dwl, AC$ and more. Options File "Save File Path" "temporary Prefix" So having a (vl-file-delete fname) in code and in Error trap is a good idea. Yes have a cleanup lisp.

 

(setq *files*  (vla-get-files  (vla-get-preferences (vlax-get-Acad-object))))
(setq pre (vla-get-TempFilePath *files*))

 

image.png.c87fe2dc09da70f1ddde39abdba70b94.png

 

Convert dcl 2 lisp rlx.lsp

  • Like 1
Posted

thank you all for answers, I create dcl inside lisp like this :

(defun tv:write-dcl (dclfile / )
  (setq dclcontent
    (strcat
      "coord_dialog : dialog {\n"
      "  label = \"Loading options\";\n"
      "  : column {\n"
      "    : boxed_column {\n"
      "      label = \"Coordinate order\";\n"
      "      : radio_column {\n"
      "		key = \"coord_order\";\n"
      "        : radio_button { key = \"coord_order_y\"; label = \"Y,X,Z\"; }\n"
      "        : radio_button { key = \"coord_order_x\"; label = \"X,Y,Z\"; }\n"
      "      }\n"
      "    }\n"
      "    : boxed_column {\n"
      "      label = \"Do points have name/number?\";\n"
      "      : radio_column {\n"
      "		key = \"pt_name\";\n"
      "        : radio_button { key = \"point_numbering_y\"; label = \"Yes\"; }\n"
      "        : radio_button { key = \"point_numbering_n\"; label = \"No\"; }\n"
      "      }\n"
      "    }\n"
      "     : boxed_column {\n"
      "      label = \"Select delimiter\";\n"
      "	  : radio_column {\n"
      "		key = \"delimiter_choice\";\n"
      "        : radio_button { key = \"del_c\"; label = \"Comma\"; }\n"
      "        : radio_button { key = \"del_sc\"; label = \"Semicolon\"; }\n"
      "        : radio_button { key = \"del_s\"; label = \"Space\"; }\n"
      "        : radio_button { key = \"del_t\"; label = \"Tab\"; }\n"
      "      }\n"
      "    }\n"
      "    : boxed_column {\n"
      "      label = \"Display settings\";\n"
      "      : edit_box {\n"
      "        key = \"text_height\";\n"
      "        label = \"Text height:\";\n"
      "        value = \"0.75\";\n"
      "      }\n"
      "      : edit_box {\n"
      "        key = \"rounding\";\n"
      "        label = \"Rounding:  \";\n"
      "        value = \"2\";\n"
      "      }\n"
      "    }\n"
      "ok_cancel;\n"
      "  }\n"
      "    : column {\n"
      "        alignment = centered;\n"
      "        : text {\n"
      "            label = \"Lisp by Tomislav Vargek\";\n"
      "            alignment = centered;\n"
      "            fixed_width = true;\n"
      "        }\n"
      "        : text {\n"
      "            label = \"  Copyright © 2025\";\n"
      "            alignment = centered;\n"
      "            fixed_width = true;\n"
      "        }\n"
      "    }\n"
      "}\n"
      )
  )  
  (setq f (open dclfile "w"))
  (write-line dclcontent f)
  (setq f(close f))
  (while (not (findfile dclfile)))
  dclfile
)

 

and using Lee's function to avoid clutter like you Bigal said in temp

(defun lm:getsavepath ( / tmp );LeeMac
    (cond      
        (   (setq tmp (getvar 'roamablerootprefix))
            (strcat (lm:fixdir tmp) "\\Support")
        )
        (   (setq tmp (findfile "acad.pat"))
            (lm:fixdir (vl-filename-directory tmp))
        )
        (   (lm:fixdir (vl-filename-directory (vl-filename-mktemp))))
    )
)

 

I know about compiling together dcl and lisp like you said SLW, but that is not the way I'm doing here, and I will investigate this approach like you Marko, but the issue is my lisp works and I saw many from others using this approach of creating dcl that work (one of lisps that I combine in my vlx is Lee's NUMInc and it works when called).

When I load just it, in lsp or vlx form, it works, but when I compile many lisps in one vlx and then load it, then calling my lisp doesn't work, and it's like that with all my lisps that create dcl from inside lsp file.

That is frustrating, knowing lisps work, but something in compiling multiple lisps makes them doesn't work.

Posted

Might not be the exact answer, but who are you protecting the LISP from to make a compiled file?

 

In my company the LISPs I create in their time I guess are company property and so are not compiled, open for them all to look at and use. The only time I'd think about compiling a LISP is if it went out the company... and then the customer would be paying and so I think should have access to the code they paid for.

 

 

Anyway, a step backwards, if it all works uncompiled then do you need to compile it?

Posted

Having said that though, I usually go with Marko / Big Al and have the DCL code nested within the LISP is it used with, might be the solution you need

Posted

Are you repeating variable names and/or keys?

 

Maybe something in this old thread.

 

Posted

@Steven P I'm not doing it for company , and I will try what they suggested ...

@SLW210 that's very usefull thread for some new view on things, thanx...

  • Like 1
Posted

just found out when I execute one lisp it creates dcl with correct name but with contents for dcl from another lisp, so something with same dcl file name definitions or something

  • Like 1
Posted

Might be a bit of old fashioned hard work, go through them all to check for unique names of DCS file (not so important) but functions names. Also handy while you are doing that to check all variables are localised and so on. Sorry but I don't have any handy LISPs to help you out with this one too handy - I'll see if I can copy one over for you for later... a bit buggy though.

Posted (edited)

Findstring may be your friend, its a window cmd you type cmd down left to go to command mode of windows. I have a bat file setup so type "fnd Ahgetvalsm" it goes to my lisp directory then runs this command.

 

Findstring ahgetvalssm *.lsp

 

It looks through all my lsp files for a match so in your case look into *.dcl for a dialog name if it comes up with two then you have a problem. Yes no quick way to get each dialog name. As suggested by @Steven P you could open every file lsp & dcl and reading a line at a time, look for "dialog" and save that line file name to a list when found. I guess then can run bat files from lisp so use Findstring.

 

image.thumb.png.ab006b6e615b94fd377fea35885f7550.png

Edited by BIGAL
  • Like 1
Posted

thank you both, what I've found is that in all lisps I use same name for function that creates dcl files (defun tv:write-dcl (dclfile / ) so had to change each to be uniqe, seems that when putting multiple lisps in vlx, some functions can't be named the same ...

Posted
28 minutes ago, Tomislav said:

thank you both, what I've found is that in all lisps I use same name for function that creates dcl files (defun tv:write-dcl (dclfile / ) so had to change each to be uniqe, seems that when putting multiple lisps in vlx, some functions can't be named the same ...

This is critical: any public 'defun' must have a unique name. If not, during loading, the latest one will overwrite the previous ones and be the one executed in all cases.

Posted

Create all dcl files in a folder that's part of your support path.

I assume the dcl name follows the lisp name so if your lsp is named "MyLsp_01.lsp" your dcl is name "MyLsp_01.dcl".

All my lsp's are saved in c:\temp\lisp\.

So when you write your dcl the code would be something like :

           (if (and (setq fn "c:\temp\lisp\MyLsp_01.dcl") (setq fp (open fn "w")) (write-line (strcat ....) fp))

 

I believe there is a max to how long a string can be so I always put the lines in a list and write them seperately.

 

After you close your filepointer use command (GC) , that is garbage collection and flushes your cache.

Your vlx migh be too fast and try to load your dcl before it was saved.

 

when loading dcl , you could use something like (if (setq dcl-fn (findfile "MyLsp_01.dcl")) ...

 

  • Like 1
Posted (edited)

If you convert your dcl code to lisp code then you don't need a file name. You use the "fname" for the file name temporary dcl files are made, these should be  auto deleted and I make sure I do a Vl-delete-file after closing the dcl as a extra step.

 

(setq fo (open (setq fname (vl-filename-mktemp "" "" ".dcl")) "w"))

 

The mktemp will make a new file every time you run the dcl code so no 2 files have the same name.

Edited by BIGAL
  • Like 1
Posted

.... though knowing I forget to clear out my temp folder I'll often specify a unique temporary file name for each new DCL - each time the DCL runs it will overwrite the same

 

 

(setq fo (open (setq fname (vl-filename-mktemp "DCL_File_Name" (getvar "TEMPPREFIX") ".dcl")) "w"))

 

I can't remember why I started specifying (getvar "TEMPPREFIX") in there, it fixed a problem once though.

 

 

 

Which reminds me, BigAls code o clear out the temporary file, think I'll do that again today

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