aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2001-11-28 20:53:28 +0000
committerStefan Monnier2001-11-28 20:53:28 +0000
commit722fa77ffa6904adc811d120a239fdb8246adf73 (patch)
treeade438edd7c06394c76d1e455407daf28a3e8aa1
parent3055c5a456cb7a551d4132a55cf5711e7e218869 (diff)
downloademacs-722fa77ffa6904adc811d120a239fdb8246adf73.tar.gz
emacs-722fa77ffa6904adc811d120a239fdb8246adf73.zip
(hif-end-of-line): New function.
(hide-ifdef-mode): Set line-move-ignore-invisible. (hide-ifdef-region-internal): New function. (hide-ifdef-region): Use it. (hif-defined): Return an integer. (hif-infix-to-prefix): Remove. (hif-tokenize): Parse from the buffer rather than from a string. Correctly tokenize integers. Use forward-comment. (hif-expr): Use hif-or. (hif-term): Use hif-and. (hif-factor): Use hif-not. Handle numbers properly. Don't require parenthesis around `defined's argument. (hif-and, hif-or, hif-not): New funs. (hif-canonicalize): Pass a region to hif-tokenize. Use hif-not. (hif-hide-line): Don't hide the \n before the line. (hif-possibly-hide): Correctly handle numeric evaluation results.
-rw-r--r--lisp/progmodes/hideif.el192
1 files changed, 88 insertions, 104 deletions
diff --git a/lisp/progmodes/hideif.el b/lisp/progmodes/hideif.el
index 2e21af69340..dbcfd593ff4 100644
--- a/lisp/progmodes/hideif.el
+++ b/lisp/progmodes/hideif.el
@@ -206,6 +206,8 @@ how the hiding is done:
206 (set (make-local-variable 'hide-ifdef-hiding) 206 (set (make-local-variable 'hide-ifdef-hiding)
207 (default-value 'hide-ifdef-hiding)) 207 (default-value 'hide-ifdef-hiding))
208 (set (make-local-variable 'hif-outside-read-only) buffer-read-only) 208 (set (make-local-variable 'hif-outside-read-only) buffer-read-only)
209 (set (make-local-variable 'line-move-ignore-invisible) t)
210 (add-hook 'change-major-mode-hook (lambda () (hide-ifdef-mode -1)))
209 211
210 (add-to-invisibility-spec '(hide-ifdef . t)) 212 (add-to-invisibility-spec '(hide-ifdef . t))
211 213
@@ -213,6 +215,7 @@ how the hiding is done:
213 (hide-ifdefs) 215 (hide-ifdefs)
214 (show-ifdefs))) 216 (show-ifdefs)))
215 ;; else end hide-ifdef-mode 217 ;; else end hide-ifdef-mode
218 (kill-local-variable 'line-move-ignore-invisible)
216 (if hide-ifdef-hiding 219 (if hide-ifdef-hiding
217 (show-ifdefs)))) 220 (show-ifdefs))))
218 221
@@ -230,15 +233,23 @@ how the hiding is done:
230 (hide-ifdefs t))) 233 (hide-ifdefs t)))
231(add-hook 'after-revert-hook 'hif-after-revert-function) 234(add-hook 'after-revert-hook 'hif-after-revert-function)
232 235
236(defun hif-end-of-line ()
237 (end-of-line)
238 (while (= (logand 1 (skip-chars-backward "\\\\")) 1)
239 (end-of-line 2)))
240
241(defun hide-ifdef-region-internal (start end)
242 (remove-overlays start end 'invisible 'hide-ifdef)
243 (let ((o (make-overlay start end)))
244 (overlay-put o 'invisible 'hide-ifdef)))
245
233(defun hide-ifdef-region (start end) 246(defun hide-ifdef-region (start end)
234 "START is the start of a #if or #else form. END is the ending part. 247 "START is the start of a #if or #else form. END is the ending part.
235Everything including these lines is made invisible." 248Everything including these lines is made invisible."
236 (save-excursion 249 (save-excursion
237 (goto-char start) (end-of-line) (setq start (point)) 250 (goto-char start) (hif-end-of-line) (setq start (point))
238 (goto-char end) (end-of-line) (setq end (point)) 251 (goto-char end) (hif-end-of-line) (setq end (point))
239 (remove-overlays start end 'invisible 'hide-ifdef) 252 (hide-ifdef-region-internal start end)))
240 (let ((o (make-overlay start end)))
241 (overlay-put o 'invisible 'hide-ifdef))))
242 253
243(defun hif-show-ifdef-region (start end) 254(defun hif-show-ifdef-region (start end)
244 "Everything between START and END is made visible." 255 "Everything between START and END is made visible."
@@ -271,13 +282,7 @@ that form should be displayed.")
271 hif-undefined-symbol))) 282 hif-undefined-symbol)))
272 283
273(defun hif-defined (var) 284(defun hif-defined (var)
274 (hif-lookup var) 285 (if (assoc var hide-ifdef-env) 1 0))
275 ;; when #if expressions are fully supported, defined result should be 1
276 ;; (if (assoc var hide-ifdef-env)
277 ;; 1
278 ;; nil)
279 )
280
281 286
282;;===%%SF%% evaluation (End) === 287;;===%%SF%% evaluation (End) ===
283 288
@@ -299,71 +304,47 @@ that form should be displayed.")
299(defvar hif-token) 304(defvar hif-token)
300(defvar hif-token-list) 305(defvar hif-token-list)
301 306
302(defun hif-infix-to-prefix (token-list)
303 "Convert list of tokens in infix into prefix list."
304 ;; (message "hif-infix-to-prefix: %s" token-list)
305 (if (= 1 (length token-list))
306 `(hif-lookup (quote ,(car token-list)))
307 (hif-parse-if-exp token-list)))
308
309;; pattern to match initial identifier, !, &&, ||, (, or ). 307;; pattern to match initial identifier, !, &&, ||, (, or ).
310;; Added ==, + and -: garyo@avs.com 8/9/94 308;; Added ==, + and -: garyo@avs.com 8/9/94
311(defconst hif-token-regexp "^\\(&&\\|||\\|[!=]=\\|!\\|[()+-]\\|[<>]=?\\|\\w+\\)") 309(defconst hif-token-regexp
312(defconst hif-end-of-comment "\\*/") 310 "\\(&&\\|||\\|[!=]=\\|!\\|[()+-]\\|[<>]=?\\|\\w+\\)")
313
314 311
315(defun hif-tokenize (expr-string) 312(defun hif-tokenize (start end)
316 "Separate string into a list of tokens." 313 "Separate string between START and END into a list of tokens."
317 (let ((token-list nil) 314 (let ((token-list nil))
318 (expr-start 0)
319 (expr-length (length expr-string)))
320 (with-syntax-table hide-ifdef-syntax-table 315 (with-syntax-table hide-ifdef-syntax-table
321 (while (< expr-start expr-length) 316 (save-excursion
322 ;; (message "expr-start = %d" expr-start) (sit-for 1) 317 (goto-char start)
323 (cond 318 (while (progn (forward-comment (point-max)) (< (point) end))
324 ((string-match "^[ \t]+" expr-string expr-start) 319 ;; (message "expr-start = %d" expr-start) (sit-for 1)
325 ;; skip whitespace 320 (cond
326 (setq expr-start (match-end 0)) 321 ((looking-at "\\\\\n")
327 ;; stick newline in string so ^ matches on the next string-match 322 (forward-char 2))
328 (aset expr-string (1- expr-start) ?\n)) 323
329 324 ((looking-at hif-token-regexp)
330 ((string-match "^/\\*" expr-string expr-start) 325 (let ((token (buffer-substring (point) (match-end 0))))
331 (setq expr-start (match-end 0)) 326 (goto-char (match-end 0))
332 (aset expr-string (1- expr-start) ?\n) 327 ;; (message "token: %s" token) (sit-for 1)
333 (or 328 (push (cond
334 (string-match hif-end-of-comment 329 ((string-equal token "||") 'or)
335 expr-string expr-start) ; eat comment 330 ((string-equal token "&&") 'and)
336 (string-match "$" expr-string expr-start)) ; multi-line comment 331 ((string-equal token "==") 'equal)
337 (setq expr-start (match-end 0)) 332 ((string-equal token "!=") 'hif-notequal)
338 (aset expr-string (1- expr-start) ?\n)) 333 ((string-equal token "!") 'not)
339 334 ((string-equal token "defined") 'hif-defined)
340 ((string-match "^//" expr-string expr-start) 335 ((string-equal token "(") 'lparen)
341 (string-match "$" expr-string expr-start) 336 ((string-equal token ")") 'rparen)
342 (setq expr-start (match-end 0))) 337 ((string-equal token ">") 'hif-greater)
343 338 ((string-equal token "<") 'hif-less)
344 ((string-match hif-token-regexp expr-string expr-start) 339 ((string-equal token ">=") 'hif-greater-equal)
345 (let ((token (substring expr-string expr-start (match-end 0)))) 340 ((string-equal token "<=") 'hif-less-equal)
346 (setq expr-start (match-end 0)) 341 ((string-equal token "+") 'hif-plus)
347 (aset expr-string (1- expr-start) ?\n) 342 ((string-equal token "-") 'hif-minus)
348 ;; (message "token: %s" token) (sit-for 1) 343 ((string-match "\\`[0-9]*\\'" token)
349 (push (cond 344 (string-to-number token))
350 ((string-equal token "||") 'or) 345 (t (intern token)))
351 ((string-equal token "&&") 'and) 346 token-list)))
352 ((string-equal token "==") 'equal) 347 (t (error "Bad #if expression: %s" (buffer-string)))))))
353 ((string-equal token "!=") 'hif-notequal)
354 ((string-equal token "!") 'not)
355 ((string-equal token "defined") 'hif-defined)
356 ((string-equal token "(") 'lparen)
357 ((string-equal token ")") 'rparen)
358 ((string-equal token ">") 'hif-greater)
359 ((string-equal token "<") 'hif-less)
360 ((string-equal token ">=") 'hif-greater-equal)
361 ((string-equal token "<=") 'hif-less-equal)
362 ((string-equal token "+") 'hif-plus)
363 ((string-equal token "-") 'hif-minus)
364 (t (intern token)))
365 token-list)))
366 (t (error "Bad #if expression: %s" expr-string)))))
367 (nreverse token-list))) 348 (nreverse token-list)))
368 349
369;;;----------------------------------------------------------------- 350;;;-----------------------------------------------------------------
@@ -379,11 +360,9 @@ that form should be displayed.")
379 (if hif-token ; is there still a token? 360 (if hif-token ; is there still a token?
380 (error "Error: unexpected token: %s" hif-token)))) 361 (error "Error: unexpected token: %s" hif-token))))
381 362
382(defun hif-nexttoken () 363(defsubst hif-nexttoken ()
383 "Pop the next token from token-list into the let variable \"hif-token\"." 364 "Pop the next token from token-list into the let variable \"hif-token\"."
384 (setq hif-token (car hif-token-list)) 365 (setq hif-token (pop hif-token-list)))
385 (setq hif-token-list (cdr hif-token-list))
386 hif-token)
387 366
388(defun hif-expr () 367(defun hif-expr ()
389 "Parse an expression as found in #if. 368 "Parse an expression as found in #if.
@@ -391,7 +370,7 @@ that form should be displayed.")
391 (let ((result (hif-term))) 370 (let ((result (hif-term)))
392 (while (eq hif-token 'or) 371 (while (eq hif-token 'or)
393 (hif-nexttoken) 372 (hif-nexttoken)
394 (setq result (list 'or result (hif-term)))) 373 (setq result (list 'hif-or result (hif-term))))
395 result)) 374 result))
396 375
397(defun hif-term () 376(defun hif-term ()
@@ -399,7 +378,7 @@ that form should be displayed.")
399 (let ((result (hif-eq-expr))) 378 (let ((result (hif-eq-expr)))
400 (while (eq hif-token 'and) 379 (while (eq hif-token 'and)
401 (hif-nexttoken) 380 (hif-nexttoken)
402 (setq result (list 'and result (hif-eq-expr)))) 381 (setq result (list 'hif-and result (hif-eq-expr))))
403 result)) 382 result))
404 383
405(defun hif-eq-expr () 384(defun hif-eq-expr ()
@@ -418,7 +397,7 @@ that form should be displayed.")
418 math : factor | math '+|-' factor." 397 math : factor | math '+|-' factor."
419 (let ((result (hif-factor)) 398 (let ((result (hif-factor))
420 (math-op nil)) 399 (math-op nil))
421 (while (or (eq hif-token 'hif-plus) (eq hif-token 'hif-minus)) 400 (while (memq hif-token '(hif-plus hif-minus))
422 (setq math-op hif-token) 401 (setq math-op hif-token)
423 (hif-nexttoken) 402 (hif-nexttoken)
424 (setq result (list math-op result (hif-factor)))) 403 (setq result (list math-op result (hif-factor))))
@@ -429,7 +408,7 @@ that form should be displayed.")
429 (cond 408 (cond
430 ((eq hif-token 'not) 409 ((eq hif-token 'not)
431 (hif-nexttoken) 410 (hif-nexttoken)
432 (list 'not (hif-factor))) 411 (list 'hif-not (hif-factor)))
433 412
434 ((eq hif-token 'lparen) 413 ((eq hif-token 'lparen)
435 (hif-nexttoken) 414 (hif-nexttoken)
@@ -441,18 +420,20 @@ that form should be displayed.")
441 420
442 ((eq hif-token 'hif-defined) 421 ((eq hif-token 'hif-defined)
443 (hif-nexttoken) 422 (hif-nexttoken)
444 (if (not (eq hif-token 'lparen)) 423 (let ((paren (when (eq hif-token 'lparen) (hif-nexttoken) t))
445 (error "Error: expected \"(\" after \"defined\"")) 424 (ident hif-token))
446 (hif-nexttoken)
447 (let ((ident hif-token))
448 (if (memq hif-token '(or and not hif-defined lparen rparen)) 425 (if (memq hif-token '(or and not hif-defined lparen rparen))
449 (error "Error: unexpected token: %s" hif-token)) 426 (error "Error: unexpected token: %s" hif-token))
450 (hif-nexttoken) 427 (when paren
451 (unless (eq hif-token 'rparen) 428 (hif-nexttoken)
452 (error "Error: expected \")\" after identifier")) 429 (unless (eq hif-token 'rparen)
430 (error "Error: expected \")\" after identifier")))
453 (hif-nexttoken) 431 (hif-nexttoken)
454 `(hif-defined (quote ,ident)))) 432 `(hif-defined (quote ,ident))))
455 433
434 ((numberp hif-token)
435 (prog1 hif-token (hif-nexttoken)))
436
456 (t ; identifier 437 (t ; identifier
457 (let ((ident hif-token)) 438 (let ((ident hif-token))
458 (if (memq ident '(or and)) 439 (if (memq ident '(or and))
@@ -466,6 +447,12 @@ that form should be displayed.")
466 ((null val) 0) 447 ((null val) 0)
467 (t val))) 448 (t val)))
468 449
450(defun hif-and (a b)
451 (and (not (zerop (hif-mathify a))) (not (zerop (hif-mathify b)))))
452(defun hif-or (a b)
453 (or (not (zerop (hif-mathify a))) (not (zerop (hif-mathify b)))))
454(defun hif-not (a)
455 (zerop (hif-mathify a)))
469(defun hif-plus (a b) 456(defun hif-plus (a b)
470 "Like ordinary plus but treat t and nil as 1 and 0." 457 "Like ordinary plus but treat t and nil as 1 and 0."
471 (+ (hif-mathify a) (hif-mathify b))) 458 (+ (hif-mathify a) (hif-mathify b)))
@@ -495,13 +482,12 @@ that form should be displayed.")
495 (save-excursion 482 (save-excursion
496 (let ((negate (looking-at hif-ifndef-regexp))) 483 (let ((negate (looking-at hif-ifndef-regexp)))
497 (re-search-forward hif-ifx-regexp) 484 (re-search-forward hif-ifx-regexp)
498 (let* ((expr-string 485 (let* ((tokens (hif-tokenize (point)
499 (buffer-substring (point) 486 (progn (hif-end-of-line) (point))))
500 (progn (skip-chars-forward "^\n\r") (point)))) 487 (expr (hif-parse-if-exp tokens)))
501 (expr (hif-infix-to-prefix (hif-tokenize expr-string))))
502 ;; (message "hif-canonicalized: %s" expr) 488 ;; (message "hif-canonicalized: %s" expr)
503 (if negate 489 (if negate
504 (list 'not expr) 490 (list 'hif-not expr)
505 expr))))) 491 expr)))))
506 492
507 493
@@ -669,12 +655,12 @@ With argument, do this that many times."
669;;; Only valid if ELSE-P is true. 655;;; Only valid if ELSE-P is true.
670;;; END The end of the range. (beginning of line) 656;;; END The end of the range. (beginning of line)
671 657
672(defun hif-make-range (start end &optional else) 658(defsubst hif-make-range (start end &optional else)
673 (list start else end)) 659 (list start else end))
674 660
675(defun hif-range-start (range) (elt range 0)) 661(defsubst hif-range-start (range) (elt range 0))
676(defun hif-range-else (range) (elt range 1)) 662(defsubst hif-range-else (range) (elt range 1))
677(defun hif-range-end (range) (elt range 2)) 663(defsubst hif-range-end (range) (elt range 2))
678 664
679 665
680 666
@@ -716,16 +702,14 @@ Point is left unchanged."
716 702
717 703
718;;; A bit slimy. 704;;; A bit slimy.
719;;; NOTE: If there's an #ifdef at the beginning of the file, we can't
720;;; hide it. There's no previous newline to replace. If we added
721;;; one, we'd throw off all the counts. Feh.
722 705
723(defun hif-hide-line (point) 706(defun hif-hide-line (point)
724 "Hide the line containing point. Does nothing if `hide-ifdef-lines' is nil." 707 "Hide the line containing point. Does nothing if `hide-ifdef-lines' is nil."
725 (if hide-ifdef-lines 708 (if hide-ifdef-lines
726 (save-excursion 709 (save-excursion
727 (goto-char point) 710 (goto-char point)
728 (hide-ifdef-region (line-end-position 0) (line-end-position))))) 711 (hide-ifdef-region-internal (line-beginning-position)
712 (progn (hif-end-of-line) (point))))))
729 713
730 714
731;;; Hif-Possibly-Hide 715;;; Hif-Possibly-Hide
@@ -769,10 +753,10 @@ It uses the judgement of `hide-ifdef-evaluator'."
769 ;; (message "test = %s" test) (sit-for 1) 753 ;; (message "test = %s" test) (sit-for 1)
770 754
771 (hif-hide-line (hif-range-end range)) 755 (hif-hide-line (hif-range-end range))
772 (if (funcall hide-ifdef-evaluator test) 756 (if (not (hif-not (funcall hide-ifdef-evaluator test)))
773 (cond ((hif-range-else range) ; case 1 757 (cond ((hif-range-else range) ; case 1
774 (hif-hide-line (hif-range-else range)) 758 (hif-hide-line (hif-range-else range))
775 (hide-ifdef-region (hif-range-else range) 759 (hide-ifdef-region (hif-range-else range)
776 (1- (hif-range-end range))) 760 (1- (hif-range-end range)))
777 (hif-recurse-on (hif-range-start range) 761 (hif-recurse-on (hif-range-start range)
778 (hif-range-else range))) 762 (hif-range-else range)))