comparison discussion.roff @ 219:8c537982d718

Further improvements of the discussion chapter. There's a bit more to come ... tomorrow.
author markus schnalke <meillo@marmaro.de>
date Sat, 14 Jul 2012 23:19:27 +0200
parents f3f65376bef9
children 95257474a123
comparison
equal deleted inserted replaced
218:8be9e84be526 219:8c537982d718
2877 2877
2878 .\" -------------------------------------------------------------- 2878 .\" --------------------------------------------------------------
2879 .H1 "Styling 2879 .H1 "Styling
2880 .P 2880 .P
2881 Kernighan and Pike have emphasized the importance of style in the 2881 Kernighan and Pike have emphasized the importance of style in the
2882 preface of their book: 2882 preface of \fPThe Practice of Programming\fP:
2883 .[ [ 2883 .[ [
2884 kernighan pike practice of programming 2884 kernighan pike practice of programming
2885 .], p. x] 2885 .], p. x]
2886 .QS 2886 .QS
2887 Chapter 1 discusses programming style. 2887 Chapter 1 discusses programming style.
2888 Good style is so important to good programming that we have chose 2888 Good style is so important to good programming that we have chosen
2889 to cover it first. 2889 to cover it first.
2890 .QE 2890 .QE
2891 This section covers changes in mmh that were guided by the desire 2891 This section covers changes in mmh that were guided by the desire
2892 to improve on style. 2892 to improve on style.
2893 Many of them follow the rules given in the quoted book. 2893 Many of them follow the advice given in the quoted book.
2894 .[
2895 kernighan pike practice of programming
2896 .]
2897 2894
2898 2895
2899 2896
2900 2897
2901 .H2 "Code Style 2898 .H2 "Code Style
2902 .Id code-style 2899 .Id code-style
2903 .P 2900 .P
2904 .U3 "Indentation Style 2901 .U3 "Indentation Style
2905 .P 2902 .P
2906 Indentation styles are the holy cow of programmers. 2903 Indentation styles are the holy cow of programming.
2907 Kernighan and Pike 2904 Kernighan and Pike write:
2908 .[ [ 2905 .[ [
2909 kernighan pike practice of programming 2906 kernighan pike practice of programming
2910 .], p. 10] 2907 .], p. 10]
2911 wrote:
2912 .QS 2908 .QS
2913 Programmers have always argued about the layout of programs, 2909 Programmers have always argued about the layout of programs,
2914 but the specific style is much less important than its consistent 2910 but the specific style is much less important than its consistent
2915 application. 2911 application.
2916 Pick one style, preferably ours, use it consistently, and don't waste 2912 Pick one style, preferably ours, use it consistently, and don't waste
2918 .QE 2914 .QE
2919 .P 2915 .P
2920 I agree that the constant application is most important, 2916 I agree that the constant application is most important,
2921 but I believe that some styles have advantages over others. 2917 but I believe that some styles have advantages over others.
2922 For instance the indentation with tab characters only. 2918 For instance the indentation with tab characters only.
2923 Tab characters directly map to the nesting level \(en 2919 The number of tabs corresponds to the nesting level \(en
2924 one tab, one level. 2920 one tab, one level.
2925 Tab characters are flexible because developers can adjust them to 2921 Tab characters provide flexible visual appearance because developers
2926 whatever width they like to have. 2922 can adjust their width as prefered.
2927 There is no more need to run 2923 There is no more need to check for the correct mixture of
2928 .Pn unexpand 2924 tabs and spaces.
2929 or 2925 Two simple rules ensure the integrity and flexibility of the visual
2930 .Pn entab 2926 appearance:
2931 programs to ensure the correct mixture of leading tabs and spaces. 2927 .LI 1
2932 The simple rules are: (1) Leading whitespace must consist of tabs only. 2928 Leading whitespace must consist of tabs only.
2933 (2) Any other whitespace should consist of spaces. 2929 .LI 2
2934 These two rules ensure the integrity of the visual appearance. 2930 All other whitespace should be spaces.
2931 .LP
2935 Although reformatting existing code should be avoided, I did it. 2932 Although reformatting existing code should be avoided, I did it.
2936 I did not waste time arguing; I just reformatted the code. 2933 I did not waste time arguing; I just reformatted the code.
2937 .Ci a485ed478abbd599d8c9aab48934e7a26733ecb1 2934 .Ci a485ed478abbd599d8c9aab48934e7a26733ecb1
2938 2935
2939 .U3 "Comments 2936 .U3 "Comments
2940 .P 2937 .P
2941 Section 1.6 of 2938 Kernighan and Pike demand: ``Don't belabor the obvious''.
2942 .[ [ 2939 .[ [
2943 kernighan pike practice of programming 2940 kernighan pike practice of programming
2944 .], p. 23] 2941 .], p. 23]
2945 demands: ``Don't belabor the obvious.'' 2942 Following the advice, I removed unnecessary comments.
2946 Hence, I simply removed all the comments in the following code excerpt: 2943 For instance, I removed all comments in the following code excerpt
2944 .Ci 426543622b377fc5d091455cba685e114b6df674 :
2947 .VS 2945 .VS
2948 context_replace(curfolder, folder); /* update current folder */ 2946 context_replace(curfolder, folder); /* update current folder */
2949 seq_setcur(mp, mp->lowsel); /* update current message */ 2947 seq_setcur(mp, mp->lowsel); /* update current message */
2950 seq_save(mp); /* synchronize message sequences */ 2948 seq_save(mp); /* synchronize message sequences */
2951 folder_free(mp); /* free folder/message structure */ 2949 folder_free(mp); /* free folder/message structure */
2959 [...] 2957 [...]
2960 2958
2961 /* NUL-terminate the field */ 2959 /* NUL-terminate the field */
2962 *cp = '\0'; 2960 *cp = '\0';
2963 VE 2961 VE
2964 .Ci 426543622b377fc5d091455cba685e114b6df674 2962 .P
2965 .P 2963 The information in each of the comments was present in the code
2966 The program code explains enough itself, already. 2964 statements already, except for the NUL-termination, which became
2965 obvious from the context.
2967 2966
2968 2967
2969 .U3 "Names 2968 .U3 "Names
2970 .P 2969 .P
2971 Kernighan and Pike suggest: 2970 Regarding this topic, Kernighan and Pike suggest:
2972 ``Use active names for functions''. 2971 ``Use active names for functions''.
2973 .[ [ 2972 .[ [
2974 kernighan pike practice of programming 2973 kernighan pike practice of programming
2975 .], p. 4] 2974 .], p. 4]
2976 One application of this rule was the rename of 2975 One application of this rule was the rename of
2977 .Fu check_charset() 2976 .Fu check_charset()
2978 to 2977 to
2979 .Fu is_native_charset() . 2978 .Fu is_native_charset()
2980 .Ci 8d77b48284c58c135a6b2787e721597346ab056d 2979 .Ci 8d77b48284c58c135a6b2787e721597346ab056d .
2981 The same change fixed a violation of ``Be accurate'' 2980 The same change additionally fixed a violation of ``Be accurate'',
2982 .[ [ 2981 .[ [
2983 kernighan pike practice of programming 2982 kernighan pike practice of programming
2984 .], p. 4] 2983 .], p. 4]
2985 as well. 2984 as the code did not match the expectation the function suggested.
2986 The code did not match the expectation the function suggested, 2985 It did not compare charset names but prefixes of them only.
2987 as it, for whatever reason, only compared the first ten characters 2986 In case the native charset was `ISO-8859-1', then
2988 of the charset name. 2987 .VS
2988 check_charset("ISO-8859-11", strlen("ISO-8859-11"))
2989 VE
2990 had returned true although the upper halves of the code pages
2991 are different.
2989 .P 2992 .P
2990 More important than using active names is using descriptive names. 2993 More important than using active names is using descriptive names.
2991 .VS 2994 .VS
2992 m_unknown(in); /* the MAGIC invocation... */ 2995 m_unknown(in); /* the MAGIC invocation... */
2993 VE 2996 VE
2994 Renaming the obscure 2997 Renaming the obscure
2995 .Fu m_unknown() 2998 .Fu m_unknown()
2996 function was a delightful event, although it made the code less funny. 2999 function was a delightful event, although it made the code less funny
2997 .Ci 611d68d19204d7cbf5bd585391249cb5bafca846 3000 .Ci 611d68d19204d7cbf5bd585391249cb5bafca846 .
2998 .P 3001 .P
2999 Magic numbers are generally considered bad style. 3002 Magic numbers are generally considered bad style.
3000 Obviously, Kernighan and Pike agree: 3003 Obviously, Kernighan and Pike agree:
3001 ``Give names to magic numbers''. 3004 ``Give names to magic numbers''.
3002 .[ [ 3005 .[ [
3003 kernighan pike practice of programming 3006 kernighan pike practice of programming
3004 .], p. 19] 3007 .], p. 19]
3005 One such change was naming the type of input \(en mbox or mail folder \(en 3008 .P
3006 to be scanned: 3009 The argument
3010 .CW outnum
3011 of the function
3012 .Fu scan()
3013 in
3014 .Fn uip/scansbr.c
3015 holds the number of the message to be created.
3016 As well it encodes program logic with negative numbers and zero.
3017 This led to obscure code.
3018 I clarified the code by introducing two variables that extracted
3019 the hidden information:
3020 .VS
3021 int incing = (outnum > 0);
3022 int ismbox = (outnum != 0);
3023 VE
3024 The readable names are thus used in conditions;
3025 the variable
3026 .CW outnum
3027 is used only to extract ordinary message numbers
3028 .Ci b8b075c77be7794f3ae9ff0e8cedb12b48fd139f .
3029 .P
3030 Through the clarity improvement of the change detours in the program
3031 logic of related code parts became apparent.
3032 The implementation was simplified.
3033 This possibility to improve had been invisible before
3034 .Ci aa60b0ab5e804f8befa890c0a6df0e3143ce0723 .
3035 .P
3036 The names just described were a first step, yet the situation
3037 was further improved by giving names to the magic values of
3038 .CW outnum :
3007 .VS 3039 .VS
3008 #define SCN_MBOX (-1) 3040 #define SCN_MBOX (-1)
3009 #define SCN_FOLD 0 3041 #define SCN_FOLD 0
3010 VE 3042 VE
3043 The two variables were updated thereafter as well:
3044 .VS
3045 int incing = (outnum != SCN_MBOX && outnum != SCN_FOLD);
3046 int scanfolder = (outnum == SCN_FOLD);
3047 VE
3048 Furthermore,
3049 .CW ismbox
3050 was replaced by
3051 .CW scanfolder
3052 because that matched better to the program logic.
3011 .Ci 7ffb36d28e517a6f3a10272056fc127592ab1c19 3053 .Ci 7ffb36d28e517a6f3a10272056fc127592ab1c19
3012 .P 3054
3013 The argument
3014 .Ar outnum
3015 of the function
3016 .Fu scan()
3017 in
3018 .Fn uip/scansbr.c
3019 defines the number of the message to be created.
3020 If no message is to be created, the argument is misused to transport
3021 program logic.
3022 This lead to obscure code.
3023 I improved the clarity of the code by introducing two variables:
3024 .VS
3025 int incing = (outnum > 0);
3026 int ismbox = (outnum != 0);
3027 VE
3028 They cover the magic values and are used for conditions.
3029 The variable
3030 .Ar outnum
3031 is only used when it holds an ordinary message number.
3032 .Ci b8b075c77be7794f3ae9ff0e8cedb12b48fd139f
3033 The clarity improvement of the change showed detours in the program logic
3034 of related code parts.
3035 Having the new variables with descriptive names, a more
3036 straight forward implementation became apparent.
3037 Before the code was clarified, the possibility to improve had not be seen.
3038 .Ci aa60b0ab5e804f8befa890c0a6df0e3143ce0723
3039 3055
3040 3056
3041 3057
3042 .H2 "Structural Rework 3058 .H2 "Structural Rework
3043 .P 3059 .P
3044 Although the stylistic changes described up to here improve the 3060 Although the stylistic changes described already improve the
3045 readability of the source code, all of them are changes ``in the small''. 3061 readability of the source code, all of them were changes ``in the small''.
3046 Structural changes affect a much larger area. 3062 Structural changes, in contrast, affect much larger code areas.
3047 They are more difficult to do but lead to larger improvements, 3063 They are more difficult to accomplish but lead to larger improvements,
3048 especially as they influence the outer shape of the tools as well. 3064 especially as they often influence the outer shape of the tools as well.
3049 .P 3065 .P
3050 At the end of their chapter on style, 3066 At the end of their chapter on style,
3051 Kernighan and Pike ask: ``But why worry about style?'' 3067 Kernighan and Pike ask: ``But why worry about style?''
3052 .[ [ 3068 .[ [
3053 kernighan pike practice of programming 3069 kernighan pike practice of programming
3054 .], p. 28] 3070 .], p. 28].
3055 Following are two examples of structural rework that show 3071 Following are two examples of structural rework that demonstrate
3056 why style is important in the first place. 3072 why style is important in the first place.
3057 3073
3058 3074
3059 .U3 "Rework of \f(CWanno\fP 3075 .U3 "Rework of \f(CWanno\fP
3060 .P 3076 .P
3061 Until 2002, 3077 Until 2002,
3062 .Pn anno 3078 .Pn anno
3063 had six functional command line switches, 3079 had six functional command line switches:
3064 .Sw -component 3080 .Sw -component
3065 and 3081 and
3066 .Sw -text , 3082 .Sw -text ,
3067 which have an argument each, 3083 each with an argument,
3068 and the two pairs of flags, 3084 and the two pairs of flags,
3069 .Sw -[no]date 3085 .Sw -[no]date
3070 and 3086 and
3071 .Sw -[no]inplace . 3087 .Sw -[no]inplace .
3072 Then Jon Steinhart introduced his attachment system. 3088 Then Jon Steinhart introduced his attachment system.
3077 .Sw -list , 3093 .Sw -list ,
3078 .Sw -delete , 3094 .Sw -delete ,
3079 .Sw -append , 3095 .Sw -append ,
3080 and 3096 and
3081 .Sw -number , 3097 .Sw -number ,
3082 the last one taking an argument. 3098 the last one taking an argument
3083 .Ci 7480dbc14bc90f2d872d434205c0784704213252 3099 .Ci 7480dbc14bc90f2d872d434205c0784704213252 .
3084 Later, 3100 Later,
3085 .Sw -[no]preserve 3101 .Sw -[no]preserve
3086 was added. 3102 was added as well
3087 .Ci d9b1d57351d104d7ec1a5621f090657dcce8cb7f 3103 .Ci d9b1d57351d104d7ec1a5621f090657dcce8cb7f .
3088 Then, the Synopsis section of the man page 3104 Then, the Synopsis section of the man page
3089 .Mp anno (1) 3105 .Mp anno (1)
3090 read: 3106 read:
3091 .VS 3107 .VS
3092 anno [+folder] [msgs] [-component field] [-inplace | -noinplace] 3108 anno [+folder] [msgs] [-component f(CIfieldfP] [-inplace | -noinplace]
3093 [-date | -nodate] [-draft] [-append] [-list] [-delete] 3109 [-date | -nodate] [-draft] [-append] [-list] [-delete]
3094 [-number [num|all]] [-preserve | -nopreserve] [-version] 3110 [-number [f(CInumfP|fPallfP]] [-preserve | -nopreserve] [-version]
3095 [-help] [-text body] 3111 [-help] [-text f(CIbodyfP]
3096 VE 3112 VE
3097 .LP 3113 .LP
3098 The implementation followed the same structure. 3114 The implementation followed the same structure.
3099 Problems became visible when 3115 Problems became visible when
3100 .Cl "anno -list -number 42 3116 .Cl "anno -list -number 42
3101 worked on the current message instead on message number 42, 3117 worked on the current message instead of on message number 42,
3102 and 3118 and
3103 .Cl "anno -list -number l:5 3119 .Cl "anno -list -number l:5
3104 did not work on the last five messages but failed with the mysterious 3120 did not work on the last five messages but failed with the mysterious
3105 error message: ``anno: missing argument to -list''. 3121 error message: ``anno: missing argument to -list''.
3106 Yet, the invocation matched the specification in the man page. 3122 Yet, the invocation matched the specification in the man page.
3120 .Sw -number 3136 .Sw -number
3121 option is also used. 3137 option is also used.
3122 .QE 3138 .QE
3123 .LP 3139 .LP
3124 The problem was manifold. 3140 The problem was manifold.
3125 The code required a numeric argument to the
3126 .Sw -number
3127 switch.
3128 If it was missing or non-numeric,
3129 .Pn anno
3130 aborted with an error message that had an off-by-one error,
3131 printing the switch one before the failing one.
3132 Semantically, the argument to the 3141 Semantically, the argument to the
3133 .Sw -number 3142 .Sw -number
3134 switch is only necessary in combination with 3143 switch is only necessary in combination with
3135 .Sw -delete , 3144 .Sw -delete ,
3136 but not with 3145 but not with
3137 .Sw -list . 3146 .Sw -list .
3138 .P 3147 The code, however, required a numeric argument in any case.
3139 Trying to fix these problems on the surface would not have solved 3148 If the argument was missing or non-numeric,
3140 them truly, as they originate from a discrepance between the 3149 .Pn anno
3150 aborted with an error message that additionally had an off-by-one error.
3151 It printed the name of the switch one before the concerned one.
3152 .P
3153 Trying to fix these problems on the surface would not have solved them.
3154 They originate from a discrepance between the
3141 structure of the problem and the structure implemented in the program. 3155 structure of the problem and the structure implemented in the program.
3142 Such structural differences can not be cured on the surface. 3156 Such structural differences can only be solved by adjusting the
3143 They need to be solved by adjusting the structure of the implementation 3157 structure of the implementation to the structure of the problem.
3144 to the structure of the problem. 3158 .P
3145 .P 3159 Steinhart had added the new
3146 In 2002, the new switches
3147 .Sw -list 3160 .Sw -list
3148 and 3161 and
3149 .Sw -delete 3162 .Sw -delete
3150 were added in the same way, the 3163 switches in a style similar to the other switches though
3151 .Sw -number 3164 they are of structural different type.
3152 switch for instance had been added.
3153 Yet, they are of structural different type.
3154 Semantically, 3165 Semantically,
3155 .Sw -list 3166 .Sw -list
3156 and 3167 and
3157 .Sw -delete 3168 .Sw -delete
3158 introduce modes of operation. 3169 introduce operation modes.
3159 Historically, 3170 Historically,
3160 .Pn anno 3171 .Pn anno
3161 had only one operation mode: adding header fields. 3172 had only one operation mode: adding header fields.
3162 With the extension it got two more modes: 3173 With the extension, two more modes were added:
3163 .\" XXX got
3164 listing and deleting header fields. 3174 listing and deleting header fields.
3165 The structure of the code changes did not pay respect to this 3175 The structure of the code changes did not pay respect to this
3166 fundamental change to 3176 fundamental change.
3167 .Pn anno 's
3168 behavior.
3169 Neither the implementation nor the documentation did clearly 3177 Neither the implementation nor the documentation did clearly
3170 define them as being exclusive modes of operation. 3178 declare the exclusive operation modes as such.
3171 Having identified the problem, I solved it by putting structure into 3179 Having identified the problem, I solved it by putting structure into
3172 .Pn anno 3180 .Pn anno
3173 and its documentation. 3181 and its documentation
3174 .Ci d54c8db8bdf01e8381890f7729bc0ef4a055ea11 3182 .Ci d54c8db8bdf01e8381890f7729bc0ef4a055ea11 .
3175 .P 3183 .P
3176 The difference is visible in both the code and the documentation. 3184 The difference is visible in both the code and the documentation.
3177 The following code excerpt: 3185 For instance in the following code excerpt:
3178 .VS 3186 .VS
3179 int delete = -2; /* delete header element if set */ 3187 int delete = -2; /* delete header element if set */
3180 int list = 0; /* list header elements if set */ 3188 int list = 0; /* list header elements if set */
3181 [...] 3189 [...]
3182 case DELETESW: /* delete annotations */ 3190 case DELETESW: /* delete annotations */
3185 case LISTSW: /* produce a listing */ 3193 case LISTSW: /* produce a listing */
3186 list = 1; 3194 list = 1;
3187 continue; 3195 continue;
3188 VE 3196 VE
3189 .LP 3197 .LP
3190 was replaced by: 3198 which was replaced by:
3191 .VS 3199 .VS
3192 static enum { MODE_ADD, MODE_DEL, MODE_LIST } mode = MODE_ADD; 3200 static enum { MODE_ADD, MODE_DEL, MODE_LIST } mode = MODE_ADD;
3193 [...] 3201 [...]
3194 case DELETESW: /* delete annotations */ 3202 case DELETESW: /* delete annotations */
3195 mode = MODE_DEL; 3203 mode = MODE_DEL;
3201 .LP 3209 .LP
3202 The replacement code does not only reflect the problem's structure better, 3210 The replacement code does not only reflect the problem's structure better,
3203 it is easier to understand as well. 3211 it is easier to understand as well.
3204 The same applies to the documentation. 3212 The same applies to the documentation.
3205 The man page was completely reorganized to propagate the same structure. 3213 The man page was completely reorganized to propagate the same structure.
3206 This is visible in the Synopsis section: 3214 This is already visible in the Synopsis section:
3207 .VS 3215 .VS
3208 anno [+folder] [msgs] [-component field] [-text body] 3216 anno [+folder] [msgs] [-component f(CIfieldfP] [-text fPbodyfP]
3209 [-append] [-date | -nodate] [-preserve | -nopreserve] 3217 [-append] [-date | -nodate] [-preserve | -nopreserve]
3210 [-Version] [-help] 3218 [-Version] [-help]
3211 3219
3212 anno -delete [+folder] [msgs] [-component field] [-text 3220 anno -delete [+folder] [msgs] [-component fPfieldfP] [-text
3213 body] [-number num | all ] [-preserve | -nopreserve] 3221 fPbodyfP] [-number fPnum fP| fPall fP] [-preserve | -nopreserve]
3214 [-Version] [-help] 3222 [-Version] [-help]
3215 3223
3216 anno -list [+folder] [msgs] [-component field] [-number] 3224 anno -list [+folder] [msgs] [-component fPfieldfP] [-number]
3217 [-Version] [-help] 3225 [-Version] [-help]
3218 VE 3226 VE
3219 .\" XXX think about explaining the -preserve rework?
3220 3227
3221 3228
3222 3229
3223 .U3 "Path Conversion 3230 .U3 "Path Conversion
3224 .P 3231 .P
3229 .LI 2 3236 .LI 2
3230 Relative Unix directory paths, like 3237 Relative Unix directory paths, like
3231 .Fn ./foo/bar . 3238 .Fn ./foo/bar .
3232 .LI 3 3239 .LI 3
3233 Absolute MH folder paths, like 3240 Absolute MH folder paths, like
3234 .Fn +friends/phil . 3241 .Fn +projects/mmh .
3235 .LI 4 3242 .LI 4
3236 Relative MH folder paths, like 3243 Relative MH folder paths, like
3237 .Fn @subfolder . 3244 .Fn @subfolder .
3238 .LP 3245 .LP
3239 The last type, relative MH folder paths, are hardly documented. 3246 Relative MH folder paths, are hardly documented
3240 Nonetheless, they are useful for large mail storages. 3247 although they are useful for large mail storages.
3241 The current mail folder is specified as `\c 3248 The current mail folder is specified as `\c
3242 .Fn @ ', 3249 .Fn @ ',
3243 just like the current directory is specified as `\c 3250 just like the current directory is specified as `\c
3244 .Fn . '. 3251 .Fn . '.
3245 .P 3252 .P
3246 To allow MH tools to understand all four notations, 3253 To allow MH tools to understand all four notations,
3247 they need to convert between them. 3254 they need to be able to convert between them.
3248 .\" XXX between?
3249 In nmh, these path name conversion functions were located in the files 3255 In nmh, these path name conversion functions were located in the files
3250 .Fn sbr/path.c 3256 .Fn sbr/path.c
3251 (``return a pathname'') and 3257 (``return a pathname'') and
3252 .Fn sbr/m_maildir.c 3258 .Fn sbr/m_maildir.c
3253 (``get the path for the mail directory''). 3259 (``get the path for the mail directory'').
3254 The seven functions in the two files were documented with no more 3260 The seven functions in the two files were documented with no more
3255 than two comments, which described obvious information. 3261 than two comments, which described obvious information.
3256 The function signatures were neither explaining: 3262 The signatures of the four exported functions did not explain their
3257 .VS 3263 semantics:
3258 char *path(char *, int); 3264 .LI 1
3259 char *pluspath(char *); 3265 .CW "char *path(char *, int);
3260 char *m_mailpath(char *); 3266 .LI 2
3261 char *m_maildir(char *); 3267 .CW "char *pluspath(char *);
3262 VE 3268 .LI 3
3263 .P 3269 .CW "char *m_mailpath(char *);
3264 My investigation provides the following description: 3270 .LI 4
3271 .CW "char *m_maildir(char *);
3272 .P
3273 My investigations provided the following descriptions:
3265 .LI 1 3274 .LI 1
3266 The second parameter of 3275 The second parameter of
3267 .Fu path() 3276 .Fu path()
3268 defines the type of path given as first parameter. 3277 defines the type as which the path given in the first parameter should
3278 be treated.
3269 Directory paths are converted to absolute directory paths. 3279 Directory paths are converted to absolute directory paths.
3270 Folder paths are converted to absolute folder paths. 3280 Folder paths are converted to absolute folder paths.
3271 Folder paths must not include a leading `\fL@\fP' character. 3281 Folder paths must not include a leading `\fL@\fP' character.
3272 Leading plus characters are preserved. 3282 Leading plus characters are preserved.
3273 The result is a pointer to newly allocated memory. 3283 The result is a pointer to newly allocated memory.
3282 .Fu m_mailpath() 3292 .Fu m_mailpath()
3283 converts directory paths to absolute directory paths. 3293 converts directory paths to absolute directory paths.
3284 The characters `\fL+\fP' or `\fL@\fP' at the beginning of the path name are 3294 The characters `\fL+\fP' or `\fL@\fP' at the beginning of the path name are
3285 treated literal, i.e. as the first character of a relative directory path. 3295 treated literal, i.e. as the first character of a relative directory path.
3286 Hence, this function can not be used for folder paths. 3296 Hence, this function can not be used for folder paths.
3287 In any case, the result is an absolute directory path. 3297 In any case, the result is an absolute directory path,
3288 The result is a pointer to newly allocated memory. 3298 returned as a pointer to newly allocated memory.
3289 .LI 4 3299 .LI 4
3290 .Fu m_maildir() 3300 .Fu m_maildir()
3291 returns the parameter unchanged if it is an absolute directory path 3301 returns the parameter unchanged if it is an absolute directory path
3292 or begins with the entry `\fL.\fP' or `\fL..\fP'. 3302 or begins with the entry `\fL.\fP' or `\fL..\fP'.
3293 All other strings are prepended with the current working directory. 3303 All other strings are prepended with the current working directory.
3294 Hence, this functions can not be used for folder paths. 3304 Hence, this function can not be used for folder paths.
3295 The result is either an absolute directory path or a relative 3305 The result is either an absolute directory path or a relative
3296 directory path, starting with a dot. 3306 directory path, starting with dot or dot-dot.
3297 In contrast to the other functions, the result is a pointer to 3307 In contrast to the other functions, the result is a pointer to
3298 static memory. 3308 static memory.
3299 .P 3309 .P
3300 The situation was obscure, irritating, error-prone, and non-orthogonal. 3310 The situation was obscure, irritating, error-prone, and non-orthogonal.
3301 No clear terminology was used to name the different kinds of path names. 3311 Additionally, no clear terminology was used to name the different
3302 The first argument of 3312 kinds of path names.
3313 Sometimes, the names were even misleading, much as the first argument of
3303 .Fu m_mailpath() , 3314 .Fu m_mailpath() ,
3304 for instance, was named 3315 which was named
3305 .Ar folder , 3316 .CW folder ,
3306 though 3317 although
3307 .Fu m_mailpath() 3318 .Fu m_mailpath()
3308 can not be used for MH folders. 3319 could not be used with MH folder arguments.
3309 .P 3320 .P
3310 I reworked the path name conversion completely, introducing clarity. 3321 I clarified the path name conversion by complete rework.
3311 First of all, the terminology needed to be defined. 3322 First of all, the terminology needed to be defined.
3312 A path name is either in the Unix domain, then it is called 3323 A path name is either in the Unix domain, then it is called
3313 \fIdirectory path\fP, `dirpath' for short, or it is in the MH domain, 3324 \fIdirectory path\fP (\fIdirpath\fP for short) or it is in the MH domain,
3314 then it is called \fIfolder path\fP, `folpath' for short. 3325 then it is called \fIfolder path\fP (\fIfolpath\fP for short).
3315 The two terms need to be used with strict distinction. 3326 The two terms need to be used with strict distinction.
3316 Having a clear terminology is often an indicator of having understood 3327 Often a clear terminology indicates that the problem is understood.
3317 the problem itself.
3318 Second, I exploited the concept of path type indicators. 3328 Second, I exploited the concept of path type indicators.
3319 By requesting every path name to start with a clear type identifier, 3329 By requiring every path name to start with a distinct type identifier,
3320 conversion between the types can be fully automated. 3330 the conversion between the types could be fully automated.
3321 Thus the tools can accept paths of any type from the user. 3331 This allows the tools to accept paths of any type from the user.
3322 Therefore, it was necessary to require relative directory paths to be 3332 Therefore, it was necessary to require relative directory paths to be
3323 prefixed with a dot character. 3333 prefixed with a dot character.
3324 In consequence, the dot character could no longer be an alias for the 3334 In consequence, the dot character could no longer be an alias for the
3325 current message. 3335 current message.
3326 .Ci cff0e16925e7edbd25b8b9d6d4fbdf03e0e60c01 3336 .Ci cff0e16925e7edbd25b8b9d6d4fbdf03e0e60c01
3327 Third, I created three new functions to replace the previous mess: 3337 Third, I created three new functions to replace the previous mess:
3328 .LI 1 3338 .LI 1
3329 .Fu expandfol() 3339 .Fu expandfol()
3330 converts folder paths to absolute folder paths, 3340 converts folder paths to absolute folder paths.
3331 without the leading plus character.
3332 Directory paths are simply passed through. 3341 Directory paths are simply passed through.
3333 This function is to be used for folder paths only, thus the name. 3342 This function is to be used for folder paths only, thus the name.
3334 The result is a pointer to static memory. 3343 The result is a pointer to static memory.
3335 .LI 2 3344 .LI 2
3336 .Fu expanddir() 3345 .Fu expanddir()
3351 Two of the functions convert relative to absolute path names of the 3360 Two of the functions convert relative to absolute path names of the
3352 same type. 3361 same type.
3353 The third function converts any path name type to the most general one, 3362 The third function converts any path name type to the most general one,
3354 the absolute directory path. 3363 the absolute directory path.
3355 All of the functions return pointers to static memory. 3364 All of the functions return pointers to static memory.
3356 All three functions are implemented in 3365 The file
3357 .Fn sbr/path.c . 3366 .Fn sbr/path.c
3367 contains the implementation of the functions;
3358 .Fn sbr/m_maildir.c 3368 .Fn sbr/m_maildir.c
3359 is removed. 3369 was removed.
3360 .Ci d39e2c447b0d163a5a63f480b23d06edb7a73aa0 3370 .Ci d39e2c447b0d163a5a63f480b23d06edb7a73aa0
3361 .P 3371 .P
3362 Along with the path conversion rework, I also replaced 3372 Along with the path conversion rework, I also replaced
3363 .Fu getfolder(FDEF) 3373 .Fu getfolder(FDEF)
3364 with 3374 with
3365 .Fu getdeffol() 3375 .Fu getdeffol()
3366 and 3376 and
3367 .Fu getfolder(FCUR) 3377 .Fu getfolder(FCUR)
3368 with 3378 with
3369 .Fu getcurfol() , 3379 .Fu getcurfol() ,
3370 which is only a convenience wrapper for 3380 which only wraps
3371 .Fu expandfol("@") . 3381 .Fu expandfol(""@"")
3382 for convenience.
3372 This code was moved from 3383 This code was moved from
3373 .Fn sbr/getfolder.c 3384 .Fn sbr/getfolder.c
3374 to 3385 into
3375 .Fn sbr/path.c . 3386 .Fn sbr/path.c
3387 as well.
3376 .Ci d39e2c447b0d163a5a63f480b23d06edb7a73aa0 3388 .Ci d39e2c447b0d163a5a63f480b23d06edb7a73aa0
3377 .P 3389 .P
3378 The related function 3390 The related function
3379 .Fu etcpath() 3391 .Fu etcpath()
3380 was moved to 3392 is now included in
3381 .Fn sbr/path.c , 3393 .Fn sbr/path.c ,
3382 too 3394 too
3383 .Ci b4c29794c12099556151d93a860ee51badae2e35 . 3395 .Ci b4c29794c12099556151d93a860ee51badae2e35 .
3384 Previously, it had been located in 3396 Previously, it had been located in
3385 .Fn config/config.c , 3397 .Fn config/config.c .
3386 for whatever reasons. 3398 .P
3387 .P 3399 Now,
3388 .Fn sbr/path.c 3400 .Fn sbr/path.c
3389 now contains all path handling code. 3401 contains all path handling code.
3390 .\" XXX naechste zeile weg? 3402 Besides being less code, its readability is highly improved.
3391 Only 173 lines of code were needed to replace the previous 252 lines. 3403 The functions follow a common style and are well documented.
3392 The readability of the code is highly improved.
3393 Additionally, each of the six exported and one static functions
3394 is introduced by an explaining comment.
3395 3404
3396 3405
3397 3406
3398 3407
3399 .H2 "Profile Reading 3408 .H2 "Profile Reading