206 |
(set (make-local-variable 'hide-ifdef-hiding) |
(set (make-local-variable 'hide-ifdef-hiding) |
207 |
(default-value 'hide-ifdef-hiding)) |
(default-value 'hide-ifdef-hiding)) |
208 |
(set (make-local-variable 'hif-outside-read-only) buffer-read-only) |
(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))) |
211 |
|
|
212 |
(add-to-invisibility-spec '(hide-ifdef . t)) |
(add-to-invisibility-spec '(hide-ifdef . t)) |
213 |
|
|
215 |
(hide-ifdefs) |
(hide-ifdefs) |
216 |
(show-ifdefs))) |
(show-ifdefs))) |
217 |
;; else end hide-ifdef-mode |
;; else end hide-ifdef-mode |
218 |
|
(kill-local-variable 'line-move-ignore-invisible) |
219 |
(if hide-ifdef-hiding |
(if hide-ifdef-hiding |
220 |
(show-ifdefs)))) |
(show-ifdefs)))) |
221 |
|
|
233 |
(hide-ifdefs t))) |
(hide-ifdefs t))) |
234 |
(add-hook 'after-revert-hook 'hif-after-revert-function) |
(add-hook 'after-revert-hook 'hif-after-revert-function) |
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 |
|
|
246 |
(defun hide-ifdef-region (start end) |
(defun hide-ifdef-region (start end) |
247 |
"START is the start of a #if or #else form. END is the ending part. |
"START is the start of a #if or #else form. END is the ending part. |
248 |
Everything including these lines is made invisible." |
Everything including these lines is made invisible." |
249 |
(save-excursion |
(save-excursion |
250 |
(goto-char start) (end-of-line) (setq start (point)) |
(goto-char start) (hif-end-of-line) (setq start (point)) |
251 |
(goto-char end) (end-of-line) (setq end (point)) |
(goto-char end) (hif-end-of-line) (setq end (point)) |
252 |
(remove-overlays start end 'invisible 'hide-ifdef) |
(hide-ifdef-region-internal start end))) |
|
(let ((o (make-overlay start end))) |
|
|
(overlay-put o 'invisible 'hide-ifdef)))) |
|
253 |
|
|
254 |
(defun hif-show-ifdef-region (start end) |
(defun hif-show-ifdef-region (start end) |
255 |
"Everything between START and END is made visible." |
"Everything between START and END is made visible." |
282 |
hif-undefined-symbol))) |
hif-undefined-symbol))) |
283 |
|
|
284 |
(defun hif-defined (var) |
(defun hif-defined (var) |
285 |
(hif-lookup var) |
(if (assoc var hide-ifdef-env) 1 0)) |
|
;; when #if expressions are fully supported, defined result should be 1 |
|
|
;; (if (assoc var hide-ifdef-env) |
|
|
;; 1 |
|
|
;; nil) |
|
|
) |
|
|
|
|
286 |
|
|
287 |
;;===%%SF%% evaluation (End) === |
;;===%%SF%% evaluation (End) === |
288 |
|
|
304 |
(defvar hif-token) |
(defvar hif-token) |
305 |
(defvar hif-token-list) |
(defvar hif-token-list) |
306 |
|
|
|
(defun hif-infix-to-prefix (token-list) |
|
|
"Convert list of tokens in infix into prefix list." |
|
|
;; (message "hif-infix-to-prefix: %s" token-list) |
|
|
(if (= 1 (length token-list)) |
|
|
`(hif-lookup (quote ,(car token-list))) |
|
|
(hif-parse-if-exp token-list))) |
|
|
|
|
307 |
;; pattern to match initial identifier, !, &&, ||, (, or ). |
;; pattern to match initial identifier, !, &&, ||, (, or ). |
308 |
;; Added ==, + and -: garyo@avs.com 8/9/94 |
;; Added ==, + and -: garyo@avs.com 8/9/94 |
309 |
(defconst hif-token-regexp "^\\(&&\\|||\\|[!=]=\\|!\\|[()+-]\\|[<>]=?\\|\\w+\\)") |
(defconst hif-token-regexp |
310 |
(defconst hif-end-of-comment "\\*/") |
"\\(&&\\|||\\|[!=]=\\|!\\|[()+-]\\|[<>]=?\\|\\w+\\)") |
|
|
|
311 |
|
|
312 |
(defun hif-tokenize (expr-string) |
(defun hif-tokenize (start end) |
313 |
"Separate string into a list of tokens." |
"Separate string between START and END into a list of tokens." |
314 |
(let ((token-list nil) |
(let ((token-list nil)) |
|
(expr-start 0) |
|
|
(expr-length (length expr-string))) |
|
315 |
(with-syntax-table hide-ifdef-syntax-table |
(with-syntax-table hide-ifdef-syntax-table |
316 |
(while (< expr-start expr-length) |
(save-excursion |
317 |
;; (message "expr-start = %d" expr-start) (sit-for 1) |
(goto-char start) |
318 |
(cond |
(while (progn (forward-comment (point-max)) (< (point) end)) |
319 |
((string-match "^[ \t]+" expr-string expr-start) |
;; (message "expr-start = %d" expr-start) (sit-for 1) |
320 |
;; skip whitespace |
(cond |
321 |
(setq expr-start (match-end 0)) |
((looking-at "\\\\\n") |
322 |
;; stick newline in string so ^ matches on the next string-match |
(forward-char 2)) |
323 |
(aset expr-string (1- expr-start) ?\n)) |
|
324 |
|
((looking-at hif-token-regexp) |
325 |
((string-match "^/\\*" expr-string expr-start) |
(let ((token (buffer-substring (point) (match-end 0)))) |
326 |
(setq expr-start (match-end 0)) |
(goto-char (match-end 0)) |
327 |
(aset expr-string (1- expr-start) ?\n) |
;; (message "token: %s" token) (sit-for 1) |
328 |
(or |
(push (cond |
329 |
(string-match hif-end-of-comment |
((string-equal token "||") 'or) |
330 |
expr-string expr-start) ; eat comment |
((string-equal token "&&") 'and) |
331 |
(string-match "$" expr-string expr-start)) ; multi-line comment |
((string-equal token "==") 'equal) |
332 |
(setq expr-start (match-end 0)) |
((string-equal token "!=") 'hif-notequal) |
333 |
(aset expr-string (1- expr-start) ?\n)) |
((string-equal token "!") 'not) |
334 |
|
((string-equal token "defined") 'hif-defined) |
335 |
((string-match "^//" expr-string expr-start) |
((string-equal token "(") 'lparen) |
336 |
(string-match "$" expr-string expr-start) |
((string-equal token ")") 'rparen) |
337 |
(setq expr-start (match-end 0))) |
((string-equal token ">") 'hif-greater) |
338 |
|
((string-equal token "<") 'hif-less) |
339 |
((string-match hif-token-regexp expr-string expr-start) |
((string-equal token ">=") 'hif-greater-equal) |
340 |
(let ((token (substring expr-string expr-start (match-end 0)))) |
((string-equal token "<=") 'hif-less-equal) |
341 |
(setq expr-start (match-end 0)) |
((string-equal token "+") 'hif-plus) |
342 |
(aset expr-string (1- expr-start) ?\n) |
((string-equal token "-") 'hif-minus) |
343 |
;; (message "token: %s" token) (sit-for 1) |
((string-match "\\`[0-9]*\\'" token) |
344 |
(push (cond |
(string-to-number token)) |
345 |
((string-equal token "||") 'or) |
(t (intern token))) |
346 |
((string-equal token "&&") 'and) |
token-list))) |
347 |
((string-equal token "==") 'equal) |
(t (error "Bad #if expression: %s" (buffer-string))))))) |
|
((string-equal token "!=") 'hif-notequal) |
|
|
((string-equal token "!") 'not) |
|
|
((string-equal token "defined") 'hif-defined) |
|
|
((string-equal token "(") 'lparen) |
|
|
((string-equal token ")") 'rparen) |
|
|
((string-equal token ">") 'hif-greater) |
|
|
((string-equal token "<") 'hif-less) |
|
|
((string-equal token ">=") 'hif-greater-equal) |
|
|
((string-equal token "<=") 'hif-less-equal) |
|
|
((string-equal token "+") 'hif-plus) |
|
|
((string-equal token "-") 'hif-minus) |
|
|
(t (intern token))) |
|
|
token-list))) |
|
|
(t (error "Bad #if expression: %s" expr-string))))) |
|
348 |
(nreverse token-list))) |
(nreverse token-list))) |
349 |
|
|
350 |
;;;----------------------------------------------------------------- |
;;;----------------------------------------------------------------- |
360 |
(if hif-token ; is there still a token? |
(if hif-token ; is there still a token? |
361 |
(error "Error: unexpected token: %s" hif-token)))) |
(error "Error: unexpected token: %s" hif-token)))) |
362 |
|
|
363 |
(defun hif-nexttoken () |
(defsubst hif-nexttoken () |
364 |
"Pop the next token from token-list into the let variable \"hif-token\"." |
"Pop the next token from token-list into the let variable \"hif-token\"." |
365 |
(setq hif-token (car hif-token-list)) |
(setq hif-token (pop hif-token-list))) |
|
(setq hif-token-list (cdr hif-token-list)) |
|
|
hif-token) |
|
366 |
|
|
367 |
(defun hif-expr () |
(defun hif-expr () |
368 |
"Parse an expression as found in #if. |
"Parse an expression as found in #if. |
370 |
(let ((result (hif-term))) |
(let ((result (hif-term))) |
371 |
(while (eq hif-token 'or) |
(while (eq hif-token 'or) |
372 |
(hif-nexttoken) |
(hif-nexttoken) |
373 |
(setq result (list 'or result (hif-term)))) |
(setq result (list 'hif-or result (hif-term)))) |
374 |
result)) |
result)) |
375 |
|
|
376 |
(defun hif-term () |
(defun hif-term () |
378 |
(let ((result (hif-eq-expr))) |
(let ((result (hif-eq-expr))) |
379 |
(while (eq hif-token 'and) |
(while (eq hif-token 'and) |
380 |
(hif-nexttoken) |
(hif-nexttoken) |
381 |
(setq result (list 'and result (hif-eq-expr)))) |
(setq result (list 'hif-and result (hif-eq-expr)))) |
382 |
result)) |
result)) |
383 |
|
|
384 |
(defun hif-eq-expr () |
(defun hif-eq-expr () |
397 |
math : factor | math '+|-' factor." |
math : factor | math '+|-' factor." |
398 |
(let ((result (hif-factor)) |
(let ((result (hif-factor)) |
399 |
(math-op nil)) |
(math-op nil)) |
400 |
(while (or (eq hif-token 'hif-plus) (eq hif-token 'hif-minus)) |
(while (memq hif-token '(hif-plus hif-minus)) |
401 |
(setq math-op hif-token) |
(setq math-op hif-token) |
402 |
(hif-nexttoken) |
(hif-nexttoken) |
403 |
(setq result (list math-op result (hif-factor)))) |
(setq result (list math-op result (hif-factor)))) |
408 |
(cond |
(cond |
409 |
((eq hif-token 'not) |
((eq hif-token 'not) |
410 |
(hif-nexttoken) |
(hif-nexttoken) |
411 |
(list 'not (hif-factor))) |
(list 'hif-not (hif-factor))) |
412 |
|
|
413 |
((eq hif-token 'lparen) |
((eq hif-token 'lparen) |
414 |
(hif-nexttoken) |
(hif-nexttoken) |
420 |
|
|
421 |
((eq hif-token 'hif-defined) |
((eq hif-token 'hif-defined) |
422 |
(hif-nexttoken) |
(hif-nexttoken) |
423 |
(if (not (eq hif-token 'lparen)) |
(let ((paren (when (eq hif-token 'lparen) (hif-nexttoken) t)) |
424 |
(error "Error: expected \"(\" after \"defined\"")) |
(ident hif-token)) |
|
(hif-nexttoken) |
|
|
(let ((ident hif-token)) |
|
425 |
(if (memq hif-token '(or and not hif-defined lparen rparen)) |
(if (memq hif-token '(or and not hif-defined lparen rparen)) |
426 |
(error "Error: unexpected token: %s" hif-token)) |
(error "Error: unexpected token: %s" hif-token)) |
427 |
(hif-nexttoken) |
(when paren |
428 |
(unless (eq hif-token 'rparen) |
(hif-nexttoken) |
429 |
(error "Error: expected \")\" after identifier")) |
(unless (eq hif-token 'rparen) |
430 |
|
(error "Error: expected \")\" after identifier"))) |
431 |
(hif-nexttoken) |
(hif-nexttoken) |
432 |
`(hif-defined (quote ,ident)))) |
`(hif-defined (quote ,ident)))) |
433 |
|
|
434 |
|
((numberp hif-token) |
435 |
|
(prog1 hif-token (hif-nexttoken))) |
436 |
|
|
437 |
(t ; identifier |
(t ; identifier |
438 |
(let ((ident hif-token)) |
(let ((ident hif-token)) |
439 |
(if (memq ident '(or and)) |
(if (memq ident '(or and)) |
447 |
((null val) 0) |
((null val) 0) |
448 |
(t val))) |
(t val))) |
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))) |
456 |
(defun hif-plus (a b) |
(defun hif-plus (a b) |
457 |
"Like ordinary plus but treat t and nil as 1 and 0." |
"Like ordinary plus but treat t and nil as 1 and 0." |
458 |
(+ (hif-mathify a) (hif-mathify b))) |
(+ (hif-mathify a) (hif-mathify b))) |
482 |
(save-excursion |
(save-excursion |
483 |
(let ((negate (looking-at hif-ifndef-regexp))) |
(let ((negate (looking-at hif-ifndef-regexp))) |
484 |
(re-search-forward hif-ifx-regexp) |
(re-search-forward hif-ifx-regexp) |
485 |
(let* ((expr-string |
(let* ((tokens (hif-tokenize (point) |
486 |
(buffer-substring (point) |
(progn (hif-end-of-line) (point)))) |
487 |
(progn (skip-chars-forward "^\n\r") (point)))) |
(expr (hif-parse-if-exp tokens))) |
|
(expr (hif-infix-to-prefix (hif-tokenize expr-string)))) |
|
488 |
;; (message "hif-canonicalized: %s" expr) |
;; (message "hif-canonicalized: %s" expr) |
489 |
(if negate |
(if negate |
490 |
(list 'not expr) |
(list 'hif-not expr) |
491 |
expr))))) |
expr))))) |
492 |
|
|
493 |
|
|
655 |
;;; Only valid if ELSE-P is true. |
;;; Only valid if ELSE-P is true. |
656 |
;;; END The end of the range. (beginning of line) |
;;; END The end of the range. (beginning of line) |
657 |
|
|
658 |
(defun hif-make-range (start end &optional else) |
(defsubst hif-make-range (start end &optional else) |
659 |
(list start else end)) |
(list start else end)) |
660 |
|
|
661 |
(defun hif-range-start (range) (elt range 0)) |
(defsubst hif-range-start (range) (elt range 0)) |
662 |
(defun hif-range-else (range) (elt range 1)) |
(defsubst hif-range-else (range) (elt range 1)) |
663 |
(defun hif-range-end (range) (elt range 2)) |
(defsubst hif-range-end (range) (elt range 2)) |
664 |
|
|
665 |
|
|
666 |
|
|
702 |
|
|
703 |
|
|
704 |
;;; A bit slimy. |
;;; A bit slimy. |
|
;;; NOTE: If there's an #ifdef at the beginning of the file, we can't |
|
|
;;; hide it. There's no previous newline to replace. If we added |
|
|
;;; one, we'd throw off all the counts. Feh. |
|
705 |
|
|
706 |
(defun hif-hide-line (point) |
(defun hif-hide-line (point) |
707 |
"Hide the line containing point. Does nothing if `hide-ifdef-lines' is nil." |
"Hide the line containing point. Does nothing if `hide-ifdef-lines' is nil." |
708 |
(if hide-ifdef-lines |
(if hide-ifdef-lines |
709 |
(save-excursion |
(save-excursion |
710 |
(goto-char point) |
(goto-char point) |
711 |
(hide-ifdef-region (line-end-position 0) (line-end-position))))) |
(hide-ifdef-region-internal (line-beginning-position) |
712 |
|
(progn (hif-end-of-line) (point)))))) |
713 |
|
|
714 |
|
|
715 |
;;; Hif-Possibly-Hide |
;;; Hif-Possibly-Hide |
753 |
;; (message "test = %s" test) (sit-for 1) |
;; (message "test = %s" test) (sit-for 1) |
754 |
|
|
755 |
(hif-hide-line (hif-range-end range)) |
(hif-hide-line (hif-range-end range)) |
756 |
(if (funcall hide-ifdef-evaluator test) |
(if (not (hif-not (funcall hide-ifdef-evaluator test))) |
757 |
(cond ((hif-range-else range) ; case 1 |
(cond ((hif-range-else range) ; case 1 |
758 |
(hif-hide-line (hif-range-else range)) |
(hif-hide-line (hif-range-else range)) |
759 |
(hide-ifdef-region (hif-range-else range) |
(hide-ifdef-region (hif-range-else range) |
760 |
(1- (hif-range-end range))) |
(1- (hif-range-end range))) |
761 |
(hif-recurse-on (hif-range-start range) |
(hif-recurse-on (hif-range-start range) |
762 |
(hif-range-else range))) |
(hif-range-else range))) |