Author Topic: (vl-prin1-to-string (quote lst)) = str ; or Strings to evaluate  (Read 1418 times)

0 Members and 1 Guest are viewing this topic.

Grrr1337

  • Swamp Rat
  • Posts: 812
(vl-prin1-to-string (quote lst)) = str ; or Strings to evaluate
« on: February 09, 2017, 04:17:13 AM »
Hi guys,
This task might be like a string manipulation challenge:

I've been reading recently here about vla-SendCommand function and decided to give it a try:
Code - Auto/Visual Lisp: [Select]
  1. (vla-SendCommand (vla-get-ActiveDocument (vlax-get-acad-object)) "CHANGE\n(ssget \"_X\")\n\nP\nC\n1\n\n") ; works
The above sample (to change all objects to color 1) works perfectly, however not in these ways:
Code - Auto/Visual Lisp: [Select]
  1.   "CHANGE
  2.  \n(ssget \"_X\")
  3.  \n
  4.  \nP
  5.  \nC
  6.  \n1
  7.  \n
  8.  \n"
  9. ) ; not working
  10. (vla-SendCommand (vla-get-ActiveDocument (vlax-get-acad-object)) "CHANGE \n (ssget \"_X\") \n \n P \n C \n 1 \n \n") ; not working

Soo after that conclusion I decided to try to input the arguments for the vla-SendCommand, by using vl-prin1-to-string with quote/apostrophe combo:
Code - Auto/Visual Lisp: [Select]
  1.         (quote (CHANGE\n(ssget "_X")\n\nP\nC\n1\n\n))
  2.       )
  3.     )
  4.   )
  5. )
BUT the problem is that the above argument string is:
Code: [Select]
"CHANGE\\\\N (SSGET \"_X\") \\\\N\\\\NP\\\\NC\\\\N1\\\\N\\\\N"While I need it to become like:
Code: [Select]
"change\n(ssget \"_x\")\n\np\nc\n1\n\n"Which means:
1. Somehow substituting the "\\\\" with "\"
2. Remove spaces " "around the syntaxes "()"
3. (strcase ... t) the whole string

Similiarly to a technique for action_tile I learned from Lee Mac, while dealing with DCL - where his genious mind created this fragment from his code:
Code - Auto/Visual Lisp: [Select]
  1. (action_tile "accept"
  2.     '(cond
  3.       (   (not (and (distof len) (< 0.0 (distof len))))
  4.         (set_tile "error" "Please enter a positive numerical length.")
  5.       )
  6.       (   (not (and (distof wid) (< 0.0 (distof wid))))
  7.         (set_tile "error" "Please enter a positive numerical width.")
  8.       )
  9.       (   (done_dialog 1))
  10.     )
  11.   )
  12. )

So my end question would be: Is it possible to reproduce the same string result with vl-prin1-to-string + quote/apostrophe combo like Lee did, without getting lost in string characters?
Say if further I'd want incorporate fragments from a code as a string to become argument for the vla-SendCommand.
Also would be nice to hear your oppinions (2+ heads are better than 1).

BTW The best way I figured out ot deal with this particular problem is to create a string list, and apply strcat to it:
Code - Auto/Visual Lisp: [Select]
  1.     '(
  2.       "CHANGE"
  3.       "\n"
  4.       "(ssget \"_X\")"
  5.       "\n"
  6.       "\nP"
  7.       "\nC"
  8.       "\n1"
  9.       "\n"
  10.       "\n"
  11.     )
  12.   )
  13. )
