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 >
Wrap
Text File
|
1993-10-31
|
3KB
|
116 lines
/* $Id: lcmp.c,v 1.1 1992/11/10 05:22:10 david Exp $
*
* lcmp.c -- Compare two lists for equality.
*
* AUTHOR: David Herron <david@twg.com> (work) or <david@davids.mmdf.com> (home)
*
* $Log: lcmp.c,v $
* Revision 1.1 1992/11/10 05:22:10 david
* Initial revision.
*
*
*/
#include <tcl.h>
/*
* USAGE: lcompare list1 list2
*
* The following is worlds faster than the closest we can get
* with TCL, namely:
*
* proc lcompare {list1 list2} {
* set l1_len [llength $list1]
* set l2_len [llength $list2]
* if {$l1_len < $l2_len} { return -1 }
* if {$l1_len > $l2_len} { return 1 }
* set i 0
* foreach e1 $list1 {
* set e2 [lindex $list2]
* if {$e1 == $e2} continue
* if {$e1 < $e2} { return -1 }
* if {$e1 > $e2} { return 1 }
* }
* return 0
* }
*
* The advantage the C code has is it only has to parse each
* list once. The above parses list1 twice, and list2 many
* times.
*
* RETURN VALUES:
*
* -1 List 1 is shorter than list 2.
* OR An element of list 1 is "less than" the matching
* element of list 2.
*
* 0 They have the same number of elements AND
* all elements are equal.
*
* 1 List 1 is longer than list 2.
* OR an element of list 1 is "greater than" the
* matching element of list2.
*
* "less than", "equal" and "greater than" are as determined by strcmp(3).
*
*
* TODO:
*
* - Add a fourth argument to be a command string to execute.
* - Or some other way the programmer could customize the comparison.
*/
static int
cmdListCompare(clientData, interp, argc, argv)
ClientData *clientData;
Tcl_Interp *interp;
int argc;
char *argv[];
{
int l1_argc, l2_argc;
char **l1_argv = (char **)NULL, **l2_argv = (char **)NULL;
if (argc != 3) {
Tcl_AppendResult(interp, "USAGE: lcompare list1 list2", NULL);
return TCL_ERROR;
}
if (Tcl_SplitList(interp, argv[1], &l1_argc, &l1_argv) == TCL_ERROR)
return TCL_ERROR;
if (Tcl_SplitList(interp, argv[2], &l2_argc, &l2_argv) == TCL_ERROR) {
if (l1_argv) free(l1_argv);
return TCL_ERROR;
}
if (l1_argc < l2_argc) Tcl_SetResult(interp, "-1", TCL_STATIC);
else if (l1_argc > l2_argc) Tcl_SetResult(interp, "1", TCL_STATIC);
else {
int i, cmpval;
for (i=0; i < l1_argc; i++) {
cmpval = strcmp(l1_argv[i], l2_argv[i]);
if (cmpval == 0) continue;
if (cmpval < 0) Tcl_SetResult(interp, "-1", TCL_STATIC);
if (cmpval > 0) Tcl_SetResult(interp, "1", TCL_STATIC);
goto all_done;
}
Tcl_SetResult(interp, "0", TCL_STATIC);
}
all_done:
if (l1_argv) free(l1_argv);
if (l2_argv) free(l2_argv);
return TCL_OK;
}
void
init_lcompare(interp)
Tcl_Interp *interp;
{
Tcl_CreateCommand(interp, "lcompare", cmdListCompare, (ClientData) NULL,
(Tcl_CmdDeleteProc *) NULL);
}