The MinGW.OSDN Installation Manager Tool
リビジョン | 1c523d48fbc447f6c81b46afcf962dabb5816f74 (tree) |
---|---|
日時 | 2020-06-24 02:01:47 |
作者 | Keith Marshall <keith@user...> |
コミッター | Keith Marshall |
Eliminate invalid comparisons of "this" with nullptr.
@@ -1,3 +1,73 @@ | ||
1 | +2020-06-23 Keith Marshall <keith@users.osdn.me> | |
2 | + | |
3 | + Eliminate invalid comparisons of "this" with nullptr. | |
4 | + | |
5 | + C++ forbids calling any non-static class member function through | |
6 | + a null pointer, but makes it impossible to verify, within any such | |
7 | + function; the result of comparing the "this" pointer with nullptr | |
8 | + is deemed to be undefined behaviour. | |
9 | + | |
10 | + * src/climain.cpp (pkgActionItem::GetScheduledSourceArchives) | |
11 | + [this != NULL]: Do not test; execute dependent code unconditionally. | |
12 | + | |
13 | + * src/dllhook.cpp (pkgXmlNodeStack::pop) [this == NULL]: Remove | |
14 | + invalid comparison; condition should never arise, at point of call. | |
15 | + (pkgSetupAction::UpdateDatabase) [this != NULL]: Relocate test... | |
16 | + (update_database) [setup == NULL]: ...to here; do not update. | |
17 | + | |
18 | + * src/pkgbase.h (pkgXmlNode::GetName, pkgXmlNode::GetParent) | |
19 | + (pkgXmlNode::GetChildren, pkgXmlNode::GetNext, pkgXmlNode::GetPropVal) | |
20 | + (pkgXmlNode::GetDocumentRoot, pkgXmlNode::IsElementOfType) | |
21 | + (pkgXmlNode::AddChild, pkgXmlNode::DeleteChild): Do not implement... | |
22 | + [this ? result : fallback]: ...any such checks; the behaviour will be | |
23 | + undefined, and the "fallback" outcome can never be achieved; simply | |
24 | + return the "result" outcome unconditionally. | |
25 | + (pkgActionItem::HasAttribute, pkgActionItem::SelectPackage) | |
26 | + [this != NULL]: Cannot verify this; return result unconditionally. | |
27 | + (pkgActionItem::Selection) [this == NULL]: Test is invalid; remove it. | |
28 | + (pkgActionItem::CancelScheduledAction): Change return type to void. | |
29 | + (pkgXmlDocument::ExecuteActions) [actions == NULL]: Do not execute. | |
30 | + | |
31 | + * src/pkgdata.cpp (pkgActionItem::EnumeratePendingActions) | |
32 | + [this != NULL]: Cannot verify; relocate test... | |
33 | + (AppWindowMaker::UpdatePackageMenuBindings): ...to here; verify... | |
34 | + [pkgData->Schedule() != NULL]: ...this, before attempting to invoke... | |
35 | + (pkgData->Schedule()->EnumeratePendingActions): ...this. | |
36 | + (AppWindowMaker::UnmarkSelectedPackage): Likewise, verify both... | |
37 | + [pkgData->Schedule() != NULL]: ...this, and then... | |
38 | + [pkgData->Schedule()->GetReference() != NULL]: ...this, before... | |
39 | + (pkgData->Schedule()->GetReference()->CancelScheduledAction): ...this. | |
40 | + (pkgActionItem::CancelScheduledAction) [this != NULL]: Remove test; it | |
41 | + results in undefined behaviour, and in any case, has become redundant. | |
42 | + Change return type to void; set flags, but otherwise return nothing. | |
43 | + | |
44 | + * src/pkgdeps.cpp (pkgActionItem::GetReference) [this != NULL]: Remove | |
45 | + invalid test; it has been made redundant, by testing at point of call. | |
46 | + (pkgXmlDocument::Schedule) [this != NULL]: Likewise; additionally... | |
47 | + [component != NULL]: ...verify this, before attempting to test... | |
48 | + [component->FindNextAssociate() != NULL]: ...this. | |
49 | + | |
50 | + * src/pkgexec.cpp (pkgActionItem::Execute) [this != NULL] | |
51 | + (pkgActionItem::Append, pkgActionItem::Insert) [this == NULL]: Remove | |
52 | + invalid tests; delegate onus for validation to respective call sites. | |
53 | + (pkgXmlDocument::Schedule): Validate referring pointers as required. | |
54 | + | |
55 | + * src/guiexec.cpp (AppWindowMaker::LoadPackageData): Confirm that... | |
56 | + [pkgXmlDocument() != NULL]: ...is true, before evaluation of... | |
57 | + [pkgXmlDocument()->IsOK()]: ...this status check. | |
58 | + (AppWindowMaker::ConfirmActionRequest): Likewise, confirm that... | |
59 | + [pkgData->Schedule() != NULL]: ...is true, before evaluation of... | |
60 | + [pkgData->Schedule()->EnumeratePendingActions() > 0]: ...this. | |
61 | + | |
62 | + * src/pkgunst.cpp (pkgManifest::GetSysRootReference) [this != NULL] | |
63 | + * src/pkginst.cpp (pkgManifest::AddEntry) [this != NULL]: Remove test; | |
64 | + assume that its outcome is always effectively true, requiring callers | |
65 | + to guarantee that this is so. | |
66 | + | |
67 | + * src/setup.cpp (pkgSetupAction::HasAttribute) [this != NULL]: Remove | |
68 | + invalid test, assuming true; relocate inline implementation... | |
69 | + * src/setup.h: ...to here. | |
70 | + | |
1 | 71 | 2020-06-22 Keith Marshall <keith@users.osdn.me> |
2 | 72 | |
3 | 73 | Do not dereference nullptr in package directory trees. |
@@ -403,27 +403,21 @@ void pkgActionItem::GetScheduledSourceArchives( unsigned long category ) | ||
403 | 403 | * for the case when the "--all-related" option is in effect for a |
404 | 404 | * "source" or "licence" request. |
405 | 405 | */ |
406 | - if( this != NULL ) | |
406 | + pkgActionItem *scheduled = this; | |
407 | + while( scheduled->prev != NULL ) scheduled = scheduled->prev; | |
408 | + | |
409 | + /* For each scheduled list entry... | |
410 | + */ | |
411 | + while( scheduled != NULL ) | |
407 | 412 | { |
408 | - /* The package list is NOT empty; ensure that we begin with | |
409 | - * a reference to its first entry. | |
413 | + /* ...process the "source" or "licence" request, as appropriate, | |
414 | + * in respect of the associated package... | |
410 | 415 | */ |
411 | - pkgActionItem *scheduled = this; | |
412 | - while( scheduled->prev != NULL ) scheduled = scheduled->prev; | |
413 | - | |
414 | - /* For each scheduled list entry... | |
416 | + scheduled->GetSourceArchive( scheduled->Selection(), category ); | |
417 | + /* | |
418 | + * ...then move on to the next entry, if any. | |
415 | 419 | */ |
416 | - while( scheduled != NULL ) | |
417 | - { | |
418 | - /* ...process the "source" or "licence" request, as appropriate, | |
419 | - * in respect of the associated package... | |
420 | - */ | |
421 | - scheduled->GetSourceArchive( scheduled->Selection(), category ); | |
422 | - /* | |
423 | - * ...then move on to the next entry, if any. | |
424 | - */ | |
425 | - scheduled = scheduled->next; | |
426 | - } | |
420 | + scheduled = scheduled->next; | |
427 | 421 | } |
428 | 422 | } |
429 | 423 |
@@ -172,10 +172,11 @@ void update_database( pkgSetupAction *setup ) | ||
172 | 172 | /* Having successfully loaded the restricted profile, load the |
173 | 173 | * map of the installation it specifies, and update it to reflect |
174 | 174 | * the installation of the mingw-get packages we are currently |
175 | - * installing. | |
175 | + * installing; (note that we must take care not to attempt to | |
176 | + * update the database, if passed a NULL setup object). | |
176 | 177 | */ |
177 | 178 | dbase.LoadSystemMap(); |
178 | - setup->UpdateDatabase( dbase ); | |
179 | + if( setup != NULL ) setup->UpdateDatabase( dbase ); | |
179 | 180 | } |
180 | 181 | /* We're finished with the setup.xml profile; delete it, and free |
181 | 182 | * the memory which xmlfile() allocated to store its path name. |
@@ -351,16 +352,12 @@ inline pkgXmlNodeStack *pkgXmlNodeStack::pop( pkgXmlNode **node ) | ||
351 | 352 | /* Method to pop a pkgXmlNode from the top of the stack, while |
352 | 353 | * saving a reference pointer for it, and returning the updated |
353 | 354 | * stack pointer. |
354 | - */ | |
355 | - if( this == NULL ) | |
356 | - /* | |
357 | - * The stack is empty; there's nothing more to do! | |
358 | - */ | |
359 | - return NULL; | |
360 | - | |
361 | - /* When the stack is NOT empty, capture the reference pointer | |
362 | - * for the SECOND entry (if any), store the top entry, delete | |
363 | - * its stack frame, and return the new stack pointer. | |
355 | + * | |
356 | + * This should never be called when the stack is empty; (this | |
357 | + * must be checked at the call site). When the stack is known | |
358 | + * to NOT be empty, capture the reference pointer for the SECOND | |
359 | + * entry (if any), store the top entry, delete its stack frame, | |
360 | + * and return the new stack pointer. | |
364 | 361 | */ |
365 | 362 | pkgXmlNodeStack *rtn = next; *node = entry; |
366 | 363 | delete this; return rtn; |
@@ -371,169 +368,168 @@ void pkgSetupAction::UpdateDatabase( pkgXmlDocument &dbase ) | ||
371 | 368 | /* Method to ensure that the mingw-get package components which are |
372 | 369 | * specified in the setup actions list are recorded as "installed", in |
373 | 370 | * the installation database manifests. |
371 | + * | |
372 | + * This method should NEVER be invoked on an empty setup actions list; | |
373 | + * (this must be verified at the call site). When it is known that the | |
374 | + * list is NOT empty, we must ensure that we commence processing from | |
375 | + * its first entry... | |
374 | 376 | */ |
375 | - if( this != NULL ) | |
377 | + pkgSetupAction *current = this; | |
378 | + while( current->prev != NULL ) current = current->prev; | |
379 | + dmh_notify( DMH_INFO, "%s: updating installation database\n", setup_key ); | |
380 | + while( current != NULL ) | |
376 | 381 | { |
377 | - /* The setup actions list is not empty; ensure that we commence | |
378 | - * processing from its first entry... | |
382 | + /* ...then processing all entries sequentially, in turn, | |
383 | + * parse the package tarname specified in the current action | |
384 | + * entry, to identify the associated package name, component | |
385 | + * class and subsystem name. | |
379 | 386 | */ |
380 | - pkgSetupAction *current = this; | |
381 | - while( current->prev != NULL ) current = current->prev; | |
382 | - dmh_notify( DMH_INFO, "%s: updating installation database\n", setup_key ); | |
383 | - while( current != NULL ) | |
384 | - { | |
385 | - /* ...then processing all entries sequentially, in turn, | |
386 | - * parse the package tarname specified in the current action | |
387 | - * entry, to identify the associated package name, component | |
388 | - * class and subsystem name. | |
387 | + const char *name_fmt = "%s-%s"; | |
388 | + pkgSpecs lookup( current->package_name ); | |
389 | + char lookup_name[1 + strlen( current->package_name )]; | |
390 | + const char *component = lookup.GetComponentClass(); | |
391 | + const char *subsystem = lookup.GetSubSystemName(); | |
392 | + if( (component != NULL) && *component ) | |
393 | + /* | |
394 | + * The package name is qualified by an explicit component | |
395 | + * name; form the composite package name string. | |
389 | 396 | */ |
390 | - const char *name_fmt = "%s-%s"; | |
391 | - pkgSpecs lookup( current->package_name ); | |
392 | - char lookup_name[1 + strlen( current->package_name )]; | |
393 | - const char *component = lookup.GetComponentClass(); | |
394 | - const char *subsystem = lookup.GetSubSystemName(); | |
395 | - if( (component != NULL) && *component ) | |
396 | - /* | |
397 | - * The package name is qualified by an explicit component | |
398 | - * name; form the composite package name string. | |
399 | - */ | |
400 | - sprintf( lookup_name, name_fmt, lookup.GetPackageName(), component ); | |
401 | - else | |
402 | - /* There is no explicit component name; just save a copy | |
403 | - * of the unqualified package name. | |
404 | - */ | |
405 | - strcpy( lookup_name, lookup.GetPackageName() ); | |
397 | + sprintf( lookup_name, name_fmt, lookup.GetPackageName(), component ); | |
398 | + else | |
399 | + /* There is no explicit component name; just save a copy | |
400 | + * of the unqualified package name. | |
401 | + */ | |
402 | + strcpy( lookup_name, lookup.GetPackageName() ); | |
406 | 403 | |
407 | - /* Locate the corresponding component package entry, if any, | |
408 | - * in the package catalogue. | |
404 | + /* Locate the corresponding component package entry, if any, | |
405 | + * in the package catalogue. | |
406 | + */ | |
407 | + if( dbase.FindPackageByName( lookup_name, subsystem ) != NULL ) | |
408 | + { | |
409 | + /* Lookup was successful; now search the installation records, | |
410 | + * if any, for any matching package entry. | |
409 | 411 | */ |
410 | - if( dbase.FindPackageByName( lookup_name, subsystem ) != NULL ) | |
412 | + pkgXmlNodeStack *stack = NULL; | |
413 | + pkgXmlNode *sysroot = dbase.GetRoot()->GetSysRoot( subsystem ); | |
414 | + pkgXmlNode *installed = sysroot->FindFirstAssociate( installed_key ); | |
415 | + while( installed != NULL ) | |
411 | 416 | { |
412 | - /* Lookup was successful; now search the installation records, | |
413 | - * if any, for any matching package entry. | |
417 | + /* There is at least one installation record; walk the chain | |
418 | + * of all such records... | |
414 | 419 | */ |
415 | - pkgXmlNodeStack *stack = NULL; | |
416 | - pkgXmlNode *sysroot = dbase.GetRoot()->GetSysRoot( subsystem ); | |
417 | - pkgXmlNode *installed = sysroot->FindFirstAssociate( installed_key ); | |
418 | - while( installed != NULL ) | |
420 | + const char *tarname = installed->GetPropVal( tarname_key, NULL ); | |
421 | + if( tarname != NULL ) | |
419 | 422 | { |
420 | - /* There is at least one installation record; walk the chain | |
421 | - * of all such records... | |
423 | + /* ...extracting package and component names from the tarname | |
424 | + * specification within each... | |
422 | 425 | */ |
423 | - const char *tarname = installed->GetPropVal( tarname_key, NULL ); | |
424 | - if( tarname != NULL ) | |
425 | - { | |
426 | - /* ...extracting package and component names from the tarname | |
427 | - * specification within each... | |
426 | + pkgSpecs ref( tarname ); | |
427 | + char ref_name[1 + strlen( tarname )]; | |
428 | + if( ((component = ref.GetComponentClass()) != NULL) && *component ) | |
429 | + /* | |
430 | + * ...once again forming the composite name, when applicable... | |
428 | 431 | */ |
429 | - pkgSpecs ref( tarname ); | |
430 | - char ref_name[1 + strlen( tarname )]; | |
431 | - if( ((component = ref.GetComponentClass()) != NULL) && *component ) | |
432 | - /* | |
433 | - * ...once again forming the composite name, when applicable... | |
434 | - */ | |
435 | - sprintf( ref_name, name_fmt, ref.GetPackageName(), component ); | |
436 | - else | |
437 | - /* ...or simply storing the unqualified package name if not. | |
438 | - */ | |
439 | - strcpy( ref_name, ref.GetPackageName() ); | |
440 | - | |
441 | - /* Check for a match between the installed package name, and | |
442 | - * the name we wish to record as newly installed... | |
432 | + sprintf( ref_name, name_fmt, ref.GetPackageName(), component ); | |
433 | + else | |
434 | + /* ...or simply storing the unqualified package name if not. | |
443 | 435 | */ |
444 | - if( (strcasecmp( ref_name, lookup_name ) == 0) | |
445 | - && (strcasecmp( tarname, current->package_name ) != 0) ) | |
446 | - /* | |
447 | - * ...pushing the current installation record on to the | |
448 | - * update stack, in case of a match... | |
449 | - */ | |
450 | - stack = stack->push( installed ); | |
451 | - } | |
452 | - /* ...then move on to the next installation record, if any. | |
436 | + strcpy( ref_name, ref.GetPackageName() ); | |
437 | + | |
438 | + /* Check for a match between the installed package name, and | |
439 | + * the name we wish to record as newly installed... | |
453 | 440 | */ |
454 | - installed = installed->FindNextAssociate( installed_key ); | |
441 | + if( (strcasecmp( ref_name, lookup_name ) == 0) | |
442 | + && (strcasecmp( tarname, current->package_name ) != 0) ) | |
443 | + /* | |
444 | + * ...pushing the current installation record on to the | |
445 | + * update stack, in case of a match... | |
446 | + */ | |
447 | + stack = stack->push( installed ); | |
455 | 448 | } |
449 | + /* ...then move on to the next installation record, if any. | |
450 | + */ | |
451 | + installed = installed->FindNextAssociate( installed_key ); | |
452 | + } | |
456 | 453 | |
457 | - /* Create a temporary package "release" descriptor... | |
454 | + /* Create a temporary package "release" descriptor... | |
455 | + */ | |
456 | + pkgXmlNode *reference_hook = new pkgXmlNode( release_key ); | |
457 | + if( reference_hook != NULL ) | |
458 | + { | |
459 | + /* ...which we may conveniently attach to the root | |
460 | + * of the XML catalogue tree. | |
458 | 461 | */ |
459 | - pkgXmlNode *reference_hook = new pkgXmlNode( release_key ); | |
460 | - if( reference_hook != NULL ) | |
461 | - { | |
462 | - /* ...which we may conveniently attach to the root | |
463 | - * of the XML catalogue tree. | |
464 | - */ | |
465 | - dbase.GetRoot()->AddChild( reference_hook ); | |
466 | - reference_hook->SetAttribute( tarname_key, current->package_name ); | |
462 | + dbase.GetRoot()->AddChild( reference_hook ); | |
463 | + reference_hook->SetAttribute( tarname_key, current->package_name ); | |
467 | 464 | |
468 | - /* Run the installer... | |
465 | + /* Run the installer... | |
466 | + */ | |
467 | + pkgTarArchiveInstaller registration_server( reference_hook ); | |
468 | + if( registration_server.IsOk() ) | |
469 | + { | |
470 | + /* ...reporting the installation as a "registration" of | |
471 | + * the specified package, but... | |
469 | 472 | */ |
470 | - pkgTarArchiveInstaller registration_server( reference_hook ); | |
471 | - if( registration_server.IsOk() ) | |
472 | - { | |
473 | - /* ...reporting the installation as a "registration" of | |
474 | - * the specified package, but... | |
475 | - */ | |
476 | - dmh_notify( DMH_INFO, "%s: register %s\n", | |
477 | - setup_key, current->package_name | |
478 | - ); | |
479 | - /* ...noting that the package content has already been | |
480 | - * "installed" by the setup tool, but without recording | |
481 | - * any details, we run this without physically extracting | |
482 | - * any files, to capture the side effect of compiling an | |
483 | - * installation record. | |
484 | - */ | |
485 | - registration_server.SaveExtractedFiles( false ); | |
486 | - registration_server.Process(); | |
487 | - } | |
488 | - /* With the installation record safely compiled, we may | |
489 | - * discard the temporary "release" descriptor from which | |
490 | - * we compiled it. | |
473 | + dmh_notify( DMH_INFO, "%s: register %s\n", | |
474 | + setup_key, current->package_name | |
475 | + ); | |
476 | + /* ...noting that the package content has already been | |
477 | + * "installed" by the setup tool, but without recording | |
478 | + * any details, we run this without physically extracting | |
479 | + * any files, to capture the side effect of compiling an | |
480 | + * installation record. | |
491 | 481 | */ |
492 | - dbase.GetRoot()->DeleteChild( reference_hook ); | |
482 | + registration_server.SaveExtractedFiles( false ); | |
483 | + registration_server.Process(); | |
493 | 484 | } |
494 | - | |
495 | - /* When the update stack, constructed above, is not empty... | |
485 | + /* With the installation record safely compiled, we may | |
486 | + * discard the temporary "release" descriptor from which | |
487 | + * we compiled it. | |
496 | 488 | */ |
497 | - if( stack != NULL ) | |
498 | - { while( stack != NULL ) | |
489 | + dbase.GetRoot()->DeleteChild( reference_hook ); | |
490 | + } | |
491 | + | |
492 | + /* When the update stack, constructed above, is not empty... | |
493 | + */ | |
494 | + if( stack != NULL ) | |
495 | + { while( stack != NULL ) | |
496 | + { | |
497 | + /* ...pop each installation record, which is to be updated, | |
498 | + * off the update stack, in turn... | |
499 | + */ | |
500 | + const char *tarname; | |
501 | + pkgXmlNode *installed; | |
502 | + stack = stack->pop( &installed ); | |
503 | + if( (tarname = installed->GetPropVal( tarname_key, NULL )) != NULL ) | |
499 | 504 | { |
500 | - /* ...pop each installation record, which is to be updated, | |
501 | - * off the update stack, in turn... | |
505 | + /* ...identify its associated installed files manifest, and | |
506 | + * disassociate it from the sysroot of the current installation; | |
507 | + * (note that this automatically deletes the manifest itself, if | |
508 | + * it is associated with no other sysroots). | |
502 | 509 | */ |
503 | - const char *tarname; | |
504 | - pkgXmlNode *installed; | |
505 | - stack = stack->pop( &installed ); | |
506 | - if( (tarname = installed->GetPropVal( tarname_key, NULL )) != NULL ) | |
507 | - { | |
508 | - /* ...identify its associated installed files manifest, and | |
509 | - * disassociate it from the sysroot of the current installation; | |
510 | - * (note that this automatically deletes the manifest itself, if | |
511 | - * it is associated with no other sysroots). | |
512 | - */ | |
513 | - pkgManifest inventory( package_key, tarname ); | |
514 | - inventory.DetachSysRoot( sysroot->GetPropVal( id_key, subsystem ) ); | |
515 | - } | |
516 | - /* Delete the installation record from the current sysroot... | |
517 | - */ | |
518 | - sysroot->DeleteChild( installed ); | |
510 | + pkgManifest inventory( package_key, tarname ); | |
511 | + inventory.DetachSysRoot( sysroot->GetPropVal( id_key, subsystem ) ); | |
519 | 512 | } |
520 | - /* ...and mark the sysroot record as "modified", as a result of | |
521 | - * all preceding updates. | |
513 | + /* Delete the installation record from the current sysroot... | |
522 | 514 | */ |
523 | - sysroot->SetAttribute( modified_key, value_yes ); | |
515 | + sysroot->DeleteChild( installed ); | |
524 | 516 | } |
517 | + /* ...and mark the sysroot record as "modified", as a result of | |
518 | + * all preceding updates. | |
519 | + */ | |
520 | + sysroot->SetAttribute( modified_key, value_yes ); | |
525 | 521 | } |
526 | - | |
527 | - /* Repeat for all packages with an associated setup action... | |
528 | - */ | |
529 | - current = current->next; | |
530 | 522 | } |
531 | - /* ...and finally, report completion of all database updates, while also | |
532 | - * committing all recorded changes to disk storage. | |
523 | + | |
524 | + /* Repeat for all packages with an associated setup action... | |
533 | 525 | */ |
534 | - dmh_notify( DMH_INFO, "%s: installation database updated\n", setup_key ); | |
535 | - dbase.UpdateSystemMap(); | |
526 | + current = current->next; | |
536 | 527 | } |
528 | + /* ...and finally, report completion of all database updates, while also | |
529 | + * committing all recorded changes to disk storage. | |
530 | + */ | |
531 | + dmh_notify( DMH_INFO, "%s: installation database updated\n", setup_key ); | |
532 | + dbase.UpdateSystemMap(); | |
537 | 533 | } |
538 | 534 | |
539 | 535 | /* $RCSfile$: end of file */ |
@@ -3,8 +3,8 @@ | ||
3 | 3 | * |
4 | 4 | * $Id$ |
5 | 5 | * |
6 | - * Written by Keith Marshall <keithmarshall@users.sourceforge.net> | |
7 | - * Copyright (C) 2012, 2013, MinGW.org Project | |
6 | + * Written by Keith Marshall <keith@users.osdn.me> | |
7 | + * Copyright (C) 2012, 2013, 2020, MinGW.org Project | |
8 | 8 | * |
9 | 9 | * |
10 | 10 | * Implementation of XML data loading services for the mingw-get GUI. |
@@ -141,10 +141,10 @@ void AppWindowMaker::LoadPackageData( bool force_update ) | ||
141 | 141 | */ |
142 | 142 | delete pkgData; |
143 | 143 | } |
144 | - | |
145 | 144 | /* Commence loading... |
146 | 145 | */ |
147 | - if( ! (pkgData = new pkgXmlDocument( dfile ))->IsOk() ) | |
146 | + pkgData = new pkgXmlDocument( dfile ); | |
147 | + if( (pkgData == NULL) || ! pkgData->IsOk() ) | |
148 | 148 | /* |
149 | 149 | * ...bailing out on failure to access the initial file. |
150 | 150 | */ |
@@ -705,7 +705,8 @@ bool AppWindowMaker::ConfirmActionRequest( const char *desc ) | ||
705 | 705 | * dialogue procedure when appropriate, or simply allowing the |
706 | 706 | * action to proceed, otherwise. |
707 | 707 | */ |
708 | - return (pkgData->Schedule()->EnumeratePendingActions() > 0) | |
708 | + pkgActionItem *pending = pkgData->Schedule(); | |
709 | + return (pending && pending->EnumeratePendingActions() > 0) | |
709 | 710 | ? DialogBox( AppInstance, MAKEINTRESOURCE( IDD_CONFIRMATION ), |
710 | 711 | AppWindow, ConfirmActionDialogue |
711 | 712 | ) == IDOK |
@@ -4,8 +4,8 @@ | ||
4 | 4 | * |
5 | 5 | * $Id$ |
6 | 6 | * |
7 | - * Written by Keith Marshall <keithmarshall@users.sourceforge.net> | |
8 | - * Copyright (C) 2009-2013, MinGW.org Project | |
7 | + * Written by Keith Marshall <keith@users.osdn.me> | |
8 | + * Copyright (C) 2009-2013, 2020, MinGW.org Project | |
9 | 9 | * |
10 | 10 | * |
11 | 11 | * Public interface for the package directory management routines; |
@@ -74,24 +74,20 @@ class pkgXmlNode : public TiXmlElement | ||
74 | 74 | inline pkgXmlNode( const pkgXmlNode& src ):TiXmlElement( src ){} |
75 | 75 | |
76 | 76 | /* Accessors... |
77 | - * | |
78 | - * Note that tinyxml is generally careless about checking for | |
79 | - * possible dereferencing of NULL pointers; thus, many of these | |
80 | - * wrappers include appropriate checks, to prevent this. | |
81 | 77 | */ |
82 | 78 | inline const char* GetName() |
83 | 79 | { |
84 | 80 | /* Retrieve the identifying name of the XML tag; |
85 | 81 | * tinyxml calls this the element "value"... |
86 | 82 | */ |
87 | - return this ? Value() : NULL; | |
83 | + return Value(); | |
88 | 84 | } |
89 | 85 | inline pkgXmlNode* GetParent() |
90 | 86 | { |
91 | 87 | /* wxXmlNode provides this equivalant of tinyxml's |
92 | 88 | * Parent() method. |
93 | 89 | */ |
94 | - return this ? (pkgXmlNode*)(Parent()) : NULL; | |
90 | + return (pkgXmlNode*)(Parent()); | |
95 | 91 | } |
96 | 92 | inline pkgXmlNode* GetChildren() |
97 | 93 | { |
@@ -99,7 +95,7 @@ class pkgXmlNode : public TiXmlElement | ||
99 | 95 | * the children of an element; it is equivalent to the |
100 | 96 | * FirstChild() method in tinyxml's arsenal. |
101 | 97 | */ |
102 | - return this ? (pkgXmlNode*)(FirstChild()) : NULL; | |
98 | + return (pkgXmlNode*)(FirstChild()); | |
103 | 99 | } |
104 | 100 | inline pkgXmlNode* GetNext() |
105 | 101 | { |
@@ -107,7 +103,7 @@ class pkgXmlNode : public TiXmlElement | ||
107 | 103 | * of an element, after the first found by GetChildren(); |
108 | 104 | * it is equivalent to tinyxml's NextSibling(). |
109 | 105 | */ |
110 | - return this ? (pkgXmlNode*)(NextSibling()) : NULL; | |
106 | + return (pkgXmlNode*)(NextSibling()); | |
111 | 107 | } |
112 | 108 | inline const char* GetPropVal( const char* name, const char* subst ) |
113 | 109 | { |
@@ -115,15 +111,16 @@ class pkgXmlNode : public TiXmlElement | ||
115 | 111 | * (which substitutes default "subst" text for an omitted property), |
116 | 112 | * but it may be trivially emulated, using the Attribute() method. |
117 | 113 | */ |
118 | - const char* retval = this ? Attribute( name ) : subst; | |
119 | - return retval ? retval : subst; | |
114 | + const char *retval; | |
115 | + if( (retval = Attribute( name )) == NULL ) return subst; | |
116 | + return retval; | |
120 | 117 | } |
121 | 118 | inline pkgXmlNode* AddChild( TiXmlNode *child ) |
122 | 119 | { |
123 | 120 | /* This is wxXmlNode's method for adding a child node, it is |
124 | 121 | * equivalent to tinyxml's LinkEndChild() method. |
125 | 122 | */ |
126 | - return this ? (pkgXmlNode*)(LinkEndChild( child )) : NULL; | |
123 | + return (pkgXmlNode*)(LinkEndChild( child )); | |
127 | 124 | } |
128 | 125 | inline bool DeleteChild( pkgXmlNode *child ) |
129 | 126 | { |
@@ -132,7 +129,7 @@ class pkgXmlNode : public TiXmlElement | ||
132 | 129 | * simply use the RemoveChild method here, where for wxXmlNode, we |
133 | 130 | * would use RemoveChild followed by `delete child'. |
134 | 131 | */ |
135 | - return this ? RemoveChild( child ) : false; | |
132 | + return RemoveChild( child ); | |
136 | 133 | } |
137 | 134 | |
138 | 135 | /* Additional methods specific to the application. |
@@ -141,14 +138,14 @@ class pkgXmlNode : public TiXmlElement | ||
141 | 138 | { |
142 | 139 | /* Convenience method to retrieve a pointer to the document root. |
143 | 140 | */ |
144 | - return this ? (pkgXmlNode*)(GetDocument()->RootElement()) : NULL; | |
141 | + return (pkgXmlNode*)(GetDocument()->RootElement()); | |
145 | 142 | } |
146 | 143 | inline bool IsElementOfType( const char* tagname ) |
147 | 144 | { |
148 | 145 | /* Confirm if the owner XML node represents a data element |
149 | 146 | * with the specified "tagname". |
150 | 147 | */ |
151 | - return this ? strcmp( GetName(), tagname ) == 0 : false; | |
148 | + return strcmp( GetName(), tagname ) == 0; | |
152 | 149 | } |
153 | 150 | |
154 | 151 | /* Methods to determine which packages should be displayed |
@@ -269,13 +266,13 @@ class pkgActionItem | ||
269 | 266 | unsigned long SetAuthorities( pkgActionItem* ); |
270 | 267 | inline unsigned long HasAttribute( unsigned long required ) |
271 | 268 | { |
272 | - return (this != NULL) ? flags & required : 0UL; | |
269 | + return flags & required; | |
273 | 270 | } |
274 | 271 | pkgActionItem* GetReference( pkgXmlNode* ); |
275 | 272 | pkgActionItem* GetReference( pkgActionItem& ); |
276 | 273 | pkgActionItem* Schedule( unsigned long, pkgActionItem& ); |
277 | 274 | inline pkgActionItem* SuppressRedundantUpgrades( void ); |
278 | - inline unsigned long CancelScheduledAction( void ); | |
275 | + inline void CancelScheduledAction( void ); | |
279 | 276 | inline void SetPrimary( pkgActionItem* ); |
280 | 277 | |
281 | 278 | /* Method to enumerate and identify pending changes, |
@@ -293,13 +290,13 @@ class pkgActionItem | ||
293 | 290 | { |
294 | 291 | /* Mark a package as the selection for a specified action. |
295 | 292 | */ |
296 | - if (this != NULL) selection[ opt ] = pkg; | |
293 | + selection[ opt ] = pkg; | |
297 | 294 | } |
298 | 295 | inline pkgXmlNode* Selection( int mode = to_install ) |
299 | 296 | { |
300 | 297 | /* Retrieve the package selection for a specified action. |
301 | 298 | */ |
302 | - return (this != NULL) ? selection[ mode ] : NULL; | |
299 | + return selection[ mode ]; | |
303 | 300 | } |
304 | 301 | void ConfirmInstallationStatus(); |
305 | 302 |
@@ -454,7 +451,7 @@ class pkgXmlDocument : public TiXmlDocument | ||
454 | 451 | |
455 | 452 | /* Method to execute a sequence of scheduled actions. |
456 | 453 | */ |
457 | - inline void ExecuteActions(){ actions->Execute(); } | |
454 | + inline void ExecuteActions(){ if( actions ) actions->Execute(); } | |
458 | 455 | |
459 | 456 | /* Method to clear the list of scheduled actions. |
460 | 457 | */ |
@@ -3,8 +3,8 @@ | ||
3 | 3 | * |
4 | 4 | * $Id$ |
5 | 5 | * |
6 | - * Written by Keith Marshall <keithmarshall@users.sourceforge.net> | |
7 | - * Copyright (C) 2012, 2013, MinGW.org Project | |
6 | + * Written by Keith Marshall <keith@users.osdn.me> | |
7 | + * Copyright (C) 2012, 2013, 2020, MinGW.org Project | |
8 | 8 | * |
9 | 9 | * |
10 | 10 | * Implementation of the classes and methods required to support the |
@@ -1085,10 +1085,9 @@ void AppWindowMaker::UpdatePackageMenuBindings() | ||
1085 | 1085 | * this is also a convenient point to consider activation of the |
1086 | 1086 | * "Apply Changes" capability. |
1087 | 1087 | */ |
1088 | - EnableMenuItem( menu, IDM_REPO_APPLY, | |
1089 | - (pkgData->Schedule()->EnumeratePendingActions() > 0) ? MF_ENABLED | |
1090 | - : MF_GRAYED | |
1091 | - ); | |
1088 | + pkgActionItem *pending = pkgData->Schedule(); | |
1089 | + unsigned long count = (pending != NULL) ? pending->EnumeratePendingActions() : 0UL; | |
1090 | + EnableMenuItem( menu, IDM_REPO_APPLY, (count > 0UL) ? MF_ENABLED : MF_GRAYED ); | |
1092 | 1091 | } |
1093 | 1092 | |
1094 | 1093 | inline void AppWindowMaker::MarkSchedule( pkgActionItem *pending_actions ) |
@@ -1191,11 +1190,11 @@ void AppWindowMaker::Schedule | ||
1191 | 1190 | } |
1192 | 1191 | } |
1193 | 1192 | |
1194 | -inline unsigned long pkgActionItem::CancelScheduledAction( void ) | |
1193 | +inline void pkgActionItem::CancelScheduledAction( void ) | |
1195 | 1194 | { |
1196 | 1195 | /* Helper method to mark a scheduled action as "cancelled". |
1197 | 1196 | */ |
1198 | - return (this != NULL) ? (flags &= ~ACTION_MASK) : 0UL; | |
1197 | + flags &= ~ACTION_MASK; | |
1199 | 1198 | } |
1200 | 1199 | |
1201 | 1200 | void AppWindowMaker::UnmarkSelectedPackage( void ) |
@@ -1223,7 +1222,9 @@ void AppWindowMaker::UnmarkSelectedPackage( void ) | ||
1223 | 1222 | * ...search the action schedule, for an action associated with |
1224 | 1223 | * this package, if any, and cancel it. |
1225 | 1224 | */ |
1226 | - pkgData->Schedule()->GetReference( pkg )->CancelScheduledAction(); | |
1225 | + pkgActionItem *pkgref = pkgData->Schedule(); | |
1226 | + if( (pkgref != NULL) && ((pkgref = pkgref->GetReference( pkg )) != NULL) ) | |
1227 | + pkgref->CancelScheduledAction(); | |
1227 | 1228 | |
1228 | 1229 | /* The scheduling state for packages shown in the list view |
1229 | 1230 | * may have changed, so refresh the icon associations and the |
@@ -1401,74 +1402,72 @@ unsigned long pkgActionItem::EnumeratePendingActions( int classified ) | ||
1401 | 1402 | * scheduled action list. |
1402 | 1403 | */ |
1403 | 1404 | unsigned long count = 0; |
1404 | - if( this != NULL ) | |
1405 | - { | |
1406 | - /* Regardless of the position of the 'this' pointer, | |
1407 | - * within the list of scheduled actions... | |
1405 | + | |
1406 | + /* Regardless of the position of the 'this' pointer, | |
1407 | + * within the list of scheduled actions... | |
1408 | + */ | |
1409 | + pkgActionItem *item = this; | |
1410 | + while( item->prev != NULL ) | |
1411 | + /* | |
1412 | + * ...we want to get a reference to the first | |
1413 | + * item in the list. | |
1408 | 1414 | */ |
1409 | - pkgActionItem *item = this; | |
1410 | - while( item->prev != NULL ) | |
1411 | - /* | |
1412 | - * ...we want to get a reference to the first | |
1413 | - * item in the list. | |
1414 | - */ | |
1415 | - item = item->prev; | |
1415 | + item = item->prev; | |
1416 | 1416 | |
1417 | - /* Now, working through the list... | |
1417 | + /* Now, working through the list... | |
1418 | + */ | |
1419 | + while( item != NULL ) | |
1420 | + { | |
1421 | + /* ...note items with any scheduled action... | |
1418 | 1422 | */ |
1419 | - while( item != NULL ) | |
1423 | + int action; | |
1424 | + if( (action = item->flags & ACTION_MASK) != 0 ) | |
1420 | 1425 | { |
1421 | - /* ...note items with any scheduled action... | |
1426 | + /* ...and, when one is found, (noting that ACTION_UPGRADE may | |
1427 | + * also be considered as a special case of ACTION_INSTALL)... | |
1422 | 1428 | */ |
1423 | - int action; | |
1424 | - if( (action = item->flags & ACTION_MASK) != 0 ) | |
1429 | + if( (action == classified) | |
1430 | + || ((action == ACTION_UPGRADE) && (classified == ACTION_INSTALL)) ) | |
1425 | 1431 | { |
1426 | - /* ...and, when one is found, (noting that ACTION_UPGRADE may | |
1427 | - * also be considered as a special case of ACTION_INSTALL)... | |
1432 | + /* ...and it matches the classification in which | |
1433 | + * we are interested, then we retrieve the tarname | |
1434 | + * for the related package... | |
1428 | 1435 | */ |
1429 | - if( (action == classified) | |
1430 | - || ((action == ACTION_UPGRADE) && (classified == ACTION_INSTALL)) ) | |
1436 | + pkgXmlNode *selected = (classified & ACTION_REMOVE) | |
1437 | + ? item->Selection( to_remove ) | |
1438 | + : item->Selection(); | |
1439 | + const char *notification = (selected != NULL) | |
1440 | + ? selected->GetPropVal( tarname_key, NULL ) | |
1441 | + : NULL; | |
1442 | + if( notification != NULL ) | |
1431 | 1443 | { |
1432 | - /* ...and it matches the classification in which | |
1433 | - * we are interested, then we retrieve the tarname | |
1434 | - * for the related package... | |
1435 | - */ | |
1436 | - pkgXmlNode *selected = (classified & ACTION_REMOVE) | |
1437 | - ? item->Selection( to_remove ) | |
1438 | - : item->Selection(); | |
1439 | - const char *notification = (selected != NULL) | |
1440 | - ? selected->GetPropVal( tarname_key, NULL ) | |
1441 | - : NULL; | |
1442 | - if( notification != NULL ) | |
1443 | - { | |
1444 | - /* ...and, provided it is valid, we append it to | |
1445 | - * the DMH driven dialogue in which the enumeration | |
1446 | - * is being reported... | |
1447 | - */ | |
1448 | - dmh_printf( "%s\n", notification ); | |
1449 | - /* | |
1450 | - * ...and include it in the accumulated count... | |
1451 | - */ | |
1452 | - ++count; | |
1453 | - } | |
1454 | - } | |
1455 | - else if( (classified == 0) | |
1456 | - /* | |
1457 | - * ...otherwise, when we aren't interested in any particular | |
1458 | - * class of action regardless of classification... | |
1444 | + /* ...and, provided it is valid, we append it to | |
1445 | + * the DMH driven dialogue in which the enumeration | |
1446 | + * is being reported... | |
1459 | 1447 | */ |
1460 | - || ((classified == ACTION_UNSUCCESSFUL) && ((flags & classified) != 0)) ) | |
1448 | + dmh_printf( "%s\n", notification ); | |
1461 | 1449 | /* |
1462 | - * ...or when we are checking for unsuccessful actions, we | |
1463 | - * count all those which are found, either unclassified, or | |
1464 | - * marked as unsuccessful, respectively. | |
1450 | + * ...and include it in the accumulated count... | |
1465 | 1451 | */ |
1466 | 1452 | ++count; |
1453 | + } | |
1467 | 1454 | } |
1468 | - /* ...then move on, to consider the next entry, if any. | |
1469 | - */ | |
1470 | - item = item->next; | |
1455 | + else if( (classified == 0) | |
1456 | + /* | |
1457 | + * ...otherwise, when we aren't interested in any particular | |
1458 | + * class of action regardless of classification... | |
1459 | + */ | |
1460 | + || ((classified == ACTION_UNSUCCESSFUL) && ((flags & classified) != 0)) ) | |
1461 | + /* | |
1462 | + * ...or when we are checking for unsuccessful actions, we | |
1463 | + * count all those which are found, either unclassified, or | |
1464 | + * marked as unsuccessful, respectively. | |
1465 | + */ | |
1466 | + ++count; | |
1471 | 1467 | } |
1468 | + /* ...then move on, to consider the next entry, if any. | |
1469 | + */ | |
1470 | + item = item->next; | |
1472 | 1471 | } |
1473 | 1472 | /* Ultimately, return the count of pending actions, |
1474 | 1473 | * as noted while processing the above loop. |
@@ -3,8 +3,8 @@ | ||
3 | 3 | * |
4 | 4 | * $Id$ |
5 | 5 | * |
6 | - * Written by Keith Marshall <keithmarshall@users.sourceforge.net> | |
7 | - * Copyright (C) 2009, 2010, 2011, 2012, MinGW Project | |
6 | + * Written by Keith Marshall <keith@users.osdn.me> | |
7 | + * Copyright (C) 2009-2012, 2020, MinGW.org Project | |
8 | 8 | * |
9 | 9 | * |
10 | 10 | * Implementation of the package dependency resolver method, of the |
@@ -859,47 +859,42 @@ void pkgActionItem::ApplyBounds( pkgXmlNode *release, const char *bounds ) | ||
859 | 859 | |
860 | 860 | pkgActionItem *pkgActionItem::GetReference( pkgXmlNode *package ) |
861 | 861 | { |
862 | - /* Method to locate a scheduled action, if any, which relates | |
863 | - * to a specified package. | |
862 | + /* Method to locate a scheduled action, if any, which relates to | |
863 | + * a specified package. Assume that the initial 'this' pointer is | |
864 | + * closer to the end, than to the beginning of the current list of | |
865 | + * scheduled actions, (which MUST NOT be empty), and... | |
864 | 866 | */ |
865 | - if( this != NULL ) | |
866 | - { | |
867 | - /* The schedule of actions is not empty. Assume that the | |
868 | - * initial 'this' pointer is closer to the end, than to the | |
869 | - * beginning of the list of scheduled actions, and... | |
867 | + pkgActionItem *item = this; | |
868 | + while( item->next != NULL ) | |
869 | + /* | |
870 | + * ...advance, to locate the very last entry in the list. | |
870 | 871 | */ |
871 | - pkgActionItem *item = this; | |
872 | - while( item->next != NULL ) | |
873 | - /* | |
874 | - * ...advance, to locate the very last entry in the list. | |
875 | - */ | |
876 | - item = item->next; | |
872 | + item = item->next; | |
877 | 873 | |
878 | - /* Now, working backward toward the beginning of the list... | |
874 | + /* Now, working backward toward the beginning of the list... | |
875 | + */ | |
876 | + while( item != NULL ) | |
877 | + { | |
878 | + /* ...identify a "release" specification associated with | |
879 | + * each action item in turn... | |
879 | 880 | */ |
880 | - while( item != NULL ) | |
881 | + pkgXmlNode *ref = item->Selection(); | |
882 | + if( (ref != NULL) || ((ref = item->Selection( to_remove )) != NULL) ) | |
881 | 883 | { |
882 | - /* ...identify a "release" specification associated with | |
883 | - * each action item in turn... | |
884 | + /* ...convert this to an actual component package, or | |
885 | + * full package, reference... | |
884 | 886 | */ |
885 | - pkgXmlNode *ref = item->Selection(); | |
886 | - if( (ref != NULL) || ((ref = item->Selection( to_remove )) != NULL) ) | |
887 | - { | |
888 | - /* ...convert this to an actual component package, or | |
889 | - * full package, reference... | |
890 | - */ | |
891 | - while( ref->IsElementOfType( release_key ) ) | |
892 | - ref = ref->GetParent(); | |
887 | + while( ref->IsElementOfType( release_key ) ) | |
888 | + ref = ref->GetParent(); | |
893 | 889 | |
894 | - /* ...and, if it matches the search target, return it. | |
895 | - */ | |
896 | - if( ref == package ) return item; | |
897 | - } | |
898 | - /* ...or, when we haven't yet found a matching package, | |
899 | - * try the preceding scheduled action item, if any. | |
890 | + /* ...and, if it matches the search target, return it. | |
900 | 891 | */ |
901 | - item = item->prev; | |
892 | + if( ref == package ) return item; | |
902 | 893 | } |
894 | + /* ...or, when we haven't yet found a matching package, | |
895 | + * try the preceding scheduled action item, if any. | |
896 | + */ | |
897 | + item = item->prev; | |
903 | 898 | } |
904 | 899 | /* If we fall through to here, then we found no action to be |
905 | 900 | * performed on the specified package; report accordingly. |
@@ -945,12 +940,6 @@ pkgActionItem* pkgXmlDocument::Schedule( unsigned long action, const char* name | ||
945 | 940 | * dependencies for the package specified by "name", honouring |
946 | 941 | * any appended version bounds specified for the parent. |
947 | 942 | */ |
948 | - if( this == NULL ) | |
949 | - /* | |
950 | - * An unassigned XML database document cannot have any | |
951 | - * assigned action; bail out, with appropriate status. | |
952 | - */ | |
953 | - return NULL; | |
954 | 943 | |
955 | 944 | /* We may call this method without any assigned package name, |
956 | 945 | * in which case, we interpret it as a request to return the |
@@ -1184,8 +1173,8 @@ pkgActionItem* pkgXmlDocument::Schedule( unsigned long action, const char* name | ||
1184 | 1173 | ResolveDependencies( upgrade, Schedule( action, latest )); |
1185 | 1174 | } |
1186 | 1175 | } |
1187 | - | |
1188 | - if( (component = component->FindNextAssociate( component_key )) != NULL ) | |
1176 | + if( (component != NULL) | |
1177 | + && ((component = component->FindNextAssociate( component_key )) != NULL) ) | |
1189 | 1178 | /* |
1190 | 1179 | * When evaluating a component-package, we extend our |
1191 | 1180 | * evaluation, to consider for any further components of |
@@ -209,16 +209,13 @@ pkgActionItem::Append( pkgActionItem *item ) | ||
209 | 209 | * being appended to the list, but the implementation preserves |
210 | 210 | * integrity of any following list items, thus also fulfilling |
211 | 211 | * an "insert after this" function. |
212 | - */ | |
213 | - if( this == NULL ) | |
214 | - /* | |
215 | - * No list exists yet; | |
216 | - * return "item" as first and only entry in new list. | |
217 | - */ | |
218 | - return item; | |
219 | - | |
220 | - /* Ensure "item" physically exists, or if not, create a generic | |
221 | - * placeholder in which to construct it... | |
212 | + * | |
213 | + * Note that this method must NEVER be invoked with a NULL "this" | |
214 | + * pointer; however, conformance with this requirement CANNOT be | |
215 | + * verified here, so MUST be verified at the call site. | |
216 | + * | |
217 | + * The "item" to be added must physically exist; if not, we create | |
218 | + * a generic placeholder in which to construct it... | |
222 | 219 | */ |
223 | 220 | if( (item == NULL) && ((item = new pkgActionItem()) == NULL) ) |
224 | 221 | /* |
@@ -249,17 +246,10 @@ pkgActionItem* | ||
249 | 246 | pkgActionItem::Insert( pkgActionItem *item ) |
250 | 247 | { |
251 | 248 | /* Add an "item" to an ActionItems list, inserting it immediately |
252 | - * before the item referenced by the "this" pointer. | |
253 | - */ | |
254 | - if( this == NULL ) | |
255 | - /* | |
256 | - * No list exists yet; | |
257 | - * return "item" as first and only entry in new list. | |
258 | - */ | |
259 | - return item; | |
260 | - | |
261 | - /* Ensure "item" physically exists, or if not, create a generic | |
262 | - * placeholder in which to construct it... | |
249 | + * before the item referenced by the "this" pointer, (which should | |
250 | + * NEVER be NULL, but this must be verified at the call site). The | |
251 | + * "item" to be added must physically exist; if not, we create a | |
252 | + * generic placeholder in which to construct it... | |
263 | 253 | */ |
264 | 254 | if( (item == NULL) && ((item = new pkgActionItem()) == NULL) ) |
265 | 255 | /* |
@@ -451,12 +441,12 @@ pkgActionItem* pkgXmlDocument::Schedule | ||
451 | 441 | * the action list, (or at the end of the list if no ranking |
452 | 442 | * position is specified)... |
453 | 443 | */ |
454 | - pkgActionItem *ref = rank ? rank : actions; | |
444 | + pkgActionItem *ref = rank ? rank : actions ? actions : &item; | |
455 | 445 | |
456 | 446 | /* If we already have a prior matching item... |
457 | 447 | */ |
458 | 448 | pkgActionItem *prior; |
459 | - if( (prior = actions->GetReference( item )) != NULL ) | |
449 | + if( (prior = (actions ? actions->GetReference( item ) : NULL)) != NULL ) | |
460 | 450 | { |
461 | 451 | /* ...then, when the current request refers to a primary action, |
462 | 452 | * we update the already scheduled request to reflect this... |
@@ -486,15 +476,14 @@ pkgActionItem* pkgXmlDocument::Schedule | ||
486 | 476 | /* ...and, when successfully raised, add it to the task list... |
487 | 477 | */ |
488 | 478 | if( rank ) |
489 | - /* | |
490 | - * ...at the specified ranking position, if any... | |
479 | + /* ...at the specified ranking position, if any... | |
491 | 480 | */ |
492 | 481 | return rank->Insert( ref ); |
493 | 482 | |
494 | 483 | else |
495 | 484 | /* ...otherwise, at the end of the list. |
496 | 485 | */ |
497 | - return actions = actions->Append( ref ); | |
486 | + return actions = actions ? actions->Append( ref ) : ref; | |
498 | 487 | } |
499 | 488 | |
500 | 489 | /* If we get to here, then no new action was scheduled; we simply |
@@ -517,147 +506,145 @@ int reinstall_action_scheduled( pkgActionItem *package ) | ||
517 | 506 | |
518 | 507 | void pkgActionItem::Execute( bool with_download ) |
519 | 508 | { |
520 | - if( this != NULL ) | |
521 | - { pkgActionItem *current = this; | |
522 | - bool init_rites_pending = true; | |
523 | - while( current->prev != NULL ) current = current->prev; | |
524 | - | |
525 | - /* Unless normal operations have been suppressed by the | |
526 | - * --print-uris option, (in order to obtain a list of all | |
527 | - * package URIs which the operation would access)... | |
509 | + pkgActionItem *current = this; | |
510 | + bool init_rites_pending = true; | |
511 | + while( current->prev != NULL ) current = current->prev; | |
512 | + | |
513 | + /* Unless normal operations have been suppressed by the | |
514 | + * --print-uris option, (in order to obtain a list of all | |
515 | + * package URIs which the operation would access)... | |
516 | + */ | |
517 | + if( pkgOptions()->Test( OPTION_PRINT_URIS ) < OPTION_PRINT_URIS ) | |
518 | + do { | |
519 | + /* ...we initiate any download requests which may | |
520 | + * be necessary to fetch all required archives into | |
521 | + * the local package cache. | |
522 | + */ | |
523 | + if( with_download ) | |
524 | + DownloadArchiveFiles( current ); | |
525 | + } while( SetAuthorities( current ) > 0 ); | |
526 | + | |
527 | + else while( current != NULL ) | |
528 | + { | |
529 | + /* The --print-uris option is in effect: we simply loop | |
530 | + * over all packages with an assigned action, printing | |
531 | + * the associated download URI for each; (note that this | |
532 | + * will print the URI regardless of prior existence of | |
533 | + * the associated package in the local cache). | |
528 | 534 | */ |
529 | - if( pkgOptions()->Test( OPTION_PRINT_URIS ) < OPTION_PRINT_URIS ) | |
530 | - do { | |
531 | - /* ...we initiate any download requests which may | |
532 | - * be necessary to fetch all required archives into | |
533 | - * the local package cache. | |
534 | - */ | |
535 | - if( with_download ) | |
536 | - DownloadArchiveFiles( current ); | |
537 | - } while( SetAuthorities( current ) > 0 ); | |
538 | - | |
539 | - else while( current != NULL ) | |
540 | - { | |
541 | - /* The --print-uris option is in effect: we simply loop | |
542 | - * over all packages with an assigned action, printing | |
543 | - * the associated download URI for each; (note that this | |
544 | - * will print the URI regardless of prior existence of | |
545 | - * the associated package in the local cache). | |
546 | - */ | |
547 | - current->PrintURI( current->Selection()->ArchiveName() ); | |
548 | - current = current->next; | |
549 | - } | |
535 | + current->PrintURI( current->Selection()->ArchiveName() ); | |
536 | + current = current->next; | |
537 | + } | |
550 | 538 | |
551 | - /* If the --download-only option is in effect, then we have | |
552 | - * nothing more to do... | |
539 | + /* If the --download-only option is in effect, then we have | |
540 | + * nothing more to do... | |
541 | + */ | |
542 | + if( pkgOptions()->Test( OPTION_DOWNLOAD_ONLY ) != OPTION_DOWNLOAD_ONLY ) | |
543 | + { | |
544 | + /* ...otherwise... | |
553 | 545 | */ |
554 | - if( pkgOptions()->Test( OPTION_DOWNLOAD_ONLY ) != OPTION_DOWNLOAD_ONLY ) | |
546 | + while( current != NULL ) | |
555 | 547 | { |
556 | - /* ...otherwise... | |
548 | + /* ...processing only those packages with assigned actions... | |
557 | 549 | */ |
558 | - while( current != NULL ) | |
550 | + if( (current->flags & ACTION_MASK) != 0 ) | |
559 | 551 | { |
560 | - /* ...processing only those packages with assigned actions... | |
552 | + /* ...print a notification of the installation process to | |
553 | + * be performed, identifying the package to be processed. | |
561 | 554 | */ |
562 | - if( (current->flags & ACTION_MASK) != 0 ) | |
555 | + const char *tarname; | |
556 | + pkgXmlNode *ref = current->Selection(); | |
557 | + if( (tarname = ref->GetPropVal( tarname_key, NULL )) == NULL ) | |
563 | 558 | { |
564 | - /* ...print a notification of the installation process to | |
565 | - * be performed, identifying the package to be processed. | |
566 | - */ | |
567 | - const char *tarname; | |
568 | - pkgXmlNode *ref = current->Selection(); | |
569 | - if( (tarname = ref->GetPropVal( tarname_key, NULL )) == NULL ) | |
570 | - { | |
571 | - ref = current->Selection( to_remove ); | |
572 | - tarname = ref->GetPropVal( tarname_key, value_unknown ); | |
573 | - } | |
574 | - dmh_printf( "%s: %s\n", reinstall_action_scheduled( current ) | |
575 | - ? "reinstall" : action_name( current->flags & ACTION_MASK ), | |
576 | - tarname | |
577 | - ); | |
578 | - | |
579 | - /* Package pre/post processing scripts may need to | |
580 | - * refer to the sysroot path for the package; place | |
581 | - * a copy in the environment, to facilitate this. | |
582 | - */ | |
583 | - pkgSpecs lookup( tarname ); | |
584 | - ref = ref->GetSysRoot( lookup.GetSubSystemName() ); | |
585 | - const char *path = ref->GetPropVal( pathname_key, NULL ); | |
586 | - if( path != NULL ) | |
587 | - { | |
588 | - /* Format the sysroot path into an environment variable | |
589 | - * assignment specification; note that the recorded path | |
590 | - * name is likely to include macros such as "%R", so we | |
591 | - * filter it through mkpath(), to expand them. | |
592 | - */ | |
593 | - const char *nothing = ""; | |
594 | - char varspec_template[9 + strlen( path )]; | |
595 | - sprintf( varspec_template, "SYSROOT=%s", path ); | |
596 | - char varspec[mkpath( NULL, varspec_template, nothing, NULL )]; | |
597 | - mkpath( varspec, varspec_template, nothing, NULL ); | |
598 | - pkgPutEnv( PKG_PUTENV_DIRSEP_MSW, varspec ); | |
599 | - } | |
559 | + ref = current->Selection( to_remove ); | |
560 | + tarname = ref->GetPropVal( tarname_key, value_unknown ); | |
561 | + } | |
562 | + dmh_printf( "%s: %s\n", reinstall_action_scheduled( current ) | |
563 | + ? "reinstall" : action_name( current->flags & ACTION_MASK ), | |
564 | + tarname | |
565 | + ); | |
600 | 566 | |
601 | - /* Check for any outstanding requirement to invoke the | |
602 | - * "self upgrade rites" process, so that we may install an | |
603 | - * upgrade for mingw-get itself... | |
567 | + /* Package pre/post processing scripts may need to | |
568 | + * refer to the sysroot path for the package; place | |
569 | + * a copy in the environment, to facilitate this. | |
570 | + */ | |
571 | + pkgSpecs lookup( tarname ); | |
572 | + ref = ref->GetSysRoot( lookup.GetSubSystemName() ); | |
573 | + const char *path = ref->GetPropVal( pathname_key, NULL ); | |
574 | + if( path != NULL ) | |
575 | + { | |
576 | + /* Format the sysroot path into an environment variable | |
577 | + * assignment specification; note that the recorded path | |
578 | + * name is likely to include macros such as "%R", so we | |
579 | + * filter it through mkpath(), to expand them. | |
604 | 580 | */ |
605 | - if( init_rites_pending ) | |
606 | - /* | |
607 | - * ...discontinuing the check once this has been completed, | |
608 | - * since it need not be performed more than once. | |
609 | - */ | |
610 | - init_rites_pending = self_upgrade_rites( tarname ); | |
581 | + const char *nothing = ""; | |
582 | + char varspec_template[9 + strlen( path )]; | |
583 | + sprintf( varspec_template, "SYSROOT=%s", path ); | |
584 | + char varspec[mkpath( NULL, varspec_template, nothing, NULL )]; | |
585 | + mkpath( varspec, varspec_template, nothing, NULL ); | |
586 | + pkgPutEnv( PKG_PUTENV_DIRSEP_MSW, varspec ); | |
587 | + } | |
611 | 588 | |
612 | - /* If we are performing an upgrade... | |
613 | - */ | |
614 | - if( ((current->flags & ACTION_MASK) == ACTION_UPGRADE) | |
589 | + /* Check for any outstanding requirement to invoke the | |
590 | + * "self upgrade rites" process, so that we may install an | |
591 | + * upgrade for mingw-get itself... | |
592 | + */ | |
593 | + if( init_rites_pending ) | |
615 | 594 | /* |
616 | - * ...and the latest version of the package is already installed... | |
595 | + * ...discontinuing the check once this has been completed, | |
596 | + * since it need not be performed more than once. | |
617 | 597 | */ |
618 | - && (current->Selection() == current->Selection( to_remove )) | |
598 | + init_rites_pending = self_upgrade_rites( tarname ); | |
599 | + | |
600 | + /* If we are performing an upgrade... | |
601 | + */ | |
602 | + if( ((current->flags & ACTION_MASK) == ACTION_UPGRADE) | |
603 | + /* | |
604 | + * ...and the latest version of the package is already installed... | |
605 | + */ | |
606 | + && (current->Selection() == current->Selection( to_remove )) | |
607 | + /* | |
608 | + * ...and the `--reinstall' option hasn't been specified... | |
609 | + */ | |
610 | + && (pkgOptions()->Test( OPTION_REINSTALL ) == 0) ) | |
619 | 611 | /* |
620 | - * ...and the `--reinstall' option hasn't been specified... | |
612 | + * ...then simply report the up-to-date status... | |
613 | + */ | |
614 | + dmh_notify( DMH_INFO, "package %s is up to date\n", tarname ); | |
615 | + | |
616 | + else | |
617 | + { /* ...otherwise, proceed to perform remove and install | |
618 | + * operations, as appropriate. | |
621 | 619 | */ |
622 | - && (pkgOptions()->Test( OPTION_REINSTALL ) == 0) ) | |
623 | - /* | |
624 | - * ...then simply report the up-to-date status... | |
620 | + if( reinstall_action_scheduled( current ) | |
621 | + || ((current->flags & ACTION_REMOVE) == ACTION_REMOVE) ) | |
622 | + { | |
623 | + /* The selected package has been marked for removal, either | |
624 | + * explicitly, or as an implicit prerequisite for upgrade, or | |
625 | + * in preparation for reinstallation. | |
625 | 626 | */ |
626 | - dmh_notify( DMH_INFO, "package %s is up to date\n", tarname ); | |
627 | + pkgRemove( current ); | |
628 | + } | |
627 | 629 | |
628 | - else | |
629 | - { /* ...otherwise, proceed to perform remove and install | |
630 | - * operations, as appropriate. | |
630 | + if( (current->flags & ACTION_INSTALL) == ACTION_INSTALL ) | |
631 | + { | |
632 | + /* The selected package has been marked for installation, | |
633 | + * either explicitly, or implicitly to complete a package upgrade. | |
631 | 634 | */ |
635 | + pkgXmlNode *tmp = current->Selection( to_remove ); | |
632 | 636 | if( reinstall_action_scheduled( current ) |
633 | - || ((current->flags & ACTION_REMOVE) == ACTION_REMOVE) ) | |
634 | - { | |
635 | - /* The selected package has been marked for removal, either | |
636 | - * explicitly, or as an implicit prerequisite for upgrade, or | |
637 | - * in preparation for reinstallation. | |
638 | - */ | |
639 | - pkgRemove( current ); | |
640 | - } | |
641 | - | |
642 | - if( (current->flags & ACTION_INSTALL) == ACTION_INSTALL ) | |
643 | - { | |
644 | - /* The selected package has been marked for installation, | |
645 | - * either explicitly, or implicitly to complete a package upgrade. | |
646 | - */ | |
647 | - pkgXmlNode *tmp = current->Selection( to_remove ); | |
648 | - if( reinstall_action_scheduled( current ) | |
649 | - || ((current->flags & ACTION_MASK) == ACTION_UPGRADE) ) | |
650 | - current->selection[ to_remove ] = NULL; | |
651 | - pkgInstall( current ); | |
652 | - current->selection[ to_remove ] = tmp; | |
653 | - } | |
637 | + || ((current->flags & ACTION_MASK) == ACTION_UPGRADE) ) | |
638 | + current->selection[ to_remove ] = NULL; | |
639 | + pkgInstall( current ); | |
640 | + current->selection[ to_remove ] = tmp; | |
654 | 641 | } |
655 | 642 | } |
656 | - /* Proceed to the next package, if any, with scheduled actions. | |
657 | - */ | |
658 | - pkgSpinWait::Report( "Processing... (%c)", pkgSpinWait::Indicator() ); | |
659 | - current = current->next; | |
660 | 643 | } |
644 | + /* Proceed to the next package, if any, with scheduled actions. | |
645 | + */ | |
646 | + pkgSpinWait::Report( "Processing... (%c)", pkgSpinWait::Indicator() ); | |
647 | + current = current->next; | |
661 | 648 | } |
662 | 649 | } |
663 | 650 | } |
@@ -227,9 +227,10 @@ void pkgManifest::AddEntry( const char *key, const char *pathname ) | ||
227 | 227 | * entries to the tracked inventory of package content. |
228 | 228 | * |
229 | 229 | * Tracking is enabled only if the manifest structure is valid, |
230 | - * AND an inventory table has been allocated... | |
230 | + * (which must have been verified by the caller), AND an inventory | |
231 | + * table has been allocated... | |
231 | 232 | */ |
232 | - if( (this != NULL) && (inventory != NULL) ) | |
233 | + if( inventory != NULL ) | |
233 | 234 | { |
234 | 235 | /* ...in which case we allocate a new tracking record, with |
235 | 236 | * "dir" or "file" reference key as appropriate, fill it out |
@@ -170,7 +170,7 @@ pkgXmlNode *pkgManifest::GetSysRootReference( const char *key ) | ||
170 | 170 | * a reference to any sysroot which claims it, returning |
171 | 171 | * a pointer to the first such reference found. |
172 | 172 | */ |
173 | - if( (this != NULL) && (manifest != NULL) && (key != NULL) ) | |
173 | + if( (manifest != NULL) && (key != NULL) ) | |
174 | 174 | { |
175 | 175 | /* We appear to have a valid manifest, and a valid sysroot |
176 | 176 | * key to match; locate this manifest's first, (and nominally |
@@ -263,14 +263,6 @@ EXTERN_C void dmh_init( const dmh_class subsystem, const char *progname ) | ||
263 | 263 | dmh = new dmhTypeGUI( strdup( progname ) ); |
264 | 264 | } |
265 | 265 | |
266 | -inline unsigned long pkgSetupAction::HasAttribute( unsigned long mask ) | |
267 | -{ | |
268 | - /* Helper function to examine the flags within a setup action | |
269 | - * item, checking for the presence of a specified attribute. | |
270 | - */ | |
271 | - return (this != NULL) ? mask & flags : 0UL; | |
272 | -} | |
273 | - | |
274 | 266 | void pkgSetupAction::ClearAllActions( void ) |
275 | 267 | { |
276 | 268 | /* Routine to clear an entire list of setup action items, |
@@ -4,8 +4,8 @@ | ||
4 | 4 | * |
5 | 5 | * $Id$ |
6 | 6 | * |
7 | - * Written by Keith Marshall <keithmarshall@users.sourceforge.net> | |
8 | - * Copyright (C) 2013, MinGW.org Project | |
7 | + * Written by Keith Marshall <keith@users.osdn.me> | |
8 | + * Copyright (C) 2013, 2020, MinGW.org Project | |
9 | 9 | * |
10 | 10 | * |
11 | 11 | * Resource ID definitions and class declarations which are specific |
@@ -96,12 +96,12 @@ class pkgSetupAction | ||
96 | 96 | * specifically to the requirements of the setup tool. |
97 | 97 | */ |
98 | 98 | public: |
99 | - inline unsigned long HasAttribute( unsigned long ); | |
100 | 99 | pkgSetupAction( pkgSetupAction *, const char *, const char * = 0 ); |
100 | + inline unsigned long HasAttribute( unsigned long mask){ return flags & mask; } | |
101 | 101 | inline void DownloadArchiveFiles( void ); |
102 | 102 | inline int UnpackScheduledArchives( void ); |
103 | - void ClearAllActions( void ); | |
104 | 103 | void UpdateDatabase( pkgXmlDocument & ); |
104 | + void ClearAllActions( void ); | |
105 | 105 | |
106 | 106 | private: |
107 | 107 | unsigned long flags; |