Annotation of researchv10dc/cmd/icon/src/iconx/rcomp.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * File: rcomp.c
        !             3:  *  Contents: anycmp, equiv, lexcmp, numcmp
        !             4:  */
        !             5: 
        !             6: #include "../h/rt.h"
        !             7: 
        !             8: /*
        !             9:  * anycmp - compare any two objects.  The result of the comparison is
        !            10:  *  an integer such that:
        !            11:  *    d1 = d2 -> 0
        !            12:  *    d1 > d2 -> >0  (1 if same type)
        !            13:  *    d1 < d2 -> <0  (-1 if same type)
        !            14:  */
        !            15: 
        !            16: anycmp(d1,d2)
        !            17: struct descrip *d1, *d2;
        !            18:    {
        !            19:    register int o1, o2;
        !            20:    register long lresult;
        !            21:    double rres1, rres2, rresult;
        !            22: 
        !            23:    /*
        !            24:     * Get a collating number for d1 and d2.
        !            25:     */
        !            26:    o1 = order(d1);
        !            27:    o2 = order(d2);
        !            28: 
        !            29:    /*
        !            30:     * If d1 and d2 aren't of the same type, return the difference of
        !            31:     *  their collating numbers.
        !            32:     */
        !            33:    if (o1 != o2)
        !            34:       return (o1 - o2);
        !            35: 
        !            36:    if (o1 == D_Null)
        !            37:       /*
        !            38:        * o1 0, (D_Null), return 0 because all null values are the same.
        !            39:        */
        !            40:       return 0;
        !            41:    if (o1 == 3)
        !            42:       /*
        !            43:        * d1 and d2 are strings, use lexcmp to compare them.
        !            44:        */
        !            45:       return lexcmp(d1,d2);
        !            46: 
        !            47:    switch (Type(*d1)) {
        !            48:       /*
        !            49:        * For numbers, return -1, 0, 1, depending on whether d1 <, =, > d2.
        !            50:        */
        !            51:       case T_Integer:
        !            52:         lresult = IntVal(*d1) - IntVal(*d2);
        !            53:         if (lresult == 0)
        !            54:            return 0;
        !            55:         return ((lresult > 0) ? 1 : -1);
        !            56: 
        !            57:       case T_Longint:
        !            58:         lresult = BlkLoc(*d1)->longint.intval - BlkLoc(*d2)->longint.intval;
        !            59:         if (lresult == 0)
        !            60:            return 0;
        !            61:         return ((lresult > 0) ? 1 : -1);
        !            62: 
        !            63:       case T_Real:
        !            64:          GetReal(d1,rres1);
        !            65:          GetReal(d2,rres2);
        !            66:          rresult = rres1 - rres2;
        !            67:         if (rresult == 0)
        !            68:            return 0;
        !            69:         return ((rresult > 0) ? 1 : -1);
        !            70: 
        !            71:       case T_Cset:
        !            72:       case T_File:
        !            73:       case T_Proc:
        !            74:       case T_List:
        !            75:       case T_Table:
        !            76:       case T_Set:
        !            77:       case T_Record:
        !            78:       case T_Coexpr:
        !            79:         /*
        !            80:          * Csets, files, procedures, lists, tables, records, co-expressions
        !            81:          *  and sets have no specified collating sequence so any two of
        !            82:          *  the same type are considered to be equal.
        !            83:          */
        !            84:         return 0;
        !            85: 
        !            86:       default:
        !            87:         syserr("anycmp: unknown datatype.");
        !            88:       }
        !            89:    }
        !            90: 
        !            91: /*
        !            92:  * order(x) - return collating number for object x.
        !            93:  */
        !            94: 
        !            95: order(d)
        !            96: struct descrip *d;
        !            97:    {
        !            98:    if (Qual(*d))
        !            99:       return 3;             /* string */
        !           100:    switch (Type(*d)) {
        !           101:       case T_Null:
        !           102:         return 0;
        !           103:       case T_Integer:
        !           104:       case T_Longint:
        !           105:         return 1;
        !           106:       case T_Real:
        !           107:         return 2;
        !           108:       case T_Cset:
        !           109:         return 4;
        !           110:       case T_Coexpr:
        !           111:         return 5;
        !           112:       case T_File:
        !           113:         return 6;
        !           114:       case T_Proc:
        !           115:         return 7;
        !           116:       case T_List:
        !           117:         return 8;
        !           118:       case T_Table:
        !           119:         return 9;
        !           120:       case T_Set:
        !           121:         return 10;
        !           122:       case T_Record:
        !           123:         return 11;
        !           124:       default:
        !           125:         syserr("order: unknown datatype.");
        !           126:       }
        !           127:    }
        !           128: 
        !           129: 
        !           130: /*
        !           131:  * equiv - test equivalence of two objects.
        !           132:  */
        !           133: 
        !           134: equiv(dp1, dp2)
        !           135: struct descrip *dp1, *dp2;
        !           136:    {
        !           137:    register int result, i;
        !           138:    register char *s1, *s2;
        !           139:    double rres1, rres2;
        !           140: 
        !           141:    result = 0;
        !           142: 
        !           143:       /*
        !           144:        * If the descriptors are identical, the objects are equivalent.
        !           145:        */
        !           146:    if (EqlDesc(*dp1,*dp2))
        !           147:       result = 1;
        !           148:    else if (Qual(*dp1) && Qual(*dp2)) {
        !           149: 
        !           150:       /*
        !           151:        *  If both are strings of equal length, compare their characters.
        !           152:        */
        !           153: 
        !           154:       if ((i = StrLen(*dp1)) == StrLen(*dp2)) {
        !           155:         s1 = StrLoc(*dp1);
        !           156:         s2 = StrLoc(*dp2);
        !           157:         result = 1;
        !           158:         while (i--)
        !           159:           if (*s1++ != *s2++) {
        !           160:              result = 0;
        !           161:              break;
        !           162:              }
        !           163:         }
        !           164:       }
        !           165:    else if (dp1->dword == dp2->dword)
        !           166:       switch (Type(*dp1)) {
        !           167:         /*
        !           168:          * For integers and reals, just compare the values.
        !           169:          */
        !           170:         case T_Integer:
        !           171:            result = (IntVal(*dp1) == IntVal(*dp2));
        !           172:            break;
        !           173: 
        !           174:         case T_Longint:
        !           175:            result =
        !           176:               (BlkLoc(*dp1)->longint.intval == BlkLoc(*dp2)->longint.intval);
        !           177:            break;
        !           178: 
        !           179:         case T_Real:
        !           180:             GetReal(dp1, rres1);
        !           181:             GetReal(dp2, rres2);
        !           182:             result = (rres1 == rres2);
        !           183:            break;
        !           184: 
        !           185:         case T_Cset:
        !           186:            /*
        !           187:             * Compare the bit arrays of the csets.
        !           188:             */
        !           189:            result = 1;
        !           190:            for (i = 0; i < CsetSize; i++)
        !           191:               if (BlkLoc(*dp1)->cset.bits[i] != BlkLoc(*dp2)->cset.bits[i]) {
        !           192:                  result = 0;
        !           193:                  break;
        !           194:                  }
        !           195:         }
        !           196:    else
        !           197:       /*
        !           198:        * dp1 and dp2 are of different types, so they can't be
        !           199:        *  equivalent.
        !           200:        */
        !           201:       result = 0;
        !           202: 
        !           203:    return result;
        !           204:    }
        !           205: 
        !           206: 
        !           207: /*
        !           208:  * lexcmp - lexically compare two strings.
        !           209:  */
        !           210: 
        !           211: lexcmp(d1, d2)
        !           212: struct descrip *d1, *d2;
        !           213:    {
        !           214:    register char *s1, *s2;
        !           215:    register int minlen;
        !           216:    int l1, l2;
        !           217: 
        !           218:    /*
        !           219:     * Get length and starting address of both strings.
        !           220:     */
        !           221:    l1 = StrLen(*d1);
        !           222:    s1 = StrLoc(*d1);
        !           223:    l2 = StrLen(*d2);
        !           224:    s2 = StrLoc(*d2);
        !           225: 
        !           226:    /*
        !           227:     * Set minlen to length of the shorter string.
        !           228:     */
        !           229:    minlen = (l1 <= l2) ? l1 : l2;
        !           230: 
        !           231:    /*
        !           232:     * Compare as many bytes as are in the smaller string.  If an
        !           233:     *  inequality is found, return the difference of the differing
        !           234:     *  bytes.
        !           235:     */
        !           236:    while (minlen--)
        !           237:       if (*s1++ != *s2++)
        !           238:         return (int)((*--s1 & 0377) - (*--s2 & 0377));
        !           239: 
        !           240:    /*
        !           241:     * The strings compared equal for the length of the shorter.  Return
        !           242:     *  the difference in their lengths.  (Thus, the strings must be of
        !           243:     *  the same length to be equal.)
        !           244:     */
        !           245:    return (l1 - l2);
        !           246:    }
        !           247: 
        !           248: 
        !           249: /*
        !           250:  * numcmp - compare two numbers.  Returns -1, 0, 1 for dp1 <, =, > dp2.
        !           251:  *  dp3 is made into a descriptor for the return value.
        !           252:  */
        !           253: 
        !           254: numcmp(dp1, dp2, dp3)
        !           255: struct descrip *dp1, *dp2, *dp3;
        !           256:    {
        !           257:    register int result;
        !           258:    union numeric n1, n2;
        !           259:    int t1, t2;
        !           260:    /*
        !           261:     * Be sure that both dp1 and dp2 are numeric.
        !           262:     */
        !           263: 
        !           264:    if ((t1 = cvnum(dp1, &n1)) == NULL)
        !           265:       runerr(102, dp1);
        !           266:    if ((t2 = cvnum(dp2, &n2)) == NULL)
        !           267:       runerr(102, dp2);
        !           268: 
        !           269:    if (!(t1 == T_Real || t2 == T_Real)) {
        !           270:    /*
        !           271:     *  dp1 and dp2 are both integers, compare them and
        !           272:     *  create an integer descriptor in dp3
        !           273:     */
        !           274: 
        !           275:          result = 0;
        !           276:          if (n1.integer < n2.integer) result = -1;
        !           277:          else if (n1.integer != n2.integer) result = 1;
        !           278:       Mkint(n2.integer, dp3);
        !           279:       }
        !           280:    else {
        !           281: 
        !           282:    /*
        !           283:     *  Either dp1 or dp2 is real. Convert the other to a real,
        !           284:     *  compare them and create a real descriptor in dp3.
        !           285:     */
        !           286: 
        !           287:       if (!(t1 == T_Real))
        !           288:         n1.real = n1.integer;
        !           289:       if (!(t2 == T_Real))
        !           290:         n2.real = n2.integer;
        !           291:          result = 0;
        !           292:          if (n1.real < n2.real) result = -1;
        !           293:          else if (n1.real != n2.real) result = 1;
        !           294:       mkreal(n2.real, dp3);
        !           295:       }
        !           296: 
        !           297:    return result;            /* return result in r0 */
        !           298:    }
        !           299: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.