docs/master
changeset 120:e49780100ffb
Wrote about the rework of anno(1).
author | markus schnalke <meillo@marmaro.de> |
---|---|
date | Tue, 26 Jun 2012 17:01:35 +0200 |
parents | f9bf4d5ac1ba |
children | edbc6e1dc636 |
files | discussion.roff |
diffstat | 1 files changed, 178 insertions(+), 15 deletions(-) [+] |
line diff
1.1 --- a/discussion.roff Tue Jun 26 17:01:10 2012 +0200 1.2 +++ b/discussion.roff Tue Jun 26 17:01:35 2012 +0200 1.3 @@ -2540,17 +2540,23 @@ 1.4 demands: ``Don't belabor the obvious.'' 1.5 Hence, I simply removed comments like the following: 1.6 .VS 1.7 -context_replace(curfolder, folder); /* update current folder */ 1.8 -context_save(); /* save the context file */ 1.9 -folder_free(mp); /* free folder structure */ 1.10 +context_replace(curfolder, folder); /* update current folder */ 1.11 +seq_setcur(mp, mp->lowsel); /* update current message */ 1.12 +seq_save(mp); /* synchronize message sequences */ 1.13 +folder_free(mp); /* free folder/message structure */ 1.14 +context_save(); /* save the context file */ 1.15 + 1.16 +[...] 1.17 + 1.18 +int c; /* current character */ 1.19 +char *cp; /* miscellaneous character pointer */ 1.20 + 1.21 +[...] 1.22 + 1.23 +/* NUL-terminate the field */ 1.24 +*cp = '\0'; 1.25 VE 1.26 -.Ci 8edc5aaf86f9f77124664f6801bc6c6cdf258173 1.27 -.VS 1.28 -seq_setcur (mp, mp->lowsel);/* set current message for folder */ 1.29 -seq_save (mp); /* synchronize message sequences */ 1.30 -folder_free (mp); /* free folder/message structure */ 1.31 -VE 1.32 -.Ci 337338b404931f06f0db2119c9e145e8ca5a9860 1.33 +.Ci 426543622b377fc5d091455cba685e114b6df674 1.34 .P 1.35 The names of the functions explain enough already. 1.36 1.37 @@ -2623,17 +2629,174 @@ 1.38 .P 1.39 At the end of their chapter on style, 1.40 Kernighan and Pike ask: ``But why worry about style?'' 1.41 -The following description of my rework on 1.42 +The following description of my rework of 1.43 .Pn anno 1.44 -shows why style matters. 1.45 +should give answers. 1.46 .P 1.47 +Until 2002, 1.48 +.Pn anno 1.49 +had six functional command line switches, 1.50 +.Sw -component 1.51 +and 1.52 +.Sw -text , 1.53 +which took an argument each, 1.54 +and the two pairs of flags, 1.55 +.Sw -[no]date 1.56 +and 1.57 +.Sw -[no]inplace., 1.58 +.Sw -component 1.59 +and 1.60 +.Sw -text , 1.61 +which took an argument each, 1.62 +and the two pairs of flags, 1.63 +.Sw -[no]date 1.64 +and 1.65 +.Sw -[no]inplace . 1.66 +Then Jon Steinhart introduced his attachment system. 1.67 +In need for more advanced annotation handling, he extended 1.68 +.Pn anno . 1.69 +He added five more switches: 1.70 +.Sw -draft , 1.71 +.Sw -list , 1.72 +.Sw -delete , 1.73 +.Sw -append , 1.74 +and 1.75 +.Sw -number , 1.76 +the last one taking an argument. 1.77 +Later, 1.78 +.Sw -[no]preserve 1.79 +was added. 1.80 +Then, the Synopsis section of the man page 1.81 +.Mp anno (1) 1.82 +read: 1.83 +.VS 1.84 +anno [+folder] [msgs] [-component field] [-inplace | -noinplace] 1.85 + [-date | -nodate] [-draft] [-append] [-list] [-delete] 1.86 + [-number [num|all]] [-preserve | -nopreserve] [-version] 1.87 + [-help] [-text body] 1.88 +VE 1.89 +.LP 1.90 +The implementation followed the same structure. 1.91 +Problems became visible when 1.92 +.Cl "anno -list -number 42 1.93 +worked on the current message instead on message number 42, 1.94 +and 1.95 +.Cl "anno -list -number l:5 1.96 +did not work on the last five messages but failed with the misterious 1.97 +error message: ``anno: missing argument to -list''. 1.98 +Yet, the invokation matched the specification in the man page. 1.99 +There, the correct use of 1.100 +.Sw -number 1.101 +was defined as being 1.102 +.Cl "[-number [num|all]] 1.103 +and the textual description for the combination with 1.104 +.Sw -list 1.105 +read: 1.106 +.QS 1.107 +The -list option produces a listing of the field bodies for 1.108 +header fields with names matching the specified component, 1.109 +one per line. The listing is numbered, starting at 1, if 1.110 +the -number option is also used. 1.111 +.QE 1.112 +.LP 1.113 +The problem was manifold. 1.114 +The code required a numeric argument to the 1.115 +.Sw -number 1.116 +switch. 1.117 +If it was missing or non-numeric, 1.118 +.Pn anno 1.119 +aborted with an error message that had an off-by-one error, 1.120 +printing the switch one before the failing one. 1.121 +Semantically, the argument to the 1.122 +.Sw -number 1.123 +switch is only necessary in combination with 1.124 +.Sw -delete , 1.125 +but not with 1.126 +.Sw -list . 1.127 +In the former case it is even necessary. 1.128 +.P 1.129 +Trying to fix these problems on the surface would not have solved it truly. 1.130 +The problems discovered originate from a discrepance between the semantic 1.131 +structure of the problem and the structure implemented in the program. 1.132 +Such structural differences can not be cured on the surface. 1.133 +They need to be solved by adjusting the structure of the implementation 1.134 +to the structure of the problem. 1.135 +.P 1.136 +In 2002, the new switches 1.137 +.Sw -list 1.138 +and 1.139 +.Sw -delete 1.140 +were added in the same way, the 1.141 +.Sw -number 1.142 +switch for instance had been added. 1.143 +Yet, they are of structural different type. 1.144 +Semantically, 1.145 +.Sw -list 1.146 +and 1.147 +.Sw -delete 1.148 +introduce modes of operation. 1.149 +Historically, 1.150 +.Pn anno 1.151 +had only one operation mode: adding header fields. 1.152 +With the extension, it got two moder modes: 1.153 +listing and deleting header fields. 1.154 +The structure of the code changes did not pay respect to this 1.155 +fundamental change to 1.156 +.Pn anno 's 1.157 +behavior. 1.158 +Neither the implementation nor the documentation did clearly 1.159 +define them as being exclusive modes of operation. 1.160 +Having identified the problem, I solved it by putting structure into 1.161 +.Pn anno 1.162 +and its documentation. 1.163 +.Ci d54c8db8bdf01e8381890f7729bc0ef4a055ea11 1.164 +.P 1.165 +The difference is visible in both, the code and the documentation. 1.166 +The following code excrept was replaced: 1.167 +.VS 1.168 +int delete = -2; /* delete header element if set */ 1.169 +int list = 0; /* list header elements if set */ 1.170 1.171 +[...] 1.172 1.173 +case DELETESW: /* delete annotations */ 1.174 + delete = 0; 1.175 + continue; 1.176 +case LISTSW: /* produce a listing */ 1.177 + list = 1; 1.178 + continue; 1.179 +VE 1.180 +At its place moved the following code: 1.181 +.VS 1.182 +static enum { MODE_ADD, MODE_DEL, MODE_LIST } mode = MODE_ADD; 1.183 1.184 +[...] 1.185 + 1.186 +case DELETESW: /* delete annotations */ 1.187 + mode = MODE_DEL; 1.188 + continue; 1.189 +case LISTSW: /* produce a listing */ 1.190 + mode = MODE_LIST; 1.191 + continue; 1.192 +VE 1.193 +.LP 1.194 +The replacement code does not only match the problem's structure, 1.195 +but it is easier to understand as well. 1.196 .P 1.197 -goto 1.198 -.P 1.199 -anno rework 1.200 +The man page was completely reorganized to propagate the same structure. 1.201 +This is already visible in the Synopsis section: 1.202 +.VS 1.203 +anno [+folder] [msgs] [-component field] [-text body] 1.204 + [-append] [-date | -nodate] [-preserve | -nopreserve] 1.205 + [-Version] [-help] 1.206 + 1.207 +anno -delete [+folder] [msgs] [-component field] [-text 1.208 + body] [-number num | all ] [-preserve | -nopreserve] 1.209 + [-Version] [-help] 1.210 + 1.211 +anno -list [+folder] [msgs] [-component field] [-number] 1.212 + [-Version] [-help] 1.213 +VE 1.214 1.215 1.216