Annotation of mstools/samples/sdktools/windiff/complist.c, revision 1.1.1.1

1.1       root        1: 
                      2: /******************************************************************************\
                      3: *       This is a part of the Microsoft Source Code Samples. 
                      4: *       Copyright (C) 1993 Microsoft Corporation.
                      5: *       All rights reserved. 
                      6: *       This source code is only intended as a supplement to 
                      7: *       Microsoft Development Tools and/or WinHelp documentation.
                      8: *       See these sources for detailed information regarding the 
                      9: *       Microsoft samples programs.
                     10: \******************************************************************************/
                     11: 
                     12: /****************************** Module Header *******************************
                     13: * Module Name: COMPLIST.C
                     14: *
                     15: * Supports a list of compitems, where each compitem represents
                     16: * a pair of matching files, or an unmatched file.
                     17: *
                     18: * Functions:
                     19: *
                     20: * complist_filedialog()
                     21: * complist_dirdialog()
                     22: * complist_args()
                     23: * complist_getitems()
                     24: * complist_delete()
                     25: * complist_savelist()
                     26: * complist_copyfiles()
                     27: * complist_dodlg_savelist()
                     28: * complist_dodlg_copyfiles()
                     29: * complist_match()
                     30: * complist_new()
                     31: * complist_dodlg_dir()
                     32: *
                     33: * Comments:
                     34: *
                     35: * We build lists of filenames from two pathnames (using the
                     36: * scandir module) and then traverse the two lists comparing names.
                     37: * Where the names match, we create a CompItem from the matching
                     38: * names. Where there is an unmatched name, we create a compitem for it.
                     39: *
                     40: * We may also be asked to create a complist for two individual files:
                     41: * here we create a single compitem for them as a matched pair even if
                     42: * the names don't match.
                     43: *
                     44: ****************************************************************************/
                     45: 
                     46: #include <windows.h>
                     47: #include <stdlib.h>
                     48: #include <string.h>
                     49: #include <dos.h>
                     50: #include <direct.h>
                     51: 
                     52: #include "gutils.h"
                     53: #include "state.h"
                     54: #include "windiff.h"
                     55: #include "wdiffrc.h"
                     56: #include "list.h"
                     57: #include "line.h"
                     58: #include "scandir.h"
                     59: #include "file.h"
                     60: #include "section.h"
                     61: #include "compitem.h"
                     62: #include "complist.h"
                     63: #include "view.h"
                     64: 
                     65: 
                     66: extern BOOL bAbort;             /* defined in windiff.c  Read only here */
                     67: 
                     68: /*
                     69:  * The COMPLIST handle is typedef-ed to be a pointer to one
                     70:  * of these struct complist
                     71:  */
                     72: struct complist {
                     73:         DIRLIST left;           /* left list of files */
                     74:         DIRLIST right;          /* right list of files */
                     75:         LIST items;             /* list of COMPITEMs */
                     76: };
                     77: 
                     78: /* ---- module-wide data -------------------------------------*/
                     79: 
                     80: /* data for communicating between the SaveList dlg and complist_savelist() */
                     81: 
                     82: char dlg_file[256];                /* filename to save to */
                     83: 
                     84: /* checkbox options */
                     85: BOOL dlg_identical, dlg_differ, dlg_left, dlg_right;
                     86: 
                     87: /* data for Directory and SaveList */
                     88: char dialog_leftname[256];
                     89: char dialog_rightname[256];
                     90: 
                     91: /*
                     92:  * data used by dodlg_copyfiles
                     93:  */
                     94: UINT dlg_options;
                     95: char dlg_root[256];
                     96: 
                     97: /*------------------------timing for performance measurements-----------------*/
                     98: 
                     99: static DWORD TickCount;         /* time operation started, then time taken*/
                    100: 
                    101: 
                    102: int FAR PASCAL complist_dodlg_savelist(HWND hDlg, UINT message,
                    103:         UINT wParam, long lParam);
                    104: int FAR PASCAL complist_dodlg_copyfiles(HWND hDlg, UINT message,
                    105:         UINT wParam, long lParam);
                    106: BOOL complist_match(COMPLIST cl, VIEW view, BOOL fDeep, BOOL fExact);
                    107: COMPLIST complist_new(void);
                    108: int FAR PASCAL complist_dodlg_dir(HWND hDlg, unsigned message,
                    109:         WORD wParam, LONG lParam);
                    110: 
                    111: 
                    112: 
                    113: /***************************************************************************
                    114:  * Function: complist_filedialog
                    115:  *
                    116:  * Purpose:
                    117:  *
                    118:  * Builds a complist by putting up two dialogs to allow the user to
                    119:  * select two files. This will build a Complist with one CompItem (even
                    120:  * if the names don't match).
                    121:  *
                    122:  ***************************************************************************/
                    123: COMPLIST
                    124: complist_filedialog(VIEW view)
                    125: {
                    126:         COMPLIST cl;
                    127:         OFSTRUCT os1, os2;
                    128:         char fname[256], FileExt[256], FileOpenSpec[256];
                    129: 
                    130:         /* ask for the filenames */
                    131:         lstrcpy(FileExt, ".c");
                    132:         lstrcpy(FileOpenSpec, "*.*");
                    133:         lstrcpy(fname,"");
                    134: 
                    135:         if (!complist_open("Select First File", FileExt, FileOpenSpec,
                    136:                         &os1, fname) )
                    137:                 return(NULL);
                    138: 
                    139:         lstrcpy(FileExt, ".c");
                    140:         lstrcpy(FileOpenSpec, "*.*");
                    141:         lstrcpy(fname,"");
                    142: 
                    143:         if (!complist_open("Select Second File", FileExt, FileOpenSpec,
                    144:                         &os2, fname) )
                    145:                 return(NULL);
                    146: 
                    147:         /* alloc a new structure */
                    148:         cl = complist_new();
                    149: 
                    150:         cl->left = dir_buildlist(os1.szPathName, TRUE);
                    151:         cl->right = dir_buildlist(os2.szPathName, TRUE);
                    152: 
                    153: 
                    154:         /* register with the view (must be done after the list is non-null) */
                    155:         view_setcomplist(view, cl);
                    156: 
                    157:         complist_match(cl, view, FALSE, TRUE);
                    158: 
                    159:         return(cl);
                    160: }/* complist_filedialog */
                    161: 
                    162: /***************************************************************************
                    163:  * Function: complist_dirdialog
                    164:  *
                    165:  * Purpose:
                    166:  *
                    167:  * Builds a new complist by querying the user for two directory
                    168:  * names and scanning those in parallel.
                    169:  *
                    170:  * Names that match in the same directory will be paired - unmatched
                    171:  * names will go in a compitem on their own.
                    172:  *
                    173:  ***************************************************************************/
                    174: COMPLIST
                    175: complist_dirdialog(VIEW view)
                    176: {
                    177:         DLGPROC lpProc;
                    178:         BOOL fOK;
                    179: 
                    180:         /* put up a dialog for the two pathnames */
                    181:         lpProc = (DLGPROC)MakeProcInstance((WNDPROC)complist_dodlg_dir, hInst);
                    182:         windiff_UI(TRUE);
                    183:         fOK = DialogBox(hInst, "Directory", hwndClient, lpProc);
                    184:         windiff_UI(FALSE);
                    185:         FreeProcInstance(lpProc);
                    186: 
                    187:         if (!fOK) {
                    188:                 return(NULL);
                    189:         }
                    190: 
                    191:         return complist_args( dialog_leftname, dialog_rightname
                    192:                             , view, FALSE );
                    193: } /* complist_dirdialog */
                    194: 
                    195: 
                    196: /***************************************************************************
                    197:  * Function: complist_args
                    198:  *
                    199:  * Purpose:
                    200:  *
                    201:  * Given two pathname strings, scan the directories and traverse them
                    202:  * in parallel comparing matching names.
                    203:  *
                    204:  ***************************************************************************/
                    205: COMPLIST
                    206: complist_args(LPSTR p1, LPSTR p2, VIEW view, BOOL fDeep)
                    207: {
                    208:         COMPLIST cl;
                    209:         char msg[256];
                    210: 
                    211: 
                    212:         /* alloc a new complist */
                    213:         cl = complist_new();
                    214: 
                    215:         cl->left = dir_buildlist(p1, TRUE);
                    216:         /* check that we could find the paths, and report if not */
                    217:         if (cl->left == NULL) {
                    218:                 wsprintf((LPTSTR)msg, "Couldn't find %s", p1);
                    219:                 MessageBox(NULL, msg, "Error", MB_OK | MB_ICONSTOP);
                    220:                 return(NULL);
                    221:         }
                    222: 
                    223:         cl->right = dir_buildlist(p2, TRUE);
                    224:         if (cl->right == NULL) {
                    225:                 wsprintf((LPTSTR)msg, "Couldn't find %s", p2);
                    226:                 MessageBox(NULL, msg, "Error", MB_OK | MB_ICONSTOP);
                    227:                 return(NULL);
                    228:         }
                    229: 
                    230:         /* register with the view (must be done after building lists) */
                    231:         view_setcomplist(view, cl);
                    232: 
                    233:         complist_match(cl, view, fDeep, TRUE);
                    234: 
                    235:         return(cl);
                    236: } /* complist_args */
                    237: 
                    238: /***************************************************************************
                    239:  * Function: complist_getitems
                    240:  *
                    241:  * Purpose:
                    242:  *
                    243:  * Gets the handle to the list of COMPITEMs. The list continues to be
                    244:  * owned by the COMPLIST, so don't delete except by calling complist_delete.
                    245:  *
                    246:  ***************************************************************************/
                    247: LIST
                    248: complist_getitems(COMPLIST cl)
                    249: {
                    250:         if (cl == NULL) {
                    251:                 return(NULL);
                    252:         }
                    253: 
                    254:         return(cl->items);
                    255: }
                    256: 
                    257: /***************************************************************************
                    258:  * Function: complist_delete
                    259:  *
                    260:  * Purpose:
                    261:  *
                    262:  * Deletes a complist and all associated CompItems and DIRLISTs. Note this
                    263:  * does not delete any VIEW - the VIEW owns the COMPLIST and not the other
                    264:  * way around.
                    265:  *
                    266:  **************************************************************************/
                    267: void
                    268: complist_delete(COMPLIST cl)
                    269: {
                    270:         COMPITEM item;
                    271: 
                    272:         if (cl == NULL) {
                    273:                 return;
                    274:         }
                    275: 
                    276:         /* delete the two directory scan lists */
                    277:         dir_delete(cl->left);
                    278:         dir_delete(cl->right);
                    279: 
                    280:         /* delete the compitems in the list */
                    281:         List_TRAVERSE(cl->items, item) {
                    282:                         compitem_delete(item);
                    283:         }
                    284: 
                    285:         /* delete the list itself */
                    286:         List_Destroy(&cl->items);
                    287: 
                    288:         gmem_free(hHeap, (LPSTR) cl, sizeof(struct complist));
                    289: 
                    290: }
                    291: 
                    292: /***************************************************************************
                    293:  * Function: complist_savelist
                    294:  *
                    295:  * Purpose:
                    296:  *
                    297:  * Writes out to a text file the list of compitems as relative filenames
                    298:  * one per line.
                    299:  *
                    300:  * If savename is non-null, use this as the filename for output; otherwise,
                    301:  * query the user via a dialog for the filename and include options.
                    302:  *
                    303:  **************************************************************************/
                    304: void
                    305: complist_savelist(COMPLIST cl, LPSTR savename, UINT options)
                    306: {
                    307:         DLGPROC lpProc;
                    308:         static BOOL done_init = FALSE;
                    309:         BOOL bOK;
                    310:         int fh, state;
                    311:         OFSTRUCT os;
                    312:         char msg[256];
                    313:         HCURSOR hcurs;
                    314:         COMPITEM ci;
                    315:         LPSTR pstr, lhead, rhead;
                    316:         int nFiles = 0;
                    317: 
                    318:         if (!done_init) {
                    319:                 /* init the options once round - but keep the same options
                    320:                  * for the rest of the session.
                    321:                  */
                    322: 
                    323:                 /* first init default options */
                    324:                 dlg_identical = FALSE;
                    325:                 dlg_differ = TRUE;
                    326:                 dlg_left = TRUE;
                    327:                 dlg_right = FALSE;
                    328: 
                    329:                 dlg_file[0] = '\0';
                    330: 
                    331:                 done_init = TRUE;
                    332:         }
                    333: 
                    334:         if (cl == NULL) {
                    335:                 return;
                    336:         }
                    337: 
                    338:         if (savename == NULL) {
                    339: 
                    340:                 /* store the left and right rootnames so that dodlg_savelist
                    341:                  * can display them in the dialog.
                    342:                  */
                    343:                 pstr = dir_getroot_list(cl->left);
                    344:                 lstrcpy(dialog_leftname, pstr);
                    345:                 dir_freeroot_list(cl->left, pstr);
                    346: 
                    347:                 pstr = dir_getroot_list(cl->right);
                    348:                 lstrcpy(dialog_rightname, pstr);
                    349:                 dir_freeroot_list(cl->right, pstr);
                    350: 
                    351:                 lpProc = (DLGPROC)MakeProcInstance((WNDPROC)complist_dodlg_savelist, hInst);
                    352:                 windiff_UI(TRUE);
                    353:                 bOK = DialogBox(hInst, "SaveList", hwndClient, lpProc);
                    354:                 windiff_UI(FALSE);
                    355:                 FreeProcInstance(lpProc);
                    356: 
                    357:                 if (!bOK) {
                    358:                         /* user cancelled from dialog box */
                    359:                         return;
                    360:                 }
                    361:                 savename = dlg_file;
                    362: 
                    363:         } else {
                    364:                 dlg_identical = (options & INCLUDE_SAME);
                    365:                 dlg_differ = (options & INCLUDE_DIFFER);
                    366:                 dlg_left = (options & INCLUDE_LEFTONLY);
                    367:                 dlg_right = (options & INCLUDE_RIGHTONLY);
                    368:         }
                    369: 
                    370: 
                    371:         /* try to open the file */
                    372:         fh = OpenFile(savename, &os, OF_CREATE|OF_READWRITE|OF_SHARE_DENY_WRITE);
                    373:         if (fh < 0) {
                    374:                 wsprintf((LPTSTR)msg, "Cannot open %s", savename);
                    375:                 windiff_UI(TRUE);
                    376:                 MessageBox(NULL, msg, "Windiff", MB_ICONSTOP|MB_OK);
                    377:                 windiff_UI(FALSE);
                    378:                 return;
                    379:         }
                    380: 
                    381:         hcurs = SetCursor(LoadCursor(NULL, IDC_WAIT));
                    382: 
                    383:         /* write out the header line */
                    384:         lhead = dir_getroot_list(cl->left);
                    385:         rhead = dir_getroot_list(cl->right);
                    386:         wsprintf((LPTSTR)msg, "-- %s : %s -- includes %s%s%s%s files\n",
                    387:                 lhead, rhead,
                    388:                 (LPSTR) (dlg_identical ? "identical," : ""),
                    389:                 (LPSTR) (dlg_left ? "left-only," : ""),
                    390:                 (LPSTR) (dlg_right ? "right-only," : ""),
                    391:                 (LPSTR) (dlg_differ ? "differing" : "") );
                    392:         _lwrite(fh, msg, lstrlen(msg));
                    393:         dir_freeroot_list(cl->left, lhead);
                    394:         dir_freeroot_list(cl->right, rhead);
                    395: 
                    396: 
                    397:         /* traverse the list of compitems looking for the
                    398:          * ones we are supposed to include
                    399:          */
                    400:         List_TRAVERSE(cl->items, ci) {
                    401: 
                    402:                 /* check if files of this type are to be listed */
                    403:                 state = compitem_getstate(ci);
                    404: 
                    405:                 if ((state == STATE_SAME) && (!dlg_identical)) {
                    406:                         continue;
                    407:                 } else if ((state == STATE_DIFFER) && (!dlg_differ)) {
                    408:                         continue;
                    409:                 } else if ((state == STATE_FILELEFTONLY) && (!dlg_left)) {
                    410:                         continue;
                    411:                 } else if ((state == STATE_FILERIGHTONLY) && (!dlg_right)) {
                    412:                         continue;
                    413:                 }
                    414: 
                    415:                 nFiles++;
                    416: 
                    417:                 /* output the list line */
                    418:                 wsprintf((LPTSTR)msg, "%s", compitem_gettext_tag(ci));
                    419:                 _lwrite(fh, msg, lstrlen(msg));
                    420: 
                    421:                 wsprintf((LPTSTR)msg, "\n");
                    422:                 _lwrite(fh, msg, strlen(msg));
                    423:         }
                    424: 
                    425:         /* write tail line */
                    426:         wsprintf((LPTSTR)msg, "-- %d files listed\n", nFiles);
                    427:         _lwrite(fh, msg, lstrlen(msg));
                    428: 
                    429:         /* - close file and we are finished */
                    430:         _lclose(fh);
                    431: 
                    432:         SetCursor(hcurs);
                    433: } /* complist_savelist */
                    434: 
                    435: /***************************************************************************
                    436:  * Function: complist_copyfiles
                    437:  *
                    438:  * Purpose:
                    439:  *
                    440:  * To copy files to a new directory newroot. if newroot is NULL, query the user
                    441:  * via a dialog to get the new dir name and options.
                    442:  *
                    443:  * Options are either COPY_FROMLEFT or COPY_FROMRIGHT (indicating which
                    444:  * tree is to be the source of the files, plus any or all of
                    445:  * INCLUDE_SAME, INCLUDE_DIFFER and INCLUDE_LEFT (INCLUDE_LEFT
                    446:  * and INCLUDE_RIGHT are treated the same here since the COPY_FROM* option
                    447:  * indicates which side to copy from).
                    448:  *
                    449:  ***************************************************************************/
                    450: void
                    451: complist_copyfiles(COMPLIST cl, LPSTR newroot, UINT options)
                    452: {
                    453:         int nFiles = 0;
                    454:         int nFails = 0;
                    455:         static BOOL done_init = FALSE;
                    456:         LPSTR pstr;
                    457:         char buffer[64];
                    458:         DIRITEM diritem;
                    459:         DLGPROC lpProc;
                    460:         BOOL bOK;
                    461:         COMPITEM ci;
                    462:         int state;
                    463: 
                    464:         if (!done_init) {
                    465:                 /*
                    466:                  * one-time initialisation of dialog defaults
                    467:                  */
                    468:                 dlg_options = COPY_FROMLEFT|INCLUDE_LEFTONLY|INCLUDE_DIFFER;
                    469:                 dlg_root[0] = '\0';
                    470:                 done_init = TRUE;
                    471:         }
                    472: 
                    473:         if (cl == NULL) {
                    474:                 return;
                    475:         }
                    476: 
                    477: 
                    478:         if (newroot == NULL) {
                    479:                 /*
                    480:                  * put up dialog to query rootname and options
                    481:                  */
                    482: 
                    483:                 /* store the left and right rootnames so that the dlg proc
                    484:                  * can display them in the dialog.
                    485:                  */
                    486:                 pstr = dir_getroot_list(cl->left);
                    487:                 lstrcpy(dialog_leftname, pstr);
                    488:                 dir_freeroot_list(cl->left, pstr);
                    489: 
                    490:                 pstr = dir_getroot_list(cl->right);
                    491:                 lstrcpy(dialog_rightname, pstr);
                    492:                 dir_freeroot_list(cl->right, pstr);
                    493: 
                    494:                 do {
                    495:                         lpProc = (DLGPROC)MakeProcInstance((WNDPROC)complist_dodlg_copyfiles, hInst);
                    496:                         windiff_UI(TRUE);
                    497:                         bOK = DialogBox(hInst, "CopyFiles", hwndClient, lpProc);
                    498:                         windiff_UI(FALSE);
                    499:                         FreeProcInstance(lpProc);
                    500: 
                    501:                         if (!bOK) {
                    502:                                 /* user cancelled from dialog box */
                    503:                                 return;
                    504:                         }
                    505:                         if (lstrlen(dlg_root) == 0) {
                    506:                                 windiff_UI(TRUE);
                    507:                                 MessageBox(NULL, "Please enter the directory name",
                    508:                                                 "Windiff", MB_ICONSTOP|MB_OK);
                    509:                                 windiff_UI(FALSE);
                    510:                         }
                    511:                 } while (lstrlen(dlg_root) == 0);
                    512: 
                    513:         } else {
                    514:                 dlg_options = options;
                    515:                 lstrcpy(dlg_root, newroot);
                    516:         }
                    517: 
                    518:         TickCount = GetTickCount();
                    519: 
                    520:         if (dlg_options & COPY_FROMLEFT) {
                    521:                 if (!dir_startcopy(cl->left))
                    522:                         return;
                    523:         } else {
                    524:                 if (!dir_startcopy(cl->right))
                    525:                         return;
                    526:         }
                    527: 
                    528:         /*
                    529:          * traverse the list of compitems copying files as necessary
                    530:          */
                    531:         List_TRAVERSE(cl->items, ci) {
                    532: 
                    533:                 if (bAbort){
                    534:                         break;  /* fall into end_copy processing */
                    535:                 }
                    536:                 /* check if files of this type are to be copied */
                    537:                 state = compitem_getstate(ci);
                    538: 
                    539:                 if ((state == STATE_SAME) && !(dlg_options & INCLUDE_SAME)) {
                    540:                         continue;
                    541:                 } else if ((state == STATE_DIFFER) && !(dlg_options & INCLUDE_DIFFER)) {
                    542:                         continue;
                    543:                 } else if (state == STATE_FILELEFTONLY) {
                    544:                         if (dlg_options & COPY_FROMRIGHT) {
                    545:                                 continue;
                    546:                         }
                    547:                         if ((dlg_options & (INCLUDE_LEFTONLY | INCLUDE_RIGHTONLY)) == 0) {
                    548:                                 continue;
                    549:                         }
                    550:                 } else if (state == STATE_FILERIGHTONLY) {
                    551:                         if (dlg_options & COPY_FROMLEFT) {
                    552:                                 continue;
                    553:                         }
                    554:                         if ((dlg_options & (INCLUDE_LEFTONLY | INCLUDE_RIGHTONLY)) == 0) {
                    555:                                 continue;
                    556:                         }
                    557:                 }
                    558: 
                    559:                 if (dlg_options & COPY_FROMLEFT) {
                    560:                         diritem = file_getdiritem(compitem_getleftfile(ci));
                    561:                 } else {
                    562:                         diritem = file_getdiritem(compitem_getrightfile(ci));
                    563:                 }
                    564: 
                    565:                 /*
                    566:                  * copy the file to the new root directory
                    567:                  */
                    568:                 if (dir_copy(diritem, dlg_root) == FALSE) {
                    569:                         nFails++;
                    570:                         pstr = dir_getrelname(diritem);
                    571:                         wsprintf((LPTSTR)buffer, "failed to copy %s", pstr);
                    572:                         dir_freerelname(diritem, pstr);
                    573: 
                    574:                         if (MessageBox(NULL, buffer, "Error", MB_OKCANCEL | MB_ICONSTOP) == IDCANCEL)
                    575:                             /* user pressed cancel - abort current operation*/
                    576:                             /* fall through to end-copy processing */
                    577:                             break;
                    578: 
                    579:                 } else {
                    580:                         nFiles++;
                    581:                 }
                    582: 
                    583:                 wsprintf((LPTSTR)buffer, "%4d files requested. Copying...", nFiles);
                    584:                 SetStatus(buffer);
                    585: 
                    586: 
                    587:                 /*
                    588:                  * allow user interface to continue
                    589:                  */
                    590:                 if (Poll()) {
                    591:                         /* abort requested */
                    592:                         TickCount = GetTickCount()-TickCount;
                    593:                         windiff_UI(TRUE);
                    594:                         MessageBox(hwndClient, "Copy Aborted",
                    595:                                 "WinDiff", MB_OK|MB_ICONINFORMATION);
                    596:                         windiff_UI(FALSE);
                    597:                         break;
                    598:                 }
                    599: 
                    600:         } /* traverse */
                    601:         if (dlg_options & COPY_FROMLEFT) {
                    602:                 nFails = dir_endcopy(cl->left);
                    603:         } else {
                    604:                 nFails = dir_endcopy(cl->right);
                    605:         }
                    606:         TickCount = GetTickCount()-TickCount;
                    607: 
                    608:         if (nFails<0) {
                    609:                 wsprintf((LPTSTR)buffer, "Copy Complete: %d files failed", -nFails);
                    610:         } else {
                    611:                 wsprintf((LPTSTR)buffer, "Copy Complete %d files copied", nFails);
                    612:         }
                    613:         windiff_UI(TRUE);
                    614:         MessageBox(hwndClient, buffer, "WinDiff", MB_OK|MB_ICONINFORMATION);
                    615:         windiff_UI(FALSE);
                    616: 
                    617:         buffer[0] = '\0';
                    618:         SetStatus(buffer);
                    619: } /* complist_copyfiles */
                    620: 
                    621: 
                    622: /***************************************************************************
                    623:  * Function: complist_match
                    624:  *
                    625:  * Purpose:
                    626:  *
                    627:  * Matches up two lists of filenames
                    628:  *
                    629:  * Commentsz:
                    630:  *
                    631:  * We can find out from the DIRLIST handle whether the original list
                    632:  * was a file or a directory name.
                    633:  * If the user typed:
                    634:  *      two file names  - match these two item even if the names differ
                    635:  *
                    636:  *      two dirs        - match only those items whose names match
                    637:  *
                    638:  *      one file and one dir
                    639:  *                      - try to find a file of that name in the dir.
                    640:  *
                    641:  * This function returns TRUE if the complist_match was ok, or FALSE if it was
                    642:  * aborted in some way.
                    643:  *
                    644:  ***************************************************************************/
                    645: BOOL
                    646: complist_match(COMPLIST cl, VIEW view, BOOL fDeep, BOOL fExact)
                    647: {
                    648:         LPSTR lname;
                    649:         LPSTR rname;
                    650:         DIRITEM leftitem, rightitem;
                    651:         int cmpvalue;
                    652: 
                    653:         TickCount = GetTickCount();
                    654: 
                    655:         if (dir_isfile(cl->left) ) {
                    656: 
                    657:                 if (dir_isfile(cl->right)) {
                    658:                         /* two files */
                    659: 
                    660:                         /* there should be one item in each list - make
                    661:                          * a compitem by matching these two and append it to the
                    662:                          * list
                    663:                          */
                    664:                         compitem_new(dir_firstitem(cl->left),
                    665:                                        dir_firstitem(cl->right), cl->items, fExact);
                    666: 
                    667:                         view_newitem(view);
                    668: 
                    669:                         TickCount = GetTickCount() - TickCount;
                    670:                         return TRUE;
                    671:                 }
                    672:                 /* left is file, right is dir */
                    673:                 leftitem = dir_firstitem(cl->left);
                    674:                 rightitem = dir_firstitem(cl->right);
                    675:                 lname = dir_getrelname(leftitem);
                    676:                 while (rightitem != NULL) {
                    677:                         rname = dir_getrelname(rightitem);
                    678:                         cmpvalue = lstrcmpi(lname, rname);
                    679:                         dir_freerelname(rightitem, rname);
                    680: 
                    681:                         if (cmpvalue == 0) {
                    682:                                 /* this is the match */
                    683:                                 compitem_new(leftitem, rightitem, cl->items, fExact);
                    684:                                 view_newitem(view);
                    685: 
                    686:                                 dir_freerelname(leftitem, lname);
                    687: 
                    688:                                 TickCount = GetTickCount() - TickCount;
                    689:                                 return(TRUE);
                    690:                         }
                    691: 
                    692:                         rightitem = dir_nextitem(cl->right, rightitem, fDeep);
                    693:                 }
                    694:                 /* not found */
                    695:                 dir_freerelname(leftitem, lname);
                    696:                 compitem_new(leftitem, NULL, cl->items, fExact);
                    697:                 view_newitem(view);
                    698:                 TickCount = GetTickCount() - TickCount;
                    699:                 return(TRUE);
                    700: 
                    701:         } else if (dir_isfile(cl->right)) {
                    702: 
                    703:                 /* left is dir, right is file */
                    704: 
                    705:                 /* loop through the left dir, looking for
                    706:                  * a file that has the same name as rightitem
                    707:                  */
                    708: 
                    709:                 leftitem = dir_firstitem(cl->left);
                    710:                 rightitem = dir_firstitem(cl->right);
                    711:                 rname = dir_getrelname(rightitem);
                    712:                 while (leftitem != NULL) {
                    713:                         lname = dir_getrelname(leftitem);
                    714:                         cmpvalue = lstrcmpi(lname, rname);
                    715:                         dir_freerelname(leftitem, lname);
                    716: 
                    717:                         if (cmpvalue == 0) {
                    718:                                 /* this is the match */
                    719:                                 compitem_new(leftitem, rightitem, cl->items, fExact);
                    720:                                 view_newitem(view);
                    721: 
                    722:                                 dir_freerelname(rightitem, rname);
                    723: 
                    724:                                 TickCount = GetTickCount() - TickCount;
                    725:                                 return(TRUE);
                    726:                         }
                    727: 
                    728:                         leftitem = dir_nextitem(cl->left, leftitem, fDeep);
                    729:                 }
                    730:                 /* not found */
                    731:                 dir_freerelname(rightitem, rname);
                    732:                 compitem_new(NULL, rightitem, cl->items, fExact);
                    733:                 view_newitem(view);
                    734:                 TickCount = GetTickCount() - TickCount;
                    735:                 return(TRUE);
                    736:         }
                    737: 
                    738:         /* two directories */
                    739: 
                    740:         /* traverse the two lists in parallel comparing the relative names*/
                    741: 
                    742:         leftitem = dir_firstitem(cl->left);
                    743:         rightitem = dir_firstitem(cl->right);
                    744:         while ((leftitem != NULL) && (rightitem != NULL)) {
                    745: 
                    746:                 lname = dir_getrelname(leftitem);
                    747:                 rname = dir_getrelname(rightitem);
                    748:                 cmpvalue = utils_CompPath(lname, rname);
                    749:                 dir_freerelname(leftitem, lname);
                    750:                 dir_freerelname(rightitem, rname);
                    751: 
                    752:                 if (cmpvalue == 0) {
                    753:                         compitem_new(leftitem, rightitem, cl->items, fExact);
                    754:                         if (view_newitem(view)) {
                    755:                                 TickCount = GetTickCount() - TickCount;
                    756:                                 return(FALSE);
                    757:                         }
                    758:                         leftitem = dir_nextitem(cl->left, leftitem, fDeep);
                    759:                         rightitem = dir_nextitem(cl->right, rightitem, fDeep);
                    760: 
                    761:                 } else if (cmpvalue < 0) {
                    762:                         compitem_new(leftitem, NULL, cl->items, fExact);
                    763:                         if (view_newitem(view)) {
                    764:                                 TickCount = GetTickCount() - TickCount;
                    765:                                 return(FALSE);
                    766:                         }
                    767:                         leftitem = dir_nextitem(cl->left, leftitem, fDeep);
                    768:                 }  else {
                    769:                         compitem_new(NULL, rightitem, cl->items, fExact);
                    770:                         if (view_newitem(view)) {
                    771:                                 TickCount = GetTickCount() - TickCount;
                    772:                                 return(FALSE);
                    773:                         }
                    774:                         rightitem = dir_nextitem(cl->right, rightitem, fDeep);
                    775:                 }
                    776:         }
                    777: 
                    778: 
                    779:         /* any left over are unmatched */
                    780:         while (leftitem != NULL) {
                    781:                 compitem_new(leftitem, NULL, cl->items, fExact);
                    782:                 if (view_newitem(view)) {
                    783:                         TickCount = GetTickCount() - TickCount;
                    784:                         return(FALSE);
                    785:                 }
                    786:                 leftitem = dir_nextitem(cl->left, leftitem, fDeep);
                    787:         }
                    788:         while (rightitem != NULL) {
                    789:                 compitem_new(NULL, rightitem, cl->items, fExact);
                    790:                 if (view_newitem(view)) {
                    791:                         TickCount = GetTickCount() - TickCount;
                    792:                         return(FALSE);
                    793:                 }
                    794:                 rightitem = dir_nextitem(cl->right, rightitem, fDeep);
                    795:         }
                    796:         TickCount = GetTickCount() - TickCount;
                    797:         return(TRUE);
                    798: } /* complist_match */
                    799: 
                    800: /* return time last operation took in milliseconds */
                    801: DWORD complist_querytime(void)
                    802: {       return TickCount;
                    803: }
                    804: 
                    805: 
                    806: /***************************************************************************
                    807:  * Function: complist_dodlg_savelist
                    808:  *
                    809:  * Purpose:
                    810:  *
                    811:  * Dialog to query about filename and types of files. Init dlg fields from
                    812:  * the dlg_* variables, and save state to the dlg_* variables on dialog
                    813:  * close. return TRUE for OK, or FALSE for cancel (from the dialogbox()
                    814:  * using EndDialog).
                    815:  *
                    816:  **************************************************************************/
                    817: int FAR PASCAL
                    818: complist_dodlg_savelist(HWND hDlg, UINT message, UINT wParam, long lParam)
                    819: {
                    820:         static char buffer[256];
                    821: 
                    822:         switch(message) {
                    823: 
                    824: 
                    825:         case WM_INITDIALOG:
                    826:                 SendDlgItemMessage(hDlg, IDD_IDENTICAL, BM_SETCHECK,
                    827:                         dlg_identical ? 1 : 0, 0);
                    828:                 SendDlgItemMessage(hDlg, IDD_DIFFER, BM_SETCHECK,
                    829:                         dlg_differ ? 1 : 0, 0);
                    830:                 SendDlgItemMessage(hDlg, IDD_LEFT, BM_SETCHECK,
                    831:                         dlg_left ? 1 : 0, 0);
                    832:                 SendDlgItemMessage(hDlg, IDD_RIGHT, BM_SETCHECK,
                    833:                         dlg_right ? 1 : 0, 0);
                    834: 
                    835:                 SetDlgItemText(hDlg, IDD_FILE, dlg_file);
                    836: 
                    837:                 /* convert 'left tree' into the right name */
                    838:                 wsprintf((LPTSTR)buffer, "Files only in %s", (LPSTR) dialog_leftname);
                    839:                 SendDlgItemMessage(hDlg, IDD_LEFT, WM_SETTEXT, 0, (DWORD) (LPSTR) buffer);
                    840: 
                    841:                 /* convert 'right tree' msg into correct path */
                    842:                 wsprintf((LPTSTR)buffer, "Files only in %s", (LPSTR) dialog_rightname);
                    843:                 SendDlgItemMessage(hDlg, IDD_RIGHT, WM_SETTEXT, 0, (DWORD) (LPSTR) buffer);
                    844: 
                    845: 
                    846:                 return(TRUE);
                    847: 
                    848:         case WM_COMMAND:
                    849:                 switch (GET_WM_COMMAND_ID(wParam, lParam)) {
                    850: 
                    851:                 case IDOK:
                    852:                         dlg_identical = (SendDlgItemMessage(hDlg, IDD_IDENTICAL,
                    853:                                         BM_GETCHECK, 0, 0) == 1);
                    854:                         dlg_differ = (SendDlgItemMessage(hDlg, IDD_DIFFER,
                    855:                                         BM_GETCHECK, 0, 0) == 1);
                    856:                         dlg_left = (SendDlgItemMessage(hDlg, IDD_LEFT,
                    857:                                         BM_GETCHECK, 0, 0) == 1);
                    858:                         dlg_right = (SendDlgItemMessage(hDlg, IDD_RIGHT,
                    859:                                         BM_GETCHECK, 0, 0) == 1);
                    860:                         GetDlgItemText(hDlg, IDD_FILE, dlg_file, sizeof(dlg_file));
                    861: 
                    862:                         EndDialog(hDlg, TRUE);
                    863:                         break;
                    864: 
                    865:                 case IDCANCEL:
                    866:                         EndDialog(hDlg, FALSE);
                    867:                         break;
                    868:                 }
                    869:         }
                    870:         return(FALSE);
                    871: } /* complist_dodlg_savelist */
                    872: 
                    873: /***************************************************************************
                    874:  * Function: complist_dodlg_copyfiles
                    875:  *
                    876:  * Purpose:
                    877:  *
                    878:  * dialog to get directory name and inclusion options. Init dlg fields from
                    879:  * the dlg_* variables, and save state to the dlg_* variables on dialog
                    880:  * close. return TRUE for OK, or FALSE for cancel (from the dialogbox()
                    881:  * using EndDialog).
                    882:  * 
                    883:  **************************************************************************/
                    884: int FAR PASCAL
                    885: complist_dodlg_copyfiles(HWND hDlg, UINT message, UINT wParam, long lParam)
                    886: {
                    887:         static char buffer[256];
                    888: 
                    889:         switch(message) {
                    890: 
                    891: 
                    892:         case WM_INITDIALOG:
                    893:                 /*
                    894:                  * set checkboxes and directory field to defaults
                    895:                  */
                    896:                 CheckDlgButton(hDlg, IDD_IDENTICAL,
                    897:                         (dlg_options & INCLUDE_SAME) ? 1 : 0);
                    898: 
                    899:                 CheckDlgButton(hDlg, IDD_DIFFER,
                    900:                         (dlg_options & INCLUDE_DIFFER) ? 1 : 0);
                    901: 
                    902:                 CheckDlgButton(hDlg, IDD_LEFT,
                    903:                         (dlg_options & (INCLUDE_LEFTONLY|INCLUDE_RIGHTONLY)) ? 1 : 0);
                    904: 
                    905:                 SetDlgItemText(hDlg, IDD_DIR1, dlg_root);
                    906: 
                    907:                 /*
                    908:                  * set 'copy from' buttons to have the full pathname
                    909:                  */
                    910:                 SetDlgItemText(hDlg, IDD_FROMLEFT, dialog_leftname);
                    911:                 SetDlgItemText(hDlg, IDD_FROMRIGHT, dialog_rightname);
                    912: 
                    913:                 /*
                    914:                  * set default radio button for copy from, and set
                    915:                  * the text on the 'files only in...' checkbox to
                    916:                  * indicate which path is being selected
                    917:                  */
                    918:                 if (dlg_options & COPY_FROMLEFT) {
                    919:                         CheckRadioButton(hDlg, IDD_FROMLEFT, IDD_FROMRIGHT,
                    920:                                         IDD_FROMLEFT);
                    921: 
                    922:                         wsprintf((LPTSTR)buffer, "Files only in %s", (LPSTR) dialog_leftname);
                    923:                         SetDlgItemText(hDlg, IDD_LEFT, buffer);
                    924:                 } else {
                    925:                         CheckRadioButton(hDlg, IDD_FROMLEFT, IDD_FROMRIGHT,
                    926:                                         IDD_FROMRIGHT);
                    927: 
                    928:                         wsprintf((LPTSTR)buffer, "Files only in %s", (LPSTR) dialog_rightname);
                    929:                         SetDlgItemText(hDlg, IDD_LEFT, buffer);
                    930:                 }
                    931: 
                    932:                 return(TRUE);
                    933: 
                    934:         case WM_COMMAND:
                    935:                 switch (GET_WM_COMMAND_ID(wParam, lParam)) {
                    936: 
                    937:                 case IDD_FROMLEFT:
                    938:                         wsprintf((LPTSTR)buffer, "Files only in %s", (LPSTR) dialog_leftname);
                    939:                         SetDlgItemText(hDlg, IDD_LEFT, buffer);
                    940: 
                    941:                         dlg_options &= ~(COPY_FROMRIGHT);
                    942:                         dlg_options |= COPY_FROMLEFT;
                    943:                         break;
                    944: 
                    945:                 case IDD_FROMRIGHT:
                    946:                         wsprintf((LPTSTR)buffer, "Files only in %s", (LPSTR) dialog_rightname);
                    947:                         SetDlgItemText(hDlg, IDD_LEFT, buffer);
                    948: 
                    949:                         dlg_options &= ~(COPY_FROMLEFT);
                    950:                         dlg_options |= COPY_FROMRIGHT;
                    951:                         break;
                    952: 
                    953:                 case IDOK:
                    954:                         if (SendDlgItemMessage(hDlg, IDD_IDENTICAL,
                    955:                             BM_GETCHECK, 0, 0) == 1) {
                    956:                                 dlg_options |= INCLUDE_SAME;
                    957:                         } else {
                    958:                                 dlg_options &= ~INCLUDE_SAME;
                    959:                         }
                    960:                         if (SendDlgItemMessage(hDlg, IDD_DIFFER,
                    961:                             BM_GETCHECK, 0, 0) == 1) {
                    962:                                 dlg_options |= INCLUDE_DIFFER;
                    963:                         } else {
                    964:                                 dlg_options &= ~INCLUDE_DIFFER;
                    965:                         }
                    966:                         if (SendDlgItemMessage(hDlg, IDD_LEFT,
                    967:                             BM_GETCHECK, 0, 0) == 1) {
                    968:                                 dlg_options |= INCLUDE_LEFTONLY;
                    969:                         } else {
                    970:                                 dlg_options &= ~INCLUDE_LEFTONLY;
                    971:                         }
                    972:                         GetDlgItemText(hDlg, IDD_DIR1, dlg_root, sizeof(dlg_root));
                    973: 
                    974:                         EndDialog(hDlg, TRUE);
                    975:                         break;
                    976: 
                    977:                 case IDCANCEL:
                    978:                         EndDialog(hDlg, FALSE);
                    979:                         break;
                    980:                 }
                    981:         }
                    982:         return(FALSE);
                    983: } /* complist_dodlg_copyfiles */
                    984: 
                    985: /***************************************************************************
                    986:  * Function: complist_new
                    987:  *
                    988:  * Purpose:
                    989:  *
                    990:  * Allocates a new complist and initialise it 
                    991:  *
                    992:  **************************************************************************/
                    993: COMPLIST
                    994: complist_new(void)
                    995: {
                    996:         COMPLIST cl;
                    997: 
                    998:         cl = (COMPLIST) gmem_get(hHeap, sizeof(struct complist));
                    999:         cl->left = NULL;
                   1000:         cl->right = NULL;
                   1001:         cl->items = List_Create();
                   1002: 
                   1003:         return(cl);
                   1004: } /* complist_new */
                   1005: 
                   1006: /***************************************************************************
                   1007:  * Function: complist_dodlg_dir
                   1008:  *
                   1009:  * Purpose:
                   1010:  *
                   1011:  * Dialog box function to ask for two directory names.
                   1012:  * no listing of files etc - just two edit fields  in which the
                   1013:  * user can type a file or a directory name.
                   1014:  *
                   1015:  * Initialises the names from win.ini, and stores them to win.ini first.
                   1016:  *
                   1017:  **************************************************************************/
                   1018: int FAR PASCAL
                   1019: complist_dodlg_dir(HWND hDlg, unsigned message, WORD wParam, LONG lParam)
                   1020: {
                   1021:         static char path[256];
                   1022:         static char buffer[256];
                   1023: 
                   1024:         switch (message) {
                   1025: 
                   1026:         case WM_INITDIALOG:
                   1027: 
                   1028:                 /* fill the edit fields with the current
                   1029:                  * directory as a good starting point
                   1030:                  */
                   1031:                 _getcwd(path, sizeof(path));
                   1032:                 AnsiLowerBuff(path, strlen(path));
                   1033:                 GetProfileString(APPNAME, "NameLeft", path, buffer, 256);
                   1034:                 SetDlgItemText(hDlg, IDD_DIR1, buffer);
                   1035:                 GetProfileString(APPNAME, "NameRight", path, buffer, 256);
                   1036:                 SetDlgItemText(hDlg, IDD_DIR2, buffer);
                   1037:                 return(TRUE);
                   1038: 
                   1039:         case WM_COMMAND:
                   1040:                 switch (LOWORD(wParam)) {
                   1041:                 case IDCANCEL:
                   1042:                         EndDialog(hDlg, FALSE);
                   1043:                         return(TRUE);
                   1044: 
                   1045:                 case IDOK:
                   1046:                         /* fetch the text from the dialog, and remember
                   1047:                          * it in win.ini
                   1048:                          */
                   1049: 
                   1050:                         GetDlgItemText(hDlg, IDD_DIR1,
                   1051:                                 dialog_leftname, sizeof(dialog_leftname));
                   1052:                         WriteProfileString(APPNAME, "NameLeft", dialog_leftname);
                   1053: 
                   1054:                         GetDlgItemText(hDlg, IDD_DIR2,
                   1055:                                 dialog_rightname, sizeof(dialog_rightname));
                   1056: 
                   1057:                         EndDialog(hDlg, TRUE);
                   1058:                         return(TRUE);
                   1059:                 }
                   1060:                 break;
                   1061:         }
                   1062:         return(FALSE);
                   1063: } /* complist_dodlg_dir */
                   1064: 
                   1065: /***************************************************************************
                   1066:  * Function: complist_open
                   1067:  *
                   1068:  * Purpose:
                   1069:  *      
                   1070:  * Puts up dialog asking the user to select an existing file to open.
                   1071:  *
                   1072:  * Parameters:
                   1073:  *
                   1074:  *      prompt - message to user indicating purpose of file
                   1075:  *               (to be displayed somewhere in dialog box.
                   1076:  *
                   1077:  *      ext    - default file extension if user enters file without
                   1078:  *               extension.
                   1079:  *
                   1080:  *      spec   - default file spec (eg *.*)
                   1081:  *
                   1082:  *      osp    - OFSTRUCT representing file, if successfully open.
                   1083:  *
                   1084:  *      fn     - buffer where filename (just final element) is returned.
                   1085:  *
                   1086:  * Returns:
                   1087:  *
                   1088:  * TRUE - if file selected and exists (tested with OF_EXIST).
                   1089:  *
                   1090:  * FALSE - if dialog cancelled. If user selects a file that we cannot
                   1091:  *           open, we complain and restart the dialog.
                   1092:  *
                   1093:  * Comments:
                   1094:  *
                   1095:  *           if TRUE is returned, the file will have been successfully opened,
                   1096:  *           for reading and then closed again.
                   1097:  *
                   1098:  **************************************************************************/
                   1099: 
                   1100: BOOL FAR PASCAL
                   1101: complist_open(LPSTR prompt, LPSTR ext, LPSTR spec, OFSTRUCT FAR *osp, LPSTR fn)
                   1102: {
                   1103:     OPENFILENAME ofn;
                   1104:     char achFilters[256];
                   1105:     char achPath[256];
                   1106:     LPSTR chp;
                   1107:     int fh;
                   1108: 
                   1109:     /* build filter-pair buffer to contain one pair - the spec filter,
                   1110:      * twice (one of the pair should be the filter, the second should be
                   1111:      * the title of the filter - we don't have a title so we use the
                   1112:      * filter both times. remember double null at end of list of strings.
                   1113:      */
                   1114:     lstrcpy(achFilters, spec);             // filter + null
                   1115:     chp = &achFilters[lstrlen(achFilters)+1];      //2nd string just after null
                   1116:     lstrcpy(chp, spec);                    // filter name (+null)
                   1117:     chp[lstrlen(chp)+1] = '\0';            // double null at end of list
                   1118:     /*
                   1119:      * initialise arguments to dialog proc
                   1120:      */
                   1121:     ofn.lStructSize = sizeof(OPENFILENAME);
                   1122:     ofn.hwndOwner = NULL;
                   1123:     ofn.hInstance = NULL;
                   1124:     ofn.lpstrFilter = achFilters;
                   1125:     ofn.lpstrCustomFilter = (LPSTR)NULL;
                   1126:     ofn.nMaxCustFilter = 0L;
                   1127:     ofn.nFilterIndex = 1L;              // first filter pair in list
                   1128:     achPath[0] = '\0';
                   1129:     ofn.lpstrFile = achPath;            // we need to get the full path to open
                   1130:     ofn.nMaxFile = sizeof(achPath);
                   1131:     ofn.lpstrFileTitle = fn;            // return final elem of name here
                   1132:     ofn.nMaxFileTitle = sizeof(fn);
                   1133:     ofn.lpstrInitialDir = NULL;
                   1134:     ofn.lpstrTitle = prompt;            // dialog title is good place for prompt text
                   1135:     ofn.Flags = OFN_FILEMUSTEXIST |
                   1136:                 OFN_HIDEREADONLY |
                   1137:                 OFN_PATHMUSTEXIST;
                   1138:     ofn.lpstrDefExt = ext;
                   1139:     ofn.nFileOffset = 0;
                   1140:     ofn.nFileExtension = 0;
                   1141:     ofn.lCustData = 0;
                   1142: 
                   1143:     /*
                   1144:      * loop until the user cancels, or selects a file that we can open
                   1145:      */
                   1146:     do {
                   1147:         if (!GetOpenFileName(&ofn)) {
                   1148:             return(FALSE);
                   1149:         }
                   1150: 
                   1151:         fh = OpenFile(achPath, osp, OF_READ);
                   1152:         
                   1153:         if (fh == HFILE_ERROR) {
                   1154:             if (MessageBox(NULL, "File Could Not Be Opened", "File Open",
                   1155:                             MB_OKCANCEL|MB_ICONSTOP) == IDCANCEL) {
                   1156:                 return(FALSE);
                   1157:             }
                   1158:         }
                   1159:     } while (fh == HFILE_ERROR);
                   1160: 
                   1161:     _lclose(fh);
                   1162: 
                   1163:     return(TRUE);
                   1164: }
                   1165: 
                   1166: /***************************************************************************
                   1167:  * Function: complist_getroot_left
                   1168:  *
                   1169:  * Purpose:
                   1170:  *
                   1171:  * Gets the root names of the left tree used to build this complist.
                   1172:  *
                   1173:  **************************************************************************/
                   1174: LPSTR
                   1175: complist_getroot_left(COMPLIST cl)
                   1176: {
                   1177:         return( dir_getroot_list(cl->left));
                   1178: }
                   1179: 
                   1180: /***************************************************************************
                   1181:  * Function: complist_getroot_right
                   1182:  *
                   1183:  * Purpose:
                   1184:  *
                   1185:  * Gets the root names of the right tree used to build this complist.
                   1186:  *
                   1187:  **************************************************************************/
                   1188: LPSTR
                   1189: complist_getroot_right(COMPLIST cl)
                   1190: {
                   1191:         return( dir_getroot_list(cl->right));
                   1192: }
                   1193: /***************************************************************************
                   1194:  * Function: complist_freeroot_*
                   1195:  *
                   1196:  * Purpose:
                   1197:  *
                   1198:  * Frees up memory allocated in a call to complist_getroot*() 
                   1199:  *
                   1200:  **************************************************************************/
                   1201: void
                   1202: complist_freeroot_left(COMPLIST cl, LPSTR path)
                   1203: {
                   1204:         dir_freeroot_list(cl->left, path);
                   1205: }
                   1206: 
                   1207: void
                   1208: complist_freeroot_right(COMPLIST cl, LPSTR path)
                   1209: {
                   1210:         dir_freeroot_list(cl->right, path);
                   1211: }
                   1212: 
                   1213: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.