Changeset 13


Ignore:
Timestamp:
Nov 23, 2000, 7:36:41 PM (25 years ago)
Author:
umoeller
Message:

Updates for V0.9.6.

Location:
trunk
Files:
2 added
26 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/helpers/memdebug.h

    r7 r13  
    4141    extern PFNCBMEMDLOG    G_pMemdLogFunc;
    4242
     43    /* ******************************************************************
     44     *
     45     *   Private declarations
     46     *
     47     ********************************************************************/
     48
     49    #ifdef MEMDEBUG_PRIVATE
     50
     51        BOOL memdLock(VOID);
     52
     53        VOID memdUnlock(VOID);
     54
     55        /*
     56         *@@ HEAPITEM:
     57         *      informational structure created for each
     58         *      malloc() call by memdMalloc. These are stored
     59         *      in a global linked list (G_pHeapItemsRoot).
     60         *
     61         *      We cannot use the linklist.c functions for
     62         *      managing the linked list because these use
     63         *      malloc in turn, which would lead to infinite
     64         *      loops.
     65         *
     66         *@@added V0.9.3 (2000-04-11) [umoeller]
     67         */
     68
     69        typedef struct _HEAPITEM
     70        {
     71            struct _HEAPITEM    *pNext;     // next item in linked list or NULL if last
     72
     73            void                *pAfterMagic; // memory pointer returned by memdMalloc;
     74                                            // this points to after the magic string
     75            unsigned long       ulSize;     // requested size (without magic head and tail)
     76
     77            const char          *pcszSourceFile;    // as passed to memdMalloc
     78            unsigned long       ulLine;             // as passed to memdMalloc
     79            const char          *pcszFunction;      // as passed to memdMalloc
     80
     81            DATETIME            dtAllocated;        // system date/time at time of memdMalloc call
     82
     83            ULONG               ulTID;      // thread ID that memdMalloc was running on
     84
     85            BOOL                fFreed;     // TRUE only after item has been freed by memdFree
     86        } HEAPITEM, *PHEAPITEM;
     87
     88        extern PHEAPITEM    G_pHeapItemsRoot;
     89        extern ULONG        G_ulItemsReleased;
     90        extern ULONG        G_ulBytesReleased;
     91
     92    #endif // MEMDEBUG_PRIVATE
     93
     94    /* ******************************************************************
     95     *
     96     *   Publics
     97     *
     98     ********************************************************************/
     99
    43100    void* memdMalloc(size_t stSize,
    44101                     const char *pcszSourceFile,
     
    57114                  const char *pcszFunction);
    58115
     116    void* memdRealloc(void *p,
     117                      size_t stSize,
     118                      const char *pcszSourceFile,
     119                      unsigned long ulLine,
     120                      const char *pcszFunction);
     121
    59122    unsigned long memdReleaseFreed(void);
    60123
     
    64127            #define malloc(ul) memdMalloc(ul, __FILE__, __LINE__, __FUNCTION__)
    65128            #define calloc(n, size) memdCalloc(n, size, __FILE__, __LINE__, __FUNCTION__)
     129            #define realloc(p, ul) memdRealloc(p, ul, __FILE__, __LINE__, __FUNCTION__)
    66130            #define free(p) memdFree(p, __FILE__, __LINE__, __FUNCTION__)
    67131
     
    79143    #ifdef PM_INCLUDED
    80144        /********************************************************************
    81          *                                                                  *
    82          *   XFolder debugging helpers                                      *
    83          *                                                                  *
     145         *
     146         *   XFolder debugging helpers
     147         *
    84148         ********************************************************************/
    85149
     
    94158
    95159        /* ******************************************************************
    96          *                                                                  *
    97          *   Heap debugging window                                          *
    98          *                                                                  *
     160         *
     161         *   Heap debugging window
     162         *
    99163         ********************************************************************/
    100164
  • trunk/include/helpers/stringh.h

    r12 r13  
    6464
    6565    ULONG strhrpl(PSZ *ppszBuf,
    66                   ULONG ulOfs,
     66                  PULONG pulOfs,
    6767                  const char *pcszSearch,
    68                   const char *pcszReplace,
    69                   PULONG pulAfterOfs);
     68                  const char *pcszReplace);
    7069
    7170    ULONG strhWords(PSZ psz);
     
    7473
    7574    PSZ strhThousandsDouble(PSZ pszTarget, double dbl, CHAR cThousands);
     75
     76    PSZ strhVariableDouble(PSZ pszTarget, double dbl, PSZ pszUnits,
     77                           CHAR cThousands);
    7678
    7779    VOID strhFileDate(PSZ pszBuf,
     
    102104                     PSZ *ppszEnd);
    103105
     106    BOOL strhIsWord(const char *pcszBuf,
     107                    const char *p,
     108                    ULONG cbSearch,
     109                    const char *pcszBeginChars,
     110                    const char *pcszEndChars);
     111
    104112    PSZ strhFindWord(const char *pszBuf,
    105113                     const char *pszSearch,
     
    192200     ********************************************************************/
    193201
    194     char* strhfind (const char *string,
    195                     const char *pattern,
    196                     BOOL repeat_find);
    197 
    198     char* strhfind_r (const char *string,
    199                       const char *pattern);
    200 
    201     char* strhfind_rb (const char *string,
    202                        const char *pattern,
    203                        size_t     *shift,
    204                        BOOL       *repeat_find);
    205 
    206     void* strhmemfind (const void  *block,
    207                        size_t       block_size,
    208                        const void  *pattern,
    209                        size_t       pattern_size,
    210                        BOOL         repeat_find);
    211 
    212     void* strhmemfind_r (const void  *block,
    213                          size_t       block_size,
    214                          const void  *pattern,
    215                          size_t       pattern_size);
    216 
    217     void* strhmemfind_rb (const void  *in_block,
    218                           size_t       block_size,
    219                           const void  *in_pattern,
    220                           size_t       pattern_size,
    221                           size_t      *shift,
    222                           BOOL        *repeat_find);
     202    void* strhmemfind(const void *in_block,
     203                      size_t block_size,
     204                      const void *in_pattern,
     205                      size_t pattern_size,
     206                      size_t *shift,
     207                      BOOL *repeat_find);
    223208
    224209    char* strhtxtfind (const char *string,
  • trunk/include/helpers/tree.h

    r7 r13  
     1
     2/*
     3 *@@sourcefile tree.h:
     4 *      header file for tree.c (red-black balanced binary trees).
     5 *      See remarks there.
     6 */
     7
     8/*
     9 *      Written:    97/11/18  Jonathan Schultz <jonathan@imatix.com>
     10 *      Revised:    98/12/08  Jonathan Schultz <jonathan@imatix.com>
     11 *
     12 *      Copyright (C) 1991-99 iMatix Corporation.
     13 *      Copyright (C) 2000 Ulrich M”ller.
     14 *      This file is part of the XWorkplace source package.
     15 *      XWorkplace is free software; you can redistribute it and/or modify
     16 *      it under the terms of the GNU General Public License as published
     17 *      by the Free Software Foundation, in version 2 as it comes in the
     18 *      "COPYING" file of the XWorkplace main distribution.
     19 *      This program is distributed in the hope that it will be useful,
     20 *      but WITHOUT ANY WARRANTY; without even the implied warranty of
     21 *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     22 *      GNU General Public License for more details.
     23 */
     24
     25
    126/*  ----------------------------------------------------------------<Prolog>-
    227    Name:       sfltree.h
     
    5277     *@@ TREE:
    5378     *      tree node.
     79     *
     80     *      To use the tree functions, all your structures
     81     *      must have a TREE structure as their first member.
     82     *
     83     *      Example:
     84     *
     85     +      typedef struct _MYTREENODE
     86     +      {
     87     +          TREE        tree;
     88     +          char        acMyData[1000];
     89     +      } MYTREENODE, *PMYTREENODE;
     90     *
     91     *      See tree.c for an introduction to the tree functions.
    5492     */
    5593
     
    6199        unsigned long   id;
    62100        TREE_COLOUR     colour;
    63     } TREE;
     101    } TREE, *PTREE;
    64102
    65103    // The tree algorithm needs to know how to sort the data.
  • trunk/include/helpers/xstring.h

    r12 r13  
    7979    #define xstrIsString(psz) ( (psz != 0) && (*(psz) != 0) )
    8080
     81    PSZ xstrFindWord(const XSTRING *pxstr,
     82                     ULONG ulOfs,
     83                     const XSTRING *pstrFind,
     84                     size_t *pShiftTable,
     85                     PBOOL pfRepeatFind,
     86                     const char *pcszBeginChars,
     87                     const char *pcszEndChars);
     88
    8189    ULONG xstrrpl(PXSTRING pxstr,
    82                   ULONG ulOfs,
     90                  PULONG pulOfs,
    8391                  const XSTRING *pstrSearch,
    8492                  const XSTRING *pstrReplace,
    85                   PULONG pulAfterOfs);
     93                  size_t *pShiftTable,
     94                  PBOOL pfRepeatFind);
    8695
    8796    ULONG xstrcrpl(PXSTRING pxstr,
    88                    ULONG ulOfs,
     97                   PULONG pulOfs,
    8998                   const char *pcszSearch,
    90                    const char *pcszReplace,
    91                    PULONG pulAfterOfs);
     99                   const char *pcszReplace);
    92100#endif
    93101
  • trunk/readme.txt

    r7 r13  
    143143    headers.
    144144
     145    Note that all the helpers C code includes their own include
     146    files this way. As a result, the XWPHelpers "include"
     147    directory must be in your include path, or this won't
     148    compile.
     149
     150    Besides, the helpers C code expects a file called "setup.h"
     151    in your include path somewhere. This is included by all
     152    the C files so you can (re)define certain macros there.
    145153
    146154
  • trunk/src/helpers/cctl_progbar.c

    r8 r13  
    140140    {
    141141        // make string
    142         sprintf(szPercent, "%d %%", ((100 * pData->ulNow) / pData->ulMax) );
     142        sprintf(szPercent, "%lu %%", ((100 * pData->ulNow) / pData->ulMax) );
    143143
    144144        // calculate string space
  • trunk/src/helpers/debug.c

    r8 r13  
    700700                            NrPublic = pubfunc_ofs = pxdi->sspub32.offset;
    701701                            read_types = TRUE;
    702                             sprintf(pxdi->szNrPub, "%s %s (%s, seg %04X : ofs %08X\n",
     702                            sprintf(pxdi->szNrPub,
     703                                    "%s %s (%s, seg %04lX : ofs %08lX\n",
    703704                                    (pxdi->sspub32.type == 1) ? " Abs" : " ",
    704705                                    ename,
    705706                                    ModName, // ()
    706                                     pxdi->sspub32.segment,
     707                                    (ULONG)pxdi->sspub32.segment,
    707708                                    pxdi->sspub32.offset
    708709                                );
     
    11771178        sprintf(pszBuf, "%f", *(double*)varptr);
    11781179    else if (type == 10)
    1179         sprintf(pszBuf, "%f", *(long double*)varptr);
     1180        sprintf(pszBuf, "%f", (double)(*(long double*)varptr));
    11801181    else if (type == 16)
    11811182        sprintf(pszBuf, "%s", *(char*)varptr ? "TRUE" : "FALSE");
     
    11871188        sprintf(pszBuf, "%c", *(char*)varptr);
    11881189    else if (type == 21)
    1189         sprintf(pszBuf, "%lc", *(short*)varptr);
     1190        sprintf(pszBuf, "%hd", (*(short*)varptr));
    11901191    else if (type == 22)
    1191         sprintf(pszBuf, "%lc", *(long*)varptr);
     1192        sprintf(pszBuf, "%ld", *(long*)varptr);
    11921193    else if (type == 23)
    11931194        sprintf(pszBuf, "void");
    11941195    else if (type >= 32)
    11951196    {
    1196         sprintf(pszBuf, "0x%p", *(ULONG *) varptr);
     1197        sprintf(pszBuf, "0x%p", (void*)(*(ULONG*)varptr));
    11971198        if (Attr & PAG_FREE)
    11981199        {
     
    12471248                              one_userdef[pos].type_index - 0x80);
    12481249
    1249                 fprintf(LogFile, "     %- 6d %- 20.20s %- 33.33s %s (user)\n",
     1250                fprintf(LogFile,
     1251                        "     %- 6ld %- 20.20s %- 33.33s %s (user)\n",
    12501252                        autovar_def[var_no].stack_offset,       // stack offset
    12511253                        autovar_def[var_no].name,               // identifier
     
    12951297                      sszVar,
    12961298                      32);
    1297             fprintf(LogFile, "     %- 6d %- 20.20s %- 33.33s %s (ptr1)\n",
     1299            fprintf(LogFile, "     %- 6ld %- 20.20s %- 33.33s %s (ptr1)\n",
    12981300                    autovar_def[var_no].stack_offset,
    12991301                    autovar_def[var_no].name,
     
    13191321                          sszVar,
    13201322                          32);
    1321                 fprintf(LogFile, "     %- 6d %- 20.20s %- 33.33s %s (ptr2)\n",
     1323                fprintf(LogFile, "     %- 6ld %- 20.20s %- 33.33s %s (ptr2)\n",
    13221324                        autovar_def[var_no].stack_offset,
    13231325                        autovar_def[var_no].name,
     
    13351337                          sszVar,
    13361338                          32);
    1337                 fprintf(LogFile, "     %- 6d %- 20.20s %- 33.33s %s (ptr3)\n",
     1339                fprintf(LogFile, "     %- 6ld %- 20.20s %- 33.33s %s (ptr3)\n",
    13381340                        autovar_def[var_no].stack_offset,
    13391341                        autovar_def[var_no].name,
     
    13721374            {
    13731375                AutoVarsFound = TRUE;
    1374                 fprintf(LogFile, "     List of auto variables at EBP %p in %s:\n", stackofs, func_name);
     1376                fprintf(LogFile, "     List of auto variables at EBP %p in %s:\n",
     1377                        (PVOID)stackofs,
     1378                        func_name);
    13751379                fprintf(LogFile, "     Offset Name                 Type                              Value            \n");
    13761380                fprintf(LogFile, "     ÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ ÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄÄ\n");
     
    13881392                          autovar_def[n].type_idx - 0x80);
    13891393
    1390                 fprintf(LogFile, "     %- 6d %- 20.20s %- 33.33s %s (simple)\n",
     1394                fprintf(LogFile, "     %- 6ld %- 20.20s %- 33.33s %s (simple)\n",
    13911395                        autovar_def[n].stack_offset,
    13921396                        autovar_def[n].name,
     
    14001404                    if (!search_pointers(LogFile, stackofs, n))
    14011405                    {
    1402                         fprintf(LogFile, "     %- 6d %-20.20s 0x%X (unknown)\n",
     1406                        fprintf(LogFile, "     %- 6ld %-20.20s 0x%X (unknown)\n",
    14031407                                autovar_def[n].stack_offset,
    14041408                                autovar_def[n].name,
     
    15061510                    {
    15071511                        // symbol found
    1508                         fprintf(LogFile, "between %s + 0x%X ", Buffer, TrapOffset - LastVal);
    1509                         fprintf(LogFile, "(ppLineDef: 0x%lX) ",
     1512                        fprintf(LogFile, "between %s + 0x%lX ", Buffer, TrapOffset - LastVal);
     1513                        /* fprintf(LogFile, "(ppLineDef: 0x%lX) ",
    15101514                                    LINEDEFOFFSET(SegDef)
    1511                                     );
     1515                                    ); */
    15121516                        fprintf(LogFile, "\n");
    15131517                    }
     
    15221526                        // symbol found, as above
    15231527                        fprintf(LogFile, "                                         "
    1524                                          "and %s - 0x%X ", Buffer, LastVal - TrapOffset);
     1528                                         "and %s - 0x%lX ", Buffer, LastVal - TrapOffset);
    15251529                        fprintf(LogFile, "\n");
    15261530                        break;
     
    15341538                    if (SymDef16.wSymVal > TrapOffset)
    15351539                    {
    1536                         fprintf(LogFile, "between %s + %X\n",
     1540                        fprintf(LogFile, "between %s + %lX\n",
    15371541                                         Buffer,
    15381542                                         TrapOffset - LastVal);
     
    15451549                    {
    15461550                        fprintf(LogFile, "                                         "
    1547                                          "and %s - %X\n",
     1551                                         "and %s - %lX\n",
    15481552                                         Buffer,
    15491553                                         LastVal - TrapOffset);
     
    16811685        else if (arc != 0)
    16821686            fprintf(LogFile,
    1683                     "Error %d reading symbol file %s\n",
     1687                    "Error %lu reading symbol file %s\n",
    16841688                    arc,
    16851689                    szSymName);
     
    17431747        if (rc != NO_ERROR)
    17441748        {
    1745             fprintf(LogFile, "Invalid EBP %8.8p (DosQueryMem returned %d)\n", Ebp, rc);
     1749            fprintf(LogFile, "Invalid EBP %8.8lX (DosQueryMem returned %lu)\n", (ULONG)Ebp, rc);
    17461750            break;
    17471751        }
    17481752        if (!(Attr & PAG_COMMIT))
    17491753        {
    1750             fprintf(LogFile, "Invalid EBP %8.8p (not committed)\n", Ebp);
     1754            fprintf(LogFile, "Invalid EBP %8.8lX (not committed)\n", (ULONG)Ebp);
    17511755            break;
    17521756        }
    17531757        if (Size < 10)
    17541758        {
    1755             fprintf(LogFile, "Invalid EBP %8.8p (mem block size < 10)\n", Ebp);
     1759            fprintf(LogFile, "Invalid EBP %8.8lX (mem block size < 10)\n", (ULONG)Ebp);
    17561760            break;
    17571761        }
     
    18531857            fprintf(LogFile, " Trap  ->  ");
    18541858        else
    1855             fprintf(LogFile, " %8.8p  ", Ebp);
     1859            fprintf(LogFile, " %8.8lX  ", (ULONG)Ebp);
    18561860
    18571861        // "Address" column
    18581862        if (f32bit)
    1859             fprintf(LogFile, ":%8.8p  ", RetAddr);
     1863            fprintf(LogFile, ":%8.8lX  ", (ULONG)RetAddr);
    18601864        else
    18611865            fprintf(LogFile, "%04.04X:%04.04X  ", Cs, Ip);
     
    18741878            if (rc != NO_ERROR || !(Attr & PAG_COMMIT))
    18751879            {
    1876                 fprintf(LogFile, "Invalid RetAddr: %8.8p\n", RetAddr);
     1880                fprintf(LogFile, "Invalid RetAddr: %8.8lX\n", (ULONG)RetAddr);
    18771881                break;          // avoid infinite loops
    18781882            }
     
    18951899
    18961900                    // print module and object
    1897                     fprintf(LogFile, "%-8s %04X  ", szName, ObjNum + 1);
     1901                    fprintf(LogFile, "%-8s %04lX  ", szName, ObjNum + 1);
    18981902
    18991903                    if (strlen(Name) > 3)
     
    19071911                else
    19081912                    fprintf(LogFile,
    1909                             "DosQueryModFromEIP failed, returned %d\n",
     1913                            "DosQueryModFromEIP failed, returned %lu\n",
    19101914                            rc);
    19111915            }
     
    19491953        if ((rc != NO_ERROR) || (Size < 4))
    19501954        {
    1951             fprintf(LogFile, "... lost stack chain - invalid EBP: %8.8p\n", Ebp);
     1955            fprintf(LogFile, "... lost stack chain - invalid EBP: %8.8lX\n", (ULONG)Ebp);
    19521956            break;
    19531957        }
  • trunk/src/helpers/dosh.c

    r8 r13  
    464464                         | OPEN_SHARE_DENYNONE,
    465465                  NULL);
     466
     467    // _Pmpf((__FUNCTION__ ": DosOpen(OPEN_FLAGS_DASD) returned %d", arc));
    466468
    467469    switch (arc)
     
    10701072    do
    10711073    {
    1072         sprintf(szCount, ".%03d", ulCount);
     1074        sprintf(szCount, ".%03lu", ulCount);
    10731075        strcpy(pszLastDot, szCount);
    10741076        ulCount++;
  • trunk/src/helpers/except.c

    r8 r13  
    299299            ulOffset = 0;
    300300    fprintf(file,
    301             "    %-8s: %08X ",
     301            "    %-8s: %08lX ",
    302302            pszDescription,
    303303            ulAddress);
     
    312312        // error:
    313313        fprintf(file,
    314                 " %-8s:%d   Error: DosQueryModFromEIP returned %d\n",
     314                " %-8s:%lu   Error: DosQueryModFromEIP returned %lu\n",
    315315                szMod1,
    316316                ulObject,
     
    322322
    323323        fprintf(file,
    324                 " %-8s:%d   ",
     324                " %-8s:%lu   ",
    325325                szMod1,
    326326                ulObject);
     
    393393               )
    394394            {
    395                 fprintf(file, "\n    %08X: ", pulStackWord);
     395                fprintf(file, "\n    %08lX: ", (ULONG)pulStackWord);
    396396                fprintf(file, "Page inaccessible");
    397397                pulStackWord += 0x1000;
     
    400400        }
    401401
    402         sprintf(szAddress, "%08X",
    403                 pulStackWord);
     402        sprintf(szAddress, "%08lX",
     403                (ULONG)pulStackWord);
    404404        excPrintStackFrame(file,
    405405                           szAddress,
     
    416416 *      This calls excPrintStackFrame for each stack frame.
    417417 *
    418  *      If DEBUG_EXCPT_STACKDUMP is #define'd, this also dumps
    419  *      the stack completely, which isn't that useful.
    420  *
    421418 *@@changed V0.9.0 [umoeller]: added support for application hook
    422419 *@@changed V0.9.0 (99-11-02) [umoeller]: added TID to dump
    423420 *@@changed V0.9.2 (2000-03-10) [umoeller]: now using excPrintStackFrame
    424421 *@@changed V0.9.3 (2000-05-03) [umoeller]: fixed crashes
     422 *@@changed V0.9.6 (2000-11-06) [umoeller]: added more register dumps
    425423 */
    426424
     
    475473    // generic exception info
    476474    fprintf(file,
    477             "\n%s:\n    Exception type: %08X\n    Address:        %08X\n    Params:         ",
     475            "\n%s:\n    Exception type: %08lX\n    Address:        %08lX\n    Params:         ",
    478476            pszHandlerName,
    479477            pReportRec->ExceptionNum,
    480             pReportRec->ExceptionAddress);
     478            (ULONG)pReportRec->ExceptionAddress);
    481479    for (ul = 0;  ul < pReportRec->cParameters;  ul++)
    482480    {
    483         fprintf(file, "%08X  ",
     481        fprintf(file, "%08lX  ",
    484482                pReportRec->ExceptionInfo[ul]);
    485483    }
     
    494492            fprintf(file, "\nAccess violation: ");
    495493            if (pReportRec->ExceptionInfo[0] & XCPT_READ_ACCESS)
    496                 fprintf(file, "Invalid read access from 0x%04X:%08X.\n",
     494                fprintf(file, "Invalid read access from 0x%04lX:%08lX.\n",
    497495                        pContextRec->ctx_SegDs, pReportRec->ExceptionInfo[1]);
    498496            else if (pReportRec->ExceptionInfo[0] & XCPT_WRITE_ACCESS)
    499                 fprintf(file, "Invalid write access to 0x%04X:%08X.\n",
     497                fprintf(file, "Invalid write access to 0x%04lX:%08lX.\n",
    500498                        pContextRec->ctx_SegDs, pReportRec->ExceptionInfo[1]);
    501499            else if (pReportRec->ExceptionInfo[0] & XCPT_SPACE_ACCESS)
    502                 fprintf(file, "Invalid space access at 0x%04X.\n",
     500                fprintf(file, "Invalid space access at 0x%04lX.\n",
    503501                        pReportRec->ExceptionInfo[1]);
    504502            else if (pReportRec->ExceptionInfo[0] & XCPT_LIMIT_ACCESS)
    505503                fprintf(file, "Invalid limit access occurred.\n");
    506504            else if (pReportRec->ExceptionInfo[0] == XCPT_UNKNOWN_ACCESS)
    507                 fprintf(file, "unknown at 0x%04X:%08X\n",
     505                fprintf(file, "unknown at 0x%04lX:%08lX\n",
    508506                            pContextRec->ctx_SegDs, pReportRec->ExceptionInfo[1]);
    509507            fprintf(file,
     
    586584                    "\n    Process module:  0x%lX (%s)"
    587585                    "\n    Trapping module: 0x%lX (%s)"
    588                     "\n    Object: %d\n",
     586                    "\n    Object: %lu\n",
    589587                    ppib->pib_ulpid,
    590588                    hMod1, szMod1,
     
    594592            fprintf(file,
    595593                    "\nTrapping thread information:"
    596                     "\n    Thread ID:       0x%lX (%d)"
     594                    "\n    Thread ID:       0x%lX (%lu)"
    597595                    "\n    Priority:        0x%lX\n",
    598596                    ptib->tib_ptib2->tib2_ultid, ptib->tib_ptib2->tib2_ultid,
     
    618616        if (pContextRec->ContextFlags & CONTEXT_INTEGER)
    619617        {
     618            // DS the following 4 added V0.9.6 (2000-11-06) [umoeller]
     619            fprintf(file, "\n    DS  = %08lX  ", pContextRec->ctx_SegDs);
     620            excDescribePage(file, pContextRec->ctx_SegDs);
     621            // ES
     622            fprintf(file, "\n    ES  = %08lX  ", pContextRec->ctx_SegEs);
     623            excDescribePage(file, pContextRec->ctx_SegEs);
     624            // FS
     625            fprintf(file, "\n    FS  = %08lX  ", pContextRec->ctx_SegFs);
     626            excDescribePage(file, pContextRec->ctx_SegFs);
     627            // GS
     628            fprintf(file, "\n    GS  = %08lX  ", pContextRec->ctx_SegGs);
     629            excDescribePage(file, pContextRec->ctx_SegGs);
     630
    620631            // EAX
    621             fprintf(file, "\n    EAX = %08X  ", pContextRec->ctx_RegEax);
     632            fprintf(file, "\n    EAX = %08lX  ", pContextRec->ctx_RegEax);
    622633            excDescribePage(file, pContextRec->ctx_RegEax);
    623634            // EBX
    624             fprintf(file, "\n    EBX = %08X  ", pContextRec->ctx_RegEbx);
     635            fprintf(file, "\n    EBX = %08lX  ", pContextRec->ctx_RegEbx);
    625636            excDescribePage(file, pContextRec->ctx_RegEbx);
    626637            // ECX
    627             fprintf(file, "\n    ECX = %08X  ", pContextRec->ctx_RegEcx);
     638            fprintf(file, "\n    ECX = %08lX  ", pContextRec->ctx_RegEcx);
    628639            excDescribePage(file, pContextRec->ctx_RegEcx);
    629640            // EDX
    630             fprintf(file, "\n    EDX = %08X  ", pContextRec->ctx_RegEdx);
     641            fprintf(file, "\n    EDX = %08lX  ", pContextRec->ctx_RegEdx);
    631642            excDescribePage(file, pContextRec->ctx_RegEdx);
    632643            // ESI
    633             fprintf(file, "\n    ESI = %08X  ", pContextRec->ctx_RegEsi);
     644            fprintf(file, "\n    ESI = %08lX  ", pContextRec->ctx_RegEsi);
    634645            excDescribePage(file, pContextRec->ctx_RegEsi);
    635646            // EDI
    636             fprintf(file, "\n    EDI = %08X  ", pContextRec->ctx_RegEdi);
     647            fprintf(file, "\n    EDI = %08lX  ", pContextRec->ctx_RegEdi);
    637648            excDescribePage(file, pContextRec->ctx_RegEdi);
    638649            fprintf(file, "\n");
     
    646657            // *** instruction
    647658
    648             fprintf(file, "Instruction pointer (where exception occured):\n    CS:EIP = %04X:%08X  ",
     659            fprintf(file, "Instruction pointer (where exception occured):\n    CS:EIP = %04lX:%08lX  ",
    649660                    pContextRec->ctx_SegCs,
    650661                    pContextRec->ctx_RegEip);
     
    653664            // *** CPU flags
    654665
    655             fprintf(file, "\n    FLG    = %08X", pContextRec->ctx_EFlags);
     666            fprintf(file, "\n    EFLAGS = %08lX", pContextRec->ctx_EFlags);
    656667
    657668            /*
     
    660671             */
    661672
    662             fprintf(file, "\nStack:\n    Base:         %08X\n    Limit:        %08X",
    663                    (ptib ? ptib->tib_pstack : 0),
    664                    (ptib ? ptib->tib_pstacklimit :0));
    665             fprintf(file, "\n    SS:ESP = %04X:%08X  ",
    666                     pContextRec->ctx_SegSs, pContextRec->ctx_RegEsp);
     673            fprintf(file, "\nStack:\n    Base:         %08lX\n    Limit:        %08lX",
     674                   (ULONG)(ptib ? ptib->tib_pstack : 0),
     675                   (ULONG)(ptib ? ptib->tib_pstacklimit : 0));
     676            fprintf(file, "\n    SS:ESP = %04lX:%08lX  ",
     677                    pContextRec->ctx_SegSs,
     678                    pContextRec->ctx_RegEsp);
    667679            excDescribePage(file, pContextRec->ctx_RegEsp);
    668680
    669             fprintf(file, "\n    EBP    =      %08X  ", pContextRec->ctx_RegEbp);
     681            fprintf(file, "\n    EBP    =      %08lX  ", pContextRec->ctx_RegEbp);
    670682            excDescribePage(file, pContextRec->ctx_RegEbp);
    671683
  • trunk/src/helpers/gpih.c

    r8 r13  
    384384        {
    385385            // _Pmpf(("Found font PP: %s", pszFontFound));
    386             sscanf(pszFontNameSize, "%d", pulSize);
     386            sscanf(pszFontNameSize, "%lu", pulSize);
    387387            *ppszFaceName = pcDot + 1;
    388388            brc = TRUE;
     
    932932        {
    933933            // _Pmpf(("Found font PP: %s", pszFontFound));
    934             sscanf(pszFontFound, "%d", &ulFontSize);
     934            sscanf(pszFontFound, "%lu", &ulFontSize);
    935935            if (plSize)
    936936                *plSize = ulFontSize;
  • trunk/src/helpers/helpers_post.in

    r9 r13  
    114114$(OUTPUTDIR)\memdebug.obj:  $(@B).c $(HLPINC)\$(@B).h \
    115115               $(PROJECTINC)\setup.h \
     116               $(HLPINC)\except.h $(HLPINC)\stringh.h
     117
     118$(OUTPUTDIR)\memdebug_win.obj:  $(@B).c $(HLPINC)\memdebug.h \
     119               $(PROJECTINC)\setup.h \
    116120               $(HLPINC)\cnrh.h $(HLPINC)\except.h $(HLPINC)\stringh.h $(HLPINC)\winh.h
    117121
  • trunk/src/helpers/helpers_pre.in

    r10 r13  
    4040
    4141PLAINCOBJS = \
    42        $(OUTPUTDIR)\linklist.obj \
    43        $(OUTPUTDIR)\tree.obj \
    44        $(OUTPUTDIR)\xml.obj \
     42$(OUTPUTDIR)\linklist.obj \
     43$(OUTPUTDIR)\tree.obj \
     44$(OUTPUTDIR)\xml.obj \
    4545
    4646CPOBJS = $(PLAINCOBJS) \
    47        $(OUTPUTDIR)\datetime.obj \
    48        $(OUTPUTDIR)\debug.obj \
    49        $(OUTPUTDIR)\dosh.obj \
    50        $(OUTPUTDIR)\dosh2.obj \
    51        $(OUTPUTDIR)\eah.obj \
    52        $(OUTPUTDIR)\except.obj \
    53        $(OUTPUTDIR)\level.obj \
    54        $(OUTPUTDIR)\procstat.obj \
    55        $(OUTPUTDIR)\prfh.obj \
    56        $(OUTPUTDIR)\prfh2.obj \
    57        $(OUTPUTDIR)\resh.obj \
    58        $(OUTPUTDIR)\stringh.obj \
    59        $(OUTPUTDIR)\syssound.obj \
    60        $(OUTPUTDIR)\threads.obj \
    61        $(OUTPUTDIR)\tmsgfile.obj \
    62        $(OUTPUTDIR)\wphandle.obj \
    63        $(OUTPUTDIR)\xprf.obj \
    64        $(OUTPUTDIR)\xprf2.obj \
    65        $(OUTPUTDIR)\xstring.obj
     47$(OUTPUTDIR)\datetime.obj \
     48$(OUTPUTDIR)\debug.obj \
     49$(OUTPUTDIR)\dosh.obj \
     50$(OUTPUTDIR)\dosh2.obj \
     51$(OUTPUTDIR)\eah.obj \
     52$(OUTPUTDIR)\except.obj \
     53$(OUTPUTDIR)\level.obj \
     54$(OUTPUTDIR)\procstat.obj \
     55$(OUTPUTDIR)\prfh.obj \
     56$(OUTPUTDIR)\prfh2.obj \
     57$(OUTPUTDIR)\resh.obj \
     58$(OUTPUTDIR)\stringh.obj \
     59$(OUTPUTDIR)\syssound.obj \
     60$(OUTPUTDIR)\tmsgfile.obj \
     61$(OUTPUTDIR)\wphandle.obj \
     62$(OUTPUTDIR)\xprf.obj \
     63$(OUTPUTDIR)\xprf2.obj \
     64$(OUTPUTDIR)\xstring.obj
    6665
    6766OBJS = $(CPOBJS) \
    68        $(OUTPUTDIR)\animate.obj \
    69        $(OUTPUTDIR)\cctl_chart.obj \
    70        $(OUTPUTDIR)\cctl_checkcnr.obj \
    71        $(OUTPUTDIR)\cctl_progbar.obj \
    72        $(OUTPUTDIR)\cctl_splitwin.obj \
    73        $(OUTPUTDIR)\cctl_tooltip.obj \
    74        $(OUTPUTDIR)\comctl.obj \
    75        $(OUTPUTDIR)\cnrh.obj \
    76        $(OUTPUTDIR)\gpih.obj \
    77        $(OUTPUTDIR)\memdebug.obj \
    78        $(OUTPUTDIR)\shapewin.obj \
    79        $(OUTPUTDIR)\textview.obj \
    80        $(OUTPUTDIR)\textv_html.obj \
    81        $(OUTPUTDIR)\winh.obj
     67$(OUTPUTDIR)\animate.obj \
     68$(OUTPUTDIR)\cctl_chart.obj \
     69$(OUTPUTDIR)\cctl_checkcnr.obj \
     70$(OUTPUTDIR)\cctl_progbar.obj \
     71$(OUTPUTDIR)\cctl_splitwin.obj \
     72$(OUTPUTDIR)\cctl_tooltip.obj \
     73$(OUTPUTDIR)\comctl.obj \
     74$(OUTPUTDIR)\cnrh.obj \
     75$(OUTPUTDIR)\gpih.obj \
     76$(OUTPUTDIR)\memdebug.obj \
     77$(OUTPUTDIR)\memdebug_win.obj \
     78$(OUTPUTDIR)\shapewin.obj \
     79$(OUTPUTDIR)\threads.obj \
     80$(OUTPUTDIR)\textview.obj \
     81$(OUTPUTDIR)\textv_html.obj \
     82$(OUTPUTDIR)\winh.obj
    8283
    8384# helpers include path
  • trunk/src/helpers/makefile

    r9 r13  
    136136# The exclamation point ( ! ) preceding the LIB command causes NMAKE
    137137# to execute the LIB command once for each dependent file in the list.
     138
    138139$(OUTPUTDIR)\helpers.lib: $(OBJS)
    139140!ifdef EMX
    140     !emxomfar cr $(OUTPUTDIR)\helpers.lib $?
     141    !emxomfar cr $* $?
    141142!else
    142     !ilib /nol /nob $(OUTPUTDIR)\helpers.lib -+$?;
     143    !ilib /nol /nob $* -+$?;
     144!endif
     145
     146# same thing for cp.lib
     147$(OUTPUTDIR)\cp.lib: $(CPOBJS)
     148!ifdef EMX
     149    !emxomfar cr $* $?
     150!else
     151    !ilib /nol /nob $* -+$?;
     152!endif
     153
     154# same thing for plainc.lib
     155$(OUTPUTDIR)\plainc.lib: $(PLAINCOBJS)
     156!ifdef EMX
     157    !emxomfar cr $* $?
     158!else
     159    !ilib /nol /nob $* -+$?;
    143160!endif
    144161
  • trunk/src/helpers/memdebug.c

    r8 r13  
    11
    22/*
    3  * memdebug.c:
    4  *      memory debugging helpers. Memory debugging is enabled
    5  *      if the __XWPMEMDEBUG__ #define is set in setup.h.
     3 *@@sourcefile memdebug.c:
     4 *      memory debugging helpers.
    65 *
    76 *      Several things are in here which might turn out to
     
    1211 *      -- Sophisticated heap debugging functions, which
    1312 *         automatically replace malloc() and free() etc.
    14  *         when XWorkplace is compiled with debug code.
     13 *         If the __XWPMEMDEBUG__ #define is set before including
     14 *         memdebug.h, all those standard library calls
     15 *         are remapped to use the functions in this file
     16 *         instead.
     17 *
     18 *         At present, malloc(), calloc(), realloc(), strdup()
     19 *         and free() are supported.
     20 *
    1521 *         These log every memory allocation made and log
    1622 *         much more data compared to the VAC++ memory
     
    2834 *         function.
    2935 *
    30  *         At present, malloc(), calloc(), strdup() and free()
    31  *         are supported. If you invoke free() on a memory block
    32  *         allocated by a function other than the above, you'll
    33  *         get a runtime error.
    34  *
    3536 *         These debug functions have been added with V0.9.3
    3637 *         and should now be compiler-independent.
    3738 *
    38  *      -- A PM heap debugging window which shows the statuzs
     39 *         V0.9.6 added realloc() support and fixed a few bugs.
     40 *
     41 *      -- A PM heap debugging window which shows the status
    3942 *         of the heap logging list. See memdCreateMemDebugWindow
    40  *         for details.
    41  *
    42  *      To enable memory debugging, do the following:
     43 *         (memdebug_win.c) for details.
     44 *
     45 *      To enable memory debugging, do the following in each (!)
     46 *      of your code modules:
    4347 *
    4448 *      1) Include at least <stdlib.h> and <string.h>.
     
    5357 *      That's all. XWorkplace's setup.h does this automatically
    5458 *      if XWorkplace is compiled with debug code.
     59 *
     60 *      A couple of WARNINGS:
     61 *
     62 *      1)  Memory debugging can greatly slow down the system
     63 *          after a while. When free() is invoked, the memory
     64 *          that was allocated is freed, but not the memory
     65 *          log entry (the HEAPITEM) to allow tracing what was
     66 *          freed. As a result, the linked list of memory items
     67 *          keeps growing longer, and free() becomes terribly
     68 *          slow after a while because it must traverse the
     69 *          entire list for each free() call. Use memdReleaseFreed
     70 *          from time to time.
     71 *
     72 *      2)  The replacement functions in this file allocate
     73 *          extra memory for the magic strings. For example, if
     74 *          you call malloc(100), more than 100 bytes get allocated
     75 *          to allow for storing the magic strings to detect
     76 *          memory overwrites. Two magic strings are allocated,
     77 *          one before the actual buffer, and one behind it.
     78 *
     79 *          As a result, YOU MUST NOT confuse the replacement
     80 *          memory functions with the original ones. If you
     81 *          use malloc() in one source file and free() the
     82 *          buffer in another one where debug memory has not
     83 *          been enabled, you'll get crashes.
     84 *
     85 *          As a rule of thumb, enable memory debugging for all
     86 *          your source files or for none. And make sure everything
     87 *          is recompiled when you change your mind.
    5588 *
    5689 *@@added V0.9.1 (2000-02-12) [umoeller]
     
    80113#define INCL_DOSERRORS
    81114
    82 #define INCL_WINWINDOWMGR
    83 #define INCL_WINFRAMEMGR
    84 #define INCL_WINCOUNTRY
    85 #define INCL_WINSYS
    86 #define INCL_WINMENUS
    87 #define INCL_WINSTDCNR
    88115#include <os2.h>
    89116
    90117#include <stdio.h>
    91118#include <string.h>
    92 // #include <malloc.h>
    93119#include <setjmp.h>
    94120
    95 #define DONT_REPLACE_MALLOC             // we need the "real" malloc in this file
     121#define DONT_REPLACE_MALLOC             // never do debug memory for this
     122#define MEMDEBUG_PRIVATE
    96123#include "setup.h"
    97124
    98125#ifdef __XWPMEMDEBUG__
    99126
    100 #include "helpers\cnrh.h"
    101127#include "helpers\except.h"
    102 // #include "helpers\memdebug.h"        // included by setup.h already
     128#include "helpers\memdebug.h"        // included by setup.h already
    103129#include "helpers\stringh.h"
    104 #include "helpers\winh.h"
    105130
    106131/*
     
    120145#define MEMBLOCKMAGIC_TAIL     "\250\210&%/dfjsk%#,dlhf\223"
    121146
    122 /*
    123  *@@ HEAPITEM:
    124  *      informational structure created for each
    125  *      malloc() call by memdMalloc. These are stored
    126  *      in a global linked list (G_pHeapItemsRoot).
    127  *
    128  *      We cannot use the linklist.c functions for
    129  *      managing the linked list because these use
    130  *      malloc in turn, which would lead to infinite
    131  *      loops.
    132  *
    133  *@@added V0.9.3 (2000-04-11) [umoeller]
    134  */
    135 
    136 typedef struct _HEAPITEM
    137 {
    138     struct _HEAPITEM    *pNext;     // next item in linked list or NULL if last
    139 
    140     void                *pAfterMagic; // memory pointer returned by memdMalloc;
    141                                     // this points to after the magic string
    142     unsigned long       ulSize;     // size of *pData
    143 
    144     const char          *pcszSourceFile;    // as passed to memdMalloc
    145     unsigned long       ulLine;             // as passed to memdMalloc
    146     const char          *pcszFunction;      // as passed to memdMalloc
    147 
    148     DATETIME            dtAllocated;        // system date/time at time of memdMalloc call
    149 
    150     ULONG               ulTID;      // thread ID that memdMalloc was running on
    151 
    152     BOOL                fFreed;     // TRUE only after item has been freed by memdFree
    153 } HEAPITEM, *PHEAPITEM;
    154 
    155147HMTX            G_hmtxMallocList = NULLHANDLE;
    156148
    157 PHEAPITEM       G_pHeapItemsRoot = NULL,
    158                 G_pHeapItemsLast = NULL;
    159 
    160 PSZ             G_pszMemCnrTitle = NULL;
     149extern PHEAPITEM G_pHeapItemsRoot = NULL;
     150PHEAPITEM       G_pHeapItemsLast = NULL;
    161151
    162152PFNCBMEMDLOG    G_pMemdLogFunc = NULL;
    163153
    164 ULONG           G_ulItemsReleased = 0,
    165                 G_ulBytesReleased = 0;
     154extern ULONG    G_ulItemsReleased = 0;
     155extern ULONG    G_ulBytesReleased = 0;
    166156
    167157/* ******************************************************************
     
    189179        arc = DosCreateMutexSem(NULL,
    190180                                &G_hmtxMallocList,
    191                                 0,
    192                                 FALSE);
    193 
    194     arc = DosRequestMutexSem(G_hmtxMallocList,
    195                              SEM_INDEFINITE_WAIT);
     181                                0,          // unshared
     182                                TRUE);      // request now!
     183    else
     184        arc = DosRequestMutexSem(G_hmtxMallocList,
     185                                 SEM_INDEFINITE_WAIT);
    196186
    197187    return (arc == NO_ERROR);
     
    435425                    pHeapItem->fFreed = TRUE;
    436426
    437                     /* lstRemoveNode(&G_llHeapItems,
    438                                   pNode); */
    439427                    fFound = TRUE;
    440428                    break;
    441                 }
     429                } // if (!pHeapItem->fFreed)
    442430
    443431            pHeapItem = pHeapItem->pNext;
     
    452440            CHAR szMsg[1000];
    453441            sprintf(szMsg,
    454                     "free() failed. Called from %s (%s, line %d) for object 0x%lX.",
     442                    "free() called with invalid object from %s (%s, line %d) for object 0x%lX.",
    455443                    pcszFunction,
    456444                        pcszSourceFile,
     
    459447            G_pMemdLogFunc(szMsg);
    460448        }
     449}
     450
     451/*
     452 *@@ memdRealloc:
     453 *      wrapper function for realloc(). See memdMalloc for
     454 *      details.
     455 *
     456 *@@added V0.9.6 (2000-11-12) [umoeller]
     457 */
     458
     459void* memdRealloc(void *p,
     460                  size_t stSize,
     461                  const char *pcszSourceFile, // in: source file name
     462                  unsigned long ulLine,       // in: source line
     463                  const char *pcszFunction)   // in: function name
     464{
     465    void *prc = NULL;
     466    BOOL fFound = FALSE;
     467
     468    if (memdLock())
     469    {
     470        PHEAPITEM pHeapItem = G_pHeapItemsRoot;
     471
     472        // search the list with the pointer which was
     473        // really returned by the original malloc(),
     474        // that is, the byte before the magic string
     475        void *pBeforeMagic = ((PBYTE)p) - sizeof(MEMBLOCKMAGIC_HEAD);
     476
     477        while (pHeapItem)
     478        {
     479            if (pHeapItem->pAfterMagic == p)
     480                // the same address may be allocated and freed
     481                // several times, so if this address has been
     482                // freed, search on
     483                if (!pHeapItem->fFreed)
     484                {
     485                    // found:
     486                    PVOID   pObjNew = 0;
     487                    ULONG   ulError = 0;
     488                    ULONG   cbCopy = 0;
     489                    PTIB    ptib;
     490                    PPIB    ppib;
     491
     492                    // check magic string
     493                    if (memcmp(pBeforeMagic,
     494                               MEMBLOCKMAGIC_HEAD,
     495                               sizeof(MEMBLOCKMAGIC_HEAD))
     496                            != 0)
     497                        ulError = 1;
     498                    else if (memcmp(((PBYTE)pHeapItem->pAfterMagic) + pHeapItem->ulSize,
     499                                    MEMBLOCKMAGIC_TAIL,
     500                                    sizeof(MEMBLOCKMAGIC_TAIL))
     501                            != 0)
     502                        ulError = 2;
     503
     504                    if (ulError)
     505                    {
     506                        // magic block has been overwritten:
     507                        if (G_pMemdLogFunc)
     508                        {
     509                            CHAR szMsg[1000];
     510                            sprintf(szMsg,
     511                                    "Magic string %s memory block at 0x%lX has been overwritten.\n"
     512                                    "This was detected by the realloc() call at %s (%s, line %d).\n"
     513                                    "The block was allocated by %s (%s, line %d).",
     514                                    (ulError == 1) ? "before" : "after",
     515                                    p,
     516                                    pcszFunction,
     517                                        pcszSourceFile,
     518                                        ulLine, // free
     519                                    pHeapItem->pcszFunction,
     520                                        pHeapItem->pcszSourceFile,
     521                                        pHeapItem->ulLine);
     522                            G_pMemdLogFunc(szMsg);
     523                        }
     524                    }
     525
     526                    // now reallocate!
     527                    pObjNew = malloc(stSize   // new size
     528                                     + sizeof(MEMBLOCKMAGIC_HEAD)
     529                                     + sizeof(MEMBLOCKMAGIC_TAIL));
     530
     531                    // store "front" magic string
     532                    memcpy(pObjNew,
     533                           MEMBLOCKMAGIC_HEAD,
     534                           sizeof(MEMBLOCKMAGIC_HEAD));
     535                    // return address: first byte after "front" magic string
     536                    prc = ((PBYTE)pObjNew) + sizeof(MEMBLOCKMAGIC_HEAD);
     537
     538                    // bytes to copy: the smaller of the old and the new size
     539                    cbCopy = pHeapItem->ulSize;
     540                    if (stSize < pHeapItem->ulSize)
     541                        cbCopy = stSize;
     542
     543                    // copy buffer from old memory object
     544                    memcpy(prc,         // after "front" magic
     545                           pHeapItem->pAfterMagic,
     546                           cbCopy);
     547
     548                    // store "tail" magic string to block which
     549                    // will be returned plus the size which was requested
     550                    memcpy(((PBYTE)prc) + stSize,
     551                           MEMBLOCKMAGIC_TAIL,
     552                           sizeof(MEMBLOCKMAGIC_TAIL));
     553
     554                    // free the old buffer
     555                    free(pBeforeMagic);
     556
     557                    // update the HEAPITEM
     558                    pHeapItem->pAfterMagic = prc;       // new pointer!
     559                    pHeapItem->ulSize = stSize;         // new size!
     560                    pHeapItem->pcszSourceFile = pcszSourceFile;
     561                    pHeapItem->ulLine = ulLine;
     562                    pHeapItem->pcszFunction = pcszFunction;
     563
     564                    // update date, time, TID
     565                    DosGetDateTime(&pHeapItem->dtAllocated);
     566                    pHeapItem->ulTID = 0;
     567                    if (DosGetInfoBlocks(&ptib, &ppib) == NO_ERROR)
     568                        if (ptib)
     569                            if (ptib->tib_ptib2)
     570                                pHeapItem->ulTID = ptib->tib_ptib2->tib2_ultid;
     571
     572                    fFound = TRUE;
     573                    break;
     574                } // if (!pHeapItem->fFreed)
     575
     576            pHeapItem = pHeapItem->pNext;
     577        }
     578
     579        memdUnlock();
     580    }
     581
     582    if (!fFound)
     583        if (G_pMemdLogFunc)
     584        {
     585            CHAR szMsg[1000];
     586            sprintf(szMsg,
     587                    "realloc() called with invalid object from %s (%s, line %d) for object 0x%lX.",
     588                    pcszFunction,
     589                        pcszSourceFile,
     590                        ulLine,
     591                    p);
     592            G_pMemdLogFunc(szMsg);
     593        }
     594
     595    return (prc);
    461596}
    462597
     
    485620        while (pHeapItem)
    486621        {
     622            // store next first, because we can change the "next" pointer
    487623            PHEAPITEM   pNext = pHeapItem->pNext;       // can be NULL
     624
    488625            if (pHeapItem->fFreed)
    489626            {
    490                 // item freed:
     627                // item was freed:
    491628                if (pPrevious == NULL)
    492629                    // head of list:
     
    499636                ulItemsReleased++;
    500637                ulBytesReleased += pHeapItem->ulSize;
     638
     639                if (pHeapItem == G_pHeapItemsLast)
     640                    // reset "last item" cache
     641                    G_pHeapItemsLast = NULL;
    501642
    502643                free(pHeapItem);
     
    550691#endif
    551692
    552 /* ******************************************************************
    553  *                                                                  *
    554  *   Heap debugging window                                          *
    555  *                                                                  *
    556  ********************************************************************/
    557 
    558 /*
    559  *@@ MEMRECORD:
    560  *
    561  *@@added V0.9.1 (99-12-04) [umoeller]
    562  */
    563 
    564 typedef struct _MEMRECORD
    565 {
    566     RECORDCORE  recc;
    567 
    568     ULONG       ulIndex;
    569 
    570     CDATE       cdateAllocated;
    571     CTIME       ctimeAllocated;
    572 
    573     PSZ         pszFreed;
    574 
    575     ULONG       ulTID;
    576 
    577     PSZ         pszFunction;    // points to szFunction
    578     CHAR        szFunction[400];
    579 
    580     PSZ         pszSource;      // points to szSource
    581     CHAR        szSource[CCHMAXPATH];
    582 
    583     ULONG       ulLine;
    584 
    585     PSZ         pszAddress;     // points to szAddress
    586     CHAR        szAddress[20];
    587 
    588     ULONG       ulSize;
    589 
    590 } MEMRECORD, *PMEMRECORD;
    591 
    592 /* ULONG       ulHeapItemsCount1,
    593             ulHeapItemsCount2;
    594 ULONG       ulTotalAllocated,
    595             ulTotalFreed;
    596 PMEMRECORD  pMemRecordThis = NULL;
    597 PSZ         pszMemCnrTitle = NULL; */
    598 
    599 #if 0
    600     /*
    601      *@@ fncbMemHeapWalkCount:
    602      *      callback func for _heap_walk function used for
    603      *      fnwpMemDebug.
    604      *
    605      *@@added V0.9.1 (99-12-04) [umoeller]
    606      */
    607 
    608     int fncbMemHeapWalkCount(const void *pObject,
    609                              size_t Size,
    610                              int useflag,
    611                              int status,
    612                              const char *filename,
    613                              size_t line)
    614     {
    615         // skip all the items which seem to be
    616         // internal to the runtime
    617         if ((filename) || (useflag == _FREEENTRY))
    618         {
    619             ulHeapItemsCount1++;
    620             if (useflag == _FREEENTRY)
    621                 ulTotalFreed += Size;
    622             else
    623                 ulTotalAllocated += Size;
    624         }
    625         return (0);
    626     }
    627 
    628     /*
    629      *@@ fncbMemHeapWalkFill:
    630      *      callback func for _heap_walk function used for
    631      *      fnwpMemDebug.
    632      *
    633      *@@added V0.9.1 (99-12-04) [umoeller]
    634      */
    635 
    636     int fncbMemHeapWalkFill(const void *pObject,
    637                             size_t Size,
    638                             int useflag,
    639                             int status,
    640                             const char *filename,
    641                             size_t line)
    642     {
    643         // skip all the items which seem to be
    644         // internal to the runtime
    645         if ((filename) || (useflag == _FREEENTRY))
    646         {
    647             ulHeapItemsCount2++;
    648             if ((pMemRecordThis) && (ulHeapItemsCount2 < ulHeapItemsCount1))
    649             {
    650                 pMemRecordThis->ulIndex = ulHeapItemsCount2 - 1;
    651 
    652                 pMemRecordThis->pObject = pObject;
    653                 pMemRecordThis->useflag = useflag;
    654                 pMemRecordThis->status = status;
    655                 pMemRecordThis->filename = filename;
    656 
    657                 pMemRecordThis->pszAddress = pMemRecordThis->szAddress;
    658 
    659                 pMemRecordThis->ulSize = Size;
    660 
    661                 pMemRecordThis->pszSource = pMemRecordThis->szSource;
    662 
    663                 pMemRecordThis->ulLine = line;
    664 
    665                 pMemRecordThis = (PMEMRECORD)pMemRecordThis->recc.preccNextRecord;
    666             }
    667             else
    668                 return (1);     // stop
    669         }
    670 
    671         return (0);
    672     }
    673 
    674     /*
    675      *@@ memdCreateRecordsVAC:
    676      *
    677      *@@added V0.9.3 (2000-04-10) [umoeller]
    678      */
    679 
    680     VOID memdCreateRecordsVAC(HWND hwndCnr)
    681     {
    682         // count heap items
    683         ulHeapItemsCount1 = 0;
    684         ulTotalFreed = 0;
    685         ulTotalAllocated = 0;
    686         _heap_walk(fncbMemHeapWalkCount);
    687 
    688         pMemRecordFirst = (PMEMRECORD)cnrhAllocRecords(hwndCnr,
    689                                                        sizeof(MEMRECORD),
    690                                                        ulHeapItemsCount1);
    691         if (pMemRecordFirst)
    692         {
    693             ulHeapItemsCount2 = 0;
    694             pMemRecordThis = pMemRecordFirst;
    695             _heap_walk(fncbMemHeapWalkFill);
    696 
    697             // the following doesn't work while _heap_walk is running
    698             pMemRecordThis = pMemRecordFirst;
    699             while (pMemRecordThis)
    700             {
    701                 switch (pMemRecordThis->useflag)
    702                 {
    703                     case _USEDENTRY: pMemRecordThis->pszUseFlag = "Used"; break;
    704                     case _FREEENTRY: pMemRecordThis->pszUseFlag = "Freed"; break;
    705                 }
    706 
    707                 switch (pMemRecordThis->status)
    708                 {
    709                     case _HEAPBADBEGIN: pMemRecordThis->pszStatus = "heap bad begin"; break;
    710                     case _HEAPBADNODE: pMemRecordThis->pszStatus = "heap bad node"; break;
    711                     case _HEAPEMPTY: pMemRecordThis->pszStatus = "heap empty"; break;
    712                     case _HEAPOK: pMemRecordThis->pszStatus = "OK"; break;
    713                 }
    714 
    715                 sprintf(pMemRecordThis->szAddress, "0x%lX", pMemRecordThis->pObject);
    716                 strcpy(pMemRecordThis->szSource,
    717                         (pMemRecordThis->filename)
    718                             ? pMemRecordThis->filename
    719                             : "?");
    720 
    721                 pMemRecordThis = (PMEMRECORD)pMemRecordThis->recc.preccNextRecord;
    722             }
    723 
    724             cnrhInsertRecords(hwndCnr,
    725                               NULL,         // parent
    726                               (PRECORDCORE)pMemRecordFirst,
    727                               TRUE,
    728                               NULL,
    729                               CRA_RECORDREADONLY,
    730                               ulHeapItemsCount2);
    731         }
    732     }
    733 
    734 #endif
    735 
    736 /*
    737  *@@ memdCreateRecords:
    738  *
    739  *@@added V0.9.3 (2000-04-10) [umoeller]
    740  */
    741 
    742 VOID memdCreateRecords(HWND hwndCnr,
    743                        PULONG pulTotalItems,
    744                        PULONG pulAllocatedItems,
    745                        PULONG pulFreedItems,
    746                        PULONG pulTotalBytes,
    747                        PULONG pulAllocatedBytes,
    748                        PULONG pulFreedBytes)
    749 {
    750     // count heap items
    751     ULONG       ulHeapItemsCount1 = 0;
    752     PMEMRECORD  pMemRecordFirst;
    753 
    754     if (memdLock())
    755     {
    756         // PLISTNODE   pNode = lstQueryFirstNode(&G_llHeapItems);
    757         PHEAPITEM pHeapItem = G_pHeapItemsRoot;
    758 
    759         *pulTotalItems = 0;
    760         *pulAllocatedItems = 0;
    761         *pulFreedItems = 0;
    762 
    763         *pulTotalBytes = 0;
    764         *pulAllocatedBytes = 0;
    765         *pulFreedBytes = 0;
    766 
    767         while (pHeapItem)
    768         {
    769             ulHeapItemsCount1++;
    770             if (pHeapItem->fFreed)
    771             {
    772                 (*pulFreedItems)++;
    773                 (*pulFreedBytes) += pHeapItem->ulSize;
    774             }
    775             else
    776             {
    777                 (*pulAllocatedItems)++;
    778                 (*pulAllocatedBytes) += pHeapItem->ulSize;
    779             }
    780 
    781             (*pulTotalBytes) += pHeapItem->ulSize;
    782 
    783             pHeapItem = pHeapItem->pNext;
    784         }
    785 
    786         *pulTotalItems = ulHeapItemsCount1;
    787 
    788         pMemRecordFirst = (PMEMRECORD)cnrhAllocRecords(hwndCnr,
    789                                                        sizeof(MEMRECORD),
    790                                                        ulHeapItemsCount1);
    791         if (pMemRecordFirst)
    792         {
    793             ULONG       ulHeapItemsCount2 = 0;
    794             PMEMRECORD  pMemRecordThis = pMemRecordFirst;
    795             pHeapItem = G_pHeapItemsRoot;
    796             // PLISTNODE   pMemNode = lstQueryFirstNode(&G_llHeapItems);
    797 
    798             while ((pMemRecordThis) && (pHeapItem))
    799             {
    800                 // PHEAPITEM pHeapItem = (PHEAPITEM)pMemNode->pItemData;
    801 
    802                 pMemRecordThis->ulIndex = ulHeapItemsCount2++;
    803 
    804                 cnrhDateTimeDos2Win(&pHeapItem->dtAllocated,
    805                                     &pMemRecordThis->cdateAllocated,
    806                                     &pMemRecordThis->ctimeAllocated);
    807 
    808                 if (pHeapItem->fFreed)
    809                     pMemRecordThis->pszFreed = "yes";
    810 
    811                 pMemRecordThis->ulTID = pHeapItem->ulTID;
    812 
    813                 strcpy(pMemRecordThis->szSource, pHeapItem->pcszSourceFile);
    814                 pMemRecordThis->pszSource = pMemRecordThis->szSource;
    815 
    816                 pMemRecordThis->ulLine = pHeapItem->ulLine;
    817 
    818                 strcpy(pMemRecordThis->szFunction, pHeapItem->pcszFunction);
    819                 pMemRecordThis->pszFunction = pMemRecordThis->szFunction;
    820 
    821                 sprintf(pMemRecordThis->szAddress, "0x%lX", pHeapItem->pAfterMagic);
    822                 pMemRecordThis->pszAddress = pMemRecordThis->szAddress;
    823 
    824                 pMemRecordThis->ulSize = pHeapItem->ulSize;
    825 
    826 
    827                 /* switch (pMemRecordThis->useflag)
    828                 {
    829                     case _USEDENTRY: pMemRecordThis->pszUseFlag = "Used"; break;
    830                     case _FREEENTRY: pMemRecordThis->pszUseFlag = "Freed"; break;
    831                 }
    832 
    833                 switch (pMemRecordThis->status)
    834                 {
    835                     case _HEAPBADBEGIN: pMemRecordThis->pszStatus = "heap bad begin"; break;
    836                     case _HEAPBADNODE: pMemRecordThis->pszStatus = "heap bad node"; break;
    837                     case _HEAPEMPTY: pMemRecordThis->pszStatus = "heap empty"; break;
    838                     case _HEAPOK: pMemRecordThis->pszStatus = "OK"; break;
    839                 }
    840 
    841                 sprintf(pMemRecordThis->szAddress, "0x%lX", pMemRecordThis->pObject);
    842                 strcpy(pMemRecordThis->szSource,
    843                         (pMemRecordThis->filename)
    844                             ? pMemRecordThis->filename
    845                             : "?"); */
    846 
    847                 pMemRecordThis = (PMEMRECORD)pMemRecordThis->recc.preccNextRecord;
    848                 pHeapItem = pHeapItem->pNext;
    849             }
    850 
    851             cnrhInsertRecords(hwndCnr,
    852                               NULL,         // parent
    853                               (PRECORDCORE)pMemRecordFirst,
    854                               TRUE,
    855                               NULL,
    856                               CRA_RECORDREADONLY,
    857                               ulHeapItemsCount2);
    858         }
    859 
    860         memdUnlock();
    861     }
    862 }
    863 
    864 /*
    865  *@@ mnu_fnCompareIndex:
    866  *
    867  *@@added V0.9.1 (99-12-03) [umoeller]
    868  */
    869 
    870 SHORT EXPENTRY mnu_fnCompareIndex(PMEMRECORD pmrc1, PMEMRECORD  pmrc2, PVOID pStorage)
    871 {
    872     // HAB habDesktop = WinQueryAnchorBlock(HWND_DESKTOP);
    873     pStorage = pStorage; // to keep the compiler happy
    874     if ((pmrc1) && (pmrc2))
    875         if (pmrc1->ulIndex < pmrc2->ulIndex)
    876             return (-1);
    877         else if (pmrc1->ulIndex > pmrc2->ulIndex)
    878             return (1);
    879 
    880     return (0);
    881 }
    882 
    883 /*
    884  *@@ mnu_fnCompareSourceFile:
    885  *
    886  *@@added V0.9.1 (99-12-03) [umoeller]
    887  */
    888 
    889 SHORT EXPENTRY mnu_fnCompareSourceFile(PMEMRECORD pmrc1, PMEMRECORD  pmrc2, PVOID pStorage)
    890 {
    891     HAB habDesktop = WinQueryAnchorBlock(HWND_DESKTOP);
    892     pStorage = pStorage; // to keep the compiler happy
    893     if ((pmrc1) && (pmrc2))
    894             switch (WinCompareStrings(habDesktop, 0, 0,
    895                                       pmrc1->szSource,
    896                                       pmrc2->szSource,
    897                                       0))
    898             {
    899                 case WCS_LT: return (-1);
    900                 case WCS_GT: return (1);
    901                 default:    // equal
    902                     if (pmrc1->ulLine < pmrc2->ulLine)
    903                         return (-1);
    904                     else if (pmrc1->ulLine > pmrc2->ulLine)
    905                         return (1);
    906 
    907             }
    908 
    909     return (0);
    910 }
    911 
    912 #define ID_MEMCNR   1000
    913 
    914 /*
    915  *@@ memd_fnwpMemDebug:
    916  *      client window proc for the heap debugger window
    917  *      accessible from the Desktop context menu if
    918  *      __XWPMEMDEBUG__ is defined. Otherwise, this is not
    919  *      compiled.
    920  *
    921  *      Usage: this is a regular PM client window procedure
    922  *      to be used with WinRegisterClass and WinCreateStdWindow.
    923  *      See dtpMenuItemSelected, which uses this.
    924  *
    925  *      This creates a container with all the memory objects
    926  *      with the size of the client area in turn.
    927  *
    928  *@@added V0.9.1 (99-12-04) [umoeller]
    929  */
    930 
    931 
    932 MRESULT EXPENTRY memd_fnwpMemDebug(HWND hwndClient, ULONG msg, MPARAM mp1, MPARAM mp2)
    933 {
    934     MRESULT mrc = 0;
    935 
    936     switch (msg)
    937     {
    938         case WM_CREATE:
    939         {
    940             TRY_LOUD(excpt1, NULL)
    941             {
    942                 // PCREATESTRUCT pcs = (PCREATESTRUCT)mp2;
    943                 HWND hwndCnr;
    944                 hwndCnr = WinCreateWindow(hwndClient,        // parent
    945                                           WC_CONTAINER,
    946                                           "",
    947                                           WS_VISIBLE | CCS_MINIICONS | CCS_READONLY | CCS_SINGLESEL,
    948                                           0, 0, 0, 0,
    949                                           hwndClient,        // owner
    950                                           HWND_TOP,
    951                                           ID_MEMCNR,
    952                                           NULL, NULL);
    953                 if (hwndCnr)
    954                 {
    955                     XFIELDINFO      xfi[11];
    956                     PFIELDINFO      pfi = NULL;
    957                     PMEMRECORD      pMemRecordFirst;
    958                     int             i = 0;
    959 
    960                     ULONG           ulTotalItems = 0,
    961                                     ulAllocatedItems = 0,
    962                                     ulFreedItems = 0;
    963                     ULONG           ulTotalBytes = 0,
    964                                     ulAllocatedBytes = 0,
    965                                     ulFreedBytes = 0;
    966 
    967                     // set up cnr details view
    968                     xfi[i].ulFieldOffset = FIELDOFFSET(MEMRECORD, ulIndex);
    969                     xfi[i].pszColumnTitle = "No.";
    970                     xfi[i].ulDataType = CFA_ULONG;
    971                     xfi[i++].ulOrientation = CFA_RIGHT;
    972 
    973                     xfi[i].ulFieldOffset = FIELDOFFSET(MEMRECORD, cdateAllocated);
    974                     xfi[i].pszColumnTitle = "Date";
    975                     xfi[i].ulDataType = CFA_DATE;
    976                     xfi[i++].ulOrientation = CFA_LEFT;
    977 
    978                     xfi[i].ulFieldOffset = FIELDOFFSET(MEMRECORD, ctimeAllocated);
    979                     xfi[i].pszColumnTitle = "Time";
    980                     xfi[i].ulDataType = CFA_TIME;
    981                     xfi[i++].ulOrientation = CFA_LEFT;
    982 
    983                     xfi[i].ulFieldOffset = FIELDOFFSET(MEMRECORD, pszFreed);
    984                     xfi[i].pszColumnTitle = "Freed";
    985                     xfi[i].ulDataType = CFA_STRING;
    986                     xfi[i++].ulOrientation = CFA_CENTER;
    987 
    988                     xfi[i].ulFieldOffset = FIELDOFFSET(MEMRECORD, ulTID);
    989                     xfi[i].pszColumnTitle = "TID";
    990                     xfi[i].ulDataType = CFA_ULONG;
    991                     xfi[i++].ulOrientation = CFA_RIGHT;
    992 
    993                     xfi[i].ulFieldOffset = FIELDOFFSET(MEMRECORD, pszFunction);
    994                     xfi[i].pszColumnTitle = "Function";
    995                     xfi[i].ulDataType = CFA_STRING;
    996                     xfi[i++].ulOrientation = CFA_LEFT;
    997 
    998                     xfi[i].ulFieldOffset = FIELDOFFSET(MEMRECORD, pszSource);
    999                     xfi[i].pszColumnTitle = "Source";
    1000                     xfi[i].ulDataType = CFA_STRING;
    1001                     xfi[i++].ulOrientation = CFA_LEFT;
    1002 
    1003                     xfi[i].ulFieldOffset = FIELDOFFSET(MEMRECORD, ulLine);
    1004                     xfi[i].pszColumnTitle = "Line";
    1005                     xfi[i].ulDataType = CFA_ULONG;
    1006                     xfi[i++].ulOrientation = CFA_RIGHT;
    1007 
    1008                     xfi[i].ulFieldOffset = FIELDOFFSET(MEMRECORD, ulSize);
    1009                     xfi[i].pszColumnTitle = "Size";
    1010                     xfi[i].ulDataType = CFA_ULONG;
    1011                     xfi[i++].ulOrientation = CFA_RIGHT;
    1012 
    1013                     xfi[i].ulFieldOffset = FIELDOFFSET(MEMRECORD, pszAddress);
    1014                     xfi[i].pszColumnTitle = "Address";
    1015                     xfi[i].ulDataType = CFA_STRING;
    1016                     xfi[i++].ulOrientation = CFA_LEFT;
    1017 
    1018                     pfi = cnrhSetFieldInfos(hwndCnr,
    1019                                             &xfi[0],
    1020                                             i,             // array item count
    1021                                             TRUE,          // no draw lines
    1022                                             3);            // return column
    1023 
    1024                     {
    1025                         PSZ pszFont = "9.WarpSans";
    1026                         WinSetPresParam(hwndCnr,
    1027                                         PP_FONTNAMESIZE,
    1028                                         strlen(pszFont),
    1029                                         pszFont);
    1030                     }
    1031 
    1032                     memdCreateRecords(hwndCnr,
    1033                                       &ulTotalItems,
    1034                                       &ulAllocatedItems,
    1035                                       &ulFreedItems,
    1036                                       &ulTotalBytes,
    1037                                       &ulAllocatedBytes,
    1038                                       &ulFreedBytes);
    1039 
    1040                     BEGIN_CNRINFO()
    1041                     {
    1042                         CHAR    szCnrTitle[1000];
    1043                         CHAR    szTotalItems[100],
    1044                                 szAllocatedItems[100],
    1045                                 szFreedItems[100],
    1046                                 szReleasedItems[100];
    1047                         CHAR    szTotalBytes[100],
    1048                                 szAllocatedBytes[100],
    1049                                 szFreedBytes[100],
    1050                                 szReleasedBytes[100];
    1051                         sprintf(szCnrTitle,
    1052                                 "Total logs in use: %s items = %s bytes\n"
    1053                                 "    Total in use: %s items = %s bytes\n"
    1054                                 "    Total freed: %s items = %s bytes\n"
    1055                                 "Total logs released: %s items = %s bytes",
    1056                                 strhThousandsDouble(szTotalItems,
    1057                                                     ulTotalItems,
    1058                                                     '.'),
    1059                                 strhThousandsDouble(szTotalBytes,
    1060                                                     ulTotalBytes,
    1061                                                     '.'),
    1062                                 strhThousandsDouble(szAllocatedItems,
    1063                                                     ulAllocatedItems,
    1064                                                     '.'),
    1065                                 strhThousandsDouble(szAllocatedBytes,
    1066                                                     ulAllocatedBytes,
    1067                                                     '.'),
    1068                                 strhThousandsDouble(szFreedItems,
    1069                                                     ulFreedItems,
    1070                                                     '.'),
    1071                                 strhThousandsDouble(szFreedBytes,
    1072                                                     ulFreedBytes,
    1073                                                     '.'),
    1074                                 strhThousandsDouble(szReleasedItems,
    1075                                                     G_ulItemsReleased,
    1076                                                     '.'),
    1077                                 strhThousandsDouble(szReleasedBytes,
    1078                                                     G_ulBytesReleased,
    1079                                                     '.'));
    1080                         G_pszMemCnrTitle = strdup(szCnrTitle);
    1081                         cnrhSetTitle(G_pszMemCnrTitle);
    1082                         cnrhSetView(CV_DETAIL | CV_MINI | CA_DETAILSVIEWTITLES
    1083                                         | CA_DRAWICON
    1084                                     | CA_CONTAINERTITLE | CA_TITLEREADONLY
    1085                                         | CA_TITLESEPARATOR | CA_TITLELEFT);
    1086                         cnrhSetSplitBarAfter(pfi);
    1087                         cnrhSetSplitBarPos(250);
    1088                     } END_CNRINFO(hwndCnr);
    1089 
    1090                     WinSetFocus(HWND_DESKTOP, hwndCnr);
    1091                 }
    1092             }
    1093             CATCH(excpt1) {} END_CATCH();
    1094 
    1095             mrc = WinDefWindowProc(hwndClient, msg, mp1, mp2);
    1096         break; }
    1097 
    1098         case WM_WINDOWPOSCHANGED:
    1099         {
    1100             PSWP pswp = (PSWP)mp1;
    1101             mrc = WinDefWindowProc(hwndClient, msg, mp1, mp2);
    1102             if (pswp->fl & SWP_SIZE)
    1103             {
    1104                 WinSetWindowPos(WinWindowFromID(hwndClient, ID_MEMCNR), // cnr
    1105                                 HWND_TOP,
    1106                                 0, 0, pswp->cx, pswp->cy,
    1107                                 SWP_SIZE | SWP_MOVE | SWP_SHOW);
    1108             }
    1109         break; }
    1110 
    1111         case WM_CONTROL:
    1112         {
    1113             USHORT usItemID = SHORT1FROMMP(mp1),
    1114                    usNotifyCode = SHORT2FROMMP(mp1);
    1115             if (usItemID == ID_MEMCNR)       // cnr
    1116             {
    1117                 switch (usNotifyCode)
    1118                 {
    1119                     case CN_CONTEXTMENU:
    1120                     {
    1121                         PMEMRECORD precc = (PMEMRECORD)mp2;
    1122                         if (precc == NULL)
    1123                         {
    1124                             // whitespace
    1125                             HWND hwndMenu = WinCreateMenu(HWND_DESKTOP,
    1126                                                           NULL); // no menu template
    1127                             winhInsertMenuItem(hwndMenu,
    1128                                                MIT_END,
    1129                                                1001,
    1130                                                "Sort by index",
    1131                                                MIS_TEXT, 0);
    1132                             winhInsertMenuItem(hwndMenu,
    1133                                                MIT_END,
    1134                                                1002,
    1135                                                "Sort by source file",
    1136                                                MIS_TEXT, 0);
    1137                             cnrhShowContextMenu(WinWindowFromID(hwndClient, ID_MEMCNR),
    1138                                                 NULL,       // record
    1139                                                 hwndMenu,
    1140                                                 hwndClient);
    1141                         }
    1142                     }
    1143                 }
    1144             }
    1145         break; }
    1146 
    1147         case WM_COMMAND:
    1148             switch (SHORT1FROMMP(mp1))
    1149             {
    1150                 case 1001:  // sort by index
    1151                     WinSendMsg(WinWindowFromID(hwndClient, ID_MEMCNR),
    1152                                CM_SORTRECORD,
    1153                                (MPARAM)mnu_fnCompareIndex,
    1154                                0);
    1155                 break;
    1156 
    1157                 case 1002:  // sort by source file
    1158                     WinSendMsg(WinWindowFromID(hwndClient, ID_MEMCNR),
    1159                                CM_SORTRECORD,
    1160                                (MPARAM)mnu_fnCompareSourceFile,
    1161                                0);
    1162                 break;
    1163             }
    1164         break;
    1165 
    1166         case WM_CLOSE:
    1167             WinDestroyWindow(WinWindowFromID(hwndClient, ID_MEMCNR));
    1168             WinDestroyWindow(WinQueryWindow(hwndClient, QW_PARENT));
    1169             free(G_pszMemCnrTitle);
    1170             G_pszMemCnrTitle = NULL;
    1171         break;
    1172 
    1173         default:
    1174             mrc = WinDefWindowProc(hwndClient, msg, mp1, mp2);
    1175     }
    1176 
    1177     return (mrc);
    1178 }
    1179 
    1180 /*
    1181  *@@ memdCreateMemDebugWindow:
    1182  *      creates a heap debugging window which
    1183  *      is a standard frame with a container,
    1184  *      listing all heap objects ever allocated.
    1185  *
    1186  *      The client of this standard frame is in
    1187  *      memd_fnwpMemDebug.
    1188  *
    1189  *      This thing lists all calls to malloc()
    1190  *      which were ever made, including the
    1191  *      source file and source line number which
    1192  *      made the call. Extreeeemely useful for
    1193  *      detecting memory leaks.
    1194  *
    1195  *      This only works if the memory functions
    1196  *      have been replaced with the debug versions
    1197  *      in this file.
    1198  */
    1199 
    1200 VOID memdCreateMemDebugWindow(VOID)
    1201 {
    1202     ULONG flStyle = FCF_TITLEBAR | FCF_SYSMENU | FCF_HIDEMAX
    1203                     | FCF_SIZEBORDER | FCF_SHELLPOSITION
    1204                     | FCF_NOBYTEALIGN | FCF_TASKLIST;
    1205     if (WinRegisterClass(WinQueryAnchorBlock(HWND_DESKTOP),
    1206                          "XWPMemDebug",
    1207                          memd_fnwpMemDebug, 0L, 0))
    1208     {
    1209         HWND hwndClient;
    1210         HWND hwndMemFrame = WinCreateStdWindow(HWND_DESKTOP,
    1211                                                0L,
    1212                                                &flStyle,
    1213                                                "XWPMemDebug",
    1214                                                "Allocated XWorkplace Memory Objects",
    1215                                                0L,
    1216                                                NULLHANDLE,     // resource
    1217                                                0,
    1218                                                &hwndClient);
    1219         if (hwndMemFrame)
    1220         {
    1221             WinSetWindowPos(hwndMemFrame,
    1222                             HWND_TOP,
    1223                             0, 0, 0, 0,
    1224                             SWP_ZORDER | SWP_SHOW | SWP_ACTIVATE);
    1225         }
    1226     }
    1227 }
    1228 
    1229693#else
    1230694void memdDummy(void)
  • trunk/src/helpers/prfh.c

    r8 r13  
    263263{
    264264    CHAR szColor[30];
    265     LONG r, g, b;
     265    ULONG r, g, b;
    266266    PrfQueryProfileString(
    267267                HINI_USER,
     
    271271                szColor,
    272272                sizeof(szColor)-1);
    273     sscanf(szColor, "%d %d %d ", &r, &g, &b);
    274     return (r*0x10000 + g*0x100 + b);
     273    sscanf(szColor, "%lu %lu %lu ", &r, &g, &b);
     274    return (LONG)(r*0x10000 + g*0x100 + b);
    275275}
    276276
     
    468468            if (PrfQueryProfile(hab, &Profiles))
    469469            {
    470                 _Pmpf(("Old user profile: %s", Profiles.pszUserName));
     470                // _Pmpf(("Old user profile: %s", Profiles.pszUserName));
    471471
    472472                // change INIs
  • trunk/src/helpers/prfh2.c

    r12 r13  
    9898    if (fLog)
    9999    {
    100         fprintf(fLog, "    Error occured: %s\n    Return code: %s (%d)\n",
     100        fprintf(fLog, "    Error occured: %s\n    Return code: %s (%lu)\n",
    101101                pszErrorString,
    102102                    (ulrc == MBID_ABORT) ? "MBID_ABORT"
     
    179179                      "hiniOld 0x%lX, pszOld %s, pfnwpCallback 0x%lX, "
    180180                      "hwnd 0x%lX, msg 0x%lX, ulCount 0x%lX, ulMax 0x%lX\n",
    181                 hOld, pszOld, fncbUpdate, hwnd, msg, ulCount, ulMax);
     181                hOld,
     182                pszOld,
     183                (ULONG)fncbUpdate,
     184                hwnd,
     185                msg,
     186                ulCount,
     187                ulMax);
    182188        fflush(fLog);
    183189    }
     
    500506                arc2 = doshSetPathAttr(szSysBackup, FILE_NORMAL);
    501507                if (fLog)
    502                     fprintf(fLog, "    rc2: %d\n", arc2);
     508                    fprintf(fLog, "    rc2: %lu\n", arc2);
    503509
    504510                // delete OS2SYS.BAK
     
    509515                arc2 = DosDelete(szSysBackup);
    510516                if (fLog)
    511                     fprintf(fLog, "    rc2: %d\n", arc2);
     517                    fprintf(fLog, "    rc2: %lu\n", arc2);
    512518
    513519                // attrib -r -s -h -a OS2SYS.INI
     
    518524                arc2 = doshSetPathAttr(Profiles.pszSysName, FILE_NORMAL);
    519525                if (fLog)
    520                     fprintf(fLog, "    rc2: %d\n", arc2);
     526                    fprintf(fLog, "    rc2: %lu\n", arc2);
    521527
    522528                // move OS2SYS.INI OS2SYS.BAK
     
    526532                arc = DosMove(Profiles.pszSysName, szSysBackup);
    527533                if (fLog)
    528                     fprintf(fLog, "    rc: %d\n", arc);
     534                    fprintf(fLog, "    rc: %lu\n", arc);
    529535
    530536                if (arc)
     
    539545                arc = DosMove(szSysNew, Profiles.pszSysName);
    540546                if (fLog)
    541                     fprintf(fLog, "    rc: %d\n", arc);
     547                    fprintf(fLog, "    rc: %lu\n", arc);
    542548                if (arc)
    543549                    ulErrorOccured = prfhINIError(MB_ABORTRETRYIGNORE, fLog, fncbError, "Error moving newly created profile to system profile.");
     
    566572                arc2 = doshSetPathAttr(szUserBackup, FILE_NORMAL);
    567573                if (fLog)
    568                     fprintf(fLog, "    rc2: %d\n", arc2);
     574                    fprintf(fLog, "    rc2: %lu\n", arc2);
    569575
    570576                // delete OS2.BAK
     
    575581                arc2 = DosDelete(szUserBackup);
    576582                if (fLog)
    577                     fprintf(fLog, "    rc2: %d\n", arc2);
     583                    fprintf(fLog, "    rc2: %lu\n", arc2);
    578584
    579585                // attrib -r -s -h -a OS2.INI
     
    583589                arc2 = doshSetPathAttr(Profiles.pszUserName, FILE_NORMAL);
    584590                if (fLog)
    585                     fprintf(fLog, "    rc2: %d\n", arc2);
     591                    fprintf(fLog, "    rc2: %lu\n", arc2);
    586592
    587593                // move OS2.INI OS2.BAK
     
    591597                arc = DosMove(Profiles.pszUserName, szUserBackup);
    592598                if (fLog)
    593                     fprintf(fLog, "    rc: %d\n", arc);
     599                    fprintf(fLog, "    rc: %lu\n", arc);
    594600
    595601                if (arc)
     
    606612                arc = DosMove(szUserNew, Profiles.pszUserName);
    607613                if (fLog)
    608                     fprintf(fLog, "    rc: %d\n", arc);
     614                    fprintf(fLog, "    rc: %lu\n", arc);
    609615
    610616                if (arc)
  • trunk/src/helpers/procstat.c

    r8 r13  
    593593                              USHORT usSemID)         // in: as in QPROCESS32.pausSem16
    594594{
    595     PQSEM32STRUC32  pSemThis = pInfo->pSem32Data;
     595    // PQSEM32STRUC32  pSemThis = pInfo->pSem32Data;
    596596
    597597    /* while (pSemThis)
  • trunk/src/helpers/stringh.c

    r12 r13  
    33 *@@sourcefile stringh.c:
    44 *      contains string/text helper functions. These are good for
    5  *      parsing/splitting strings and other stuff used throughout XWorkplace.
     5 *      parsing/splitting strings and other stuff used throughout
     6 *      XWorkplace.
     7 *
     8 *      Note that these functions are really a bunch of very mixed
     9 *      up string helpers, which you may or may not find helpful.
     10 *      If you're looking for string functions with memory
     11 *      management, look at xstring.c instead.
    612 *
    713 *      Usage: All OS/2 programs.
     
    180186 *      this creates a new PSZ containing the string
    181187 *      from pBegin to pEnd, excluding the pEnd character.
    182  *      The new string is null-terminated.
     188 *      The new string is null-terminated. The caller
     189 *      must free() the new string after use.
    183190 *
    184191 *      Example:
     
    424431 *      be free()'able.
    425432 *
    426  *      Use of this wrapper is not recommended because
    427  *      it is considerably slower than xstrrpl.
     433 *      Repetitive use of this wrapper is not recommended
     434 *      because it is considerably slower than xstrrpl.
    428435 *
    429436 *@@added V0.9.6 (2000-11-01) [umoeller]
     
    431438
    432439ULONG strhrpl(PSZ *ppszBuf,                // in/out: string
    433               ULONG ulOfs,                  // in: where to begin search (0 = start)
    434               const char *pcszSearch,    // in: search string; cannot be NULL
    435               const char *pcszReplace,   // in: replacement string; cannot be NULL
    436               PULONG pulAfterOfs)           // out: offset where found (ptr can be NULL)
     440              PULONG pulOfs,               // in: where to begin search (0 = start);
     441                                           // out: ofs of first char after replacement string
     442              const char *pcszSearch,      // in: search string; cannot be NULL
     443              const char *pcszReplace)     // in: replacement string; cannot be NULL
    437444{
    438445    ULONG   ulrc = 0;
     
    440447            xstrFind,
    441448            xstrReplace;
     449    size_t  ShiftTable[256];
     450    BOOL    fRepeat = FALSE;
    442451    xstrInit(&xstrBuf, 0);
    443452    xstrset(&xstrBuf, *ppszBuf);
     
    447456    xstrset(&xstrReplace, (PSZ)pcszReplace);
    448457
    449     if (ulrc = xstrrpl(&xstrBuf, ulOfs, &xstrFind, &xstrReplace, pulAfterOfs))
     458    if ((ulrc = xstrrpl(&xstrBuf,
     459                        pulOfs,
     460                        &xstrFind,
     461                        &xstrReplace,
     462                        ShiftTable,
     463                        &fRepeat)))
    450464        // replaced:
    451465        *ppszBuf = xstrBuf.psz;
     
    482496 *      converts a ULONG into a decimal string, while
    483497 *      inserting thousands separators into it. Specify
    484  *      the separator char in cThousands.
     498 *      the separator character in cThousands.
     499 *
    485500 *      Returns pszTarget so you can use it directly
    486501 *      with sprintf and the "%s" flag.
     502 *
    487503 *      For cThousands, you should use the data in
    488504 *      OS2.INI ("PM_National" application), which is
    489505 *      always set according to the "Country" object.
     506 *      You can use prfhQueryCountrySettings to
     507 *      retrieve this setting.
     508 *
    490509 *      Use strhThousandsDouble for "double" values.
    491510 */
     
    497516    USHORT ust, uss, usc;
    498517    CHAR   szTemp[40];
    499     sprintf(szTemp, "%d", ul);
     518    sprintf(szTemp, "%lu", ul);
    500519
    501520    ust = 0;
     
    548567
    549568/*
     569 *@@ strhVariableDouble:
     570 *      like strhThousandsULong, but for a "double" value, and
     571 *      with a variable number of decimal places depending on the
     572 *      size of the quantity.
     573 *
     574 *@@added V0.9.6 (2000-11-12) [pr]
     575 */
     576
     577PSZ strhVariableDouble(PSZ pszTarget,
     578                       double dbl,
     579                       PSZ pszUnits,
     580                       CHAR cThousands)
     581{
     582    if (dbl < 100.0)
     583        sprintf(pszTarget, "%.2f%s", dbl, pszUnits);
     584    else
     585        if (dbl < 1000.0)
     586            sprintf(pszTarget, "%.1f%s", dbl, pszUnits);
     587        else
     588            strcat(strhThousandsDouble(pszTarget, dbl, cThousands),
     589                   pszUnits);
     590
     591    return(pszTarget);
     592}
     593
     594/*
    550595 *@@ strhFileDate:
    551596 *      converts file date data to a string (to pszBuf).
     
    566611 *      cDateSep is used as a date separator (e.g. '.').
    567612 *      This can be queried using:
    568  +              prfhQueryProfileChar(HINI_USER, "PM_National", "sDate", '/');
     613 +          prfhQueryProfileChar(HINI_USER, "PM_National", "sDate", '/');
    569614 *
    570615 *      Alternatively, you can query all the country settings
    571  *      at once using prfhQueryCountrySettings (prfh.c, new with V0.9.0).
     616 *      at once using prfhQueryCountrySettings (prfh.c).
    572617 *
    573618 *@@changed (99-11-07) [umoeller]: now calling strhDateTime
     
    611656 *
    612657 *      Alternatively, you can query all the country settings
    613  *      at once using prfhQueryCountrySettings (prfh.c, new with V0.9.0).
     658 *      at once using prfhQueryCountrySettings (prfh.c).
    614659 *
    615660 *@@changed 99-03-15 fixed 12-hour crash
     
    637682/*
    638683 *@@ strhDateTime:
    639  *      converts Control Programe DATETIME info
    640  *      to two strings. See strhFileDate and strhFileTime
     684 *      converts Control Program DATETIME info
     685 *      into two strings. See strhFileDate and strhFileTime
    641686 *      for more detailed parameter descriptions.
    642687 *
     
    821866
    822867/*
     868 *@@ strhIsWord:
     869 *      returns TRUE if p points to a "word"
     870 *      in pcszBuf.
     871 *
     872 *      p is considered a word if the character _before_
     873 *      it is in pcszBeginChars and the char _after_
     874 *      it (i.e. *(p+cbSearch)) is in pcszEndChars.
     875 *
     876 *@@added V0.9.6 (2000-11-12) [umoeller]
     877 */
     878
     879BOOL strhIsWord(const char *pcszBuf,
     880                const char *p,                 // in: start of word
     881                ULONG cbSearch,                // in: length of word
     882                const char *pcszBeginChars,    // suggestion: "\x0d\x0a ()/\\-,."
     883                const char *pcszEndChars)      // suggestion: "\x0d\x0a ()/\\-,.:;"
     884{
     885    BOOL    fEndOK = FALSE;
     886
     887    // check previous char
     888    if (    (p == pcszBuf)
     889         || (strchr(pcszBeginChars, *(p-1)))
     890       )
     891    {
     892        // OK, valid begin char:
     893        // check end char
     894        CHAR    cNextChar = *(p + cbSearch);
     895        if (cNextChar == 0)
     896            fEndOK = TRUE;
     897        else
     898        {
     899            char *pc = strchr(pcszEndChars, cNextChar);
     900            if (pc)
     901                // OK, is end char: avoid doubles of that char,
     902                // but allow spaces
     903                if (    (cNextChar+1 != *pc)
     904                     || (cNextChar+1 == ' ')
     905                     || (cNextChar+1 == 0)
     906                   )
     907                    fEndOK = TRUE;
     908        }
     909    }
     910
     911    return (fEndOK);
     912}
     913
     914/*
    823915 *@@ strhFindWord:
    824916 *      searches for pszSearch in pszBuf, which is
     
    836928 *
    837929 *      The algorithm here uses strstr to find pszSearch in pszBuf
    838  *      and performs additional "is-word" checks for each item found.
    839  *      With VAC++ 3.0, this is still much faster than searching
    840  *      words first and then comparing each word with pszSearch.
    841  *      I've tried it that way too, and that took nearly double as
    842  *      long. Apparently, the VAC++ runtime library uses some
    843  *      optimized search algorithm here, so we better use that one.
     930 *      and performs additional "is-word" checks for each item found
     931 *      (by calling strhIsWord).
     932 *
     933 *      Note that this function is fairly slow compared to xstrFindWord.
    844934 *
    845935 *@@added V0.9.0 (99-11-08) [umoeller]
     
    859949    {
    860950        const char *p = pszBuf;
    861 
    862         /*  // go thru all characters
    863         while (*p)
    864         {
    865             // check if current character is either the
    866             // very first or a "begin word" character
    867             if (    (p == pszBuf)
    868                  || (strchr(pcszBeginChars, *p) == 0)
    869                )
    870             {
    871                 // yes: go for next
    872                 if (*(++p))
    873                 {
    874                     // compare with search string
    875                     if (strcmp(p, pszSearch) == 0)
    876                     {
    877                         // is the same:
    878                         // check if still in buffer
    879                         if (p < pszBuf + cbBuf)
    880                         {
    881                             CHAR    cAfterEndOfWord = *(p + cbSearch);
    882                             if (cAfterEndOfWord == 0)
    883                             {
    884                                 // end of string:
    885                                 // that's ok
    886                                 pszReturn = (PSZ)p;
    887                                 break;
    888                             }
    889                             else
    890                             {
    891                                 // check if in "end of word" list
    892                                 char *pc2 = strchr(pcszEndChars, cAfterEndOfWord);
    893                                 if (pc2)
    894                                     // OK, is end char: avoid doubles of that char,
    895                                     // but allow spaces
    896                                     if (    (cAfterEndOfWord+1 != *pc2)
    897                                          || (cAfterEndOfWord+1 == ' ')
    898                                          || (cAfterEndOfWord+1 == 0)
    899                                        )
    900                                     {
    901                                         // end of string:
    902                                         // that's ok
    903                                         pszReturn = (PSZ)p;
    904                                         break;
    905                                     }
    906                             }
    907                         }
    908                     }
    909                 }
    910                 else
    911                     // end of string:
    912                     break;
    913             }
    914 
    915             ++p;
    916         } // end while
    917         */
    918951
    919952        do  // while p
     
    925958                // check if that's a word
    926959
    927                 // check previous char
    928                 if (    (p == pszBuf)
    929                      || (strchr(pcszBeginChars, *(p-1)))
    930                    )
     960                if (strhIsWord(pszBuf,
     961                               p,
     962                               cbSearch,
     963                               pcszBeginChars,
     964                               pcszEndChars))
    931965                {
    932                     // OK, valid begin char:
    933                     BOOL    fEndOK = FALSE;
    934                     // check end char
    935                     CHAR    cNextChar = *(p + cbSearch);
    936                     if (cNextChar == 0)
    937                         fEndOK = TRUE;
    938                     else
    939                     {
    940                         char *pc = strchr(pcszEndChars, cNextChar);
    941                         if (pc)
    942                             // OK, is end char: avoid doubles of that char,
    943                             // but allow spaces
    944                             if (    (cNextChar+1 != *pc)
    945                                  || (cNextChar+1 == ' ')
    946                                  || (cNextChar+1 == 0)
    947                                )
    948                                 fEndOK = TRUE;
    949                     }
    950 
    951                     if (fEndOK)
    952                     {
    953                         // valid end char:
    954                         pszReturn = (PSZ)p;
    955                         break;
    956                     }
     966                    // valid end char:
     967                    pszReturn = (PSZ)p;
     968                    break;
    957969                }
     970
    958971                p += cbSearch;
    959972            }
     
    11861199            if (pEOL)
    11871200            {
    1188                 XSTRING strBuf,
    1189                         strFind,
    1190                         strReplace;
     1201                XSTRING strBuf;
     1202                ULONG   ulOfs = 0;
    11911203
    11921204                PSZ pszOldCopy = (PSZ)malloc(cbOldParam+1);
     
    11961208                xstrInit(&strBuf, 0);
    11971209                xstrset(&strBuf, *ppszBuf);         // this must not be freed!
    1198                 xstrInit(&strFind, 0);
     1210                /* xstrInit(&strFind, 0);
    11991211                xstrset(&strFind, pszOldCopy);      // this must not be freed!
    12001212                xstrInit(&strReplace, 0);
    12011213                xstrset(&strReplace, pszNewParam);  // this must not be freed!
     1214                   */
    12021215
    12031216                // check for upper case desired?
     
    12061219                        strupr(pszNewParam);
    12071220
    1208                 xstrrpl(&strBuf, 0, &strFind, &strReplace, NULL);
     1221                xstrcrpl(&strBuf, &ulOfs, pszOldCopy, pszNewParam);
    12091222
    12101223                free(pszOldCopy);
     
    13731386    PSZ pParam;
    13741387    if ((pParam = strhFindAttribValue(pszSearchIn, pszTag)))
    1375         sscanf(pParam, "%d", pl);
     1388        sscanf(pParam, "%ld", pl);
    13761389
    13771390    return (pParam);
     
    17991812            pszLine += ulIndent;
    18001813        }
    1801         pszLine += sprintf(pszLine, "%02lX ", *pbCurrent);
     1814        pszLine += sprintf(pszLine, "%02lX ", (ULONG)*pbCurrent);
    18021815
    18031816        if ( (*pbCurrent > 31) && (*pbCurrent < 127) )
     
    18691882
    18701883/*
    1871  *@@ skip_comp_os2:
     1884 * skip_comp_os2:
    18721885 *      Return a pointer to the next component of the path SRC, for OS/2
    18731886 *      and DOS styles.  When the end of the string is reached, a pointer
     
    24672480
    24682481/*
    2469  *@@ strhfind:
    2470  *      searches for a pattern in a string using the Boyer-Moore-
    2471  *      Horspool-Sunday algorithm.  The string and pattern are null-terminated
    2472  *      strings.  Returns a pointer to the pattern if found within the string,
    2473  *      or NULL if the pattern was not found.  If you repeatedly scan for the
    2474  *      same pattern, use the repeat_find argument.  If this is TRUE, the
    2475  *      function does not re-parse the pattern.  You must of course call the
    2476  *      function with repeat_find equal to FALSE the first time.  This function
    2477  *      is meant to handle  character data, and is most effective when you work
    2478  *      with large strings.  To search binary data use strhmemfind().  Will not work
    2479  *      on multibyte characters.
    2480  *
    2481  *      Examples:
    2482  +      char *result;
     2482 *@@ strhmemfind:
     2483 *      searches for a pattern in a block of memory using the
     2484 *      Boyer-Moore-Horspool-Sunday algorithm.
     2485 *
     2486 *      The block and pattern may contain any values; you must
     2487 *      explicitly provide their lengths. If you search for strings,
     2488 *      use strlen() on the buffers.
     2489 *
     2490 *      Returns a pointer to the pattern if found within the block,
     2491 *      or NULL if the pattern was not found.
     2492 *
     2493 *      This algorithm needs a "shift table" to cache data for the
     2494 *      search pattern. This table can be reused when performing
     2495 *      several searches with the same pattern.
     2496 *
     2497 *      "shift" must point to an array big enough to hold 256 (8**2)
     2498 *      "size_t" values.
     2499 *
     2500 *      If (*repeat_find == FALSE), the shift table is initialized.
     2501 *      So on the first search with a given pattern, *repeat_find
     2502 *      should be FALSE. This function sets it to TRUE after the
     2503 *      shift table is initialised, allowing the initialisation
     2504 *      phase to be skipped on subsequent searches.
     2505 *
     2506 *      This function is most effective when repeated searches are
     2507 *      made for the same pattern in one or more large buffers.
     2508 *
     2509 *      Example:
     2510 *
     2511 +          PSZ     pszHaystack = "This is a sample string.",
     2512 +                  pszNeedle = "string";
     2513 +          size_t  shift[256];
     2514 +          BOOL    fRepeat = FALSE;
    24832515 +
    2484  +      result = strhfind ("abracadabra", "cad", FALSE);
    2485  +      if (result)
    2486  +          puts (result);
    2487  +
     2516 +          PSZ     pFound = strhmemfind(pszHaystack,
     2517 +                                       strlen(pszHaystack),   // block size
     2518 +                                       pszNeedle,
     2519 +                                       strlen(pszNeedle),     // pattern size
     2520 +                                       shift,
     2521 +                                       &fRepeat);
     2522 *
    24882523 *      Taken from the "Standard Function Library", file sflfind.c.
    24892524 *      Copyright:  Copyright (c) 1991-99 iMatix Corporation.
    2490  *      Slightly modified.
     2525 *      Slightly modified by umoeller.
    24912526 *
    24922527 *@@added V0.9.3 (2000-05-08) [umoeller]
    24932528 */
    24942529
    2495 char* strhfind (const char *string,            //  String containing data
    2496                 const char *pattern,           //  Pattern to search for
    2497                 BOOL repeat_find)              //  Same pattern as last time
    2498 {
    2499     static size_t
    2500         searchbuf [256];                //  Fixed search buffer
    2501 
    2502     ASSERT (string);                    //  Expect non-NULL pointers, but
    2503     ASSERT (pattern);                   //  fall through if not debugging
    2504 
    2505     return (char *) strhmemfind_rb (string,    strlen (string),
    2506                                 pattern,   strlen (pattern),
    2507                                 searchbuf, &repeat_find);
    2508 }
    2509 
    2510 /*
    2511  *@@ strhfind_r:
    2512  *      searches for a pattern in a string using the Boyer-Moore-
    2513  *      Horspool-Sunday algorithm.  The string and pattern are null-terminated
    2514  *      strings.  Returns a pointer to the pattern if found within the string,
    2515  *      or NULL if the pattern was not found.  This function is meant to handle
    2516  *      character data, and is most effective when you work with large strings.
    2517  *      To search binary data use strhmemfind().  Will not work on multibyte
    2518  *      characters.  Reentrant.
    2519  *
    2520  *      Examples:
    2521  +      char *result;
    2522  +
    2523  +      result = strhfind_r ("abracadabra", "cad");
    2524  +      if (result)
    2525  +          puts (result);
    2526  *
    2527  *      Taken from the "Standard Function Library", file sflfind.c.
    2528  *      Copyright:  Copyright (c) 1991-99 iMatix Corporation.
    2529  *      Slightly modified.
    2530  *
    2531  *@@added V0.9.3 (2000-05-08) [umoeller]
    2532  */
    2533 
    2534 char* strhfind_r (const char *string,          //  String containing data
    2535                   const char *pattern)         //  Pattern to search for
    2536 {
    2537     size_t
    2538         searchbuf [256];                //  One-time search buffer
    2539     BOOL
    2540         secondtime = FALSE;             //  Search buffer init needed
    2541 
    2542     ASSERT (string);                    //  Expect non-NULL pointers, but
    2543     ASSERT (pattern);                   //  fall through if not debugging
    2544 
    2545     return (char *) strhmemfind_rb (string,    strlen (string),
    2546                                     pattern,   strlen (pattern),
    2547                                     searchbuf, &secondtime);
    2548 }
    2549 
    2550 /*
    2551  *@@ strhfind_rb:
    2552  *      searches for a pattern in a string using the Boyer-Moore-
    2553  *      Horspool-Sunday algorithm.  The string and pattern are null-terminated
    2554  *      strings.  Returns a pointer to the pattern if found within the string,
    2555  *      or NULL if the pattern was not found.  Supports more efficient repeat
    2556  *      searches (for the same pattern), through a supplied search buffer.  The
    2557  *      search buffer must be long enough to contain 256 (2**8) size_t entries.
    2558  *      On the first call repeat_find must be set to FALSE.  After the search
    2559  *      buffer has been initialised, repeat_find will be set to TRUE by the
    2560  *      function, avoiding the search buffer initialisation on later calls.
    2561  *
    2562  *      This function is most effective when repeated searches are made for
    2563  *      the same pattern in one or more strings.  This function is meant to
    2564  *      handle  character data, and is most effective when you work with
    2565  *      large strings.  To search binary data use strhmemfind().  Will not work
    2566  *      on multibyte characters.  Reentrant.
    2567  *
    2568  *      Examples:
    2569  +      char   *result;
    2570  +      BOOL   repeat_search = FALSE;
    2571  +      size_t searchbuf[256];
    2572  +
    2573  +      result = strhfind_rb ("abracadabra", "cad", searchbuf, &repeat_search);
    2574  +      if (result)
    2575  +        {
    2576  +          puts (result);
    2577  +          result = strhfind_rb ("cad/cam", "cad", searchbuf, &repeat_search);
    2578  +          if (result)
    2579  +              puts (result);
    2580  +        }
    2581  *
    2582  *      Taken from the "Standard Function Library", file sflfind.c.
    2583  *      Copyright:  Copyright (c) 1991-99 iMatix Corporation.
    2584  *      Slightly modified.
    2585  *
    2586  *@@added V0.9.3 (2000-05-08) [umoeller]
    2587  */
    2588 
    2589 char* strhfind_rb (const char *string,         //  String containing data
    2590                    const char *pattern,        //  Pattern to search for
    2591                    size_t     *shift,          //  Working buffer between searches
    2592                    BOOL       *repeat_find)    //  Flag for first/later search
    2593 {
    2594     ASSERT (string);                    //  Expect non-NULL pointers, but
    2595     ASSERT (pattern);                   //  fall through if not debugging
    2596     ASSERT (shift);
    2597     ASSERT (repeat_find);
    2598 
    2599     return (char *) strhmemfind_rb (string,    strlen (string),
    2600                                     pattern,   strlen (pattern),
    2601                                     shift,     repeat_find);
    2602 }
    2603 
    2604 /*
    2605  *@@ strhmemfind:
    2606  *      searches for a pattern in a block of memory using the Boyer-
    2607  *      Moore-Horspool-Sunday algorithm.  The block and pattern may contain any
    2608  *      values; you must explicitly provide their lengths.  Returns a pointer to
    2609  *      the pattern if found within the block, or NULL if the pattern was not
    2610  *      found.  If you repeatedly scan for the same pattern, use the repeat_find
    2611  *      argument.  If this is TRUE, the function does not re-parse the pattern.
    2612  *      This function is meant to handle binary data.  If you need to search
    2613  *      strings, use the strhfind_r or strhfind_rb() functions.  Non-Reentrant.
    2614  *
    2615  *      Taken from the "Standard Function Library", file sflfind.c.
    2616  *      Copyright:  Copyright (c) 1991-99 iMatix Corporation.
    2617  *      Slightly modified.
    2618  *
    2619  *@@added V0.9.3 (2000-05-08) [umoeller]
    2620  */
    2621 
    2622 void* strhmemfind (const void  *block,            //  Block containing data
    2623                    size_t       block_size,       //  Size of block in bytes
    2624                    const void  *pattern,          //  Pattern to search for
    2625                    size_t       pattern_size,     //  Size of pattern block
    2626                    BOOL         repeat_find)      //  Same pattern as last time
    2627 {
    2628     static size_t
    2629         searchbuf [256];                //  Static shared search buffer
    2630 
    2631     ASSERT (block);                     //  Expect non-NULL pointers, but
    2632     ASSERT (pattern);                   //  full through if not debugging
    2633 
    2634     return strhmemfind_rb (block, block_size, pattern, pattern_size,
    2635                        searchbuf, &repeat_find);
    2636 }
    2637 
    2638 /*
    2639  *@@ strhmemfind_r:
    2640  *      searches for a pattern in a block of memory using the Boyer-
    2641  *      Moore-Horspool-Sunday algorithm.  The block and pattern may contain any
    2642  *      values; you must explicitly provide their lengths.  Returns a pointer to
    2643  *      the pattern if found within the block, or NULL if the pattern was not
    2644  *      found.
    2645  *
    2646  *      This function is meant to handle binary data, for a single search for
    2647  *      a given pattern.  If you need to search strings, use the strhfind_r()
    2648  *      or strhfind_rb() functions.  If you want to do efficient repeated searches
    2649  *      for one pattern, use strhmemfind_rb().  Reentrant.
    2650  *
    2651  *      Taken from the "Standard Function Library", file sflfind.c.
    2652  *      Copyright:  Copyright (c) 1991-99 iMatix Corporation.
    2653  *      Slightly modified.
    2654  *
    2655  *@@added V0.9.3 (2000-05-08) [umoeller]
    2656  */
    2657 
    2658 void* strhmemfind_r (const void  *block,          //  Block containing data
    2659                      size_t       block_size,     //  Size of block in bytes
    2660                      const void  *pattern,        //  Pattern to search for
    2661                      size_t       pattern_size)   //  Size of pattern block
    2662 {
    2663     size_t
    2664         searchbuf [256];                //  One-time search buffer
    2665     BOOL
    2666         secondtime  = FALSE;
    2667 
    2668     ASSERT (block);                     //  Expect non-NULL pointers, but
    2669     ASSERT (pattern);                   //  full through if not debugging
    2670 
    2671     return strhmemfind_rb (block, block_size, pattern, pattern_size,
    2672                            searchbuf, &secondtime);
    2673 }
    2674 
    2675 /*
    2676  *@@ strhmemfind_rb:
    2677  *      searches for a pattern in a block of memory using the Boyer-
    2678  *      Moore-Horspool-Sunday algorithm.  The block and pattern may contain any
    2679  *      values; you must explicitly provide their lengths.  Returns a pointer to
    2680  *      the pattern if found within the block, or NULL if the pattern was not
    2681  *      found.  On the first search with a given pattern, *repeat_find should
    2682  *      be FALSE.  It will be set to TRUE after the shift table is initialised,
    2683  *      allowing the initialisation phase to be skipped on subsequent searches.
    2684  *      shift must point to an array big enough to hold 256 (8**2) size_t values.
    2685  *
    2686  *      This function is meant to handle binary data, for repeated searches
    2687  *      for the same pattern.  If you need to search strings, use the
    2688  *      strhfind_r() or strhfind_rb() functions.  If you wish to search for a
    2689  *      pattern only once consider using strhmemfind_r(). Reentrant.
    2690  *
    2691  *      Taken from the "Standard Function Library", file sflfind.c.
    2692  *      Copyright:  Copyright (c) 1991-99 iMatix Corporation.
    2693  *      Slightly modified.
    2694  *
    2695  *@@added V0.9.3 (2000-05-08) [umoeller]
    2696  */
    2697 
    2698 void* strhmemfind_rb (const void  *in_block,      //  Block containing data
    2699                       size_t       block_size,    //  Size of block in bytes
    2700                       const void  *in_pattern,    //  Pattern to search for
    2701                       size_t       pattern_size,  //  Size of pattern block
    2702                       size_t      *shift,         //  Shift table (search buffer)
    2703                       BOOL        *repeat_find)   //  TRUE: search buffer already init
    2704 {
    2705     size_t
    2706         byte_nbr,                       //  Distance through block
    2707         match_size;                     //  Size of matched part
     2530void* strhmemfind(const void *in_block,     // in: block containing data
     2531                  size_t block_size,        // in: size of block in bytes
     2532                  const void *in_pattern,   // in: pattern to search for
     2533                  size_t pattern_size,      // in: size of pattern block
     2534                  size_t *shift,            // in/out: shift table (search buffer)
     2535                  BOOL *repeat_find)        // in/out: if TRUE, *shift is already initialized
     2536{
     2537    size_t      byte_nbr,                       //  Distance through block
     2538                match_size;                     //  Size of matched part
    27082539    const unsigned char
    2709         *match_base = NULL,             //  Base of match of pattern
    2710         *match_ptr  = NULL,             //  Point within current match
    2711         *limit      = NULL;             //  Last potiental match point
     2540                *match_base = NULL,             //  Base of match of pattern
     2541                *match_ptr  = NULL,             //  Point within current match
     2542                *limit      = NULL;             //  Last potiental match point
    27122543    const unsigned char
    2713         *block   = (unsigned char *) in_block,   //  Concrete pointer to block data
    2714         *pattern = (unsigned char *) in_pattern; //  Concrete pointer to search value
    2715 
    2716     ASSERT (block);                     //  Expect non-NULL pointers, but
    2717     ASSERT (pattern);                   //  fail gracefully if not debugging
    2718     ASSERT (shift);                     //  NULL repeat_find => is false
    2719     if (block == NULL || pattern == NULL || shift == NULL)
     2544                *block   = (unsigned char *) in_block,   //  Concrete pointer to block data
     2545                *pattern = (unsigned char *) in_pattern; //  Concrete pointer to search value
     2546
     2547    if (    (block == NULL)
     2548         || (pattern == NULL)
     2549         || (shift == NULL)
     2550       )
    27202551        return (NULL);
    27212552
     
    27362567
    27372568    if (!repeat_find || !*repeat_find)
    2738       {
    2739         for (byte_nbr = 0; byte_nbr < 256; byte_nbr++)
    2740             shift [byte_nbr] = pattern_size + 1;
    2741         for (byte_nbr = 0; byte_nbr < pattern_size; byte_nbr++)
    2742             shift [(unsigned char) pattern [byte_nbr]] = pattern_size - byte_nbr;
     2569    {
     2570        for (byte_nbr = 0;
     2571             byte_nbr < 256;
     2572             byte_nbr++)
     2573            shift[byte_nbr] = pattern_size + 1;
     2574        for (byte_nbr = 0;
     2575             byte_nbr < pattern_size;
     2576             byte_nbr++)
     2577            shift[(unsigned char)pattern[byte_nbr]] = pattern_size - byte_nbr;
    27432578
    27442579        if (repeat_find)
    27452580            *repeat_find = TRUE;
    2746       }
     2581    }
    27472582
    27482583    //  Search for the block, each time jumping up by the amount
     
    27542589    for (match_base = block;
    27552590         match_base < limit;
    2756          match_base += shift [*(match_base + pattern_size)])
    2757       {
     2591         match_base += shift[*(match_base + pattern_size)])
     2592    {
    27582593        match_ptr  = match_base;
    27592594        match_size = 0;
    27602595
    27612596        //  Compare pattern until it all matches, or we find a difference
    2762         while (*match_ptr++ == pattern [match_size++])
    2763           {
     2597        while (*match_ptr++ == pattern[match_size++])
     2598        {
    27642599            ASSERT (match_size <= pattern_size &&
    27652600                    match_ptr == (match_base + match_size));
    27662601
    2767             //  If we found a match, return the start address
     2602            // If we found a match, return the start address
    27682603            if (match_size >= pattern_size)
    2769               return ((void*)(match_base));
    2770 
    2771           }
    2772       }
     2604                return ((void*)(match_base));
     2605
     2606        }
     2607    }
    27732608    return (NULL);                      //  Found nothing
    27742609}
  • trunk/src/helpers/syssound.c

    r8 r13  
    153153            {
    154154                // individual volume settings per sound
    155                 sscanf(p1, "%d", pulVolume);
     155                sscanf(p1, "%lu", pulVolume);
    156156                ulrc++;
    157157            }
     
    290290                                          "100",
    291291                                          szData2, sizeof(szData2));
    292                     sscanf(szData2, "%d", pulVolume);
     292                    sscanf(szData2, "%lu", pulVolume);
    293293                }
    294294
     
    332332        CHAR szData[1000];
    333333        // format: soundfile#description#volume
    334         sprintf(szData, "%s#%s#%d", pszFile, pszDescr, ulVolume);
     334        sprintf(szData, "%s#%s#%lu", pszFile, pszDescr, ulVolume);
    335335        brc = PrfWriteProfileString(hiniMMPM,
    336336                                    MMINIKEY_SYSSOUNDS, szKey,
     
    475475                    ulKeyLen = strlen(szFile)+1;    // go beyond null byte
    476476                    ulKeyLen += sprintf(szFile+ulKeyLen,
    477                                 "%d",
     477                                "%lu",
    478478                                ulVolume) + 1;
    479479                    // and write to OS2SYS.INI
     
    608608                            // copy it
    609609                            sscanf(pSchemeSoundData + cbSchemeSoundFile,
    610                                    "%d",
     610                                   "%lu",
    611611                                   &ulVolume);
    612612
    613613                        // and write data to MMPM.INI
    614614                        // format: soundfile#description#volume
    615                         sprintf(szData, "%s#%s#%d", szFile, szDescription, ulVolume);
     615                        sprintf(szData, "%s#%s#%lu", szFile, szDescription, ulVolume);
    616616                        if (PrfWriteProfileString(hiniMMPM,
    617617                                                  MMINIKEY_SYSSOUNDS, // "MMPM2_AlarmSounds"
  • trunk/src/helpers/textv_html.c

    r11 r13  
    175175
    176176VOID AppendChar(PCOPYTARGET pct,  // in/out: formatting buffer
    177                 CHAR c)
     177                unsigned char c)
    178178{
    179179    // calculate ofs where to store next char
     
    685685                                                pct->ulListLevel - 1);
    686686        if (pListDesc)
     687        {
    687688            if (pListDesc->ulListType == 1)
    688689                // is ordered list:
    689                 sprintf(szMarker, "%d.", (pListDesc->ulItem)++);
     690                sprintf(szMarker, "%lu.", (pListDesc->ulItem)++);
    690691            else if (pListDesc->ulListType == 0)
    691692                // is unordered list:
    692693                // set bullet type according to unordered nesting
    693694                szMarker[2] = pct->ulUnorderedListLevel;
     695        }
    694696    }
    695697
     
    864866    if (pct->fInLink)
    865867    {
    866         sprintf(szAnchor, "%04lX", pct->usAnchorIndex);
     868        sprintf(szAnchor, "%04hX", pct->usAnchorIndex);
    867869        AppendString(pct,
    868870                     TXVESC_LINK);
     
    933935                case 'd': // ADDRESS
    934936                    if (stricmp(p2, "DRESS") == 0)
     937                    {
    935938                        if (!fEndOfTag)
    936939                            return TagI;
    937940                        else
    938941                            return TagXI;
     942                    }
    939943            }
    940944        break;
     
    976980                case 'o':
    977981                    if (stricmp(p2, "DE") == 0)
     982                    {
    978983                        if (!fEndOfTag)
    979984                            return TagCODE;
    980985                        else
    981986                            return TagXCODE;
     987                    }
    982988                break;
    983989            }
     
    9981004                    if (*p2 == 'R')
    9991005                        if (*(pCheck + 3) == 0)
     1006                        {
    10001007                            if (!fEndOfTag)
    10011008                                return TagUL;
    10021009                            else
    10031010                                return TagXUL;
     1011                        }
    10041012                break;
    10051013
     
    10071015                case 'l': // DL
    10081016                    if (*p2 == 0)
     1017                    {
    10091018                        if (!fEndOfTag)
    10101019                            return TagDL;
    10111020                        else
    10121021                            return TagXDL;
     1022                    }
    10131023                break;
    10141024
     
    10251035            if ( (c1 == 'M') || (c1 == 'm') )  // EM
    10261036                if (*p2 == 0)
     1037                {
    10271038                    if (!fEndOfTag)
    10281039                        return TagI;
    10291040                    else
    10301041                        return TagXI;
     1042                }
    10311043        break;
    10321044
     
    10731085        case 'i':
    10741086            if (c1 == 0)
     1087            {
    10751088                if (!fEndOfTag)
    10761089                    return TagI;
    10771090                else
    10781091                    return TagXI;
     1092            }
    10791093        break;
    10801094
     
    10891103        case 'm':
    10901104            if (stricmp(p2, "NU") == 0)
     1105            {
    10911106                if (!fEndOfTag)
    10921107                    return TagUL;
    10931108                else
    10941109                    return TagXUL;
     1110            }
    10951111        break;
    10961112
     
    10991115            if ((c1 == 'L') || (c1 == 'l'))
    11001116                if (*p2 == 0)
     1117                {
    11011118                    if (!fEndOfTag)
    11021119                        return TagOL;
    11031120                    else
    11041121                        return TagXOL;
     1122                }
    11051123        break;
    11061124
     
    11181136                    if ((*p2 == 'E') || (*p2 == 'e'))
    11191137                        if (*(pCheck + 3) == 0)
     1138                        {
    11201139                            if (!fEndOfTag)
    11211140                                return TagPRE;
    11221141                            else
    11231142                                return TagXPRE;
     1143                        }
    11241144                break;
    11251145            }
     
    11331153                case 't': // STRONG
    11341154                    if (stricmp(p2, "RONG") == 0)
     1155                    {
    11351156                        if (!fEndOfTag)
    11361157                            return TagB;
    11371158                        else
    11381159                            return TagXB;
     1160                    }
    11391161                    else if (stricmp(p2, "RIKE") == 0)
     1162                    {
    11401163                        if (!fEndOfTag)
    11411164                            return TagSTRIKE;
    11421165                        else
    11431166                            return TagXSTRIKE;
     1167                    }
    11441168                break;
    11451169
     
    11471171                case 'a':
    11481172                    if (stricmp(p2, "MP") == 0)
     1173                    {
    11491174                        if (!fEndOfTag)
    11501175                            return TagCODE;
    11511176                        else
    11521177                            return TagXCODE;
     1178                    }
    11531179                break;
    11541180            }
     
    11741200                case 't':
    11751201                    if (*p2 == 0)
     1202                    {
    11761203                        if (!fEndOfTag)
    11771204                            return TagCODE;
    11781205                        else
    11791206                            return TagXCODE;
     1207                    }
    11801208                break;
    11811209            }
     
    11951223                case 'l':
    11961224                    if (*p2 == 0)
     1225                    {
    11971226                        if (!fEndOfTag)
    11981227                            return TagUL;
    11991228                        else
    12001229                            return TagXUL;
     1230                    }
    12011231                break;
    12021232            }
     
    13931423 */
    13941424
    1395 CHAR ConvertEscape(PSZ pszTag)
     1425unsigned char ConvertEscape(PSZ pszTag)
    13961426{
    13971427    CHAR c0, c1;
  • trunk/src/helpers/textview.c

    r12 r13  
    13111311                                pWordThis->pvRectangle = (PVOID)pRect;
    13121312                                lstAppendItem(&pRect->llWords, pWordThis);
     1313                                            // ### memory leak right here!!!
    13131314                                ulWordsInThisRect++;
    13141315
  • trunk/src/helpers/tmsgfile.c

    r8 r13  
    724724
    725725            // determine entry
    726             sprintf(szEntry, "%s %u %u" NEWLINE,
     726            sprintf(szEntry, "%s %lu %lu" NEWLINE,
    727727                    pCurrentNameStart,
    728728                    ulCurrentMessagePos,
  • trunk/src/helpers/tree.c

    r11 r13  
    1515 *      This has been taken from the Standard Function Library (SFL)
    1616 *      by iMatix Corporation and changed to user the "id" member for
    17  *      tree sorting/comparison.
     17 *      tree sorting/comparison. This implementation is released
     18 *      under the GPL.
    1819 *
    1920 *      <B>Using binary trees</B>
     21 *
     22 *      You can use any structure as elements in a tree, provided
     23 *      that the first member in the structure is a TREE structure
     24 *      (i.e. it has the left, right, parent, id, and colour members).
     25 *      The tree functions don't care what follows.
     26 *
     27 *      So the implementation here is slightly different from the
     28 *      linked lists in linklist.c, because the LISTNODE structs
     29 *      only have pointers to the data. By contrast, the TREE structs
     30 *      are expected to contain the data themselves. See treeInsertID()
     31 *      for a sample.
    2032 *
    2133 *      Each TREE node does not only contain data, but also an
     
    5567 *      Differences compared to linklist.c:
    5668 *
     69 *      -- Trees are considerably slower when inserting and removing
     70 *         nodes because the tree has to be rebalanced every time
     71 *         a node changes. By contrast, trees are much faster finding
     72 *         nodes because the tree is always sorted.
     73 *
     74 *      -- You must always supply a comparison function to allow the
     75 *         tree functions to sort the tree.
     76 *
    5777 *      -- As opposed to a LISTNODE, the TREE structure (which
    58  *         represents a tree node) does not contain a data pointer.
    59  *         Instead, all tree nodes are assumed to contain the
    60  *         data themselves. As a result, you must define your
    61  *         own structures which start with a TREE structure.
    62  *
    63  *         See treeInsertID() for samples.
    64  *
    65  *      -- You must supply a comparison function to allow the
    66  *         tree functions to sort the tree.
     78 *         represents a tree node) does not contain a data pointer,
     79 *         as said above.
    6780 *
    6881 *@@added V0.9.5 (2000-09-29) [umoeller]
     
    838851 *      and will receive the "pUser" parameter, which you can use
    839852 *      as a data pointer to some structure for whatever you like.
    840  */
    841 
    842 void treeTraverse(TREE *tree,
    843                   TREE_PROCESS *process,
    844                   void *pUser,
    845                   int method)
     853 *
     854 *      "method" specifies in which order the nodes are traversed.
     855 *      This can be:
     856 *
     857 *      -- 1: current node first, then left node, then right node.
     858 *      -- 2: left node first, then right node, then current node.
     859 *      -- other: left node first, then current node, then right node.
     860 */
     861
     862void treeTraverse(TREE *tree,               // in: root of tree
     863                  TREE_PROCESS *process,    // in: callback for each node
     864                  void *pUser,              // in: user param for callback
     865                  int method)               // in: traversal mode
    846866{
    847867    if ((!tree)
  • trunk/src/helpers/winh.c

    r12 r13  
    29792979    if (pszText)
    29802980    {
    2981         if (strhrpl(&pszText, 0, pszSearch, pszReplaceWith, 0) > 0)
     2981        ULONG ulOfs = 0;
     2982        if (strhrpl(&pszText, &ulOfs, pszSearch, pszReplaceWith) > 0)
    29822983        {
    29832984            WinSetWindowText(hwnd, pszText);
  • trunk/src/helpers/xml.c

    r12 r13  
    240240PSZ xmlTokenize(const char *pcszXML)
    241241{
     242    return (0);
    242243}
    243244
  • trunk/src/helpers/xstring.c

    r12 r13  
    5151 *      3) If you need the char* pointer (e.g. for a call
    5252 *         to another function), use XSTRING.psz. However,
    53  *         you should NEVER modify the psz pointer yourself
    54  *         because then these functions will get into trouble.
     53 *         you should ONLY modify the psz pointer yourself
     54 *         if the other XSTRING members are updated accordingly.
     55 *         You may, for example, change single characters
     56 *         in the psz buffer. By contrast, if you change the
     57 *         length of the string, you must update XSTRING.ulLength.
     58 *         Otherwise these functions will get into trouble.
    5559 *
    5660 *         Also, you should never assume that the "psz"
    5761 *         pointer has not changed after you have called
    5862 *         one of the xstr* functions because these can
    59  *         always reallocate the buffer if needed.
     63 *         always reallocate the buffer if more memory
     64 *         was needed.
    6065 *
    6166 *      4) If (and only if) you have a char* buffer which
     
    6873 *      The functions in this file used to be in stringh.c
    6974 *      before V0.9.3 (2000-04-01). These have been largely
    70  *      rewritten with V0.9.6 (2000-11-01).
     75 *      rewritten with V0.9.6 (2000-11-01) and are now much
     76 *      more efficient.
    7177 *
    7278 *      Note: Version numbering in this file relates to XWorkplace
     
    145151 *      the XSTRING with.
    146152 *
     153 *      This does not create a copy of pszNew. Instead,
     154 *      pszNew is used as the member string in pxstr
     155 *      directly.
     156 *
    147157 *      Do not use this on an XSTRING which is already
    148158 *      initialized. Use xstrset instead.
     159 *
     160 *      Example:
     161 *
     162 +          XSTRING str;
     163 +          xstrInitSet(&str, strdup("blah"));
    149164 *
    150165 *@@added V0.9.6 (2000-11-01) [umoeller]
     
    173188 *      of an existing string.
    174189 *
     190 *      As opposed to xstrInitSet, this does create
     191 *      a copy of pcszSource.
     192 *
    175193 *      Do not use this on an XSTRING which is already
    176194 *      initialized. Use xstrcpy instead.
     195 *
     196 *      Example:
     197 *
     198 +          XSTRING str;
     199 +          xstrInitCopy(&str, "blah");
    177200 *
    178201 *@@added V0.9.6 (2000-11-01) [umoeller]
     
    301324 +          xstrInit(&str, 0);
    302325 +          xstrcpy(&str, "blah");
     326 *
     327 *      This sequence can be abbreviated using xstrInitCopy.
    303328 *
    304329 *@@changed V0.9.2 (2000-04-01) [umoeller]: renamed from strhxcpy
     
    351376/*
    352377 *@@ xstrcat:
    353  *      appends pcszSource to pxstr, for which memory is allocated
    354  *      as necessary.
     378 *      appends pcszSource to pxstr, for which memory is
     379 *      reallocated if necessary.
    355380 *
    356381 *      If pxstr is empty, this behaves just like xstrcpy.
     
    366391 +          xstrcat(&str, "blup");
    367392 *
    368  *      would do the following:
    369  *      a)  free the old value of str ("blah");
    370  *      b)  reallocate str;
    371  *      c)  so that psz afterwards points to a new string containing
    372  *          "blahblup".
     393 *      After this, psz points to a new string containing
     394 *      "blahblup".
    373395 *
    374396 *@@changed V0.9.1 (99-12-20) [umoeller]: fixed memory leak
     
    424446
    425447            // 2) append source string:
    426             strcpy(pxstr->psz + pxstr->ulLength,
    427                    pcszSource);
     448            memcpy(pxstr->psz + pxstr->ulLength,
     449                   pcszSource,
     450                   ulSourceLength + 1);     // null terminator
    428451
    429452            // in all cases, set new length
    430453            pxstr->ulLength += ulSourceLength;
    431454            ulrc = ulSourceLength;
    432         }
     455
     456        } // end if (ulSourceLength)
    433457        // else no source specified or source is empty:
    434458        // do nothing
     
    439463
    440464/*
     465 *@@ xstrFindWord:
     466 *      searches for pstrFind in pxstr, starting at ulOfs.
     467 *      However, this only finds pstrFind if it's a "word",
     468 *      i.e. surrounded by one of the characters in the
     469 *      pcszBeginChars and pcszEndChars array.
     470 *
     471 *      This is similar to strhFindWord, but this uses
     472 *      strhmemfind for fast searching, and it doesn't
     473 *      have to calculate the string lengths because these
     474 *      already in XSTRING.
     475 *
     476 *      Returns 0 if no "word" was found, or the offset
     477 *      of the "word" in pxstr if found.
     478 *
     479 *@@added V0.9.6 (2000-11-12) [umoeller]
     480 */
     481
     482PSZ xstrFindWord(const XSTRING *pxstr,        // in: buffer to search ("haystack")
     483                 ULONG ulOfs,                 // in: where to begin search (0 = start)
     484                 const XSTRING *pstrFind,     // in: word to find ("needle")
     485                 size_t *pShiftTable,         // in: shift table (see strhmemfind)
     486                 PBOOL pfRepeatFind,          // in: repeat find? (see strhmemfind)
     487                 const char *pcszBeginChars,  // suggestion: "\x0d\x0a ()/\\-,."
     488                 const char *pcszEndChars)    // suggestion: "\x0d\x0a ()/\\-,.:;"
     489{
     490    PSZ     pReturn = 0;
     491    ULONG   ulFoundLen = pstrFind->ulLength;
     492
     493    if ((pxstr->ulLength) && (ulFoundLen))
     494    {
     495        const char *p = pxstr->psz + ulOfs;
     496
     497        do  // while p
     498        {
     499            // p = strstr(p, pstrFind->psz);
     500            p = (PSZ)strhmemfind(p,         // in: haystack
     501                                 pxstr->ulLength - (p - pxstr->psz),
     502                                            // remaining length of haystack
     503                                 pstrFind->psz,
     504                                 ulFoundLen,
     505                                 pShiftTable,
     506                                 pfRepeatFind);
     507            if (p)
     508            {
     509                // string found:
     510                // check if that's a word
     511
     512                if (strhIsWord(pxstr->psz,
     513                               p,
     514                               ulFoundLen,
     515                               pcszBeginChars,
     516                               pcszEndChars))
     517                {
     518                    // valid end char:
     519                    pReturn = (PSZ)p;
     520                    break;
     521                }
     522
     523                p += ulFoundLen;
     524            }
     525        } while (p);
     526
     527    }
     528    return (pReturn);
     529}
     530
     531/*
    441532 *@@ xstrrpl:
    442  *      replaces pstrSearch with pstrReplace in pxstr.
     533 *      replaces the first occurence of pstrSearch with
     534 *      pstrReplace in pxstr.
    443535 *
    444536 *      Starting with V0.9.6, this operates entirely on
    445537 *      XSTRING's for speed because we then know the string
    446538 *      lengths already and can use memcpy instead of strcpy.
    447  *      This new version should be magnitudes faster.
     539 *      This new version should be magnitudes faster,
     540 *      especially with large string bufffers.
    448541 *
    449542 *      None of the pointers can be NULL, but if pstrReplace
     
    454547 *      (and pxstr was therefore not changed).
    455548 *
    456  *      If the string was found and (pulAfterOfs != NULL),
    457  *      *pulAfterOfs will be set to the first character
    458  *      after the new replacement string. This allows you
    459  *      to call this func again with the same strings to
    460  *      have several occurences replaced.
    461  *
    462  *      Only the first occurence is replaced. To replace
    463  *      all occurences in a buffer, repeat calling this
    464  *      function until it returns 0.
     549 *      This starts the search at *pulOffset. If
     550 *      (*pulOffset == 0), this starts from the beginning
     551 *      of pxstr.
     552 *      If the string was found, *pulOffset will be set to the
     553 *      first character after the new replacement string. This
     554 *      allows you to call this func again with the same strings
     555 *      to have several occurences replaced (see the example below).
    465556 *
    466557 *      There are two wrappers around this function which
     
    476567 *
    477568 +          XSTRING str;
    478  +          ULONG ulPos = 0;
     569 +          ULONG ulOffset = 0;
    479570 +          xstrInit(&str, 0);
    480571 +          xstrcpy(&str, "Test phrase 1. Test phrase 2.");
    481572 +          while (xstrrpl(&str,
    482  +                         ulPos,
     573 +                         &ulPos,      // in/out: offset
    483574 +                         "Test",      // search
    484  +                         "Dummy",     // replace
    485  +                         &ulPos))
     575 +                         "Dummy")     // replace
    486576 +              ;
    487577 *
     
    493583 *@@changed V0.9.2 (2000-04-01) [umoeller]: renamed from strhxrpl
    494584 *@@changed V0.9.6 (2000-11-01) [umoeller]: rewritten
     585 *@@changed V0.9.6 (2000-11-12) [umoeller]: now using strhmemfind
    495586 */
    496587
    497588ULONG xstrrpl(PXSTRING pxstr,               // in/out: string
    498               ULONG ulOfs,                  // in: where to begin search (0 = start)
     589              PULONG pulOfs,                // in: where to begin search (0 = start);
     590                                            // out: ofs of first char after replacement string
    499591              const XSTRING *pstrSearch,    // in: search string; cannot be NULL
    500592              const XSTRING *pstrReplace,   // in: replacement string; cannot be NULL
    501               PULONG pulAfterOfs)           // out: offset where found (ptr can be NULL)
    502 {
    503     ULONG    ulrc = 0;
     593              size_t *pShiftTable,          // in: shift table (see strhmemfind)
     594              PBOOL pfRepeatFind)           // in: repeat find? (see strhmemfind)
     595{
     596    ULONG    ulrc = 0;      // default: not found
    504597
    505598    if ((pxstr) && (pstrSearch) && (pstrReplace))
     
    508601
    509602        // can we search this?
    510         if (    (ulOfs < pxstr->ulLength)
     603        if (    (*pulOfs < pxstr->ulLength)
    511604             && (cSearchLen)
    512605           )
    513606        {
    514607            // yes:
    515             PSZ     pFound = strstr(pxstr->psz + ulOfs,
    516                                     pstrSearch->psz);
    517 
     608            /* PSZ     pFound = strstr(pxstr->psz + *pulOfs,
     609                                    pstrSearch->psz);        */
     610            PSZ pFound = (PSZ)strhmemfind(pxstr->psz + *pulOfs, // in: haystack
     611                                          pxstr->ulLength - *pulOfs,
     612                                          pstrSearch->psz,
     613                                          cSearchLen,
     614                                          pShiftTable,
     615                                          pfRepeatFind);
    518616            if (pFound)
    519617            {
     
    569667                                + 1); // null terminator
    570668
     669                    // replace old buffer with new one
    571670                    free(pxstr->psz);
    572671                    pxstr->psz = pszNew;
     
    627726                // return new length
    628727                ulrc = cbNeeded - 1;
    629                 if (pulAfterOfs)
    630                     *pulAfterOfs = ulFoundOfs + cReplaceLen;
    631             }
    632         }
    633     }
     728                *pulOfs = ulFoundOfs + cReplaceLen;
     729            } // end if (pFound)
     730        } // end if (    (*pulOfs < pxstr->ulLength) ...
     731    } // end if ((pxstr) && (pstrSearch) && (pstrReplace))
    634732
    635733    return (ulrc);
     
    638736/*
    639737 *@@ xstrcrpl:
    640  *      wrapper around xstrrpl which allows using C strings
     738 *      wrapper around xstrrpl() which allows using C strings
    641739 *      for the find and replace parameters.
    642740 *
     741 *      This creates two temporary XSTRING's for pcszSearch
     742 *      pcszReplace. As a result, this is slower than xstrrpl.
     743 *      If you search with the same strings several times,
     744 *      you'll be better off using xstrrpl() directly.
     745 *
    643746 *@@added V0.9.6 (2000-11-01) [umoeller]
    644747 */
    645748
    646749ULONG xstrcrpl(PXSTRING pxstr,              // in/out: string
    647                ULONG ulOfs,                 // in: where to begin search (0 = start)
     750               PULONG pulOfs,               // in: where to begin search (0 = start);
     751                                            // out: ofs of first char after replacement string
    648752               const char *pcszSearch,      // in: search string; cannot be NULL
    649                const char *pcszReplace,     // in: replacement string; cannot be NULL
    650                PULONG pulAfterOfs)          // out: offset where found (ptr can be NULL)
    651 {
    652     ULONG   ulrc = 0;
     753               const char *pcszReplace)     // in: replacement string; cannot be NULL
     754{
     755    // ULONG   ulrc = 0;
    653756    XSTRING xstrFind,
    654757            xstrReplace;
    655     xstrInit(&xstrFind, 0);
    656     xstrset(&xstrFind, (PSZ)pcszSearch);
    657     xstrInit(&xstrReplace, 0);
    658     xstrset(&xstrReplace, (PSZ)pcszReplace);
    659 
    660     return (xstrrpl(pxstr, ulOfs, &xstrFind, &xstrReplace, pulAfterOfs));
     758    size_t  ShiftTable[256];
     759    BOOL    fRepeat = FALSE;
     760    // initialize find/replace strings... note that the
     761    // C strings are not free()'able, so we MUST NOT use xstrClear
     762    // before leaving
     763    xstrInitSet(&xstrFind, (PSZ)pcszSearch);
     764    xstrInitSet(&xstrReplace, (PSZ)pcszReplace);
     765
     766    return (xstrrpl(pxstr, pulOfs, &xstrFind, &xstrReplace, ShiftTable, &fRepeat));
    661767}
    662768
Note: See TracChangeset for help on using the changeset viewer.