home *** CD-ROM | disk | FTP | other *** search
/ ftp.mactech.com 2010 / ftp.mactech.com.tar / ftp.mactech.com / online / source / c / compilers / Tickle-4.0.sit.hqx / Tickle-4.0 / src / lcompare.c < prev    next >
Text File  |  1993-10-31  |  3KB  |  116 lines

  1. /* $Id: lcmp.c,v 1.1 1992/11/10 05:22:10 david Exp $
  2.  *
  3.  * lcmp.c -- Compare two lists for equality.
  4.  *
  5.  * AUTHOR: David Herron <david@twg.com> (work) or <david@davids.mmdf.com> (home)
  6.  *
  7.  * $Log: lcmp.c,v $
  8.  * Revision 1.1  1992/11/10  05:22:10  david
  9.  * Initial revision.
  10.  *
  11.  *
  12.  */
  13.  
  14. #include <tcl.h>
  15.  
  16. /*
  17.  * USAGE: lcompare list1 list2
  18.  *
  19.  * The following is worlds faster than the closest we can get
  20.  * with TCL, namely:
  21.  *
  22.  *    proc lcompare {list1 list2} {
  23.  *        set l1_len [llength $list1]
  24.  *        set l2_len [llength $list2]
  25.  *         if {$l1_len < $l2_len} { return -1 }
  26.  *        if {$l1_len > $l2_len} { return  1 }
  27.  *        set i 0
  28.  *        foreach e1 $list1 {
  29.  *            set e2 [lindex $list2]
  30.  *            if {$e1 == $e2} continue
  31.  *            if {$e1 <  $e2} { return -1 }
  32.  *            if {$e1 >  $e2} { return  1 }
  33.  *        }
  34.  *        return 0
  35.  *    }
  36.  *
  37.  * The advantage the C code has is it only has to parse each
  38.  * list once.  The above parses list1 twice, and list2 many
  39.  * times.
  40.  *
  41.  * RETURN VALUES:
  42.  *
  43.  *    -1    List 1 is shorter than list 2.
  44.  *        OR An element of list 1 is "less than" the matching
  45.  *        element of list 2.
  46.  *
  47.  *    0    They have the same number of elements AND
  48.  *        all elements are equal.
  49.  *
  50.  *    1    List 1 is longer than list 2.
  51.  *        OR an element of list 1 is "greater than" the
  52.  *        matching element of list2.
  53.  *
  54.  * "less than", "equal" and "greater than" are as determined by strcmp(3).
  55.  *
  56.  *
  57.  * TODO:
  58.  *
  59.  * - Add a fourth argument to be a command string to execute.
  60.  * - Or some other way the programmer could customize the comparison.
  61.  */
  62.  
  63.  
  64. static int
  65. cmdListCompare(clientData, interp, argc, argv)
  66.     ClientData *clientData;
  67.     Tcl_Interp *interp;
  68.     int argc;
  69.     char *argv[];
  70.     {
  71.     int l1_argc, l2_argc;
  72.     char **l1_argv = (char **)NULL, **l2_argv = (char **)NULL;
  73.  
  74.     if (argc != 3) {
  75.         Tcl_AppendResult(interp, "USAGE: lcompare list1 list2", NULL);
  76.         return TCL_ERROR;
  77.     }
  78.  
  79.     if (Tcl_SplitList(interp, argv[1], &l1_argc, &l1_argv) == TCL_ERROR)
  80.         return TCL_ERROR;
  81.  
  82.     if (Tcl_SplitList(interp, argv[2], &l2_argc, &l2_argv) == TCL_ERROR) {
  83.         if (l1_argv) free(l1_argv);
  84.         return TCL_ERROR;
  85.     }
  86.  
  87.          if (l1_argc < l2_argc) Tcl_SetResult(interp, "-1", TCL_STATIC);
  88.     else if (l1_argc > l2_argc) Tcl_SetResult(interp, "1", TCL_STATIC);
  89.     else {
  90.         int i, cmpval;
  91.         for (i=0; i < l1_argc; i++) {
  92.             cmpval = strcmp(l1_argv[i], l2_argv[i]);
  93.             if (cmpval == 0) continue;
  94.             if (cmpval < 0)  Tcl_SetResult(interp, "-1", TCL_STATIC);
  95.             if (cmpval > 0)  Tcl_SetResult(interp, "1", TCL_STATIC);
  96.             goto all_done;
  97.         }
  98.         Tcl_SetResult(interp, "0", TCL_STATIC);
  99.     }
  100.  
  101. all_done:
  102.     if (l1_argv) free(l1_argv);
  103.     if (l2_argv) free(l2_argv);
  104.  
  105.     return TCL_OK;
  106.     }
  107.  
  108. void
  109. init_lcompare(interp)
  110. Tcl_Interp *interp;
  111.     {
  112.     Tcl_CreateCommand(interp, "lcompare", cmdListCompare, (ClientData) NULL,
  113.             (Tcl_CmdDeleteProc *) NULL);
  114.     }
  115.  
  116.