Jump to content

DCL action_tile string is too long


MJLM

Recommended Posts

I m having an issue with my lisp code for a DCL dialog box I made. It seems my string is too long for action_tile "accept" and I m getting error "bad argument type: lselsetp nil". The problem is, apparently, that I have too many input values that makes it long. If I remove one or two lines it works but I need to get them all in, store them and do validation checking.

 

Is there a way to make it work like spiting the string or maybe rewrite it better to alleviate the problem?

 

Any suggestions will be appreciated.

 

Here is the section I m talking about.

 

(action_tile "accept"
	(strcat
		"(progn
			(setq lfm_ (get_tile \"lfm\"))
			(setq lfv_ (get_tile \"lfv\"))
			(setq lhd_ (get_tile \"lhd\"))
			(setq lbl_ (get_tile \"lbl\"))
			(setq nhb_ (get_tile \"nhb\"))
			(setq nbl_ (get_tile \"nbl\"))
			(setq los_ (get_tile \"los\"))
			(setq lor_ (get_tile \"lor\"))
			(setq lom_ (get_tile \"lom\"))
			(setq nsr_ (get_tile \"nsr\"))
			(setq orient_ (nth (atoi (get_tile \"orient\")) orientls))
			(setq sud_ (nth (atoi (get_tile \"sud\")) sudls))
			(setq rbn_ (get_tile \"rbn\"))
			(setq ris_ (get_tile \"ris\"))
			(setq off_ (get_tile \"off\"))

			(cond
				((or (not (distof lfm_)) (<= (atof lfm_) 0))
					(set_tile \"error\" \"Invalid input!\")
					(mode_tile \"lfm\" 2)							; set focus on error item
				)
				((or (not (distof lfv_)) (<= (atof lfv_) 0))
					(set_tile \"error\" \"Invalid input!\")
					(mode_tile \"lfv\" 2)							; set focus on error item
				)
				((or (not (distof lhd_)) (<= (atof lhd_) 0))
					(set_tile \"error\" \"Invalid input!\")
					(mode_tile \"lhd\" 2)							; set focus on error item
				)
				((or (not (distof lbl_)) (<= (atof lbl_) 0))
					(set_tile \"error\" \"Invalid input!\")
					(mode_tile \"lbl\" 2)							; set focus on error item
				)
				((or (not (distof nhb_)) (vl-string-position (ascii \".\") nhb_) (<= (atof nhb_) 0))
					(set_tile \"error\" \"Invalid input!\")
					(mode_tile \"nhb\" 2)							; set focus on error item
				)
				((or (not (distof nbl_)) (vl-string-position (ascii \".\") nbl_) (<= (atof nbl_) 0))
					(set_tile \"error\" \"Invalid input!\")
					(mode_tile \"nbl\" 2)							; set focus on error item
				)
				((or (not (distof los_)) (<= (atof los_) 0))
					(set_tile \"error\" \"Invalid input!\")
					(mode_tile \"los\" 2)							; set focus on error item
				)
				((or (not (distof lor_)) (<= (atof lor_) 0))
					(set_tile \"error\" \"Invalid input!\")
					(mode_tile \"lor\" 2)							; set focus on error item
				)
				((or (not (distof lom_)) (<= (atof lom_) 0))
					(set_tile \"error\" \"Invalid input!\")
					(mode_tile \"lom\" 2)							; set focus on error item
				)
				((or (not (distof nsr_)) (vl-string-position (ascii \".\") nsr_) (<= (atof nsr_) 0) (> (atoi nsr_) (atoi nhb_)))
					(set_tile \"error\" \"Invalid input!\")
					(mode_tile \"nsr\" 2)							; set focus on error item
				)

				(t (done_dialog) (setq userclick T))
			)
		)"
	)
   )

Link to comment
Share on other sites

Heres my suggestion, it could be shortened more:

 

(action_tile "accept"
 (vl-prin1-to-string
   '(progn
     (mapcar 'set '(lfm_ lfv_ lhd_ lbl_ nhb_ nbl_ los_ lor_ lom_ nsr_ rbn_ ris_ off_)
       (mapcar 'get_tile '("lfm" "lfv" "lhd" "lbl" "nhb" "nbl" "los" "lor" "lom" "nsr" "rbn" "ris" "off"))
     )
     (setq orient_ (nth (atoi (get_tile "orient")) orientls))
     (setq sud_ (nth (atoi (get_tile "sud")) sudls))
     (or
       (and (set_tile "error" "Invalid input!")
         (vl-some (function (lambda (x) (if (eval (car x)) (mapcar 'eval (cdr x)))))  
           '(( (or (not (distof lfm_)) (<= (atof lfm_) 0)) (mode_tile "lfm" 2) )
             ( (or (not (distof lfv_)) (<= (atof lfv_) 0)) (mode_tile "lfv" 2) )
             ( (or (not (distof lhd_)) (<= (atof lhd_) 0)) (mode_tile "lhd" 2) )
             ( (or (not (distof lbl_)) (<= (atof lbl_) 0)) (mode_tile "lbl" 2) )
             ( (or (not (distof nhb_)) (vl-string-position (ascii ".") nhb_) (<= (atof nhb_) 0)) (mode_tile "nhb" 2) )
             ( (or (not (distof nbl_)) (vl-string-position (ascii ".") nbl_) (<= (atof nbl_) 0)) (mode_tile "nbl" 2) )
             ( (or (not (distof los_)) (<= (atof los_) 0)) (mode_tile "los" 2) )
             ( (or (not (distof lor_)) (<= (atof lor_) 0)) (mode_tile "lor" 2) )
             ( (or (not (distof lom_)) (<= (atof lom_) 0)) (mode_tile "lom" 2) )
             ( (or (not (distof nsr_)) (vl-string-position (ascii ".") nsr_) (<= (atof nsr_) 0) (> (atoi nsr_) (atoi nhb_))) (mode_tile "nsr" 2) )
           ); list 
         ); vl-some
       ); and
       (setq userclick (done_dialog))
     ); or
   ); progn
 ); vl-prin1-to-string
); action_tile 

 

However I'm not sure that this is the cause of the error.

 

EDIT:

Shortening, such as replacing the (vl-some) block, with:

(or 
 (vl-some (function (lambda (x) (if (or (not (distof (car x))) (<= (atof (car x)) 0)) (mode_tile (cadr x) 2))))
   '((lfm_ "lfm") (lfv_ "lfv") (lhd_ "lhd") (lbl_ "lbl") (los_ "los") (lor_ "lor") (lom_ "lom")) 
 )
 (vl-some (function (lambda (x) (if (or (not (distof (car x))) (vl-string-position (ascii ".") (car x)) (<= (atof (car x)) 0)) (mode_tile (cadr x) 2))))
   '((nhb_ "nhb") (nbl_ "nbl"))
 )
 (if (or (not (distof nsr_)) (vl-string-position (ascii ".") nsr_) (<= (atof nsr_) 0) (> (atoi nsr_) (atoi nhb_))) (mode_tile "nsr" 2) )
); or

Link to comment
Share on other sites

MJLM

Usually, each tile has it's own action, like this:

(action_tile "lfm" "(setq lfm_ $value) (err $key $value)")
(action_tile "lfv" "(setq lfv_ $value) (err $key $value)")
.
.

If you like, you can use this:

(mapcar
 '(lambda (key var)
    (action_tile key
      (strcat
        (vl-prin1-to-string (list 'setq var '$value))
        (vl-prin1-to-string '(err $key $value))
      )
    )
  )
 '("lfm" "lfv" "lhd" "lbl" "nhb" "nbl" "los" "lor" "lom" "nsr" "orient" "sud" "rbn" "ris" "off")
 '(lfm_ lfv_ lhd_ lbl_ nhb_ nbl_ los_ lor_ lom_ nsr_ orient_ sud_ rbn_ ris_ off_)
)

The error function called in each tile, can be like this:

(defun err (key val / n)
 (if
   (or
     (not (setq n (distof val)))
     (minusp n)
   )
   (progn
     (set_tile "error" "Invalid input!")
     (mode_tile key 2)
   )
 )
)

Of course, you have to set the error function to fit your need.

 

By default, "accept" exit with value 1 and "cancel" with 0, but it is not wrong to assign an action to these tiles.

I would prefer to use this schema:

(setq r (start_dialog))
(unload_dialog dcl_ID)
.
.
.
(if
 (= r 1)
 (do_some_stuff lfm_ lfv_ ..... )
)

Link to comment
Share on other sites

@Grrr,

 

thank you, you first suggestion works great and it have helped me to understand how can I consolidate my code a bit. However your second suggestion, which I prefer, does not seem to work. I replaced the vl-sort block but I just cant make it work.

 

@Stefan,

thank you. The implementation of your method seems easier but when i tried to do it I was getting errors with my variables while converting to reals with atof.

 

EDIT: Ok, I managed to fixed that and it s working OK now.

Edited by MJLM
Link to comment
Share on other sites

Another, untested:

(action_tile "accept"
   (vl-prin1-to-string
      '(if
           (not
               (vl-some
                  '(lambda ( pat lst )
                       (vl-some
                          '(lambda ( key )
                               (if (wcmatch (get_tile key) pat)
                                   (progn
                                       (mode_tile key 2)
                                       (set_tile "error" "Invalid input!")
                                   )
                               )
                           )
                           lst
                       )
                   )
                  '("*[~.0-9]*,*`.*`.*" "*[~0-9]*")
                  '(("lfm" "lfv" "lhd" "lbl" "los" "lor" "lom") ("nhb" "nbl" "nsr" "rbn" "ris" "off"))
               )
           )
           (done_dialog 1)
       )
   )
)

Link to comment
Share on other sites

My main problem with this DCL is that I cannot follow the steps while executing inside the visual lisp editor. When I run the code the program does not break on error and I cannot know what is going wrong. Am I doing something wrong here or DCL sucks so much?

Link to comment
Share on other sites

@MJLM,

just curios did Lee's suggestion work?

 

@Lee,

I know that you usually use the if function, but note that

(if (not <test expr>) <then expr>)

could be shortened a bit, to:

(or <test expr> <then expr>)

 

Although awesome suggestion, I'll keep it if MJLM confirm that it works.

Link to comment
Share on other sites

I tried to implement Lee's way but I think there is something going wrong with the pattern ("*[~.0-9]*,*`.*`.*" "*[~0-9]*"). I get "invalid input" for almost all boxes.

Link to comment
Share on other sites

The pattern checks for numerical input in the decimal format. Your comment suggests you are working in the imperial format.

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