aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorRichard M. Stallman2001-10-30 01:54:29 +0000
committerRichard M. Stallman2001-10-30 01:54:29 +0000
commit1f79789d4aea615815127596ccb7f3acc0db5c7f (patch)
tree14d0a6c4897d1047dea9dd2132628ee6a65d7e3a /src
parentb2304472681772a10f335a0c1e2f040037d2e085 (diff)
downloademacs-1f79789d4aea615815127596ccb7f3acc0db5c7f.tar.gz
emacs-1f79789d4aea615815127596ccb7f3acc0db5c7f.zip
(Frequire): Detect recursive try to require the same
feature 3 or more levels deep, and get error. (require_unwind): New subroutine. (require_nesting_list): New variable. (syms_of_fns): Init and staticpro it.
Diffstat (limited to 'src')
-rw-r--r--src/fns.c44
1 files changed, 43 insertions, 1 deletions
diff --git a/src/fns.c b/src/fns.c
index a948ed7b567..62f9d85682c 100644
--- a/src/fns.c
+++ b/src/fns.c
@@ -3075,6 +3075,18 @@ particular subfeatures supported in this version of FEATURE. */)
3075 3075
3076 return feature; 3076 return feature;
3077} 3077}
3078
3079/* `require' and its subroutines. */
3080
3081/* List of features currently being require'd, innermost first. */
3082
3083Lisp_Object require_nesting_list;
3084
3085require_unwind (old_value)
3086 Lisp_Object old_value;
3087{
3088 require_nesting_list = old_value;
3089}
3078 3090
3079DEFUN ("require", Frequire, Srequire, 1, 3, 0, 3091DEFUN ("require", Frequire, Srequire, 1, 3, 0,
3080 doc: /* If feature FEATURE is not loaded, load it from FILENAME. 3092 doc: /* If feature FEATURE is not loaded, load it from FILENAME.
@@ -3091,7 +3103,10 @@ The normal messages at start and end of loading FILENAME are suppressed. */)
3091 Lisp_Object feature, filename, noerror; 3103 Lisp_Object feature, filename, noerror;
3092{ 3104{
3093 register Lisp_Object tem; 3105 register Lisp_Object tem;
3106 struct gcpro gcpro1, gcpro2;
3107
3094 CHECK_SYMBOL (feature, 0); 3108 CHECK_SYMBOL (feature, 0);
3109
3095 tem = Fmemq (feature, Vfeatures); 3110 tem = Fmemq (feature, Vfeatures);
3096 3111
3097 LOADHIST_ATTACH (Fcons (Qrequire, feature)); 3112 LOADHIST_ATTACH (Fcons (Qrequire, feature));
@@ -3099,26 +3114,50 @@ The normal messages at start and end of loading FILENAME are suppressed. */)
3099 if (NILP (tem)) 3114 if (NILP (tem))
3100 { 3115 {
3101 int count = specpdl_ptr - specpdl; 3116 int count = specpdl_ptr - specpdl;
3117 int nesting = 0;
3118
3119 /* A certain amount of recursive `require' is legitimate,
3120 but if we require the same feature recursively 3 times,
3121 signal an error. */
3122 tem = require_nesting_list;
3123 while (! NILP (tem))
3124 {
3125 if (! NILP (Fequal (feature, XCAR (tem))))
3126 nesting++;
3127 tem = XCDR (tem);
3128 }
3129 if (nesting > 2)
3130 error ("Recursive `require' for feature `%s'",
3131 XSYMBOL (feature)->name->data);
3132
3133 /* Update the list for any nested `require's that occur. */
3134 record_unwind_protect (require_unwind, require_nesting_list);
3135 require_nesting_list = Fcons (feature, require_nesting_list);
3102 3136
3103 /* Value saved here is to be restored into Vautoload_queue */ 3137 /* Value saved here is to be restored into Vautoload_queue */
3104 record_unwind_protect (un_autoload, Vautoload_queue); 3138 record_unwind_protect (un_autoload, Vautoload_queue);
3105 Vautoload_queue = Qt; 3139 Vautoload_queue = Qt;
3106 3140
3141 /* Load the file. */
3142 GCPRO2 (feature, filename);
3107 tem = Fload (NILP (filename) ? Fsymbol_name (feature) : filename, 3143 tem = Fload (NILP (filename) ? Fsymbol_name (feature) : filename,
3108 noerror, Qt, Qnil, (NILP (filename) ? Qt : Qnil)); 3144 noerror, Qt, Qnil, (NILP (filename) ? Qt : Qnil));
3145 UNGCPRO;
3146
3109 /* If load failed entirely, return nil. */ 3147 /* If load failed entirely, return nil. */
3110 if (NILP (tem)) 3148 if (NILP (tem))
3111 return unbind_to (count, Qnil); 3149 return unbind_to (count, Qnil);
3112 3150
3113 tem = Fmemq (feature, Vfeatures); 3151 tem = Fmemq (feature, Vfeatures);
3114 if (NILP (tem)) 3152 if (NILP (tem))
3115 error ("Required feature %s was not provided", 3153 error ("Required feature `%s' was not provided",
3116 XSYMBOL (feature)->name->data); 3154 XSYMBOL (feature)->name->data);
3117 3155
3118 /* Once loading finishes, don't undo it. */ 3156 /* Once loading finishes, don't undo it. */
3119 Vautoload_queue = Qt; 3157 Vautoload_queue = Qt;
3120 feature = unbind_to (count, feature); 3158 feature = unbind_to (count, feature);
3121 } 3159 }
3160
3122 return feature; 3161 return feature;
3123} 3162}
3124 3163
@@ -5276,6 +5315,9 @@ syms_of_fns ()
5276 staticpro (&string_char_byte_cache_string); 5315 staticpro (&string_char_byte_cache_string);
5277 string_char_byte_cache_string = Qnil; 5316 string_char_byte_cache_string = Qnil;
5278 5317
5318 require_nesting_list = Qnil;
5319 staticpro (&require_nesting_list);
5320
5279 Fset (Qyes_or_no_p_history, Qnil); 5321 Fset (Qyes_or_no_p_history, Qnil);
5280 5322
5281 DEFVAR_LISP ("features", &Vfeatures, 5323 DEFVAR_LISP ("features", &Vfeatures,