MJLM Posted April 26, 2017 Share Posted April 26, 2017 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)) ) )" ) ) Quote Link to comment Share on other sites More sharing options...
Grrr Posted April 26, 2017 Share Posted April 26, 2017 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 Quote Link to comment Share on other sites More sharing options...
Stefan BMR Posted April 26, 2017 Share Posted April 26, 2017 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_ ..... ) ) Quote Link to comment Share on other sites More sharing options...
MJLM Posted April 26, 2017 Author Share Posted April 26, 2017 (edited) @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 April 26, 2017 by MJLM Quote Link to comment Share on other sites More sharing options...
Lee Mac Posted April 26, 2017 Share Posted April 26, 2017 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) ) ) ) Quote Link to comment Share on other sites More sharing options...
MJLM Posted April 26, 2017 Author Share Posted April 26, 2017 Jesus! for a moment I though you were just throwing gibberish just for fun. Thanks Lee. I will try your way too. Quote Link to comment Share on other sites More sharing options...
MJLM Posted April 26, 2017 Author Share Posted April 26, 2017 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? Quote Link to comment Share on other sites More sharing options...
Grrr Posted April 26, 2017 Share Posted April 26, 2017 @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. Quote Link to comment Share on other sites More sharing options...
MJLM Posted April 27, 2017 Author Share Posted April 27, 2017 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. Quote Link to comment Share on other sites More sharing options...
Roy_043 Posted April 27, 2017 Share Posted April 27, 2017 The pattern checks for numerical input in the decimal format. Your comment suggests you are working in the imperial format. Quote Link to comment Share on other sites More sharing options...
MJLM Posted April 27, 2017 Author Share Posted April 27, 2017 No, not really. I m working in metric with just reals and integers. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.