help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: Compilation warnings of ELisp seem wrong and misleading


From: Ludwig, Mark
Subject: RE: Compilation warnings of ELisp seem wrong and misleading
Date: Mon, 30 Mar 2015 15:40:21 +0000

"Pascal J. Bourguignon" wrote:

> "Ludwig, Mark" <ludwig.mark@siemens.com> writes:
> 
> > Greetings,
> >
> > I've been using an ancient Emacs (19.29) on Solaris and finally
> > got around to installing a current one (24.4).
> >
> > I find my custom Elisp generates warnings that seem pretty stupid.
> > For example:
> >
> > emacs.el:255:10:Warning: reference to free variable `if'
> > emacs.el:219:8:Warning: reference to free variable `save-excursion'
> > emacs.el:331:41:Warning: reference to free variable `forward-char'
> > emacs.el:261:17:Warning: reference to free variable `insert'
> > emacs.el:261:17:Warning: reference to free variable `forward-sexp'
> >
> > Those are all valid functions.  For example, here are lines 255-258:
> >
> >     (if (not (= ans ?q))
> >         (progn
> >           (goto-char found-start)
> >           (delete-region found-start found-end)))
> >
> > This is inside a large-ish "let*" form (111 lines).

> We cannot see either, because the meaning of a sexp is determined by its
> surrounding form, which you didn't provide.
> 
> You probably have a parenthesis problem in your let* form which makes
> lisp interpret some parts as being variable names instead of operators.

No, I know how to balance parentheses.  I've been
programming Emacs Lisp for almost 30 years.  I rely on Emacs
for its outstanding job of showing structural problems
through its automatic indentation (in all programming
languages, but certainly within its own).  By all means, if
there's anything wrong with that (if ...) form, please
explain.

For context, the "let*" is on line 239; the warning
(mentioned above as being on line 255 column 10) is
referring to the form after the comment "Make the
substitution."  If you read the warnings carefully, you'll
note that it warns about two different things on line 261,
column 17.  That line is the one with the comment, 'Now it's
"strlcpy" or whatever.'  Clearly, the byte-compiler is
pretty confused....

      (let* ((c1 (string-to-char to1))
             (c2 (string-to-char to2))
             (ans 0))

        ;; Get one of the first characters from the two substitutions

        (while (and (not (= ans c1))
                    (not (= ans c2))
                    (not (= ans ?q)))   ; Quit, don't substitute anything
          (setq ans (read-char-exclusive
                     (concat "Replace " from " with "
                             to1 " (will truncate silently) or "
                             to2 " (dstat)? (" (char-to-string c1) "/" 
(char-to-string c2) "/q) "))))

        ;; Make the substitution

        (if (not (= ans ?q))
            (progn
              (goto-char found-start)
              (delete-region found-start found-end)))

        (cond ((= ans c1)
               (insert to1)             ; Now it's "strlcpy" or whatever
               )

              ((= ans c2)
               (insert "dstat = " to2)  ; Now it's "dstat = nlsStrLCpy" or 
whatever
               (back-to-indentation)
               (setq ans 0)
               (while (and (not (= ans ?d))
                           (not (= ans ?e))
                           (not (= ans ?n)))
                 (setq ans (read-char-exclusive "Use DSOK/EXIT/no form? ")))

               (let ((if-pos (point)))

                 (cond ((= ans ?d)
                        (insert "if (DSOK) ")
                        (forward-sexp 3) ; After the closing parenthesis for 
the function call
                        )

                       ((= ans ?e)
                        (insert "if (")
                        (forward-sexp 3) ; After the closing parenthesis for 
the function call
                        (insert ")")
                        (newline-and-indent)
                        (insert "goto EXIT") ; The semi-colon should end up 
after "EXIT"
                        (c-indent-command) ; Make the "goto" be correctly 
indented under the "if"
                        )

                       ((= ans ?n)
                        ;; no form
                        )
                       )

                 ;; Try to look ahead, in case the function call we just
                 ;; modified was a one-statement "block" in an "if," so
                 ;; we've just unintentionally modified the meaning of
                 ;; that "if" statement
                        
                 (if (not (= ans ?n))
                     (condition-case nil
                         (progn
                           (forward-sexp 1) ; Skip over "else" if it's there
                           (forward-sexp -1) ; Back in front of "else" if it's 
there
                           (if (looking-at "else")
                               (progn
                                 (goto-char if-pos) ; Go back to where we 
inserted "if"

                                 (cond ((= ans ?d)
                                        ;; Skip over: "if" "(DSOK)" "dstat" "= 
..." "()"
                                        (forward-sexp 5)
                                        )

                                       ((= ans ?e)
                                        ;; Skip over:
                                        ;; "if" "(dstat = ...)" "goto" "EXIT"
                                        (forward-sexp 4)
                                        )

                                       (if (not (looking-at ";"))
                                           (error "First expected ';' not: 
\"%s\"" (buffer-substring (point)
                                                                                
                     (progn (end-of-line 1)
                                                                                
                            (point)))))
                                       (save-excursion
                                         (goto-char if-pos) ; Go back to where 
we inserted "if"
                                         (insert "{
"))
                                       (if (not (looking-at ";"))
                                           (error "Second expected ';' not: 
\"%s\"" (buffer-substring (point)
                                                                                
                      (progn (end-of-line 1)
                                                                                
                             (point)))))
                                       (forward-char 1)

                                       ;; We should be looking at the end of 
line
                                       (if (not (looking-at "\\s-*$"))
                                           (error "Second expected end of line, 
not: \"%s\"" (buffer-substring (point)
                                                                                
                               (progn (end-of-line 1)
                                                                                
                                      (point)))))
                                       (insert "
}")
                                       (forward-sexp -1)
                                       (c-indent-exp)
                                       ))))
                       (error nil)      ;hand-rolled (ignore-errors ...)
                       )
                   )
                 )
               )
              )
        )

> 
> --
> __Pascal Bourguignon__                 http://www.informatimago.com/
> “The factory of the future will have only two employees, a man and a
> dog. The man will be there to feed the dog. The dog will be there to
> keep the man from touching the equipment.” -- Carl Bass CEO Autodesk

reply via email to

[Prev in Thread] Current Thread [Next in Thread]