+ int flags=global_flags,retval=0;
+ char *x,*y;
+
+#ifdef CONFIG_FEATURE_SORT_BIG
+ struct sort_key *key;
+
+ for(key=key_list;!retval && key;key=key->next_key) {
+ flags=(key->flags) ? key->flags : global_flags;
+ /* Chop out and modify key chunks, handling -dfib */
+ x=get_key(*(char **)xarg,key,flags);
+ y=get_key(*(char **)yarg,key,flags);
+#else
+ /* This curly bracket serves no purpose but to match the nesting
+ level of the for() loop we're not using */
+ {
+ x=*(char **)xarg;
+ y=*(char **)yarg;
+#endif
+ /* Perform actual comparison */
+ switch(flags&7) {
+ default:
+ bb_error_msg_and_die("Unknown sort type.");
+ break;
+ /* Ascii sort */
+ case 0:
+ retval=strcmp(x,y);
+ break;
+#ifdef CONFIG_FEATURE_SORT_BIG
+ case FLAG_g:
+ {
+ char *xx,*yy;
+ double dx=strtod(x,&xx), dy=strtod(y,&yy);
+ /* not numbers < NaN < -infinity < numbers < +infinity) */
+ if(x==xx) retval=(y==yy ? 0 : -1);
+ else if(y==yy) retval=1;
+ /* Check for isnan */
+ else if(dx != dx) retval = (dy != dy) ? 0 : -1;
+ else if(dy != dy) retval = 1;
+ /* Check for infinity. Could underflow, but it avoids libm. */
+ else if(1.0/dx == 0.0) {
+ if(dx<0) retval=((1.0/dy == 0.0 && dy<0) ? 0 : -1);
+ else retval=((1.0/dy == 0.0 && dy>0) ? 0 : 1);
+ } else if(1.0/dy == 0.0) retval=dy<0 ? 1 : -1;
+ else retval=dx>dy ? 1 : (dx<dy ? -1 : 0);
+ break;
+ }
+ case FLAG_M:
+ {
+ struct tm thyme;
+ int dx;
+ char *xx,*yy;
+
+ xx=strptime(x,"%b",&thyme);
+ dx=thyme.tm_mon;
+ yy=strptime(y,"%b",&thyme);
+ if(!xx) retval=(!yy ? 0 : -1);
+ else if(!yy) retval=1;
+ else retval=(dx==thyme.tm_mon ? 0 : dx-thyme.tm_mon);
+ break;
+ }
+ /* Full floating point version of -n */
+ case FLAG_n:
+ {
+ double dx=atof(x),dy=atof(y);
+ retval=dx>dy ? 1 : (dx<dy ? -1 : 0);
+ break;
+ }
+ }
+ /* Free key copies. */
+ if(x!=*(char **)xarg) free(x);
+ if(y!=*(char **)yarg) free(y);
+ if(retval) break;
+#else
+ /* Integer version of -n for tiny systems */
+ case FLAG_n:
+ retval=atoi(x)-atoi(y);
+ break;
+ }
+#endif
+ }
+ /* Perform fallback sort if necessary */
+ if(!retval && !(global_flags&FLAG_s))
+ retval=strcmp(*(char **)xarg, *(char **)yarg);
+//dprintf(2,"reverse=%d\n",flags&FLAG_r);
+ return ((flags&FLAG_r)?-1:1)*retval;