(apply ''((a b c)(a b c))
  '(
    (( f L ) (apply 'strcat (f L)))
    (( L ) (if L (cons (chr (car L)) (f (cdr L)))))
    (72 101 108 108 111 32 87 111 114 108 100)
  )
)
vevo.bg

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: (vl-prin1-to-string (quote lst)) = str ; or Strings to evaluate
« Reply #1 on: February 09, 2017, 05:13:02 AM »
Two hints:
1.
Try substituting "\n" with " " in your first experiment. This will explain why your second experiment fails.
2.
Instead of:
Code - Auto/Visual Lisp: [Select]
  1. (apply 'strcat '("a" "b" "c"))
You can of course use:
Code - Auto/Visual Lisp: [Select]
  1. (strcat "a" "b" "c")

Grrr1337

  • Swamp Rat
  • Posts: 812
Re: (vl-prin1-to-string (quote lst)) = str ; or Strings to evaluate
« Reply #2 on: February 09, 2017, 05:45:40 AM »
Code: [Select]
(vla-SendCommand (vla-get-ActiveDocument (vlax-get-acad-object)) "CHANGE (ssget \"_X\")  P C 1  "); works
@Roy:
Ooh, I see now! The double-spaces are substituted with single, and if there are any in the end/start of the list are being removed:
Code: [Select]
_$ (quote (CHANGE (ssget "_X")  P C 1  ))
(CHANGE (SSGET "_X") P C 1)
_$
Therefore some partial string manipulation must be performed (to suit this particular string argument) :
Code: [Select]
(vla-SendCommand (vla-get-ActiveDocument (vlax-get-acad-object)) ; works
  (vl-string-subst " P" "P"
    (strcat
      (vl-string-right-trim ")"
        (vl-string-left-trim "("
          (vl-prin1-to-string
            (quote (CHANGE (ssget "_X")  P C 1  ))
          )
        )
      )
      "  "
    )
  )
)

Thanks alot!
P.S. I often overthink the stuff I write, so I often forget that a single strcat function could be used instead of apply 'strcat
...this defect of mine is usually caused of too many list manipulations  :uglystupid2:
(apply ''((a b c)(a b c))
  '(
    (( f L ) (apply 'strcat (f L)))
    (( L ) (if L (cons (chr (car L)) (f (cdr L)))))
    (72 101 108 108 111 32 87 111 114 108 100)
  )
)
vevo.bg

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: (vl-prin1-to-string (quote lst)) = str ; or Strings to evaluate
« Reply #3 on: February 09, 2017, 08:15:58 AM »
In my first hint I was referring to this as the 2nd experiment:
... however not in these ways:
Code - Auto/Visual Lisp: [Select]
  1.   "CHANGE
  2.  \n(ssget \"_X\")
  3.  \n
  4.  \nP
  5.  \nC
  6.  \n1
  7.  \n
  8.  \n"
  9. ) ; not working
  10. (vla-SendCommand (vla-get-ActiveDocument (vlax-get-acad-object)) "CHANGE \n (ssget \"_X\") \n \n P \n C \n 1 \n \n") ; not working
It fails because the characters used to format the code are part of the string that is sent:
Code: [Select]
"CHANGE\n  \n(ssget ...) ..."

Grrr1337

  • Swamp Rat
  • Posts: 812
Re: (vl-prin1-to-string (quote lst)) = str ; or Strings to evaluate
« Reply #4 on: February 10, 2017, 08:12:20 AM »
Thanks Roy,
I was analysing some codes from marko_ribar and assumed that the "\n" represents ENTER key:
Code - Auto/Visual Lisp: [Select]
  1. ; "CHANGE" -> "CHANGE\n" -> "CHANGE\n(ssget \"_X\")" -> "CHANGE\n(ssget \"_X\")\n" -> "CHANGE\n(ssget \"_X\")\n\nP"
  2. ; -> "CHANGE\n(ssget \"_X\")\n\nP\n" -> "CHANGE\n(ssget \"_X\")\n\nP\nC" -> "CHANGE\n(ssget \"_X\")\n\nP\nC\n"
  3. ; -> "CHANGE\n(ssget \"_X\")\n\nP\nC\n1" -> "CHANGE\n(ssget \"_X\")\n\nP\nC\n1\n" -> "CHANGE\n(ssget \"_X\")\n\nP\nC\n1\n\n"
  4. (vla-SendCommand (vla-get-ActiveDocument (vlax-get-acad-object)) "CHANGE\n(ssget \"_X\")\n\nP\nC\n1\n\n") ; works
This was the tracing of the string argument filling I did.
(apply ''((a b c)(a b c))
  '(
    (( f L ) (apply 'strcat (f L)))
    (( L ) (if L (cons (chr (car L)) (f (cdr L)))))
    (72 101 108 108 111 32 87 111 114 108 100)
  )
)
vevo.bg