docs/master
changeset 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 | 8be9e84be526 |
children | 95257474a123 |
files | discussion.roff |
diffstat | 1 files changed, 174 insertions(+), 165 deletions(-) [+] |
line diff
1.1 --- a/discussion.roff Sat Jul 14 18:05:19 2012 +0200 1.2 +++ b/discussion.roff Sat Jul 14 23:19:27 2012 +0200 1.3 @@ -2879,21 +2879,18 @@ 1.4 .H1 "Styling 1.5 .P 1.6 Kernighan and Pike have emphasized the importance of style in the 1.7 -preface of their book: 1.8 +preface of \fPThe Practice of Programming\fP: 1.9 .[ [ 1.10 kernighan pike practice of programming 1.11 .], p. x] 1.12 .QS 1.13 Chapter 1 discusses programming style. 1.14 -Good style is so important to good programming that we have chose 1.15 +Good style is so important to good programming that we have chosen 1.16 to cover it first. 1.17 .QE 1.18 This section covers changes in mmh that were guided by the desire 1.19 to improve on style. 1.20 -Many of them follow the rules given in the quoted book. 1.21 -.[ 1.22 -kernighan pike practice of programming 1.23 -.] 1.24 +Many of them follow the advice given in the quoted book. 1.25 1.26 1.27 1.28 @@ -2903,12 +2900,11 @@ 1.29 .P 1.30 .U3 "Indentation Style 1.31 .P 1.32 -Indentation styles are the holy cow of programmers. 1.33 -Kernighan and Pike 1.34 +Indentation styles are the holy cow of programming. 1.35 +Kernighan and Pike write: 1.36 .[ [ 1.37 kernighan pike practice of programming 1.38 .], p. 10] 1.39 -wrote: 1.40 .QS 1.41 Programmers have always argued about the layout of programs, 1.42 but the specific style is much less important than its consistent 1.43 @@ -2920,30 +2916,32 @@ 1.44 I agree that the constant application is most important, 1.45 but I believe that some styles have advantages over others. 1.46 For instance the indentation with tab characters only. 1.47 -Tab characters directly map to the nesting level \(en 1.48 +The number of tabs corresponds to the nesting level \(en 1.49 one tab, one level. 1.50 -Tab characters are flexible because developers can adjust them to 1.51 -whatever width they like to have. 1.52 -There is no more need to run 1.53 -.Pn unexpand 1.54 -or 1.55 -.Pn entab 1.56 -programs to ensure the correct mixture of leading tabs and spaces. 1.57 -The simple rules are: (1) Leading whitespace must consist of tabs only. 1.58 -(2) Any other whitespace should consist of spaces. 1.59 -These two rules ensure the integrity of the visual appearance. 1.60 +Tab characters provide flexible visual appearance because developers 1.61 +can adjust their width as prefered. 1.62 +There is no more need to check for the correct mixture of 1.63 +tabs and spaces. 1.64 +Two simple rules ensure the integrity and flexibility of the visual 1.65 +appearance: 1.66 +.LI 1 1.67 +Leading whitespace must consist of tabs only. 1.68 +.LI 2 1.69 +All other whitespace should be spaces. 1.70 +.LP 1.71 Although reformatting existing code should be avoided, I did it. 1.72 I did not waste time arguing; I just reformatted the code. 1.73 .Ci a485ed478abbd599d8c9aab48934e7a26733ecb1 1.74 1.75 .U3 "Comments 1.76 .P 1.77 -Section 1.6 of 1.78 +Kernighan and Pike demand: ``Don't belabor the obvious''. 1.79 .[ [ 1.80 kernighan pike practice of programming 1.81 .], p. 23] 1.82 -demands: ``Don't belabor the obvious.'' 1.83 -Hence, I simply removed all the comments in the following code excerpt: 1.84 +Following the advice, I removed unnecessary comments. 1.85 +For instance, I removed all comments in the following code excerpt 1.86 +.Ci 426543622b377fc5d091455cba685e114b6df674 : 1.87 .VS 1.88 context_replace(curfolder, folder); /* update current folder */ 1.89 seq_setcur(mp, mp->lowsel); /* update current message */ 1.90 @@ -2961,14 +2959,15 @@ 1.91 /* NUL-terminate the field */ 1.92 *cp = '\0'; 1.93 VE 1.94 -.Ci 426543622b377fc5d091455cba685e114b6df674 1.95 .P 1.96 -The program code explains enough itself, already. 1.97 +The information in each of the comments was present in the code 1.98 +statements already, except for the NUL-termination, which became 1.99 +obvious from the context. 1.100 1.101 1.102 .U3 "Names 1.103 .P 1.104 -Kernighan and Pike suggest: 1.105 +Regarding this topic, Kernighan and Pike suggest: 1.106 ``Use active names for functions''. 1.107 .[ [ 1.108 kernighan pike practice of programming 1.109 @@ -2976,16 +2975,20 @@ 1.110 One application of this rule was the rename of 1.111 .Fu check_charset() 1.112 to 1.113 -.Fu is_native_charset() . 1.114 -.Ci 8d77b48284c58c135a6b2787e721597346ab056d 1.115 -The same change fixed a violation of ``Be accurate'' 1.116 +.Fu is_native_charset() 1.117 +.Ci 8d77b48284c58c135a6b2787e721597346ab056d . 1.118 +The same change additionally fixed a violation of ``Be accurate'', 1.119 .[ [ 1.120 kernighan pike practice of programming 1.121 .], p. 4] 1.122 -as well. 1.123 -The code did not match the expectation the function suggested, 1.124 -as it, for whatever reason, only compared the first ten characters 1.125 -of the charset name. 1.126 +as the code did not match the expectation the function suggested. 1.127 +It did not compare charset names but prefixes of them only. 1.128 +In case the native charset was `ISO-8859-1', then 1.129 +.VS 1.130 +check_charset("ISO-8859-11", strlen("ISO-8859-11")) 1.131 +VE 1.132 +had returned true although the upper halves of the code pages 1.133 +are different. 1.134 .P 1.135 More important than using active names is using descriptive names. 1.136 .VS 1.137 @@ -2993,8 +2996,8 @@ 1.138 VE 1.139 Renaming the obscure 1.140 .Fu m_unknown() 1.141 -function was a delightful event, although it made the code less funny. 1.142 -.Ci 611d68d19204d7cbf5bd585391249cb5bafca846 1.143 +function was a delightful event, although it made the code less funny 1.144 +.Ci 611d68d19204d7cbf5bd585391249cb5bafca846 . 1.145 .P 1.146 Magic numbers are generally considered bad style. 1.147 Obviously, Kernighan and Pike agree: 1.148 @@ -3002,57 +3005,70 @@ 1.149 .[ [ 1.150 kernighan pike practice of programming 1.151 .], p. 19] 1.152 -One such change was naming the type of input \(en mbox or mail folder \(en 1.153 -to be scanned: 1.154 +.P 1.155 +The argument 1.156 +.CW outnum 1.157 +of the function 1.158 +.Fu scan() 1.159 +in 1.160 +.Fn uip/scansbr.c 1.161 +holds the number of the message to be created. 1.162 +As well it encodes program logic with negative numbers and zero. 1.163 +This led to obscure code. 1.164 +I clarified the code by introducing two variables that extracted 1.165 +the hidden information: 1.166 +.VS 1.167 +int incing = (outnum > 0); 1.168 +int ismbox = (outnum != 0); 1.169 +VE 1.170 +The readable names are thus used in conditions; 1.171 +the variable 1.172 +.CW outnum 1.173 +is used only to extract ordinary message numbers 1.174 +.Ci b8b075c77be7794f3ae9ff0e8cedb12b48fd139f . 1.175 +.P 1.176 +Through the clarity improvement of the change detours in the program 1.177 +logic of related code parts became apparent. 1.178 +The implementation was simplified. 1.179 +This possibility to improve had been invisible before 1.180 +.Ci aa60b0ab5e804f8befa890c0a6df0e3143ce0723 . 1.181 +.P 1.182 +The names just described were a first step, yet the situation 1.183 +was further improved by giving names to the magic values of 1.184 +.CW outnum : 1.185 .VS 1.186 #define SCN_MBOX (-1) 1.187 #define SCN_FOLD 0 1.188 VE 1.189 +The two variables were updated thereafter as well: 1.190 +.VS 1.191 +int incing = (outnum != SCN_MBOX && outnum != SCN_FOLD); 1.192 +int scanfolder = (outnum == SCN_FOLD); 1.193 +VE 1.194 +Furthermore, 1.195 +.CW ismbox 1.196 +was replaced by 1.197 +.CW scanfolder 1.198 +because that matched better to the program logic. 1.199 .Ci 7ffb36d28e517a6f3a10272056fc127592ab1c19 1.200 -.P 1.201 -The argument 1.202 -.Ar outnum 1.203 -of the function 1.204 -.Fu scan() 1.205 -in 1.206 -.Fn uip/scansbr.c 1.207 -defines the number of the message to be created. 1.208 -If no message is to be created, the argument is misused to transport 1.209 -program logic. 1.210 -This lead to obscure code. 1.211 -I improved the clarity of the code by introducing two variables: 1.212 -.VS 1.213 -int incing = (outnum > 0); 1.214 -int ismbox = (outnum != 0); 1.215 -VE 1.216 -They cover the magic values and are used for conditions. 1.217 -The variable 1.218 -.Ar outnum 1.219 -is only used when it holds an ordinary message number. 1.220 -.Ci b8b075c77be7794f3ae9ff0e8cedb12b48fd139f 1.221 -The clarity improvement of the change showed detours in the program logic 1.222 -of related code parts. 1.223 -Having the new variables with descriptive names, a more 1.224 -straight forward implementation became apparent. 1.225 -Before the code was clarified, the possibility to improve had not be seen. 1.226 -.Ci aa60b0ab5e804f8befa890c0a6df0e3143ce0723 1.227 + 1.228 1.229 1.230 1.231 .H2 "Structural Rework 1.232 .P 1.233 -Although the stylistic changes described up to here improve the 1.234 -readability of the source code, all of them are changes ``in the small''. 1.235 -Structural changes affect a much larger area. 1.236 -They are more difficult to do but lead to larger improvements, 1.237 -especially as they influence the outer shape of the tools as well. 1.238 +Although the stylistic changes described already improve the 1.239 +readability of the source code, all of them were changes ``in the small''. 1.240 +Structural changes, in contrast, affect much larger code areas. 1.241 +They are more difficult to accomplish but lead to larger improvements, 1.242 +especially as they often influence the outer shape of the tools as well. 1.243 .P 1.244 At the end of their chapter on style, 1.245 Kernighan and Pike ask: ``But why worry about style?'' 1.246 .[ [ 1.247 kernighan pike practice of programming 1.248 -.], p. 28] 1.249 -Following are two examples of structural rework that show 1.250 +.], p. 28]. 1.251 +Following are two examples of structural rework that demonstrate 1.252 why style is important in the first place. 1.253 1.254 1.255 @@ -3060,11 +3076,11 @@ 1.256 .P 1.257 Until 2002, 1.258 .Pn anno 1.259 -had six functional command line switches, 1.260 +had six functional command line switches: 1.261 .Sw -component 1.262 and 1.263 .Sw -text , 1.264 -which have an argument each, 1.265 +each with an argument, 1.266 and the two pairs of flags, 1.267 .Sw -[no]date 1.268 and 1.269 @@ -3079,26 +3095,26 @@ 1.270 .Sw -append , 1.271 and 1.272 .Sw -number , 1.273 -the last one taking an argument. 1.274 -.Ci 7480dbc14bc90f2d872d434205c0784704213252 1.275 +the last one taking an argument 1.276 +.Ci 7480dbc14bc90f2d872d434205c0784704213252 . 1.277 Later, 1.278 .Sw -[no]preserve 1.279 -was added. 1.280 -.Ci d9b1d57351d104d7ec1a5621f090657dcce8cb7f 1.281 +was added as well 1.282 +.Ci d9b1d57351d104d7ec1a5621f090657dcce8cb7f . 1.283 Then, the Synopsis section of the man page 1.284 .Mp anno (1) 1.285 read: 1.286 .VS 1.287 -anno [+folder] [msgs] [-component field] [-inplace | -noinplace] 1.288 +anno [+folder] [msgs] [-component f(CIfieldfP] [-inplace | -noinplace] 1.289 [-date | -nodate] [-draft] [-append] [-list] [-delete] 1.290 - [-number [num|all]] [-preserve | -nopreserve] [-version] 1.291 - [-help] [-text body] 1.292 + [-number [f(CInumfP|fPallfP]] [-preserve | -nopreserve] [-version] 1.293 + [-help] [-text f(CIbodyfP] 1.294 VE 1.295 .LP 1.296 The implementation followed the same structure. 1.297 Problems became visible when 1.298 .Cl "anno -list -number 42 1.299 -worked on the current message instead on message number 42, 1.300 +worked on the current message instead of on message number 42, 1.301 and 1.302 .Cl "anno -list -number l:5 1.303 did not work on the last five messages but failed with the mysterious 1.304 @@ -3122,59 +3138,51 @@ 1.305 .QE 1.306 .LP 1.307 The problem was manifold. 1.308 -The code required a numeric argument to the 1.309 -.Sw -number 1.310 -switch. 1.311 -If it was missing or non-numeric, 1.312 -.Pn anno 1.313 -aborted with an error message that had an off-by-one error, 1.314 -printing the switch one before the failing one. 1.315 Semantically, the argument to the 1.316 .Sw -number 1.317 switch is only necessary in combination with 1.318 .Sw -delete , 1.319 but not with 1.320 .Sw -list . 1.321 +The code, however, required a numeric argument in any case. 1.322 +If the argument was missing or non-numeric, 1.323 +.Pn anno 1.324 +aborted with an error message that additionally had an off-by-one error. 1.325 +It printed the name of the switch one before the concerned one. 1.326 .P 1.327 -Trying to fix these problems on the surface would not have solved 1.328 -them truly, as they originate from a discrepance between the 1.329 +Trying to fix these problems on the surface would not have solved them. 1.330 +They originate from a discrepance between the 1.331 structure of the problem and the structure implemented in the program. 1.332 -Such structural differences can not be cured on the surface. 1.333 -They need to be solved by adjusting the structure of the implementation 1.334 -to the structure of the problem. 1.335 +Such structural differences can only be solved by adjusting the 1.336 +structure of the implementation to the structure of the problem. 1.337 .P 1.338 -In 2002, the new switches 1.339 +Steinhart had added the new 1.340 .Sw -list 1.341 and 1.342 .Sw -delete 1.343 -were added in the same way, the 1.344 -.Sw -number 1.345 -switch for instance had been added. 1.346 -Yet, they are of structural different type. 1.347 +switches in a style similar to the other switches though 1.348 +they are of structural different type. 1.349 Semantically, 1.350 .Sw -list 1.351 and 1.352 .Sw -delete 1.353 -introduce modes of operation. 1.354 +introduce operation modes. 1.355 Historically, 1.356 .Pn anno 1.357 had only one operation mode: adding header fields. 1.358 -With the extension it got two more modes: 1.359 -.\" XXX got 1.360 +With the extension, two more modes were added: 1.361 listing and deleting header fields. 1.362 The structure of the code changes did not pay respect to this 1.363 -fundamental change to 1.364 -.Pn anno 's 1.365 -behavior. 1.366 +fundamental change. 1.367 Neither the implementation nor the documentation did clearly 1.368 -define them as being exclusive modes of operation. 1.369 +declare the exclusive operation modes as such. 1.370 Having identified the problem, I solved it by putting structure into 1.371 .Pn anno 1.372 -and its documentation. 1.373 -.Ci d54c8db8bdf01e8381890f7729bc0ef4a055ea11 1.374 +and its documentation 1.375 +.Ci d54c8db8bdf01e8381890f7729bc0ef4a055ea11 . 1.376 .P 1.377 The difference is visible in both the code and the documentation. 1.378 -The following code excerpt: 1.379 +For instance in the following code excerpt: 1.380 .VS 1.381 int delete = -2; /* delete header element if set */ 1.382 int list = 0; /* list header elements if set */ 1.383 @@ -3187,7 +3195,7 @@ 1.384 continue; 1.385 VE 1.386 .LP 1.387 -was replaced by: 1.388 +which was replaced by: 1.389 .VS 1.390 static enum { MODE_ADD, MODE_DEL, MODE_LIST } mode = MODE_ADD; 1.391 [...] 1.392 @@ -3203,20 +3211,19 @@ 1.393 it is easier to understand as well. 1.394 The same applies to the documentation. 1.395 The man page was completely reorganized to propagate the same structure. 1.396 -This is visible in the Synopsis section: 1.397 +This is already visible in the Synopsis section: 1.398 .VS 1.399 -anno [+folder] [msgs] [-component field] [-text body] 1.400 +anno [+folder] [msgs] [-component f(CIfieldfP] [-text fPbodyfP] 1.401 [-append] [-date | -nodate] [-preserve | -nopreserve] 1.402 [-Version] [-help] 1.403 1.404 -anno -delete [+folder] [msgs] [-component field] [-text 1.405 - body] [-number num | all ] [-preserve | -nopreserve] 1.406 +anno -delete [+folder] [msgs] [-component fPfieldfP] [-text 1.407 + fPbodyfP] [-number fPnum fP| fPall fP] [-preserve | -nopreserve] 1.408 [-Version] [-help] 1.409 1.410 -anno -list [+folder] [msgs] [-component field] [-number] 1.411 +anno -list [+folder] [msgs] [-component fPfieldfP] [-number] 1.412 [-Version] [-help] 1.413 VE 1.414 -.\" XXX think about explaining the -preserve rework? 1.415 1.416 1.417 1.418 @@ -3231,21 +3238,20 @@ 1.419 .Fn ./foo/bar . 1.420 .LI 3 1.421 Absolute MH folder paths, like 1.422 -.Fn +friends/phil . 1.423 +.Fn +projects/mmh . 1.424 .LI 4 1.425 Relative MH folder paths, like 1.426 .Fn @subfolder . 1.427 .LP 1.428 -The last type, relative MH folder paths, are hardly documented. 1.429 -Nonetheless, they are useful for large mail storages. 1.430 +Relative MH folder paths, are hardly documented 1.431 +although they are useful for large mail storages. 1.432 The current mail folder is specified as `\c 1.433 .Fn @ ', 1.434 just like the current directory is specified as `\c 1.435 .Fn . '. 1.436 .P 1.437 To allow MH tools to understand all four notations, 1.438 -they need to convert between them. 1.439 -.\" XXX between? 1.440 +they need to be able to convert between them. 1.441 In nmh, these path name conversion functions were located in the files 1.442 .Fn sbr/path.c 1.443 (``return a pathname'') and 1.444 @@ -3253,19 +3259,23 @@ 1.445 (``get the path for the mail directory''). 1.446 The seven functions in the two files were documented with no more 1.447 than two comments, which described obvious information. 1.448 -The function signatures were neither explaining: 1.449 -.VS 1.450 -char *path(char *, int); 1.451 -char *pluspath(char *); 1.452 -char *m_mailpath(char *); 1.453 -char *m_maildir(char *); 1.454 -VE 1.455 +The signatures of the four exported functions did not explain their 1.456 +semantics: 1.457 +.LI 1 1.458 +.CW "char *path(char *, int); 1.459 +.LI 2 1.460 +.CW "char *pluspath(char *); 1.461 +.LI 3 1.462 +.CW "char *m_mailpath(char *); 1.463 +.LI 4 1.464 +.CW "char *m_maildir(char *); 1.465 .P 1.466 -My investigation provides the following description: 1.467 +My investigations provided the following descriptions: 1.468 .LI 1 1.469 The second parameter of 1.470 .Fu path() 1.471 -defines the type of path given as first parameter. 1.472 +defines the type as which the path given in the first parameter should 1.473 +be treated. 1.474 Directory paths are converted to absolute directory paths. 1.475 Folder paths are converted to absolute folder paths. 1.476 Folder paths must not include a leading `\fL@\fP' character. 1.477 @@ -3284,41 +3294,41 @@ 1.478 The characters `\fL+\fP' or `\fL@\fP' at the beginning of the path name are 1.479 treated literal, i.e. as the first character of a relative directory path. 1.480 Hence, this function can not be used for folder paths. 1.481 -In any case, the result is an absolute directory path. 1.482 -The result is a pointer to newly allocated memory. 1.483 +In any case, the result is an absolute directory path, 1.484 +returned as a pointer to newly allocated memory. 1.485 .LI 4 1.486 .Fu m_maildir() 1.487 returns the parameter unchanged if it is an absolute directory path 1.488 or begins with the entry `\fL.\fP' or `\fL..\fP'. 1.489 All other strings are prepended with the current working directory. 1.490 -Hence, this functions can not be used for folder paths. 1.491 +Hence, this function can not be used for folder paths. 1.492 The result is either an absolute directory path or a relative 1.493 -directory path, starting with a dot. 1.494 +directory path, starting with dot or dot-dot. 1.495 In contrast to the other functions, the result is a pointer to 1.496 static memory. 1.497 .P 1.498 The situation was obscure, irritating, error-prone, and non-orthogonal. 1.499 -No clear terminology was used to name the different kinds of path names. 1.500 -The first argument of 1.501 +Additionally, no clear terminology was used to name the different 1.502 +kinds of path names. 1.503 +Sometimes, the names were even misleading, much as the first argument of 1.504 .Fu m_mailpath() , 1.505 -for instance, was named 1.506 -.Ar folder , 1.507 -though 1.508 +which was named 1.509 +.CW folder , 1.510 +although 1.511 .Fu m_mailpath() 1.512 -can not be used for MH folders. 1.513 +could not be used with MH folder arguments. 1.514 .P 1.515 -I reworked the path name conversion completely, introducing clarity. 1.516 +I clarified the path name conversion by complete rework. 1.517 First of all, the terminology needed to be defined. 1.518 A path name is either in the Unix domain, then it is called 1.519 -\fIdirectory path\fP, `dirpath' for short, or it is in the MH domain, 1.520 -then it is called \fIfolder path\fP, `folpath' for short. 1.521 +\fIdirectory path\fP (\fIdirpath\fP for short) or it is in the MH domain, 1.522 +then it is called \fIfolder path\fP (\fIfolpath\fP for short). 1.523 The two terms need to be used with strict distinction. 1.524 -Having a clear terminology is often an indicator of having understood 1.525 -the problem itself. 1.526 +Often a clear terminology indicates that the problem is understood. 1.527 Second, I exploited the concept of path type indicators. 1.528 -By requesting every path name to start with a clear type identifier, 1.529 -conversion between the types can be fully automated. 1.530 -Thus the tools can accept paths of any type from the user. 1.531 +By requiring every path name to start with a distinct type identifier, 1.532 +the conversion between the types could be fully automated. 1.533 +This allows the tools to accept paths of any type from the user. 1.534 Therefore, it was necessary to require relative directory paths to be 1.535 prefixed with a dot character. 1.536 In consequence, the dot character could no longer be an alias for the 1.537 @@ -3327,8 +3337,7 @@ 1.538 Third, I created three new functions to replace the previous mess: 1.539 .LI 1 1.540 .Fu expandfol() 1.541 -converts folder paths to absolute folder paths, 1.542 -without the leading plus character. 1.543 +converts folder paths to absolute folder paths. 1.544 Directory paths are simply passed through. 1.545 This function is to be used for folder paths only, thus the name. 1.546 The result is a pointer to static memory. 1.547 @@ -3353,10 +3362,11 @@ 1.548 The third function converts any path name type to the most general one, 1.549 the absolute directory path. 1.550 All of the functions return pointers to static memory. 1.551 -All three functions are implemented in 1.552 -.Fn sbr/path.c . 1.553 +The file 1.554 +.Fn sbr/path.c 1.555 +contains the implementation of the functions; 1.556 .Fn sbr/m_maildir.c 1.557 -is removed. 1.558 +was removed. 1.559 .Ci d39e2c447b0d163a5a63f480b23d06edb7a73aa0 1.560 .P 1.561 Along with the path conversion rework, I also replaced 1.562 @@ -3367,31 +3377,30 @@ 1.563 .Fu getfolder(FCUR) 1.564 with 1.565 .Fu getcurfol() , 1.566 -which is only a convenience wrapper for 1.567 -.Fu expandfol("@") . 1.568 +which only wraps 1.569 +.Fu expandfol(""@"") 1.570 +for convenience. 1.571 This code was moved from 1.572 .Fn sbr/getfolder.c 1.573 -to 1.574 -.Fn sbr/path.c . 1.575 +into 1.576 +.Fn sbr/path.c 1.577 +as well. 1.578 .Ci d39e2c447b0d163a5a63f480b23d06edb7a73aa0 1.579 .P 1.580 The related function 1.581 .Fu etcpath() 1.582 -was moved to 1.583 +is now included in 1.584 .Fn sbr/path.c , 1.585 too 1.586 .Ci b4c29794c12099556151d93a860ee51badae2e35 . 1.587 Previously, it had been located in 1.588 -.Fn config/config.c , 1.589 -for whatever reasons. 1.590 +.Fn config/config.c . 1.591 .P 1.592 +Now, 1.593 .Fn sbr/path.c 1.594 -now contains all path handling code. 1.595 -.\" XXX naechste zeile weg? 1.596 -Only 173 lines of code were needed to replace the previous 252 lines. 1.597 -The readability of the code is highly improved. 1.598 -Additionally, each of the six exported and one static functions 1.599 -is introduced by an explaining comment. 1.600 +contains all path handling code. 1.601 +Besides being less code, its readability is highly improved. 1.602 +The functions follow a common style and are well documented. 1.603 1.604 1.605