$include (..\lib\compStch.ext) /* *============================================================================ * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE * * Permission to use for any purpose, modify, copy, and make enhancements * and derivative works of the software is granted if attribution is given to * R.M. Gillmore, dba the ACME Software Deli, as the author * * While the ACME Software Deli does not work for money, there is nonetheless * a significant amount of work involved. The ACME Software Deli maintains the * rights to all code written, though it may be used and distributed as long as * the following conditions are maintained. * * 1. The copyright statement at the top of each code block is maintained in * your distribution. * 2. You do not identify yourself as the ACME Software Deli * 3. Any changes made to the software are sent to the ACME Software Deli *============================================================================ */ /* * Simple string pattern matching functions using wildcards ('?' & '*'). */ qSortModule: do; $if not noID declare IDString (*) byte data ( '@(#)qSort.p86 $Author: rmgillmore $ $Date:: 2025-05-04 19:35:39#$:', 0 ); $endif $include (..\lib\ptrMath.ext) declare size_t literally 'integer', char literally 'byte'; runCompare: procedure ( leftPtr, rightPtr, comparFuncPtr ) word external; declare ( leftPtr, rightPtr, comparFuncPtr ) pointer; end runCompare; swap_internal: procedure ( aPtr, bPtr, elementSize ) reentrant public; declare aPtr pointer, bPtr pointer, elementSize size_t; declare aLocalPtr pointer, bLocalPtr pointer, a based aLocalPtr (*) char, b based bLocalPtr (*) char, localSize integer; aLocalPtr = aPtr; bLocalPtr = bPtr; localSize = elementSize; if ( ptdw( aLocalPtr ) <> ptdw( bLocalPtr ) ) then do; declare t char; do while ( localSize > 0 ); t = a(0); a(0) = b(0); aLocalPtr = dwtp( ptdw( aLocalPtr ) + 1 ); b(0) = t; bLocalPtr = dwtp( ptdw( bLocalPtr ) + 1 ); localSize = localSize - 1; end; end; /* if */ end swap_internal; qsort_internal: procedure ( beginPtr, endPtr, elementSize, comparPtr ) reentrant public; declare beginPtr pointer, endPtr pointer, elementSize size_t, comparPtr pointer; declare begin based beginPtr (*) char, ending based endPtr (*) char; if ( ending( 0 ) > begin( 0 ) ) then do; declare pivot pointer, beginDword dword at ( @beginPtr ), endDword dword at ( @endPtr ), pivotDword dword at ( @pivot ), leftPtr pointer, leftDword dword at ( @leftPtr ), rightPtr pointer, rightDword dword at ( @rightPtr ), left based leftPtr char, right based rightPtr char, pivotChar based pivot char; pivot = beginPtr; leftDword = beginDword + dword( elementSize ); rightPtr = endPtr; leftDword = beginDword + dword( elementSize ); do while ( leftPtr < rightPtr ); if ( runCompare( leftPtr, pivot, comparPtr ) <= 0 ) then do; leftDword = leftDword + dword( elementSize ); end; else do; rightDword = rightDword - dword( elementSize ); call swap_internal( leftPtr, rightPtr, elementSize ); end; end; leftDword = leftDword - dword( elementSize ); call swap_internal( beginPtr, leftPtr, elementSize); call qsort_internal( beginPtr, leftPtr, elementSize, comparPtr ); call qsort_internal( rightPtr, endPtr, elementSize, comparPtr ); end; end qsort_internal; qsort: procedure ( base, nmemb, dataSize, compar ) reentrant public; declare base pointer, nmemb size_t, dataSize size_t, compar pointer; declare endPtr pointer, endDword dword at ( @endPtr ), baseDword dword at ( @base ); endDword = baseDword + dword( nmemb ) * dword( dataSize ); call qsort_internal( base, endPtr, dataSize, compar ); end qsort; end qSortModule;