|
|
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: include.c ! 14: * ! 15: * This module contains routines that manipulate the linked lists ! 16: * of labels (symbols plus id values). ! 17: * ! 18: * Functions: ! 19: * AddLabel() ! 20: * FindLabel() ! 21: * FindID() ! 22: * FindIDInRes() ! 23: * DeleteLabel() ! 24: * IsSymbol() ! 25: * IDToLabel() ! 26: * LabelToID() ! 27: * FreeLabels() ! 28: * ! 29: * Comments: ! 30: * ! 31: * The following describes the linked lists of LABEL structures that ! 32: * contain all the symbols that are in the include file. It is ! 33: * important that these structures and lists be maintained properly ! 34: * for the udpating of the include file to occur properly. ! 35: * ! 36: * The following fields are in the LABEL structure: ! 37: * ! 38: * npNext - points to * the next label in the list. This is NULL ! 39: * for the last link in the list. ! 40: * pszLabel - points to a null terminated, allocated string that ! 41: * has the symbol. This needs to be free'd if the structure ! 42: * is free'd. ! 43: * id - the current id value for this symbol. ! 44: * idOrig - the id value as read from the include file. This ! 45: * field is used to determine if the id value has been changed ! 46: * or not, so it is the same as the id unless the user has ! 47: * modified the id value of the symbol. ! 48: * fpos - the file pointer offset to the "#" in the "#define" in ! 49: * the include file as it was read in. This field is used ! 50: * to determine where the "#define" line starts in the ! 51: * file. If the label is added by the user (it does not exist ! 52: * in the include file) this field will be set to FPOS_MAX. ! 53: * nValueOffset - the offset in bytes from the fpos value to the start of ! 54: * the id value in the "#define" line in the include file. This ! 55: * will be ignored if fpos is set to FPOS_MAX. ! 56: * ! 57: * The order of the linked lists of labels are very important. The order ! 58: * will be exactly the same as is read from the include file. This ! 59: * allows any changes to be merged back out to the new include file ! 60: * when it is saved. If any labels are added by the user, they will be ! 61: * added to the end of the list. The start of the new ones is detected ! 62: * by the first label with an fpos value of FPOS_MAX (which all the ! 63: * new ones should have). Because the order of the new labels is not ! 64: * critical (they will be added to the end of the include file) the ! 65: * new labels are sorted by id value. Because the id values given ! 66: * to dialogs and controls by default are ascending, this will tend to ! 67: * group dialogs labels and their associated control labels together. ! 68: * ! 69: * Linked lists of labels always come in pairs. There is the linked ! 70: * list of current labels (ones read from the include file followed ! 71: * by labels added later), and there is also a separate linked list ! 72: * of "deleted" labels. The deleted label list is required because ! 73: * when the include file is saved, the deleted labels must be removed ! 74: * from the include file, so the label structure for them (which ! 75: * contains their file offset and so on) must be kept around. When ! 76: * the user deletes a label, it is removed from the current label ! 77: * linked list and added to the deleted label list. The deleted label ! 78: * list MUST be kept in order by fpos, but if the label that is ! 79: * deleted is one that did not exist in the include file (its fpos ! 80: * was FPOS_MAX) then it does NOT have to be added to the deleted ! 81: * list, and can simply be free'd. When the user adds a new label, ! 82: * the deleted list is searched first to see if the label was ! 83: * previously deleted. If it was, it is removed from the deleted list ! 84: * and placed back in the current label list (sorted by fpos, of ! 85: * course). If it is a new label, it is simply added to the new labels ! 86: * at the end of the list (sorted by id value). This is why every ! 87: * function that takes a pointer to the head of a label list also ! 88: * takes a pointer to the head of a deleted label list. ! 89: * ! 90: ****************************************************************************/ ! 91: ! 92: #include "dlgedit.h" ! 93: #include "dlgfuncs.h" ! 94: #include "dlgextrn.h" ! 95: ! 96: ! 97: ! 98: /************************************************************************ ! 99: * AddLabel ! 100: * ! 101: * This adds a symbol/label into the given include file list. The deleted ! 102: * include list is first searched and if a deleted label is found with the ! 103: * same symbol, it is transfered back into the include list. This is to ! 104: * handle the case where a user reads in an include file, deletes one of ! 105: * the labels then adds it back in later. ! 106: * ! 107: * The npLabelSkip parameter is for the special case of changing a ! 108: * label. This is done by adding a new label then deleting the old ! 109: * one, so setting this parameter prevents a spurious "duplicate id" ! 110: * message during the add. ! 111: * ! 112: * The pfDups parameter can be used to set a flag when there is a ! 113: * duplicate symbol, or a symbol with the same id found in the include ! 114: * list. If this parameter is NULL, nothing is returned and the appropriate ! 115: * error message is displayed if a dup is found. If this parameter is not ! 116: * NULL, it is assumed to point to a BOOL that will be set to TRUE if either ! 117: * of these conditions is found. The flag will NOT be set to FALSE if this ! 118: * condition is NOT found, so AddLabel can be used in a loop and when the ! 119: * loop is done, *pfDups will contain TRUE if there were any duplicates. ! 120: * Note that if pfDups is not NULL, the dup error messages will be supressed. ! 121: * This routine truncates pszLabel at the first space. It can allocate ! 122: * memory for a LABEL and for its string. The pplHead and pplDelHead lists ! 123: * are updated. ! 124: * ! 125: * Arguments: ! 126: * LPTSTR pszLabel = The label to add. ! 127: * INT id = The id associated with rgchLabel. ! 128: * DWORD fpos = The file position in the include file where the ! 129: * "#define" for this label starts, or FPOS_MAX ! 130: * if the label was not read from an include file. ! 131: * INT nValueOffset = Offset from fpos where the id value begins. ! 132: * NPLABEL *pplHead = Pointer to the head of the include list to use. ! 133: * NPLABEL *pplDelHead = Pointer to the head of the deleted include list. ! 134: * NPLABEL npLabelSkip = If not NULL, points to a label to skip when ! 135: * checking for duplicates. ! 136: * BOOL *pfDups = Points to a BOOL that is set to TRUE if there ! 137: * is a duplicate symbol or id found. ! 138: * ! 139: * Returns: ! 140: * Pointer to the allocated LABEL structure - NULL for an error. ! 141: * ! 142: ************************************************************************/ ! 143: ! 144: NPLABEL AddLabel( ! 145: LPTSTR pszLabel, ! 146: INT id, ! 147: DWORD fpos, ! 148: INT nValueOffset, ! 149: NPLABEL *pplHead, ! 150: NPLABEL *pplDelHead, ! 151: NPLABEL npLabelSkip, ! 152: BOOL *pfDups) ! 153: { ! 154: register NPLABEL npTmp; ! 155: NPLABEL npLabel; ! 156: NPLABEL npPrevLabel; ! 157: BOOL fFoundDeleted = FALSE; ! 158: ! 159: /* ! 160: * First check for a duplicate id or symbol. ! 161: */ ! 162: for (npTmp = *pplHead; npTmp; npTmp = npTmp->npNext) { ! 163: if ((npTmp->id == id || lstrcmp(pszLabel, npTmp->pszLabel) == 0) && ! 164: npTmp != npLabelSkip) { ! 165: if (pfDups) { ! 166: *pfDups = TRUE; ! 167: } ! 168: else { ! 169: if (npTmp->id == id) ! 170: Message(MSG_LABELDUPID); ! 171: else ! 172: Message(MSG_SYMEXISTS); ! 173: } ! 174: ! 175: return NULL; ! 176: } ! 177: } ! 178: ! 179: /* ! 180: * Search for this symbol in the deleted list first. ! 181: */ ! 182: npPrevLabel = NULL; ! 183: for (npLabel = *pplDelHead; npLabel; npLabel = npLabel->npNext) { ! 184: if (lstrcmp(pszLabel, npLabel->pszLabel) == 0) { ! 185: fFoundDeleted = TRUE; ! 186: break; ! 187: } ! 188: ! 189: npPrevLabel = npLabel; ! 190: } ! 191: ! 192: /* ! 193: * Was the label found in the deleted list? ! 194: */ ! 195: if (fFoundDeleted) { ! 196: /* ! 197: * Close up the deleted list where the deleted label was. ! 198: */ ! 199: if (npPrevLabel) ! 200: npPrevLabel->npNext = npLabel->npNext; ! 201: else ! 202: *pplDelHead = npLabel->npNext; ! 203: ! 204: /* ! 205: * Set the id in case the user is adding the same symbol ! 206: * but with a different id. ! 207: */ ! 208: npLabel->id = id; ! 209: ! 210: /* ! 211: * Search for where the label should be inserted ! 212: * based on its fpos. ! 213: */ ! 214: npPrevLabel = NULL; ! 215: for (npTmp = *pplHead; npTmp; npTmp = npTmp->npNext) { ! 216: if (npTmp->fpos == FPOS_MAX || npTmp->fpos > npLabel->fpos) ! 217: break; ! 218: ! 219: npPrevLabel = npTmp; ! 220: } ! 221: } ! 222: else { ! 223: /* ! 224: * Label was not found in the deleted list. Allocate, etc. ! 225: */ ! 226: if (!(npLabel = (NPLABEL)MyAlloc(sizeof(LABEL)))) ! 227: return NULL; ! 228: ! 229: npLabel->id = id; ! 230: npLabel->idOrig = id; ! 231: npLabel->fpos = fpos; ! 232: npLabel->nValueOffset = nValueOffset; ! 233: ! 234: if (!(npLabel->pszLabel = ! 235: (LPTSTR)MyAlloc((lstrlen(pszLabel) + 1) * sizeof(TCHAR)))) { ! 236: MyFree(npLabel); ! 237: return NULL; ! 238: } ! 239: ! 240: lstrcpy(npLabel->pszLabel, pszLabel); ! 241: ! 242: /* ! 243: * Find where to insert the new label. This will either be ! 244: * at the end of the list, or in ascending numerical order ! 245: * among the new labels. ! 246: */ ! 247: npPrevLabel = NULL; ! 248: for (npTmp = *pplHead; ! 249: npTmp && (npTmp->fpos != FPOS_MAX || npTmp->id < id); ! 250: npTmp = npTmp->npNext) ! 251: npPrevLabel = npTmp; ! 252: } ! 253: ! 254: /* ! 255: * At this point, npLabel points to the label to add, either ! 256: * transferred from the deleted list, or allocated fresh. ! 257: * The variable npPrevLabel points to the label to insert ! 258: * after, or is NULL to indicate that the new label should ! 259: * be inserted at the head of the list. ! 260: */ ! 261: ! 262: /* ! 263: * If this is the first label in the list, or if the ! 264: * first label had a greater fpos than the new label, ! 265: * insert the new label at the head of the list. ! 266: */ ! 267: if (!npPrevLabel) { ! 268: npLabel->npNext = *pplHead; ! 269: *pplHead = npLabel; ! 270: } ! 271: /* ! 272: * Otherwise, insert it either in the middle of the ! 273: * list or at the end. ! 274: */ ! 275: else { ! 276: npLabel->npNext = npPrevLabel->npNext; ! 277: npPrevLabel->npNext = npLabel; ! 278: } ! 279: ! 280: return npLabel; ! 281: } ! 282: ! 283: ! 284: ! 285: /************************************************************************ ! 286: * FindLabel ! 287: * ! 288: * Tells you if the named label is in the given include label list. ! 289: * ! 290: * Arguments: ! 291: * LPTSTR pszLabel = The label to find. ! 292: * NPLABEL plHead = Head of the include list to traverse. ! 293: * ! 294: * Returns: ! 295: * NULL if the label is not found. ! 296: * Pointer to label structure if the label was found. ! 297: * ! 298: * ! 299: ************************************************************************/ ! 300: ! 301: NPLABEL FindLabel( ! 302: LPTSTR pszLabel, ! 303: NPLABEL plHead) ! 304: { ! 305: NPLABEL npLabel; ! 306: ! 307: for (npLabel = plHead; npLabel; npLabel = npLabel->npNext) { ! 308: if (lstrcmp(pszLabel, npLabel->pszLabel) == 0) ! 309: break; ! 310: } ! 311: ! 312: return npLabel; ! 313: } ! 314: ! 315: ! 316: ! 317: /************************************************************************ ! 318: * FindID ! 319: * ! 320: * Tells you if the named id is in the given include file buffer. ! 321: * ! 322: * Arguments: ! 323: * INT id = The id to find. ! 324: * NPLABEL plHead = Head of the label list to use. ! 325: * ! 326: * Returns: ! 327: * NULL if the id was not found. ! 328: * Pointer to label struct if the id was found. ! 329: * ! 330: * ! 331: ************************************************************************/ ! 332: ! 333: NPLABEL FindID( ! 334: INT id, ! 335: NPLABEL plHead) ! 336: { ! 337: NPLABEL npLabel; ! 338: ! 339: for (npLabel = plHead; npLabel; npLabel = npLabel->npNext) { ! 340: if (npLabel->id == id) ! 341: break; ! 342: } ! 343: ! 344: return npLabel; ! 345: } ! 346: ! 347: ! 348: ! 349: /************************************************************************ ! 350: * FindIDInRes ! 351: * ! 352: * Tells you if the named id is used by any control in the current ! 353: * resource list. This also includes searching through the dialog ! 354: * currently being edited, if there is one. ! 355: * ! 356: * Arguments: ! 357: * INT id = The id to find. ! 358: * ! 359: * Returns: ! 360: * TRUE if the id was found, or FALSE if it was not. ! 361: * ! 362: * ! 363: ************************************************************************/ ! 364: ! 365: BOOL FindIDInRes( ! 366: INT id) ! 367: { ! 368: INT cControls; ! 369: PRESLINK prl; ! 370: PRES pRes; ! 371: PDIALOGBOXHEADER pdbh; ! 372: PCONTROLDATA pcd; ! 373: NPCTYPE npc; ! 374: BOOL fFound = FALSE; ! 375: ! 376: /* ! 377: * Is there a current dialog? If so, search it first and ! 378: * we will skip any image for it in the resource list (the ! 379: * resource list is probably out of date, anyways). ! 380: */ ! 381: if (gfEditingDlg) { ! 382: /* ! 383: * Is the id the same as the current dialog's name? ! 384: */ ! 385: if (IsOrd(gcd.pszDlgName) && id == (INT)OrdID(gcd.pszDlgName)) ! 386: return TRUE; ! 387: ! 388: /* ! 389: * Loop through the current controls, looking for an id match. ! 390: */ ! 391: for (npc = npcHead; npc; npc = npc->npcNext) ! 392: if (npc->id == id) ! 393: return TRUE; ! 394: } ! 395: ! 396: for (prl = gprlHead; prl && !fFound; prl = prl->prlNext) { ! 397: /* ! 398: * Is this a dialog resource and is it NOT the current ! 399: * dialog being edited? If it is the current dialog, ! 400: * we skip it because it is probably out of date. ! 401: */ ! 402: if (prl->fDlgResource && prl != gcd.prl) { ! 403: if (IsOrd(prl->pszName) && id == (INT)OrdID(prl->pszName)) { ! 404: fFound = TRUE; ! 405: } ! 406: else { ! 407: pRes = (PRES)GlobalLock(prl->hRes); ! 408: pdbh = (PDIALOGBOXHEADER)SkipResHeader(pRes); ! 409: cControls = (INT)pdbh->NumberOfItems; ! 410: pcd = SkipDialogBoxHeader(pdbh); ! 411: while (cControls--) { ! 412: if (id == (INT)pcd->wId) { ! 413: fFound = TRUE; ! 414: break; ! 415: } ! 416: ! 417: pcd = SkipControlData(pcd); ! 418: } ! 419: ! 420: GlobalUnlock(prl->hRes); ! 421: } ! 422: } ! 423: } ! 424: ! 425: return fFound; ! 426: } ! 427: ! 428: ! 429: ! 430: /************************************************************************ ! 431: * DeleteLabel ! 432: * ! 433: * Removes the LABEL with text pszLabel from the list of labels in ! 434: * pplHead, closing up the link, and might add it to the deleted list. ! 435: * ! 436: * If the label is one that exists in the include file (fpos is valid) ! 437: * then the label is added to the pplDelHead list in the proper position ! 438: * (sorted ascending by fpos). If the label does not exist in the ! 439: * include file, there is no need to track it and it can be tossed. ! 440: * ! 441: * Arguments: ! 442: * LPTSTR pszLabel = The text of the label to delete. ! 443: * NPLABEL *pplHead = Pointer to the head of the include list to use. ! 444: * NPLABEL *pplDelHead = Pointer to the head of the deleted include list. ! 445: * ! 446: * Side Effects: ! 447: * Deletes from the pplHead list. ! 448: * Can null *pplHead if the last label is deleted. ! 449: * Can add to the pplDelHead list. ! 450: * Can free the memory associated with the LABEL and its string. ! 451: * ! 452: * ! 453: ************************************************************************/ ! 454: ! 455: VOID DeleteLabel( ! 456: LPTSTR pszLabel, ! 457: NPLABEL *pplHead, ! 458: NPLABEL *pplDelHead) ! 459: { ! 460: NPLABEL npLabel; ! 461: NPLABEL npDelLabel; ! 462: NPLABEL npPrevLabel; ! 463: ! 464: npPrevLabel = NULL; ! 465: for (npLabel = *pplHead; npLabel; npLabel = npLabel->npNext) { ! 466: if (lstrcmp(pszLabel, npLabel->pszLabel) == 0) { ! 467: /* ! 468: * Close up the linked list where the deleted label was. ! 469: */ ! 470: if (npPrevLabel) ! 471: npPrevLabel->npNext = npLabel->npNext; ! 472: else ! 473: *pplHead = npLabel->npNext; ! 474: ! 475: /* ! 476: * Is this a label that is NOT in the include file? ! 477: * If so, just toss it away. ! 478: */ ! 479: if (npLabel->fpos == FPOS_MAX) { ! 480: MyFree(npLabel->pszLabel); ! 481: MyFree(npLabel); ! 482: } ! 483: /* ! 484: * Otherwise, it must be added to the deleted list. ! 485: */ ! 486: else { ! 487: /* ! 488: * Search for where the label should be inserted ! 489: * based on its fpos. ! 490: */ ! 491: npPrevLabel = NULL; ! 492: for (npDelLabel = *pplDelHead; npDelLabel; ! 493: npDelLabel = npDelLabel->npNext) { ! 494: if (npDelLabel->fpos > npLabel->fpos) ! 495: break; ! 496: ! 497: npPrevLabel = npDelLabel; ! 498: } ! 499: ! 500: /* ! 501: * If this is the first label in the deleted list, or ! 502: * if the first label had a greater fpos than the new ! 503: * label, insert the new label at the head of the list. ! 504: */ ! 505: if (!npPrevLabel) { ! 506: npLabel->npNext = *pplDelHead; ! 507: *pplDelHead = npLabel; ! 508: } ! 509: /* ! 510: * Otherwise, insert it either in the middle of the ! 511: * list or at the end. ! 512: */ ! 513: else { ! 514: npLabel->npNext = npPrevLabel->npNext; ! 515: npPrevLabel->npNext = npLabel; ! 516: } ! 517: } ! 518: ! 519: break; ! 520: } ! 521: ! 522: npPrevLabel = npLabel; ! 523: } ! 524: } ! 525: ! 526: ! 527: ! 528: /**************************************************************************** ! 529: * IsSymbol ! 530: * ! 531: * This routine returns TRUE if the given string is a valid "C" or "RC" ! 532: * identifier. ! 533: * ! 534: * Valid is: First char is a letter or '_'. ! 535: * ! 536: ****************************************************************************/ ! 537: ! 538: BOOL IsSymbol( ! 539: LPTSTR pszSym) ! 540: { ! 541: register TCHAR ch = *pszSym; ! 542: ! 543: return ((ch >= CHAR_CAP_A && ch <= CHAR_CAP_Z) || ! 544: (ch >= CHAR_A && ch <= CHAR_Z) || ! 545: (ch == CHAR_UNDERLINE)); ! 546: } ! 547: ! 548: ! 549: ! 550: /************************************************************************ ! 551: * IDToLabel ! 552: * ! 553: * This function finds the label with the given id. ! 554: * The first LABEL in the list with the given id will be found. ! 555: * The label will be put in pchLabel. ! 556: * If the id was not found then the id is converted to an ascii ! 557: * representation and put in pchLabel. This ascii representation ! 558: * will be in hex notation if hex mode is in effect (unless fHexOK ! 559: * is FALSE). ! 560: * ! 561: * This function special cases the IDOK and IDCANCEL id values. ! 562: * If there happens to be a label in the include file for these values ! 563: * then that label will be returned, but if not, either "IDOK" or ! 564: * "IDCANCEL" will be returned. ! 565: * ! 566: * Arguments: ! 567: * LPTSTR pchLabel - Where to put the label. ! 568: * INT id - The id of the label to find or match. ! 569: * BOOL fHexOK - TRUE if hex representations of the id are allowed. ! 570: * ! 571: * ! 572: ************************************************************************/ ! 573: ! 574: VOID IDToLabel( ! 575: LPTSTR pchLabel, ! 576: INT id, ! 577: BOOL fHexOK) ! 578: { ! 579: NPLABEL npLabel; ! 580: ! 581: npLabel = FindID(id, plInclude); ! 582: ! 583: if (npLabel) { ! 584: lstrcpy(pchLabel, npLabel->pszLabel); ! 585: } ! 586: else { ! 587: if (id == IDOK && !FindLabel(ids(IDS_IDOK), plInclude)) { ! 588: lstrcpy(pchLabel, ids(IDS_IDOK)); ! 589: } ! 590: else if (id == IDCANCEL && !FindLabel(ids(IDS_IDCANCEL), plInclude)) { ! 591: lstrcpy(pchLabel, ids(IDS_IDCANCEL)); ! 592: } ! 593: else { ! 594: if (fHexOK) ! 595: Myitoa(id, pchLabel); ! 596: else ! 597: itoaw(id, pchLabel, 10); ! 598: } ! 599: } ! 600: } ! 601: ! 602: ! 603: ! 604: /************************************************************************ ! 605: * LabelToID ! 606: * ! 607: * This function converts a label string to its associated id value. ! 608: * It first checks the labels in the current include file for a ! 609: * match. If it is not found, it then checks for some special values, ! 610: * like "IDOK", "IDCANCEL" and "(Unused)". ! 611: * ! 612: * The return value will be TRUE of the label (symbol) was found, or ! 613: * FALSE if it was not. ! 614: * ! 615: * Arguments: ! 616: * LPTSTR pszLabel - The symbol to search for. ! 617: * PINT pID - Where to return the associated id, if found. ! 618: * ! 619: ************************************************************************/ ! 620: ! 621: BOOL LabelToID( ! 622: LPTSTR pszLabel, ! 623: PINT pID) ! 624: { ! 625: INT id; ! 626: NPLABEL npLabel; ! 627: ! 628: /* ! 629: * Is it an existing label? ! 630: */ ! 631: if (npLabel = FindLabel(pszLabel, plInclude)) { ! 632: id = npLabel->id; ! 633: } ! 634: /* ! 635: * Is it the "unused" symbol? ! 636: */ ! 637: else if (lstrcmp(pszLabel, ids(IDS_UNUSED)) == 0) { ! 638: id = IDUNUSED; ! 639: } ! 640: /* ! 641: * How about the special IDOK entry? ! 642: */ ! 643: else if (lstrcmp(pszLabel, ids(IDS_IDOK)) == 0) { ! 644: id = IDOK; ! 645: } ! 646: /* ! 647: * How about the special IDCANCEL entry? ! 648: */ ! 649: else if (lstrcmp(pszLabel, ids(IDS_IDCANCEL)) == 0) { ! 650: id = IDCANCEL; ! 651: } ! 652: else { ! 653: return FALSE; ! 654: } ! 655: ! 656: *pID = id; ! 657: return TRUE; ! 658: } ! 659: ! 660: ! 661: ! 662: /**************************************************************************** ! 663: * FreeLabels ! 664: * ! 665: * This function frees the labels in the label list pointed to by ! 666: * nppLabels, including the strings. When it is done, the label ! 667: * list head is set to NULL. ! 668: * ! 669: ****************************************************************************/ ! 670: ! 671: VOID FreeLabels( ! 672: NPLABEL *nppLabels) ! 673: { ! 674: register NPLABEL npl; ! 675: register NPLABEL nplTemp; ! 676: ! 677: npl = *nppLabels; ! 678: ! 679: while (npl) { ! 680: MyFree(npl->pszLabel); ! 681: ! 682: nplTemp = npl->npNext; ! 683: ! 684: MyFree(npl); ! 685: npl = nplTemp; ! 686: } ! 687: ! 688: *nppLabels = NULL; ! 689: } ! 690: ! 691: ! 692:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.