/*
 *  call-seq:
 *     str <=> other_str   => -1, 0, +1
 *  
 *  Comparison---Returns -1 if <i>other_str</i> is less than, 0 if
 *  <i>other_str</i> is equal to, and +1 if <i>other_str</i> is greater than
 *  <i>str</i>. If the strings are of different lengths, and the strings are
 *  equal when compared up to the shortest length, then the longer string is
 *  considered greater than the shorter one. If the variable <code>$=</code> is
 *  <code>false</code>, the comparison is based on comparing the binary values
 *  of each character in the string. In older versions of Ruby, setting
 *  <code>$=</code> allowed case-insensitive comparisons; this is now deprecated
 *  in favor of using <code>String#casecmp</code>.
 *
 *  <code><=></code> is the basis for the methods <code><</code>,
 *  <code><=</code>, <code>></code>, <code>>=</code>, and <code>between?</code>,
 *  included from module <code>Comparable</code>.  The method
 *  <code>String#==</code> does not use <code>Comparable#==</code>.
 *     
 *     "abcdef" <=> "abcde"     #=> 1
 *     "abcdef" <=> "abcdef"    #=> 0
 *     "abcdef" <=> "abcdefg"   #=> -1
 *     "abcdef" <=> "ABCDEF"    #=> 1
 */

static VALUE
rb_str_cmp_m(str1, str2)
    VALUE str1, str2;
{
    long result;

    if (TYPE(str2) != T_STRING) {
        if (!rb_respond_to(str2, rb_intern("to_str"))) {
            return Qnil;
        }
        else if (!rb_respond_to(str2, rb_intern("<=>"))) {
            return Qnil;
        }
        else {
            VALUE tmp = rb_funcall(str2, rb_intern("<=>"), 1, str1);

            if (NIL_P(tmp)) return Qnil;
            if (!FIXNUM_P(tmp)) {
                return rb_funcall(LONG2FIX(0), '-', 1, tmp);
            }
            result = -FIX2LONG(tmp);
        }
    }
    else {
        result = rb_str_cmp(str1, str2);
    }
    return LONG2NUM(result);
}