@@ -47,16 +47,45 @@ enum { DiscreteNode, ContinuousNode, PredictorNode };
4747enum { Classification , Regression };
4848enum { IntVar , FloatVar };
4949
50- int compar_attr ;
50+ /*
51+ * Common interface for qsort_r
52+ * (there are 3 (possibly more) different qsort_r call styles in the wild).
53+ *
54+ */
55+
56+ #if (defined __APPLE__ || defined __DARWIN__ || defined __BSD__ )
57+ #define QSORT_R_STYLE_BSD
58+ #define QSORT_R_FUNC (base , nel , size , thunk , compar ) \
59+ qsort_r(base, nel, size, thunk, compar)
60+ #elif (defined __GLIBC__ || defined __GNU__ || defined __linux__ )
61+ #define QSORT_R_STYLE_GNU
62+ #define QSORT_R_FUNC (base , nel , size , thunk , compar ) \
63+ qsort_r(base, nel, size, compar, thunk)
64+ #elif (defined _MSC_VER )
65+ #define QSORT_R_STYLE_MSVC
66+ #define QSORT_R_FUNC (base , nel , size , thunk , compar ) \
67+ qsort_s(base, nel, size, compar, thunk)
68+ #endif
5169
52- /* This function uses the global variable compar_attr.
70+
71+ #if (defined QSORT_R_STYLE_BSD || defined QSORT_R_STYLE_MSVC )
72+ #define SORT_CMP_FUNC (name ) \
73+ int name(void *context, const void *ptr1, const void *ptr2)
74+ #elif (defined QSORT_R_STYLE_GNU )
75+ #define SORT_CMP_FUNC (name ) \
76+ int name(const void *ptr1, const void *ptr2, void *context)
77+ #else
78+ #error "Unkown qsort_r comparator call convention"
79+ #endif
80+
81+
82+ /*
5383 * Examples with unknowns are larger so that, when sorted, they appear at the bottom.
5484 */
55- int
56- compar_examples (const void * ptr1 , const void * ptr2 )
85+ SORT_CMP_FUNC (compar_examples )
5786{
5887 double x1 , x2 ;
59-
88+ int compar_attr = * ( int * ) context ;
6089 x1 = ((struct Example * )ptr1 )-> x [compar_attr ];
6190 x2 = ((struct Example * )ptr2 )-> x [compar_attr ];
6291 if (isnan (x1 ))
@@ -102,7 +131,7 @@ gain_ratio_c(struct Example *examples, int size, int attr, float cls_entropy, st
102131 struct Example * ex , * ex_end , * ex_next ;
103132 int i , cls , cls_vals , min_instances , size_known ;
104133 float score , * dist_lt , * dist_ge , * attr_dist , best_score , size_weight ;
105-
134+ int compar_attr ;
106135 cls_vals = args -> cls_vals ;
107136
108137 /* min_instances should be at least 1, otherwise there is no point in splitting */
@@ -115,7 +144,7 @@ gain_ratio_c(struct Example *examples, int size, int attr, float cls_entropy, st
115144
116145 /* sort */
117146 compar_attr = attr ;
118- qsort (examples , size , sizeof (struct Example ), compar_examples );
147+ QSORT_R_FUNC (examples , size , sizeof (struct Example ), ( void * ) & compar_attr , compar_examples );
119148
120149 /* compute gain ratio for every split */
121150 size_known = size ;
@@ -236,6 +265,7 @@ mse_c(struct Example *examples, int size, int attr, float cls_mse, struct Args *
236265 struct Example * ex , * ex_end , * ex_next ;
237266 int i , min_instances , size_known ;
238267 float size_attr_known , size_weight , cls_val , best_score , size_attr_cls_known , score ;
268+ int compar_attr ;
239269
240270 struct Variance {
241271 double n , sum , sum2 ;
@@ -246,7 +276,7 @@ mse_c(struct Example *examples, int size, int attr, float cls_mse, struct Args *
246276
247277 /* sort */
248278 compar_attr = attr ;
249- qsort (examples , size , sizeof (struct Example ), compar_examples );
279+ QSORT_R_FUNC (examples , size , sizeof (struct Example ), ( void * ) & compar_attr , compar_examples );
250280
251281 /* compute mse for every split */
252282 size_known = size ;
0 commit comments