/* * f x a d d o . c */ /*)LIBRARY */ #ifdef DOCUMENTATION title fxaddo Add Ordered To a Flex index Add ordered to a flex index Locate last element added ordered to a flex synopsis #ifdef vms #include "c:flex.h" #else #include #endif FLEX *fxaddo(fx,itm,ord) FLEX *fx; char *itm; int (*ord)(); extern unsigned fxladd; description fxaddo is similar to fxadd except that it ensures that the items in the flex are in increasing order, where "in order" is defined by a passed function, ord. ord must return values akin to strcmp: ord(a,b) is -1 if ab. Elements that compare equal will be stored in the order they are passed. The global fxladd gets the item number at which itm was added. WARNING: fxaddo() uses straight insertion to maintain the ordering. This is an O(n**2) algorithm and will become very slow when the flex gets large. If you need to build a large, sorted flex, it is probably best to fill it first and then use something like qqsort() to sort it when you are done. (Another approach, more in keeping with the philosophy of fxaddo(), would be to define, say, fxaddh(), which keeps the flex ordered as a heap, and then scan through it as a heap. I leave this to someone else.) Note: If for some reason you don't want to include equal elements, you can safely issue an error message in ord() and use, for example, setjmp() and longjmp() to abort the insertion. This process will leave the flex unchanged. Alternatively, set a flag and use fxladd to eject the item later. bugs author Jerry Leichter #endif /* * )EDITLEVEL=16 * Edit history * 0.0 5-May-81 JSL Invention * 1.0 6-May-81 JSL Completely re-done using fxinject(); added fxladd. * 1.1 7-May-81 JSL Define fxinject() locally as flex.h no longer does. * 1.2 20-May-81 JSL Documentation now standard and up-to-date. * 1.3 14-Jul-81 JSL flex.h again defines fxinject(). */ #ifdef vms #include "c:flex.h" #else #include #endif #define NULL 0 unsigned fxladd; /* Where this routine stored an item */ FLEX * fxaddo(fx,itm,ord) FLEX *fx; char *itm; int (*ord)(); { register char *p,*data; register unsigned isz; if (fx == NULL || fx->fxdata == NULL) return(NULL); isz = fx->fxisz; data = fx->fxdata; p = data + isz*(fx->fxused - 1); while (p >= data && (*ord)(p,itm) > 0) p -= isz; return(fxinject(fx,itm,(fxladd = (p-data+isz)/isz))); }