comparison discussion.roff @ 220:95257474a123

Further improvements in the discussion; added build dependency graphs.
author markus schnalke <meillo@marmaro.de>
date Sun, 15 Jul 2012 18:41:35 +0200
parents 8c537982d718
children 1fa5a74bf138
comparison
equal deleted inserted replaced
219:8c537982d718 220:95257474a123
459 is not related to the mail client, and 459 is not related to the mail client, and
460 .Pn msh 460 .Pn msh
461 conflicts with the basic concept of MH. 461 conflicts with the basic concept of MH.
462 These two tools might still be useful, but they should not be part of mmh. 462 These two tools might still be useful, but they should not be part of mmh.
463 .P 463 .P
464 .Id slocal
464 Finally, there is 465 Finally, there is
465 .Pn slocal , 466 .Pn slocal ,
466 which is an MDA and thus not directly MUA-related. 467 which is an MDA and thus not directly MUA-related.
467 It should be removed from mmh because including it conflicts with 468 It should be removed from mmh because including it conflicts with
468 the idea that mmh is an MUA only. 469 the idea that mmh is an MUA only.
3405 3406
3406 3407
3407 3408
3408 .H2 "Profile Reading 3409 .H2 "Profile Reading
3409 .P 3410 .P
3410 The MH profile contains the configuration for the user-specific MH setup. 3411 The MH profile contains the configuration of a user-specific MH setup.
3411 MH tools read the profile right after starting up, 3412 MH tools read the profile right after starting up
3412 as it contains the location of the user's mail storage 3413 because it contains the location of the user's mail storage
3413 and similar settings that influence the whole setup. 3414 and similar settings that influence the whole setup.
3414 Furthermore, the profile contains the default switches for the tools, 3415 Furthermore, the profile contains the default switches for the tools
3415 hence, it must be read before the command line switches are processed. 3416 as well.
3417 The context file is read along with the profile.
3416 .P 3418 .P
3417 For historic reasons, some MH tools did not read the profile and context. 3419 For historic reasons, some MH tools did not read the profile and context.
3418 Among them were 3420 Among them were
3419 .Pn post /\c 3421 .Pn post /\c
3420 .Pn spost , 3422 .Pn spost ,
3421 .Pn mhmail , 3423 .Pn mhmail ,
3422 and 3424 and
3423 .Pn slocal . 3425 .Pn slocal .
3424 The reason why these tools ignored the profile were not clearly stated. 3426 The reason why these tools ignored the profile were not clearly stated.
3425 During the discussion on the nmh-workers mailing list, 3427 During a discussion on the nmh-workers mailing list,
3426 David Levine posted an explanation, quoting John Romine: 3428 David Levine posted an explanation, quoting John Romine:
3427 .[ 3429 .[
3428 nmh-workers levine post profile 3430 nmh-workers levine post profile
3429 .] 3431 .]
3432
3430 .QS 3433 .QS
3431 I asked John Romine and here's what he had to say, which 3434 I asked John Romine and here's what he had to say, which
3432 agrees and provides an example that convinces me: 3435 agrees and provides an example that convinces me:
3433 .QS 3436 .QS
3434 My take on this is that 3437 My take on this is that
3456 use an environment variable (I think 3459 use an environment variable (I think
3457 .Pn send /\c 3460 .Pn send /\c
3458 .Pn whatnow 3461 .Pn whatnow
3459 do this). 3462 do this).
3460 .QE 3463 .QE
3464 .sp \n(PDu
3461 I think that's the way to go. 3465 I think that's the way to go.
3462 My personal preference is to use a command line option, 3466 My personal preference is to use a command line option,
3463 not an environment variable. 3467 not an environment variable.
3464 .QE 3468 .QE
3465 .P 3469
3466 To solve the problem of 3470 .P
3471 To solve the problem that
3467 .Pn post 3472 .Pn post
3468 not honoring the 3473 does not honor the
3469 .Pe fileproc 3474 .Pe fileproc
3470 profile entry, 3475 profile entry,
3471 the community roughly agreed that a switch 3476 the community roughly agreed that a switch
3472 .Sw -fileproc 3477 .Sw -fileproc
3473 should be added to 3478 should be added to
3474 .Pn post 3479 .Pn post
3475 to be able to pass a different fileproc. 3480 to be able to pass a different fileproc.
3476 I strongly disagree with this approach because it does not solve 3481 I strongly disagree with this approach because it does not solve
3477 the problem; it only removes a single symptom. 3482 the problem; it only removes a single symptom.
3478 The problem is that 3483 The actual problem is that
3479 .Pn post 3484 .Pn post
3480 does not behave as expected. 3485 does not behave as expected,
3481 But all programs should behave as expected. 3486 though all programs should behave as expected.
3482 Clear and simple concepts are a precondition for this. 3487 Clear and general concepts are a precondition for this.
3483 Hence, the real solution is having all MH tools read the profile. 3488 Thus, there should be no separation into ``front-end UI programs''
3484 .P 3489 and ones that ``should not be called by users directly''.
3485 The problem has a further aspect. 3490 The real solution is having all MH tools read the profile.
3486 It mainly originates in 3491 .P
3487 .Pn mhmail . 3492 But the problem has a further aspect,
3493 which originates from
3494 .Pn mhmail
3495 mainly.
3488 .Pn mhmail 3496 .Pn mhmail
3489 was intended to be a replacement for 3497 was intended to be a replacement for
3490 .Pn mailx 3498 .Pn mailx
3491 on systems with MH installations. 3499 on systems with MH installations.
3500 In difference to
3501 .Pn mailx ,
3492 .Pn mhmail 3502 .Pn mhmail
3493 should have been able to use just like 3503 used MH's
3494 .Pn mailx ,
3495 but sending the message via MH's
3496 .Pn post 3504 .Pn post
3497 instead of 3505 to send the message.
3498 .Pn sendmail . 3506 The idea was that using
3499 Using
3500 .Pn mhmail 3507 .Pn mhmail
3501 should not be influenced by the question whether the user had 3508 should not be influenced whether the user had
3502 MH set up for himself or not. 3509 MH set up for himself or not.
3510 Therefore
3503 .Pn mhmail 3511 .Pn mhmail
3504 did not read the profile as this requests the user to set up MH 3512 had not read the profile.
3505 if not done yet.
3506 As 3513 As
3507 .Pn mhmail 3514 .Pn mhmail
3508 used 3515 used
3509 .Pn post , 3516 .Pn post ,
3510 .Pn post 3517 .Pn post
3511 could not read the profile neither. 3518 was not allowed to read the profile neither.
3512 This is the reason why
3513 .Pn post
3514 does not read the profile.
3515 This is the reason for the actual problem. 3519 This is the reason for the actual problem.
3516 It was not much of a problem because 3520 Yet, this was not considered much of a problem because
3517 .Pn post 3521 .Pn post
3518 was not intended to be used by users directly. 3522 was not intended to be used by users directly.
3523 To invoke
3524 .Pn post ,
3519 .Pn send 3525 .Pn send
3520 is the interactive front-end to 3526 was used an a front-end.
3521 .Pn post .
3522 .Pn send 3527 .Pn send
3523 read the profile and passed all relevant values on the command line to 3528 read the profile and passed all relevant values on the command line to
3524 .Pn post 3529 .Pn post
3525 \(en an awkward solution. 3530 \(en an awkward solution.
3526 .P 3531 .P
3527 The important insight is that 3532 The important insight is that
3528 .Pn mhmail 3533 .Pn mhmail
3529 is no true MH tool. 3534 is a wolf in sheep's clothing.
3530 The concepts broke because this outlandish tool was treated as any other 3535 This alien tool broke the concepts because it was treated like
3531 MH tool. 3536 a normal MH tool.
3532 Instead it should have been treated accordingly to its foreign style. 3537 Instead it should have been treated accordingly to its foreign style.
3533 The solution is not to prevent the tools reading the profile but 3538 .P
3534 to instruct them reading a different profile. 3539 The solution is not to prevent the tools from reading the profile but
3540 to instruct them to read a different profile.
3535 .Pn mhmail 3541 .Pn mhmail
3536 could have set up a well-defined profile and caused all MH tools 3542 could have set up a well-defined profile and caused the following
3537 in the session to use it by exporting an environment variable.
3538 With this approach, no special cases would have been introduced,
3539 no surprises would have been caused.
3540 By writing a clean-profile-wrapper, the concept could have been
3541 generalized orthogonally to the whole MH tool chest.
3542 Then Rose's motivation behind the decision that
3543 .Pn post 3543 .Pn post
3544 ignores the profile, as quoted by Jeffrey Honig, 3544 to use this profile by exporting an environment variable.
3545 would have become possible: 3545 With this approach, no special cases would have been introduced
3546 and no surprises would have been caused.
3547 By writing a wrapper program to provide a clean temporary profile,
3548 the concept could have been generalized orthogonally to the whole
3549 MH tool chest.
3550 .P
3551 In mmh, the wish to have
3552 .Pn mhmail
3553 as a replacement for
3554 .Pn mailx
3555 is considered obsolete.
3556 Mmh's
3557 .Pn mhmail
3558 does no longer cover this use-case
3559 .Ci d36e56e695fe1c482c7920644bfbb6386ac9edb0 .
3560 Currently,
3561 .Pn mhmail
3562 is in a transition state
3563 .Ci 32d4f9daaa70519be3072479232ff7be0500d009 .
3564 It may become a front-end to
3565 .Pn comp ,
3566 which provides an alternative interface which can be more convenient
3567 in some cases.
3568 This would convert
3569 .Pn mhmail
3570 into an ordinary MH tool.
3571 If, however, this idea does not convince, then
3572 .Pn mhmail
3573 will be removed.
3574 .P
3575 In the mmh tool chest, every program reads the profile.
3576 (\c
3577 .Pn slocal
3578 is not considered part of the mmh tool chest (cf. Sec.
3579 .Cf slocal ).)
3580 Mmh has no
3581 .Pn post
3582 program, but it has
3583 .Pn spost ,
3584 which now does read the profile
3585 .Ci 3e017a7abbdf69bf0dff7a4073275961eda1ded8 .
3586 Following this change,
3587 .Pn send
3588 and
3589 .Pn spost
3590 can be considered for merging.
3591 Besides
3592 .Pn send ,
3593 .Pn spost
3594 is only invoked directly by the to-be-changed
3595 .Pn mhmail
3596 implementation and by
3597 .Pn rcvdist ,
3598 which requires rework anyway.
3599
3600 .P
3601 Jeffrey Honig quoted Marshall T. Rose explaining the decision that
3602 .Pn post
3603 ignores the profile:
3546 .[ 3604 .[
3547 nmh-workers honig post profile 3605 nmh-workers honig post profile
3548 .] 3606 .]
3549 .QS 3607 .QS
3550 when you run mh commands in a script, you want all the defaults to be 3608 when you run mh commands in a script, you want all the defaults to be
3551 what the man page says. 3609 what the man page says.
3552 when you run a command by hand, then you want your own defaults... 3610 when you run a command by hand, then you want your own defaults...
3553 .QE 3611 .QE
3554 .LP 3612 .LP
3555 Yet, I consider this explanation shortsighted. 3613 The explanation neither matches the problem concered exactly
3556 We should rather regard theses two cases as just two different MH setups, 3614 nor is the interpretation clear.
3557 based on two different profiles. 3615 If the described desire addresses the technical level,
3558 Mapping such problems on the concepts of switching between different 3616 then it conflicts fundametally with the Unix philosophy,
3559 profiles, solves them once for all. 3617 precisely because the indistinquishability of human and script
3560 .P 3618 input is the main reason for the huge software leverage in Unix.
3561 In mmh, the wish to have 3619 If, however, the described desire addresses the user's view,
3562 .Pn mhmail 3620 then different technical solutions are more appropriate.
3563 as a replacement for 3621 The two cases can be regarded simply as two different MH setups.
3564 .Pn mailx 3622 Hence, mapping the problem of different behavior between interactive and
3565 is considered obsolete. 3623 automated use on the concept of switching between different profiles,
3566 Mmh's 3624 marks it already solved.
3567 .Pn mhmail
3568 does no longer cover this use-case.
3569 Currently,
3570 .Pn mhmail
3571 is in a transition state.
3572 .Ci 32d4f9daaa70519be3072479232ff7be0500d009
3573 It may become a front-end to
3574 .Pn comp ,
3575 which provides an interface more convenient in some cases.
3576 In this case,
3577 .Pn mhmail
3578 will become an ordinary MH tool, reading the profile.
3579 If, however, this idea will not convince, then
3580 .Pn mhmail
3581 will be removed.
3582 .P
3583 Every program in the mmh tool chest reads the profile.
3584 The only exception is
3585 .Pn slocal ,
3586 which is not considered part of the mmh tool chest.
3587 This MDA is only distributed with mmh, currently.
3588 Mmh has no
3589 .Pn post
3590 program, but
3591 .Pn spost ,
3592 which now reads the profile.
3593 .Ci 3e017a7abbdf69bf0dff7a4073275961eda1ded8
3594 With this change,
3595 .Pn send
3596 and
3597 .Pn spost
3598 can be considered to be merged.
3599 .Pn spost
3600 is only invoked directly by the to-be-changed
3601 .Pn mhmail
3602 implementation and by
3603 .Pn rcvdist ,
3604 which will require rework.
3605 .P
3606 The
3607 .Fu context_foil()
3608 function to pretend to have read an empty profile was removed.
3609 .Ci 68af8da96bea87a5541988870130b6209ce396f6
3610 All mmh tools read the profile.
3611 3625
3612 3626
3613 3627
3614 .H2 "Standard Libraries 3628 .H2 "Standard Libraries
3615 .P 3629 .P
3616 MH is one decade older than the POSIX and ANSI C standards. 3630 MH is one decade older than the POSIX and ANSI C standards.
3617 Hence, MH included own implementations of functions 3631 Hence, MH included own implementations of functions
3618 that are standardized and thus widely available today, 3632 that were neither standardized nor widely available, back then.
3619 but were not back then. 3633 Today, twenty years after POSIX and ANSI C were published,
3620 Today, twenty years after the POSIX and ANSI C were published, 3634 developers can expect that systems comply with these standards.
3621 developers can expect systems to comply with these standards.
3622 In consequence, MH-specific replacements for standard functions 3635 In consequence, MH-specific replacements for standard functions
3623 can and should be dropped. 3636 can and should be dropped.
3624 Kernighan and Pike advise: ``Use standard libraries.'' 3637 Kernighan and Pike advise: ``Use standard libraries''.
3625 .[ [ 3638 .[ [
3626 kernighan pike practice of programming 3639 kernighan pike practice of programming
3627 .], p. 196] 3640 .], p. 196]
3628 Actually, MH had followed this advice in history, 3641 Actually, MH had followed this advice in history,
3629 but it had not adjusted to the changes in this field. 3642 but it had not adjusted to more recent changes in this field.
3630 The 3643 The
3631 .Fu snprintf() 3644 .Fu snprintf()
3632 function, for instance, was standardized with C99 and is available 3645 function, for instance, was standardized with C99 and is available
3633 almost everywhere because of its high usefulness. 3646 almost everywhere because of its high usefulness.
3634 The project's own implementation of 3647 Thus, the project's own implementation of
3635 .Fu snprintf() 3648 .Fu snprintf()
3636 was dropped in March 2012 in favor for using the one of the 3649 was dropped in March 2012 in favor for using the one of the
3637 standard library. 3650 standard library
3638 .Ci 0052f1024deb0a0a2fc2e5bacf93d45a5a9c9b32 3651 .Ci 0052f1024deb0a0a2fc2e5bacf93d45a5a9c9b32 .
3639 Such decisions limit the portability of mmh 3652 Such decisions limit the portability of mmh
3640 if systems do not support these standardized and widespread functions. 3653 if systems do not support these standardized and widespread functions.
3641 This compromise is made because mmh focuses on the future. 3654 This compromise is made because mmh focuses on the future.
3642 .P 3655 .P
3643 .\" XXX kuerzen und mit dem naechsten Absatz vereinen 3656 .\" XXX kuerzen und mit dem naechsten Absatz vereinen
3644 I am still in my twenties and my C and Unix experience comprises 3657 As I am still in my twenties, have no programming experience from
3645 only half a dozen years. 3658 past decades.
3646 Hence, I need to learn about the history in retrospective. 3659 I have not followed the evolution of C through time.
3647 I have not used those ancient constructs myself. 3660 I have not suffered from the the Unix wars.
3648 I have not suffered from their incompatibilities.
3649 I have not longed for standardization. 3661 I have not longed for standardization.
3650 All my programming experience is from a time when ANSI C and POSIX 3662 All my programming experience is from a time when ANSI C and POSIX
3651 were well established already. 3663 were well established already.
3664 Thus, I needed to learn about the history in retrospective.
3652 I have only read a lot of books about the (good) old times. 3665 I have only read a lot of books about the (good) old times.
3653 This puts me in a difficult position when working with old code. 3666 This put me in a difficult position when working with old code.
3654 I need to freshly acquire knowledge about old code constructs and ancient 3667 I need to freshly acquire knowledge about old code constructs and ancient
3655 programming styles, whereas older programmers know these things by 3668 programming styles, whereas older programmers know these things by
3656 heart from their own experience. 3669 heart from their own experience.
3657 .P
3658 Being aware of the situation, I rather let people with more historic 3670 Being aware of the situation, I rather let people with more historic
3659 experience replace ancient code constructs with standardized ones. 3671 experience do the transition from ancient code constructs to
3672 standardized ones.
3660 Lyndon Nerenberg covered large parts of this task for the nmh project. 3673 Lyndon Nerenberg covered large parts of this task for the nmh project.
3661 He converted project-specific functions to POSIX replacements, 3674 He converted project-specific functions to POSIX replacements,
3662 also removing the conditionals compilation of now standardized features. 3675 also removing the conditionals compilation of now standardized features.
3663 Ken Hornstein and David Levine had their part in the work, too. 3676 Ken Hornstein and David Levine had their part in this work, as well.
3664 Often, I only needed to pull over changes from nmh into mmh. 3677 Often, I only pulled the changes over from nmh into mmh.
3665 These changes include many commits; these are among them: 3678 These changes include many commits, among them:
3666 .Ci 768b5edd9623b7238e12ec8dfc409b82a1ed9e2d 3679 .Ci 768b5edd9623b7238e12ec8dfc409b82a1ed9e2d
3667 .Ci 0052f1024deb0a0a2fc2e5bacf93d45a5a9c9b32 . 3680 .Ci 0052f1024deb0a0a2fc2e5bacf93d45a5a9c9b32 .
3668 .P 3681 .P
3669 During my own work, I tidied up the \fIMH standard library\fP, 3682 Nevertheless, I worked on the task as well, tidying up the
3670 .Fn libmh.a , 3683 \fIMH standard library\fP,
3671 which is located in the 3684 .Fn libmh.a .
3685 It is located in the
3672 .Fn sbr 3686 .Fn sbr
3673 (``subroutines'') directory in the source tree. 3687 (``subroutines'') directory in the source tree and
3674 The MH library includes functions that mmh tools usually need. 3688 includes functions that mmh tools usually need.
3675 Among them are MH-specific functions for profile, context, sequence, 3689 Among them are MH-specific functions for profile, context, sequence,
3676 and folder handling, but as well 3690 and folder handling, but as well
3677 MH-independent functions, such as auxiliary string functions, 3691 MH-independent functions, such as auxiliary string functions,
3678 portability interfaces and error-checking wrappers for critical 3692 portability interfaces and error-checking wrappers for critical
3679 functions of the standard library. 3693 functions of the standard library.
3680 .P 3694 .BU
3681 I have replaced the 3695 I have replaced the
3682 .Fu atooi() 3696 .Fu atooi()
3683 function with calls to 3697 function with calls to
3698 .Fu strtoul() ,
3699 setting the third parameter, the base, to eight.
3684 .Fu strtoul() 3700 .Fu strtoul()
3685 with the third parameter, the base, set to eight. 3701 is part of C89 and thus considered safe to use
3686 .Fu strtoul() 3702 .Ci c490c51b3c0f8871b6953bd0c74551404f840a74 .
3687 is part of C89 and thus considered safe to use. 3703 .BU
3688 .Ci c490c51b3c0f8871b6953bd0c74551404f840a74
3689 .P
3690 I did remove project-included fallback implementations of 3704 I did remove project-included fallback implementations of
3691 .Fu memmove() 3705 .Fu memmove()
3692 and 3706 and
3693 .Fu strerror() , 3707 .Fu strerror()
3708 .Ci b067ff5c465a5d243ce5a19e562085a9a1a97215 ,
3694 although Peter Maydell had re-included them into nmh in 2008 3709 although Peter Maydell had re-included them into nmh in 2008
3695 to support SunOS 4. 3710 to support SunOS 4.
3696 Nevertheless, these functions are part of ANSI C. 3711 Nevertheless, these functions are part of ANSI C.
3697 Systems that do not even provide full ANSI C support should not 3712 Systems that do not even provide full ANSI C support should not
3698 put a load on mmh. 3713 put a load on mmh.
3699 .Ci b067ff5c465a5d243ce5a19e562085a9a1a97215 3714 .BU
3700 .P
3701 The 3715 The
3702 .Fu copy() 3716 .Fu copy()
3703 function copies the string in parameter one to the location in 3717 function copies the string in parameter one to the location in
3704 parameter two. 3718 parameter two.
3705 In contrast to 3719 In contrast to
3716 was more convenient. 3730 was more convenient.
3717 Therefore, the definition of 3731 Therefore, the definition of
3718 .Fu copy() 3732 .Fu copy()
3719 was moved into the source file of 3733 was moved into the source file of
3720 .Fu concat() 3734 .Fu concat()
3721 and its visibility is now limited to it. 3735 and its visibility it limited to that
3722 .Ci 552fd7253e5ee9e554c5c7a8248a6322aa4363bb 3736 .Ci 552fd7253e5ee9e554c5c7a8248a6322aa4363bb .
3723 .P 3737 .BU
3724 The function 3738 The function
3725 .Fu r1bindex() 3739 .Fu r1bindex()
3726 had been a generalized version of 3740 had been a generalized version of
3727 .Fu basename() 3741 .Fu basename()
3728 with minor differences. 3742 with minor differences.
3729 As all calls to 3743 As all calls to
3730 .Fu r1bindex() 3744 .Fu r1bindex()
3731 had the slash (`/') as delimiter anyway, 3745 had the slash (`\fL/\fP') as delimiter anyway,
3732 replacing 3746 replacing
3733 .Fu r1bindex() 3747 .Fu r1bindex()
3734 with the more specific and better-named function 3748 with the more specific and better-named function
3735 .Fu basename() 3749 .Fu basename()
3736 became desirable. 3750 became desirable.
3741 .Fu basename() . 3755 .Fu basename() .
3742 Hence, 3756 Hence,
3743 .Fu r1bindex() 3757 .Fu r1bindex()
3744 was kept but renamed to 3758 was kept but renamed to
3745 .Fu mhbasename() , 3759 .Fu mhbasename() ,
3746 fixing the delimiter to the slash. 3760 setting the delimiter to the slash
3747 .Ci 240013872c392fe644bd4f79382d9f5314b4ea60 3761 .Ci 240013872c392fe644bd4f79382d9f5314b4ea60 .
3748 For possible uses of 3762 For possible uses of
3749 .Fu r1bindex() 3763 .Fu r1bindex()
3750 with a different delimiter, 3764 with a different delimiter,
3751 the ANSI C function 3765 the ANSI C function
3752 .Fu strrchr() 3766 .Fu strrchr()
3753 provides the core functionality. 3767 provides the core functionality.
3754 .P 3768 .BU
3755 The 3769 The
3756 .Fu ssequal() 3770 .Fu ssequal()
3757 function \(en apparently for ``substring equal'' \(en 3771 function \(en apparently for ``substring equal'' \(en
3758 was renamed to 3772 was renamed to
3759 .Fu isprefix() , 3773 .Fu isprefix() ,
3760 because this is what it actually checks. 3774 because this is what it actually checked
3761 .Ci c20b4fa14515c7ab388ce35411d89a7a92300711 3775 .Ci c20b4fa14515c7ab388ce35411d89a7a92300711.
3762 Its source file had included the following comments, no joke. 3776 Its source file had included both of the following comments, no joke.
3777 .in -\n(PIu
3763 .VS 3778 .VS
3764 /* 3779 /*
3765 * THIS CODE DOES NOT WORK AS ADVERTISED. 3780 * THIS CODE DOES NOT WORK AS ADVERTISED.
3766 * It is actually checking if s1 is a PREFIX of s2. 3781 * It is actually checking if s1 is a PREFIX of s2.
3767 * All calls to this function need to be checked to see 3782 * All calls to this function need to be checked to see
3772 /* 3787 /*
3773 * Check if s1 is a substring of s2. 3788 * Check if s1 is a substring of s2.
3774 * If yes, then return 1, else return 0. 3789 * If yes, then return 1, else return 0.
3775 */ 3790 */
3776 VE 3791 VE
3777 Two months later, it was completely removed by replacing it with 3792 .in +\n(PIu
3778 .Fu strncmp() . 3793 Eventually, the function was completely replaced with calls to
3779 .Ci b0b1dd37ff515578cf7cba51625189eb34a196cb 3794 .Fu strncmp()
3795 .Ci b0b1dd37ff515578cf7cba51625189eb34a196cb .
3780 3796
3781 3797
3782 3798
3783 3799
3784 3800
3790 in the user's home directory. 3806 in the user's home directory.
3791 It contains the static configuration. 3807 It contains the static configuration.
3792 It also contains the location of the MH directory in the profile entry 3808 It also contains the location of the MH directory in the profile entry
3793 .Pe Path . 3809 .Pe Path .
3794 The MH directory contains the mail storage and is the first 3810 The MH directory contains the mail storage and is the first
3795 place to search for personal forms, scan formats, and similar 3811 place to search for form files, scan formats, and similar
3796 configuration files. 3812 configuration files.
3797 The location of the MH directory can be chosen freely by the user. 3813 The location of the MH directory can be chosen freely by the user.
3798 The default and usual name is a directory named 3814 The usual name is a directory named
3799 .Fn Mail 3815 .Fn Mail
3800 in the home directory. 3816 in the user's home directory.
3801 .P 3817 .P
3802 The way MH data is split between profile and MH directory is a legacy. 3818 The way MH data is split between profile and MH directory is a legacy.
3803 It is only sensible in a situation where the profile is the only 3819 It is only sensible in a situation where the profile is the only
3804 configuration file. 3820 configuration file.
3805 Why else should the mail storage and the configuration files be intermixed? 3821 Why else should the mail storage and the configuration files be intermixed?
3806 They are different kinds of data: 3822 They are of different kind:
3807 The data to be operated on and the configuration to change how 3823 One kind is the data to be operated on and the other kind is
3808 tools operate. 3824 the configuration to change how tools operate.
3809 .\" XXX bad ... inapropriate?
3810 Splitting the configuration between the profile and the MH directory 3825 Splitting the configuration between the profile and the MH directory
3811 is bad. 3826 is inappropriate, as well.
3812 Merging the mail storage and the configuration in one directory is bad 3827 I improved the situation by breaking compatibility.
3813 as well. 3828 .P
3814 As the mail storage and the configuration were not separated sensibly 3829 In mmh, personal data is grouped by type.
3815 in the first place, I did it now. 3830 This results in two distinct parts:
3816 .P
3817 Personal mmh data is grouped by type, resulting in two distinct parts:
3818 the mail storage and the configuration. 3831 the mail storage and the configuration.
3819 In mmh, the mail storage directory still contains all the messages, 3832 The mail storage directory still contains all the messages,
3820 but, in exception of public sequences files, nothing else. 3833 but, in exception of public sequences files, nothing else.
3821 In difference to nmh, the auxiliary configuration files are no longer 3834 In difference to nmh, the auxiliary configuration files are no longer
3822 located there. 3835 located there.
3823 Therefore, the directory is no longer called the user's \fIMH directory\fP 3836 Therefore, the directory is no longer called the user's \fIMH directory\fP
3824 but his \fImail storage\fP. 3837 but the user's \fImail storage\fP.
3825 Its location is still user-chosen, with the default name 3838 Its location is still user-chosen, with the default name
3826 .Fn Mail , 3839 .Fn Mail
3827 in the user's home directory. 3840 in the user's home directory.
3828 In mmh, the configuration is grouped together in 3841 The configuration is grouped together in the hidden directory
3829 the hidden directory
3830 .Fn \&.mmh 3842 .Fn \&.mmh
3831 in the user's home directory. 3843 in the user's home directory.
3832 This \fImmh directory\fP contains the context file, personal forms, 3844 This \fImmh directory\fP contains the context file, personal forms,
3833 scan formats, and the like, but also the user's profile, now named 3845 scan formats, and the like, but also the user's profile, now named
3834 .Fn profile . 3846 .Fn profile .
3835 The location of the profile is no longer fixed to 3847 The path to the profile is no longer
3836 .Fn $HOME/.mh_profile 3848 .Fn $HOME/.mh_profile
3837 but to 3849 but
3838 .Fn $HOME/.mmh/profile . 3850 .Fn $HOME/.mmh/profile .
3839 Having both the file 3851 (The alternative of having file
3840 .Fn $HOME/.mh_profile 3852 .Fn $HOME/.mh_profile
3841 and the configuration directory 3853 and a configuration directory
3842 .Fn $HOME/.mmh 3854 .Fn $HOME/.mmh
3843 appeared to be inconsistent. 3855 appeared to be inconsistent.)
3856 .P
3844 The approach chosen for mmh is consistent, simple, and familiar to 3857 The approach chosen for mmh is consistent, simple, and familiar to
3845 Unix users. 3858 Unix users.
3859 The main achievement of the change is the clear and sensible separation
3860 of the mail storage and the configuration.
3846 .Ci 7030d7edb099bff36ded7548bb5380f7acab4f9b 3861 .Ci 7030d7edb099bff36ded7548bb5380f7acab4f9b
3847 .P 3862 .P
3848 MH allows users to have multiple MH setups. 3863 As MH allows users to have multiple MH setups,
3849 Therefore, it is necessary to select a different profile. 3864 it is necessary to switch the profile.
3850 The profile is the single entry point to access the rest of a 3865 The profile is the single entry point to access the rest of a
3851 personal MH setup. 3866 personal MH setup.
3852 In nmh, the environment variable 3867 In nmh, the environment variable
3853 .Ev MH 3868 .Ev MH
3854 could be used to specify a different profile. 3869 is used to specify a different profile.
3855 To operate in the same MH setup with a separate context, 3870 To operate in the same MH setup with a separate context, the
3856 the
3857 .Ev MHCONTEXT 3871 .Ev MHCONTEXT
3858 environment variable could be used. 3872 environment variable is used.
3859 This allows having own current folders and current messages in 3873 This allows having a separate current folder in each terminal at
3860 each terminal, for instance. 3874 the same time, for instance.
3861 In mmh, three environment variables are used. 3875 In mmh, three environment variables replace the two of nmh.
3862 .Ev MMH 3876 .Ev MMH
3863 overrides the default location of the mmh directory (\c 3877 overrides the default location of the mmh directory (\c
3864 .Fn .mmh ). 3878 .Fn .mmh ).
3865 .Ev MMHP 3879 .Ev MMHP
3866 and 3880 and
3867 .Ev MMHC 3881 .Ev MMHC
3868 override the paths to the profile and context files, respectively. 3882 override the paths to the profile and context file, respectively.
3869 This approach allows the set of personal configuration files to be chosen 3883 This approach allows the set of personal configuration files to be chosen
3870 independently from the profile, context, and mail storage. 3884 independently of the profile, context, and mail storage.
3871 .Ci 7030d7edb099bff36ded7548bb5380f7acab4f9b
3872 .P
3873 The separation of the files by type is sensible and convenient.
3874 The new approach has no functional disadvantages, 3885 The new approach has no functional disadvantages,
3875 as every setup I can imagine can be implemented with both approaches, 3886 as every setup I can imagine can be implemented with both approaches,
3876 possibly even easier with the new approach. 3887 possibly even easier with the new one.
3877 The main achievement of the change is the clear and sensible split 3888 .Ci 7030d7edb099bff36ded7548bb5380f7acab4f9b
3878 between mail storage and configuration.
3879 3889
3880 3890
3881 3891
3882 3892
3883 3893
3884 .H2 "Modularization 3894 .H2 "Modularization
3895 .Id modularization
3885 .P 3896 .P
3886 The source code of the mmh tools is located in the 3897 The source code of the mmh tools is located in the
3887 .Fn uip 3898 .Fn uip
3888 (``user interface programs'') directory. 3899 (``user interface programs'') directory.
3889 Each tool has a source file with the name of the command. 3900 Each tool has a source file with the name of the command.
3909 (These numbers and the ones in the following text ignore the MH library 3920 (These numbers and the ones in the following text ignore the MH library
3910 as well as shell scripts and multiple names for the same program.) 3921 as well as shell scripts and multiple names for the same program.)
3911 .\" XXX graph 3922 .\" XXX graph
3912 .P 3923 .P
3913 Splitting the source code of a large program into multiple files can 3924 Splitting the source code of a large program into multiple files can
3914 increase the readability of its source code. 3925 increase the readability of its source code,
3915 .\" XXX however? 3926 but most of the mmh tools are small and straight-forward programs.
3916 Most of the mmh tools are simple and straight-forward programs. 3927 In exception of the MIME handling tools (i.e.
3917 With the exception of the MIME handling tools,
3918 .Pn pick
3919 is the largest tool.
3920 It contains 1\|037 lines of source code, excluding the MH library.
3921 Only the MIME handling tools (\c
3922 .Pn mhbuild , 3928 .Pn mhbuild ,
3923 .Pn mhstore , 3929 .Pn mhstore ,
3924 .Pn show , 3930 .Pn show ,
3925 etc.) 3931 etc.),
3926 are larger. 3932 .Pn pick
3927 Splitting programs with less than 1\|000 lines of code into multiple 3933 is the only tool with more than one thousand lines of source code.
3928 source files seldom leads to better readability. 3934 Splitting programs with less than one thousand lines of code into
3929 For such tools, splitting makes sense 3935 multiple source files leads seldom to better readability.
3930 when parts of the code are reused in other programs, 3936 For such tools, splitting still makes sense
3937 when parts of the code are reused in other programs
3931 and the reused code fragment is (1) not general enough 3938 and the reused code fragment is (1) not general enough
3932 for including it in the MH library 3939 for including it in the MH library
3933 or (2) has dependencies on a library that only few programs need. 3940 or (2) has dependencies on a library that only few programs need.
3934 .Fn uip/packsbr.c , 3941 .Fn uip/packsbr.c ,
3935 for instance, provides the core program logic for the 3942 for instance, provides the core program logic for the
3942 .Fn uip/rcvpack.c 3949 .Fn uip/rcvpack.c
3943 mainly wrap the core function appropriately. 3950 mainly wrap the core function appropriately.
3944 No other tools use the folder packing functions. 3951 No other tools use the folder packing functions.
3945 As another example, 3952 As another example,
3946 .Fn uip/termsbr.c 3953 .Fn uip/termsbr.c
3947 provides termcap support, which requires linking with a termcap or 3954 accesses terminal properties, which requires linking with the
3948 curses library. 3955 \fItermcap\fP or a \fIcurses\fP library.
3949 Including 3956 If
3950 .Fn uip/termsbr.c 3957 .Fn uip/termsbr.c
3951 into the MH library would require every program to be linked with 3958 is included in the MH library, then every program needs to be linked
3952 termcap or curses, although only few of the programs require it. 3959 with termcap or curses, although only few of the programs use
3960 the library.
3953 .P 3961 .P
3954 The task of MIME handling is complex enough that splitting its code 3962 The task of MIME handling is complex enough that splitting its code
3955 into multiple source files improves the readability. 3963 into multiple source files improves the readability.
3956 The program 3964 The program
3957 .Pn mhstore , 3965 .Pn mhstore ,
3958 for instance, is compiled out of seven source files with 2\|500 3966 for instance, is compiled out of seven source files with 2\|500
3959 lines of code in summary. 3967 lines of code in summary.
3960 The main code file 3968 The main code file
3961 .Fn uip/mhstore.c 3969 .Fn uip/mhstore.c
3962 consists of 800 lines; the other 1\|700 lines of code are reused in 3970 consists of 800 lines; the other 1\|700 lines are code reused in
3963 other MIME handling tools. 3971 other MIME handling tools.
3964 It seems to be worthwhile to bundle the generic MIME handling code into 3972 It seems to be worthwhile to bundle the generic MIME handling code into
3965 a MH-MIME library, as a companion to the MH standard library. 3973 a MH-MIME library, as a companion to the MH standard library.
3966 This is left open for the future. 3974 This is left to be done.
3967 .P 3975 .P
3968 The work already accomplished focussed on the non-MIME tools. 3976 The work already accomplished focussed on the non-MIME tools.
3969 The amount of code compiled into each program was reduced. 3977 The amount of code compiled into each program was reduced.
3970 This eases the understanding of the code base. 3978 This eases the understanding of the code base.
3971 In nmh, 3979 In nmh,
3987 the core function of 3995 the core function of
3988 .Pn whatnow , 3996 .Pn whatnow ,
3989 .Pn send , 3997 .Pn send ,
3990 and 3998 and
3991 .Pn anno 3999 .Pn anno
3992 were compiled into 4000 were all compiled into
3993 .Pn comp . 4001 .Pn comp .
3994 This saved the need to execute these programs with 4002 This saved the need to execute these programs with
4003 the expensive system calls
3995 .Fu fork() 4004 .Fu fork()
3996 and 4005 and
3997 .Fu exec() , 4006 .Fu exec() .
3998 two expensive system calls.
3999 Whereas this approach improved the time performance, 4007 Whereas this approach improved the time performance,
4000 it interwove the source code. 4008 it interwove the source code.
4001 Core functionalities were not encapsulated into programs but into 4009 Core functionalities were not encapsulated into programs but into
4002 function, which were then wrapped by programs. 4010 function, which were then wrapped by programs.
4003 For example, 4011 For example,
4014 .Pn anno , 4022 .Pn anno ,
4015 it had seven parameters, reflecting the command line switches of the tool. 4023 it had seven parameters, reflecting the command line switches of the tool.
4016 When another pair of command line switches was added to 4024 When another pair of command line switches was added to
4017 .Pn anno , 4025 .Pn anno ,
4018 a rather ugly hack was implemented to avoid adding another parameter 4026 a rather ugly hack was implemented to avoid adding another parameter
4019 to the function. 4027 to the function
4020 .Ci d9b1d57351d104d7ec1a5621f090657dcce8cb7f 4028 .Ci d9b1d57351d104d7ec1a5621f090657dcce8cb7f .
4021 .P 4029 .P
4022 Separation simplifies the understanding of program code
4023 because the area influenced by any particular statement is smaller.
4024 The separating on the program-level is more strict than the separation
4025 on the function level.
4026 In mmh, the relevant code of 4030 In mmh, the relevant code of
4027 .Pn comp 4031 .Pn comp
4028 comprises the two files 4032 comprises the two files
4029 .Fn uip/comp.c 4033 .Fn uip/comp.c
4030 and 4034 and
4031 .Fn uip/whatnowproc.c , 4035 .Fn uip/whatnowproc.c ,
4032 together 210 lines of code. 4036 together 210 lines of code,
4033 In nmh, 4037 whereas in nmh,
4034 .Pn comp 4038 .Pn comp
4035 comprises six files with 2\|450 lines. 4039 comprises six files with 2\|450 lines.
4036 Not all of the code in these six files was actually used by 4040 Not all of the code in these six files is actually used by
4037 .Pn comp , 4041 .Pn comp ,
4038 but the code reader needed to read all of the code first to know which 4042 but the reader needed to read it all to know which parts are relevant.
4039 parts were used. 4043 Understanding nmh's
4040 .P
4041 As I have read a lot in the code base during the last two years,
4042 I learned about the easy and the difficult parts.
4043 Code is easy to understand if the influenced code area is small
4044 and its boundaries are strictly defined.
4045 Furthermore, the code needs to solve the problem in a straight-forward way.
4046 .P
4047 .\" XXX move this paragraph somewhere else?
4048 Reading
4049 .Pn rmm 's
4050 source code in
4051 .Fn uip/rmm.c
4052 is my recommendation for a beginner's entry point into the code base of nmh.
4053 The reasons are that the task of
4054 .Pn rmm
4055 is straight forward and it consists of one small source code file only,
4056 yet its source includes code constructs typical for MH tools.
4057 With the introduction of the trash folder in mmh,
4058 .Pn rmm
4059 became a bit more complex, because it invokes
4060 .Pn refile .
4061 Still, it is a good example for a simple tool with clear sources.
4062 .P
4063 Understanding
4064 .Pn comp
4065 .\" XXX kate fragen: more vs. as much
4066 requires to read 210 lines of code in mmh, but ten times more in nmh.
4067 Due to the aforementioned hack in
4068 .Pn anno
4069 to save the additional parameter, information passed through the program's
4070 source base in obscure ways.
4071 Thus, understanding
4072 .Pn comp , 4044 .Pn comp ,
4073 required understanding the inner workings of 4045 required understanding the inner workings of
4074 .Fn uip/annosbr.c 4046 .Fn uip/annosbr.c
4075 first. 4047 first.
4076 To be sure to fully understand a program, its whole source code needs 4048 To be sure to fully understand a program, its whole source code needs
4077 to be examined. 4049 to be examined.
4078 Not doing so is a leap of faith, assuming that the developers 4050 Not doing so is a leap of faith, assuming that the developers
4079 have avoided obscure programming techniques. 4051 have avoided obscure programming techniques.
4080 By separating the tools on the program-level, the boundaries are 4052 Here, it should be recalled that information passed in obscure ways
4081 clearly visible and technically enforced. 4053 through the program's source base, due to the aforementioned hack
4082 The interfaces are calls to 4054 to save an additional parameter in nmh's
4055 .Pn anno .
4056 .P
4057 In mmh, understanding
4058 .Pn comp
4059 requires to read only 210 lines of code to read, whereas the amount
4060 is ten times more for nmh's
4061 .Pn comp .
4062 .P
4063 By separating the tools on the program-level,
4064 the boundaries are clearly visible, as the interfaces are calls to
4083 .Fu exec() 4065 .Fu exec()
4084 rather than arbitrary function calls. 4066 rather than arbitrary function calls.
4085 .P 4067 Additionally, this kind of separation is more strict because
4086 But the real problem is another: 4068 it is technically enforced by the operating system;
4069 it can not be simply bypassed with global variables.
4070 Good separation simplifies the understanding of program code
4071 because the area influenced by any particular statement is small.
4072 As I have read a lot in nmh's code base during the last two years,
4073 I have learned about the easy and the difficult parts.
4074 In my observation, the understanding of code is enormously eased
4075 if the influenced area is small and clearly bounded.
4076 .P
4077 Yet, the real problem is another:
4087 Nmh violates the golden ``one tool, one job'' rule of the Unix philosophy. 4078 Nmh violates the golden ``one tool, one job'' rule of the Unix philosophy.
4088 .\" XXX ref
4089 Understanding 4079 Understanding
4090 .Pn comp 4080 .Pn comp
4091 requires understanding 4081 requires understanding
4092 .Fn uip/annosbr.c 4082 .Fn uip/annosbr.c
4093 and 4083 and
4094 .Fn uip/sendsbr.c 4084 .Fn uip/sendsbr.c
4095 because 4085 because
4096 .Pn comp 4086 .Pn comp
4097 does annotate and send messages. 4087 annotates and sends messages.
4098 In nmh, there surely exists the tool 4088 In nmh, there surely exist the tools
4089 .Pn anno
4090 and
4099 .Pn send , 4091 .Pn send ,
4100 which does mainly send messages. 4092 which cover these jobs,
4101 But 4093 but
4102 .Pn comp 4094 .Pn comp
4103 and 4095 and
4104 .Pn repl 4096 .Pn repl
4105 and 4097 and
4106 .Pn forw 4098 .Pn forw
4107 and 4099 and
4108 .Pn dist 4100 .Pn dist
4109 and 4101 and
4110 .Pn whatnow 4102 .Pn whatnow
4111 and 4103 and
4112 .Pn viamail , 4104 .Pn viamail
4113 they all (!) have the same message sending function included, as well. 4105 \(en they all (!) \(en
4114 In result, 4106 have the same annotating and sending functions included, once more.
4107 As a result,
4115 .Pn comp 4108 .Pn comp
4116 sends messages without using 4109 sends messages without using
4117 .Pn send . 4110 .Pn send .
4118 The situation is the same as if 4111 The situation is the same as if
4119 .Pn grep 4112 .Pn grep
4120 would page without 4113 would page its output without using
4121 .Pn more 4114 .Pn more
4122 just because both programs are part of the same code base. 4115 just because both programs are part of the same code base.
4123 .P 4116 .P
4124 The clear separation on the surface \(en the tool chest approach \(en 4117 The clear separation on the surface of nmh
4118 \(en the tool chest approach \(en
4125 is violated on the level below. 4119 is violated on the level below.
4126 This violation is for the sake of time performance. 4120 This violation is for the sake of time performance.
4127 On systems where 4121 Decades ago, sacrificing readability and conceptional beauty
4128 .Fu fork() 4122 for speed might have been necessary to prevent MH from being
4129 and 4123 unusably slow, but today this is not the case anymore.
4130 .Fu exec() 4124 No longer should speed improvements that became unnecessary be kept.
4131 are expensive, the quicker response might be noticable. 4125 No longer should readability or conceptional beauty be sacrificed.
4132 In the old times, sacrificing readability and conceptional beauty for 4126 No longer should the Unix philosophy's ``one tool, one job''
4133 speed might even have been a must to prevent MH from being unusably slow. 4127 guideline be violated.
4134 Whatever the reasons had been, today they are gone.
4135 No longer should we sacrifice readability or conceptional beauty.
4136 No longer should we violate the Unix philosophy's ``one tool, one job''
4137 guideline.
4138 .\" XXX ref
4139 No longer should we keep speed improvements that became unnecessary.
4140 .P
4141 Therefore, mmh's 4128 Therefore, mmh's
4142 .Pn comp 4129 .Pn comp
4143 does no longer send messages. 4130 no longer sends messages.
4131 .P
4144 In mmh, different jobs are divided among separate programs that 4132 In mmh, different jobs are divided among separate programs that
4145 invoke each other as needed. 4133 invoke each other as needed.
4146 In consequence, 4134 In consequence,
4147 .Pn comp 4135 .Pn comp
4148 invokes 4136 invokes
4149 .Pn whatnow 4137 .Pn whatnow
4150 which thereafter invokes 4138 which thereafter invokes
4151 .Pn send . 4139 .Pn send
4152 .Ci 3df5ab3c116e6d4a2fb4bb5cc9dfc5f781825815 4140 .Ci 3df5ab3c116e6d4a2fb4bb5cc9dfc5f781825815
4153 .Ci c73c00bfccd22ec77e9593f47462aeca4a8cd9c0 4141 .Ci c73c00bfccd22ec77e9593f47462aeca4a8cd9c0 .
4154 The clear separation on the surface is maintained on the level below. 4142 The clear separation on the surface is maintained on the level below.
4155 Human users and the tools use the same interface \(en 4143 Human users and other tools use the same interface \(en
4156 annotations, for example, are made by invoking 4144 annotations, for example, are made by invoking
4157 .Pn anno , 4145 .Pn anno ,
4158 no matter if requested by programs or by human beings. 4146 no matter if requested by programs or by human beings
4159 .Ci 469a4163c2a1a43731d412eaa5d9cae7d670c48b 4147 .Ci 469a4163c2a1a43731d412eaa5d9cae7d670c48b
4160 .Ci aed384169af5204b8002d06e7a22f89197963d2d 4148 .Ci aed384169af5204b8002d06e7a22f89197963d2d
4161 .Ci 3caf9e298a8861729ca8b8a84f57022b6f3ea742 4149 .Ci 3caf9e298a8861729ca8b8a84f57022b6f3ea742 .
4162 The decrease of tools built from multiple source files and thus 4150 The decrease of tools built from multiple source files and thus
4163 the decrease of 4151 the decrease of
4164 .Fn uip/*sbr.c 4152 .Fn uip/*sbr.c
4165 files confirm the improvement. 4153 files confirm the improvement
4166 .Ci 9e6d91313f01c96b4058d6bf419a8ca9a207bc33 4154 .Ci 9e6d91313f01c96b4058d6bf419a8ca9a207bc33
4167 .ci 81744a46ac9f845d6c2b9908074d269275178d2e 4155 .ci 81744a46ac9f845d6c2b9908074d269275178d2e
4168 .Ci f0f858069d21111f0dbea510044593f89c9b0829 4156 .Ci f0f858069d21111f0dbea510044593f89c9b0829
4169 .Ci 0503a6e9be34f24858b55b555a5c948182b9f24b 4157 .Ci 0503a6e9be34f24858b55b555a5c948182b9f24b
4170 .Ci 27826f9353e0f0b04590b7d0f8f83e60462b90f0 4158 .Ci 27826f9353e0f0b04590b7d0f8f83e60462b90f0
4171 .Ci d1da1f94ce62160aebb30df4063ccbc53768656b 4159 .Ci d1da1f94ce62160aebb30df4063ccbc53768656b
4172 .Ci c42222869e318fff5dec395eca3e776db3075455 4160 .Ci c42222869e318fff5dec395eca3e776db3075455 .
4173 .P 4161 This is also visible in the complexity of the build dependency graphs:
4174 .\" XXX move this paragraph up somewhere 4162
4175 One disadvantage needs to be taken with this change: 4163 .sp
4176 The compiler can no longer check the integrity of the interfaces. 4164 Nmh:
4177 By changing the command line interfaces of tools, it is 4165 .BP input/deps-nmh.eps .5i
4178 the developer's job to adjust the invocations of these tools as well. 4166 .EP
4179 As this is a manual task and regression tests, which could detect such 4167 .sp
4180 problems, are not available yet, it is prone to errors. 4168 Mmh:
4181 These errors will not be detected at compile time but at run time. 4169 .BP input/deps-mmh.eps .8i
4182 Installing regression tests is a pending task. 4170 .EP
4183 In the best case, a uniform way of invoking tools from other tools 4171
4184 can be developed to allow automated testing at compile time. 4172 The figures display all program to source file relationships
4185 4173 that are not one-to-one,
4186 4174 i.e. all programs that are built from multiple source files.
4187 .ig 4175 The primary source file of each program is omited from the graph.
4188 XXX consider writing about mhl vs. mhlproc
4189
4190 sbr/showfile.c
4191
4192 23 /*
4193 24 ** If you have your lproc listed as "mhl",
4194 25 ** then really invoked the mhlproc instead
4195 26 ** (which is usually mhl anyway).
4196 27 */
4197
4198 Sat Nov 24 19:09:14 1984 /mtr (agent: Marshall Rose) <uci@udel-dewey>
4199
4200 sbr/showfile.c: if lproc is "mhl", use mhlproc for consistency
4201 (Actually, user should use "lproc: show", "showproc: mhl".)
4202 ..