Function: c-get-lang-constant

c-get-lang-constant is a byte-compiled function defined in cc-defs.el.gz.

Signature

(c-get-lang-constant NAME &optional SOURCE-FILES MODE)

Source Code

;; Defined in /usr/src/emacs/lisp/progmodes/cc-defs.el.gz
(defun c-get-lang-constant (name &optional source-files mode)
  ;; Used by `c-lang-const'.

  (or mode
      (setq mode c-buffer-is-cc-mode)
      (error "No current language"))

  (let* ((sym (intern (symbol-name name) c-lang-constants))
	 (source (get sym 'source))
	 elem
	 (eval-in-sym (and c-lang-constants-under-evaluation
			   (caar c-lang-constants-under-evaluation))))

    ;; Record the dependencies between this symbol and the one we're
    ;; being evaluated in.
    (when eval-in-sym
      (or (memq eval-in-sym (get sym 'dependents))
	  (put sym 'dependents (cons eval-in-sym (get sym 'dependents)))))

    ;; Make sure the source files have entries on the `source'
    ;; property so that loading will take place when necessary.
    (while source-files
      (unless (assq (car source-files) source)
	(put sym 'source
	     (setq source (cons (list (car source-files)) source)))
	;; Might pull in more definitions which affect the value.  The
	;; clearing of dependent values etc is done when the
	;; definition is encountered during the load; this is just to
	;; jump past the check for a cached value below.
	(set sym nil))
      (setq source-files (cdr source-files)))

    (if (and (boundp sym)
	     (setq elem (assq mode (symbol-value sym))))
	(cdr elem)

      ;; Check if an evaluation of this symbol is already underway.
      ;; In that case we just continue with the "assignment" before
      ;; the one currently being evaluated, thereby creating the
      ;; illusion if a `setq'-like sequence of assignments.
      (let* ((c-buffer-is-cc-mode mode)
	     (source-pos
	      (or (assq sym c-lang-constants-under-evaluation)
		  (cons sym (vector source nil))))
	     ;; Append `c-lang-constants-under-evaluation' even if an
	     ;; earlier entry is found.  It's only necessary to get
	     ;; the recording of dependencies above correct.
	     (c-lang-constants-under-evaluation
	      (cons source-pos c-lang-constants-under-evaluation))
	     (fallback (get mode 'c-fallback-mode))
	     value
	     ;; Make sure the recursion limits aren't very low
	     ;; since the `c-lang-const' dependencies can go deep.
	     (max-specpdl-size (max max-specpdl-size 3000))
	     (max-lisp-eval-depth (max max-lisp-eval-depth 1000)))

	(if (if fallback
		(let ((backup-source-pos (copy-sequence (cdr source-pos))))
		  (and
		   ;; First try the original mode but don't accept an
		   ;; entry matching all languages since the fallback
		   ;; mode might have an explicit entry before that.
		   (eq (setq value (c-find-assignment-for-mode
				    (cdr source-pos) mode nil name))
		       c-lang--novalue)
		   ;; Try again with the fallback mode from the
		   ;; original position.  Note that
		   ;; `c-buffer-is-cc-mode' still is the real mode if
		   ;; language parameterization takes place.
		   (eq (setq value (c-find-assignment-for-mode
				    (setcdr source-pos backup-source-pos)
				    fallback t name))
		       c-lang--novalue)))
	      ;; A simple lookup with no fallback mode.
	      (eq (setq value (c-find-assignment-for-mode
			       (cdr source-pos) mode t name))
		  c-lang--novalue))
	    (error
	     "`%s' got no (prior) value in %S (might be a cyclic reference)"
	     name mode))

	(condition-case err
	    (setq value (funcall value))
	  (error
	   ;; Print a message to aid in locating the error.  We don't
	   ;; print the error itself since that will be done later by
	   ;; some caller higher up.
	   (message "Eval error in the `c-lang-defconst' for `%S' in %s:"
		    sym mode)
	   (makunbound sym)
	   (signal (car err) (cdr err))))

	(set sym (cons (cons mode value) (symbol-value sym)))
	value))))