@@ -60,6 +60,43 @@ static zend_class_entry * spl_find_ce_by_name(zend_string *name, bool autoload)
6060 return ce ;
6161}
6262
63+ static void spl_add_class_name (HashTable * list , zend_string * name )
64+ {
65+ zval t ;
66+ ZVAL_STR_COPY (& t , name );
67+ zend_hash_add (list , name , & t );
68+ }
69+
70+ static void spl_add_interfaces (HashTable * list , const zend_class_entry * pce )
71+ {
72+ if (pce -> num_interfaces ) {
73+ ZEND_ASSERT (pce -> ce_flags & ZEND_ACC_LINKED );
74+ for (uint32_t num_interfaces = 0 ; num_interfaces < pce -> num_interfaces ; num_interfaces ++ ) {
75+ spl_add_class_name (list , pce -> interfaces [num_interfaces ]-> name );
76+ }
77+ }
78+ }
79+
80+ static void spl_add_traits (HashTable * list , const zend_class_entry * pce )
81+ {
82+ for (uint32_t num_traits = 0 ; num_traits < pce -> num_traits ; num_traits ++ ) {
83+ spl_add_class_name (list , pce -> trait_names [num_traits ].name );
84+ }
85+ }
86+
87+ static void spl_add_classes (HashTable * list , const zend_class_entry * pce , bool only_classes , bool only_interfaces )
88+ {
89+ ZEND_ASSERT (pce );
90+ ZEND_ASSERT (!(only_classes && only_interfaces ) && "Cannot have both only classes and only interfaces be enabled" );
91+ if (
92+ (only_classes && (pce -> ce_flags & ZEND_ACC_INTERFACE ) == ZEND_ACC_INTERFACE )
93+ || (only_interfaces && (pce -> ce_flags & ZEND_ACC_INTERFACE ) == 0 )
94+ ) {
95+ return ;
96+ }
97+ spl_add_class_name (list , pce -> name );
98+ }
99+
63100/* {{{ Return an array containing the names of all parent classes */
64101PHP_FUNCTION (class_parents )
65102{
@@ -88,7 +125,7 @@ PHP_FUNCTION(class_parents)
88125 array_init (return_value );
89126 const zend_class_entry * parent_class = ce -> parent ;
90127 while (parent_class ) {
91- spl_add_class_name (return_value , parent_class , 0 , 0 );
128+ spl_add_class_name (Z_ARR_P ( return_value ) , parent_class -> name );
92129 parent_class = parent_class -> parent ;
93130 }
94131}
@@ -119,7 +156,7 @@ PHP_FUNCTION(class_implements)
119156 }
120157
121158 array_init (return_value );
122- spl_add_interfaces (return_value , ce , 1 , ZEND_ACC_INTERFACE );
159+ spl_add_interfaces (Z_ARR_P ( return_value ) , ce );
123160}
124161/* }}} */
125162
@@ -148,69 +185,69 @@ PHP_FUNCTION(class_uses)
148185 }
149186
150187 array_init (return_value );
151- spl_add_traits (return_value , ce , 1 , ZEND_ACC_TRAIT );
188+ spl_add_traits (Z_ARR_P ( return_value ) , ce );
152189}
153190/* }}} */
154191
155- #define SPL_ADD_CLASS (class_name , z_list , sub , allow , ce_flags ) \
156- spl_add_classes(spl_ce_ ## class_name, z_list, sub, allow, ce_flags )
157-
158- #define SPL_LIST_CLASSES (z_list , sub , allow , ce_flags ) \
159- SPL_ADD_CLASS(AppendIterator, z_list, sub, allow, ce_flags ); \
160- SPL_ADD_CLASS(ArrayIterator, z_list, sub, allow, ce_flags ); \
161- SPL_ADD_CLASS(ArrayObject, z_list, sub, allow, ce_flags ); \
162- SPL_ADD_CLASS(BadFunctionCallException, z_list, sub, allow, ce_flags ); \
163- SPL_ADD_CLASS(BadMethodCallException, z_list, sub, allow, ce_flags ); \
164- SPL_ADD_CLASS(CachingIterator, z_list, sub, allow, ce_flags ); \
165- SPL_ADD_CLASS(CallbackFilterIterator, z_list, sub, allow, ce_flags ); \
166- SPL_ADD_CLASS(DirectoryIterator, z_list, sub, allow, ce_flags ); \
167- SPL_ADD_CLASS(DomainException, z_list, sub, allow, ce_flags ); \
168- SPL_ADD_CLASS(EmptyIterator, z_list, sub, allow, ce_flags ); \
169- SPL_ADD_CLASS(FilesystemIterator, z_list, sub, allow, ce_flags ); \
170- SPL_ADD_CLASS(FilterIterator, z_list, sub, allow, ce_flags ); \
171- SPL_ADD_CLASS(GlobIterator, z_list, sub, allow, ce_flags ); \
172- SPL_ADD_CLASS(InfiniteIterator, z_list, sub, allow, ce_flags ); \
173- SPL_ADD_CLASS(InvalidArgumentException, z_list, sub, allow, ce_flags ); \
174- SPL_ADD_CLASS(IteratorIterator, z_list, sub, allow, ce_flags ); \
175- SPL_ADD_CLASS(LengthException, z_list, sub, allow, ce_flags ); \
176- SPL_ADD_CLASS(LimitIterator, z_list, sub, allow, ce_flags ); \
177- SPL_ADD_CLASS(LogicException, z_list, sub, allow, ce_flags ); \
178- SPL_ADD_CLASS(MultipleIterator, z_list, sub, allow, ce_flags ); \
179- SPL_ADD_CLASS(NoRewindIterator, z_list, sub, allow, ce_flags ); \
180- SPL_ADD_CLASS(OuterIterator, z_list, sub, allow, ce_flags ); \
181- SPL_ADD_CLASS(OutOfBoundsException, z_list, sub, allow, ce_flags ); \
182- SPL_ADD_CLASS(OutOfRangeException, z_list, sub, allow, ce_flags ); \
183- SPL_ADD_CLASS(OverflowException, z_list, sub, allow, ce_flags ); \
184- SPL_ADD_CLASS(ParentIterator, z_list, sub, allow, ce_flags ); \
185- SPL_ADD_CLASS(RangeException, z_list, sub, allow, ce_flags ); \
186- SPL_ADD_CLASS(RecursiveArrayIterator, z_list, sub, allow, ce_flags ); \
187- SPL_ADD_CLASS(RecursiveCachingIterator, z_list, sub, allow, ce_flags ); \
188- SPL_ADD_CLASS(RecursiveCallbackFilterIterator, z_list, sub, allow, ce_flags ); \
189- SPL_ADD_CLASS(RecursiveDirectoryIterator, z_list, sub, allow, ce_flags ); \
190- SPL_ADD_CLASS(RecursiveFilterIterator, z_list, sub, allow, ce_flags ); \
191- SPL_ADD_CLASS(RecursiveIterator, z_list, sub, allow, ce_flags ); \
192- SPL_ADD_CLASS(RecursiveIteratorIterator, z_list, sub, allow, ce_flags ); \
193- SPL_ADD_CLASS(RecursiveRegexIterator, z_list, sub, allow, ce_flags ); \
194- SPL_ADD_CLASS(RecursiveTreeIterator, z_list, sub, allow, ce_flags ); \
195- SPL_ADD_CLASS(RegexIterator, z_list, sub, allow, ce_flags ); \
196- SPL_ADD_CLASS(RuntimeException, z_list, sub, allow, ce_flags ); \
197- SPL_ADD_CLASS(SeekableIterator, z_list, sub, allow, ce_flags ); \
198- SPL_ADD_CLASS(SplDoublyLinkedList, z_list, sub, allow, ce_flags ); \
199- SPL_ADD_CLASS(SplFileInfo, z_list, sub, allow, ce_flags ); \
200- SPL_ADD_CLASS(SplFileObject, z_list, sub, allow, ce_flags ); \
201- SPL_ADD_CLASS(SplFixedArray, z_list, sub, allow, ce_flags ); \
202- SPL_ADD_CLASS(SplHeap, z_list, sub, allow, ce_flags ); \
203- SPL_ADD_CLASS(SplMinHeap, z_list, sub, allow, ce_flags ); \
204- SPL_ADD_CLASS(SplMaxHeap, z_list, sub, allow, ce_flags ); \
205- SPL_ADD_CLASS(SplObjectStorage, z_list, sub, allow, ce_flags ); \
206- SPL_ADD_CLASS(SplObserver, z_list, sub, allow, ce_flags ); \
207- SPL_ADD_CLASS(SplPriorityQueue, z_list, sub, allow, ce_flags ); \
208- SPL_ADD_CLASS(SplQueue, z_list, sub, allow, ce_flags ); \
209- SPL_ADD_CLASS(SplStack, z_list, sub, allow, ce_flags ); \
210- SPL_ADD_CLASS(SplSubject, z_list, sub, allow, ce_flags ); \
211- SPL_ADD_CLASS(SplTempFileObject, z_list, sub, allow, ce_flags ); \
212- SPL_ADD_CLASS(UnderflowException, z_list, sub, allow, ce_flags ); \
213- SPL_ADD_CLASS(UnexpectedValueException, z_list, sub, allow, ce_flags ); \
192+ #define SPL_ADD_CLASS (class_name , z_list , only_classes , only_interfaces ) \
193+ spl_add_classes(Z_ARR_P(z_list), spl_ce_ ## class_name, only_classes, only_interfaces )
194+
195+ #define SPL_LIST_CLASSES (z_list , only_classes , only_interfaces ) \
196+ SPL_ADD_CLASS(AppendIterator, z_list, only_classes, only_interfaces ); \
197+ SPL_ADD_CLASS(ArrayIterator, z_list, only_classes, only_interfaces ); \
198+ SPL_ADD_CLASS(ArrayObject, z_list, only_classes, only_interfaces ); \
199+ SPL_ADD_CLASS(BadFunctionCallException, z_list, only_classes, only_interfaces ); \
200+ SPL_ADD_CLASS(BadMethodCallException, z_list, only_classes, only_interfaces ); \
201+ SPL_ADD_CLASS(CachingIterator, z_list, only_classes, only_interfaces ); \
202+ SPL_ADD_CLASS(CallbackFilterIterator, z_list, only_classes, only_interfaces ); \
203+ SPL_ADD_CLASS(DirectoryIterator, z_list, only_classes, only_interfaces ); \
204+ SPL_ADD_CLASS(DomainException, z_list, only_classes, only_interfaces ); \
205+ SPL_ADD_CLASS(EmptyIterator, z_list, only_classes, only_interfaces ); \
206+ SPL_ADD_CLASS(FilesystemIterator, z_list, only_classes, only_interfaces ); \
207+ SPL_ADD_CLASS(FilterIterator, z_list, only_classes, only_interfaces ); \
208+ SPL_ADD_CLASS(GlobIterator, z_list, only_classes, only_interfaces ); \
209+ SPL_ADD_CLASS(InfiniteIterator, z_list, only_classes, only_interfaces ); \
210+ SPL_ADD_CLASS(InvalidArgumentException, z_list, only_classes, only_interfaces ); \
211+ SPL_ADD_CLASS(IteratorIterator, z_list, only_classes, only_interfaces ); \
212+ SPL_ADD_CLASS(LengthException, z_list, only_classes, only_interfaces ); \
213+ SPL_ADD_CLASS(LimitIterator, z_list, only_classes, only_interfaces ); \
214+ SPL_ADD_CLASS(LogicException, z_list, only_classes, only_interfaces ); \
215+ SPL_ADD_CLASS(MultipleIterator, z_list, only_classes, only_interfaces ); \
216+ SPL_ADD_CLASS(NoRewindIterator, z_list, only_classes, only_interfaces ); \
217+ SPL_ADD_CLASS(OuterIterator, z_list, only_classes, only_interfaces ); \
218+ SPL_ADD_CLASS(OutOfBoundsException, z_list, only_classes, only_interfaces ); \
219+ SPL_ADD_CLASS(OutOfRangeException, z_list, only_classes, only_interfaces ); \
220+ SPL_ADD_CLASS(OverflowException, z_list, only_classes, only_interfaces ); \
221+ SPL_ADD_CLASS(ParentIterator, z_list, only_classes, only_interfaces ); \
222+ SPL_ADD_CLASS(RangeException, z_list, only_classes, only_interfaces ); \
223+ SPL_ADD_CLASS(RecursiveArrayIterator, z_list, only_classes, only_interfaces ); \
224+ SPL_ADD_CLASS(RecursiveCachingIterator, z_list, only_classes, only_interfaces ); \
225+ SPL_ADD_CLASS(RecursiveCallbackFilterIterator, z_list, only_classes, only_interfaces ); \
226+ SPL_ADD_CLASS(RecursiveDirectoryIterator, z_list, only_classes, only_interfaces ); \
227+ SPL_ADD_CLASS(RecursiveFilterIterator, z_list, only_classes, only_interfaces ); \
228+ SPL_ADD_CLASS(RecursiveIterator, z_list, only_classes, only_interfaces ); \
229+ SPL_ADD_CLASS(RecursiveIteratorIterator, z_list, only_classes, only_interfaces ); \
230+ SPL_ADD_CLASS(RecursiveRegexIterator, z_list, only_classes, only_interfaces ); \
231+ SPL_ADD_CLASS(RecursiveTreeIterator, z_list, only_classes, only_interfaces ); \
232+ SPL_ADD_CLASS(RegexIterator, z_list, only_classes, only_interfaces ); \
233+ SPL_ADD_CLASS(RuntimeException, z_list, only_classes, only_interfaces ); \
234+ SPL_ADD_CLASS(SeekableIterator, z_list, only_classes, only_interfaces ); \
235+ SPL_ADD_CLASS(SplDoublyLinkedList, z_list, only_classes, only_interfaces ); \
236+ SPL_ADD_CLASS(SplFileInfo, z_list, only_classes, only_interfaces ); \
237+ SPL_ADD_CLASS(SplFileObject, z_list, only_classes, only_interfaces ); \
238+ SPL_ADD_CLASS(SplFixedArray, z_list, only_classes, only_interfaces ); \
239+ SPL_ADD_CLASS(SplHeap, z_list, only_classes, only_interfaces ); \
240+ SPL_ADD_CLASS(SplMinHeap, z_list, only_classes, only_interfaces ); \
241+ SPL_ADD_CLASS(SplMaxHeap, z_list, only_classes, only_interfaces ); \
242+ SPL_ADD_CLASS(SplObjectStorage, z_list, only_classes, only_interfaces ); \
243+ SPL_ADD_CLASS(SplObserver, z_list, only_classes, only_interfaces ); \
244+ SPL_ADD_CLASS(SplPriorityQueue, z_list, only_classes, only_interfaces ); \
245+ SPL_ADD_CLASS(SplQueue, z_list, only_classes, only_interfaces ); \
246+ SPL_ADD_CLASS(SplStack, z_list, only_classes, only_interfaces ); \
247+ SPL_ADD_CLASS(SplSubject, z_list, only_classes, only_interfaces ); \
248+ SPL_ADD_CLASS(SplTempFileObject, z_list, only_classes, only_interfaces ); \
249+ SPL_ADD_CLASS(UnderflowException, z_list, only_classes, only_interfaces ); \
250+ SPL_ADD_CLASS(UnexpectedValueException, z_list, only_classes, only_interfaces ); \
214251
215252/* {{{ Return an array containing the names of all classes and interfaces defined in SPL */
216253PHP_FUNCTION (spl_classes )
@@ -219,7 +256,7 @@ PHP_FUNCTION(spl_classes)
219256
220257 array_init (return_value );
221258
222- SPL_LIST_CLASSES (return_value , 0 , 0 , 0 )
259+ SPL_LIST_CLASSES (return_value , false, false )
223260}
224261/* }}} */
225262
@@ -486,7 +523,7 @@ PHP_MINFO_FUNCTION(spl)
486523 php_info_print_table_row (2 , "SPL support" , "enabled" );
487524
488525 array_init (& list );
489- SPL_LIST_CLASSES (& list , 0 , 1 , ZEND_ACC_INTERFACE )
526+ SPL_LIST_CLASSES (& list , false, true )
490527 strg = estrdup ("" );
491528 ZEND_HASH_MAP_FOREACH_VAL (Z_ARRVAL_P (& list ), zv ) {
492529 spl_build_class_list_string (zv , & strg );
@@ -496,7 +533,7 @@ PHP_MINFO_FUNCTION(spl)
496533 efree (strg );
497534
498535 array_init (& list );
499- SPL_LIST_CLASSES (& list , 0 , -1 , ZEND_ACC_INTERFACE )
536+ SPL_LIST_CLASSES (& list , true, false )
500537 strg = estrdup ("" );
501538 ZEND_HASH_MAP_FOREACH_VAL (Z_ARRVAL_P (& list ), zv ) {
502539 spl_build_class_list_string (zv , & strg );
0 commit comments