diff options
| author | Henrik Rydberg <rydberg@euromail.se> | 2011-10-08 20:30:28 +0200 |
|---|---|---|
| committer | Henrik Rydberg <rydberg@euromail.se> | 2011-10-08 20:30:28 +0200 |
| commit | 5df79c53745fde5d6c3340a2979b1429cd5892c1 (patch) | |
| tree | 1a81af141708b826e9c61e8a04019994fcca8298 | |
Initial import of htcd system 1.0
Signed-off-by: Henrik Rydberg <rydberg@euromail.se>
196 files changed, 24839 insertions, 0 deletions
diff --git a/htc/dml.htc b/htc/dml.htc new file mode 100644 index 0000000..9781952 --- /dev/null +++ b/htc/dml.htc | |||
| @@ -0,0 +1,382 @@ | |||
| 1 | \include{system.htc} | ||
| 2 | \include{html.htc} | ||
| 3 | \const{dml.address}{nobody} | ||
| 4 | \def{dml.init}{xxxx}{ | ||
| 5 | %{listname}{group}{path}{http} | ||
| 6 | \global{dml.listname}{\1} | ||
| 7 | \global{dml.group}{\2} | ||
| 8 | \global{dml.path}{\3} | ||
| 9 | \global{dml.http}{\4} | ||
| 10 | \if(count \dml.group){\open{DML}{\dml.path/data/dml.hdb}{1}} | ||
| 11 | } | ||
| 12 | \def{dml.mailuser}{xx}{ | ||
| 13 | \if{\user.id}{ | ||
| 14 | \log{mail user: \1} | ||
| 15 | \mail{\dml.address}{}{\user.email}{DML Server}{\now}{\1}{text/plain}{\2} | ||
| 16 | } | ||
| 17 | } | ||
| 18 | \def{dml.dfs}{xr}{ | ||
| 19 | \find.rec{\1}{ | ||
| 20 | \2; | ||
| 21 | \query(PARENT==\1){ | ||
| 22 | \dml.dfs(INDEX){\2} | ||
| 23 | } | ||
| 24 | } | ||
| 25 | } | ||
| 26 | \def{dml.bfs}{xr}{ | ||
| 27 | [cur:="";bfs:=\1]; | ||
| 28 | \while(count bfs){ | ||
| 29 | [cur=first bfs]; | ||
| 30 | \find.rec(cur){\2}; | ||
| 31 | \query(PARENT==cur)(bfs=bfs+++INDEX); | ||
| 32 | [bfs=rest bfs]; | ||
| 33 | } | ||
| 34 | } | ||
| 35 | \def{dml.ups}{xr}{ | ||
| 36 | [cur:=\1]; | ||
| 37 | \while(cur){ | ||
| 38 | \find.rec(cur){\2;[cur=PARENT]}(cur=0) | ||
| 39 | } | ||
| 40 | } | ||
| 41 | \def{dml.watchers}{}{ | ||
| 42 | \if(count \dml.group){ | ||
| 43 | [ | ||
| 44 | m.<-@; | ||
| 45 | break:=\dml.ups(m.INDEX){[BREAK] }; | ||
| 46 | attime:=\if(m.PROTECT)(m.TIME){\now}; | ||
| 47 | people:=\db{USERS}{\query(\allowed{\dml.group}(attime)){[UID] }} | ||
| 48 | ]; | ||
| 49 | [people---break]; | ||
| 50 | } | ||
| 51 | } | ||
| 52 | \def{dml.resubj}{x}{ | ||
| 53 | [tmp:=first \1];\if(tmp nen "re" && tmp nen "re:"){Re: \1}{\1} | ||
| 54 | } | ||
| 55 | \def{dml.opennode}{x}{ | ||
| 56 | \db{DML}{ | ||
| 57 | \dml.ups{\1}(BREAK=BREAK---\user.id); | ||
| 58 | \dml.confirm{Opening \dml.listname\[\1\]}; | ||
| 59 | } | ||
| 60 | } | ||
| 61 | \def{dml.closenode}{x}{ | ||
| 62 | \db{DML}{ | ||
| 63 | \find.rec{\1}{ | ||
| 64 | [BREAK=BREAK|||\user.id]; | ||
| 65 | \dml.confirm{Closing \dml.listname\[\1\]}; | ||
| 66 | } | ||
| 67 | } | ||
| 68 | } | ||
| 69 | \def{dml.addnode}{x}{ | ||
| 70 | %(node) - add to this node | ||
| 71 | %T.from - mail address | ||
| 72 | %T.reply - reply address | ||
| 73 | %T.name - user name | ||
| 74 | %T.subject - subject | ||
| 75 | %T.mime - MIME type | ||
| 76 | %T.body - message | ||
| 77 | %T.parts - attachments | ||
| 78 | %T.mime[i] - attachment MIME type | ||
| 79 | %T.body[i] - attachment body | ||
| 80 | %RETURN - node number | ||
| 81 | \db{DML}{ | ||
| 82 | [ | ||
| 83 | t.TIME:=\now; | ||
| 84 | t.PARENT:=\1; | ||
| 85 | t.AUTHOR:=\user.id; | ||
| 86 | t.MIME:=\T.mime; | ||
| 87 | t.SUBJECT:=\T.subject; | ||
| 88 | t.BODY:=\T.body; | ||
| 89 | t.INDEX:=\lastkey+1; | ||
| 90 | t.PROTECT:=1; | ||
| 91 | @<-t.; | ||
| 92 | ]; | ||
| 93 | \log{dml: adding \dml.listname\[[INDEX]\]}; | ||
| 94 | [t.INDEX]; | ||
| 95 | \for(i:=0)(i<\T.parts)(i+=1){ | ||
| 96 | [file:="A"++INDEX++"_"++\filesafe{\T.body[i]}]; | ||
| 97 | \log{dml: uploading \dml.listname\[[file]\]}; | ||
| 98 | \save{\dml.path/attach/[file]}{T.body[i]}{385}; | ||
| 99 | [ATTACH=ATTACH|||file]; | ||
| 100 | } | ||
| 101 | } | ||
| 102 | } | ||
| 103 | \def{dml.footer}{x}{ | ||
| 104 | \if(\1 eq "text/html"){<hr>}{----------------------------------------------} | ||
| 105 | Help: send email to \dml.address with subject 'help \dml.listname' | ||
| 106 | } | ||
| 107 | \def{dml.quickguide}{}{ | ||
| 108 | QUICK GUIDE | ||
| 109 | |||
| 110 | Mailing-lists on this server (\dml.address): | ||
| 111 | |||
| 112 | \getlists;[ex:=\dml.listname] | ||
| 113 | |||
| 114 | Mails received from the server ALWAYS starts with the listname | ||
| 115 | enclosed in stars (*). For example, | ||
| 116 | |||
| 117 | *[ex]\[7\]* hello world | ||
| 118 | |||
| 119 | means you've received a message from the list '[ex]' with | ||
| 120 | subject 'hello world'. The message is identified by its | ||
| 121 | message number, in this case 7. | ||
| 122 | |||
| 123 | EXAMPLES | ||
| 124 | |||
| 125 | To post a new message on '[ex]' with subject 'hello world', | ||
| 126 | mail to \dml.address with subject | ||
| 127 | |||
| 128 | new [ex] hello world | ||
| 129 | |||
| 130 | To post a new message on a particular message number, e.g. 7, | ||
| 131 | mail to \dml.address with subject | ||
| 132 | |||
| 133 | new [ex]\[7\] hello world | ||
| 134 | |||
| 135 | Note that message number 1 is the message root, and is the same | ||
| 136 | as issuing new without the \[\]. | ||
| 137 | |||
| 138 | To reply to a message from the list, use 'reply' in your mailing program, | ||
| 139 | but DO NOT REMOVE anything before the subject. The server will | ||
| 140 | insert the appropriate 'Re:'. For instance, replying to the first example | ||
| 141 | above would normally give a reply-subject in your mailprogram like | ||
| 142 | |||
| 143 | Re: *[ex]\[7\]* hello world | ||
| 144 | |||
| 145 | which will be sent from the server as | ||
| 146 | |||
| 147 | *[ex]\[n\]* Re: hello world | ||
| 148 | |||
| 149 | where n is some new number assigned to your message. | ||
| 150 | } | ||
| 151 | \def{dml.message}{}{ | ||
| 152 | HELP ON USAGE OF THE *\dml.listname* MAILING LIST AT \dml.address. | ||
| 153 | |||
| 154 | The address handles multiple mailinglists, and takes commands on the form: | ||
| 155 | |||
| 156 | <cmd> <list>\[<node>\] <subject> | ||
| 157 | or | ||
| 158 | <cmd> *<list>\[<node>\]* <subject> | ||
| 159 | |||
| 160 | where <cmd> is a command, <list> is a mailinglist, | ||
| 161 | <node> is a message number, and <subject> is the subject | ||
| 162 | line. The brackets \[\] should however be there as is. | ||
| 163 | |||
| 164 | Mailing-lists on this server (\dml.address): | ||
| 165 | |||
| 166 | \getlists | ||
| 167 | |||
| 168 | You are \user.name, and your user name at \dml.address | ||
| 169 | is \user.email. You may have clearance to several of | ||
| 170 | the lists above. | ||
| 171 | \if(\dml.listname eq "demo"){ | ||
| 172 | \n; | ||
| 173 | This is a demo mailing list and will not work to send mails to. | ||
| 174 | You will need to know the name of a list to which you belong. | ||
| 175 | } | ||
| 176 | Commands are not case sensitive. Available commands <cmd> are: | ||
| 177 | |||
| 178 | HELP \dml.listname | ||
| 179 | |||
| 180 | Displays this message. | ||
| 181 | |||
| 182 | WHO \dml.listname\[<node>\] | ||
| 183 | |||
| 184 | Retrieve which people are registered at the list. | ||
| 185 | If a node number is given, it tells which people | ||
| 186 | will receive a new message from that node. | ||
| 187 | Note that this command may be restricted on some lists. | ||
| 188 | |||
| 189 | SILENT \dml.listname\[<node>\] | ||
| 190 | |||
| 191 | Adds a new message to message number <node> on \dml.listname, | ||
| 192 | without broadcasting. | ||
| 193 | |||
| 194 | NEW \dml.listname\[<node>\] <subject> | ||
| 195 | |||
| 196 | Adds a new message to message number <node> on \dml.listname, | ||
| 197 | and broadcasts to \dml.listname. | ||
| 198 | |||
| 199 | REPLY \dml.listname\[<node>\] <subject> | ||
| 200 | |||
| 201 | Replies to message number <node> on \dml.listname. | ||
| 202 | Possible acronyms are Re, Re:, Sv, Sv:. | ||
| 203 | Note that this command is issued when you do | ||
| 204 | a normal reply, whether it be on a swedish or | ||
| 205 | american mail program. | ||
| 206 | |||
| 207 | OPEN \dml.listname\[<node>\] | ||
| 208 | |||
| 209 | Opens a <node>. When a <node> is open, you recieve | ||
| 210 | broadcast messages descending from that <node>. | ||
| 211 | |||
| 212 | CLOSE \dml.listname\[<node>\] | ||
| 213 | |||
| 214 | Closes a <node>. When a <node> is closed, you do not | ||
| 215 | recieve the broadcast messages descending from that <node>. | ||
| 216 | The obvious usage of this command is to turn off | ||
| 217 | uninteresting of lengthy threads. Also, since everything | ||
| 218 | added to this node will pass unnoticed, it may be used | ||
| 219 | to structure e.q. news in topics, together with the | ||
| 220 | SILENT command. | ||
| 221 | |||
| 222 | MAIL \dml.listname\[<node>\] | ||
| 223 | |||
| 224 | Retrieve message number <node> from \dml.listname. | ||
| 225 | This command may not serve certain messages on the basis of your | ||
| 226 | clearance and when you first entered the list. | ||
| 227 | |||
| 228 | \if(\dml.listname ne "demo"){ | ||
| 229 | To get additional help on how to use this system, how to | ||
| 230 | view or protect message trees, you may visit the | ||
| 231 | \dml.http/ web page. Of course the commands listed | ||
| 232 | above can be issued from there as well. You PIN code | ||
| 233 | at the server is \user.pin. | ||
| 234 | } | ||
| 235 | } | ||
| 236 | \def{dml.layout}{?xx}{ | ||
| 237 | [mime:=\on.arg{0}{\0}(MIME)]; | ||
| 238 | \2 | ||
| 239 | \if(ATTACH ne ""){ | ||
| 240 | \if(mime eq "text/html"){ | ||
| 241 | <hr> | ||
| 242 | Attachments (PIN: \su{\1}{\user.pin}) | ||
| 243 | \forall{i}(ATTACH){ | ||
| 244 | \href{\dml.http/attach/[i]?alias=\su{\1}{\user.alias}}(i)\n; | ||
| 245 | } | ||
| 246 | }{ | ||
| 247 | ---------------------------------------------- | ||
| 248 | Attachments (PIN: \su{\1}{\user.pin}) | ||
| 249 | \forall{i}(ATTACH){ | ||
| 250 | \dml.http/attach/[i]?alias=\su{\1}{\user.alias}\n; | ||
| 251 | } | ||
| 252 | } | ||
| 253 | }; | ||
| 254 | \dml.footer(mime) | ||
| 255 | } | ||
| 256 | \def{dml.error}{x}{ | ||
| 257 | %T.cmd | ||
| 258 | %T.list | ||
| 259 | %T.node | ||
| 260 | %T.subject | ||
| 261 | \mail.root{mailer: \1}{ | ||
| 262 | check <\T.cmd> \T.list\[\T.node\] \T.subject | ||
| 263 | }; | ||
| 264 | \dml.mailuser{error}{ | ||
| 265 | An error occurred while processing your command | ||
| 266 | |||
| 267 | \T.cmd \T.list\[\T.node\] \T.subject | ||
| 268 | |||
| 269 | \1 | ||
| 270 | ---------------------------------------------- | ||
| 271 | \dml.quickguide | ||
| 272 | \dml.footer(MIME) | ||
| 273 | } | ||
| 274 | } | ||
| 275 | \def{dml.help}{}{ | ||
| 276 | \dml.mailuser{help \dml.listname}{ | ||
| 277 | \dml.quickguide | ||
| 278 | |||
| 279 | ---------------------------------------------- | ||
| 280 | \dml.message | ||
| 281 | } | ||
| 282 | } | ||
| 283 | \def{dml.who}{x}{ | ||
| 284 | %(node) - mail this node to group | ||
| 285 | \db{DML}{ | ||
| 286 | \find.rec{\1}{ | ||
| 287 | \dml.mailuser{who \dml.listname}{ | ||
| 288 | PEOPLE LISTENING TO \dml.listname;\[\1\] at \dml.address | ||
| 289 | |||
| 290 | \forall{i}{\dml.watchers}{ | ||
| 291 | \su(i){\user.name <\user.email>}\n | ||
| 292 | } | ||
| 293 | } | ||
| 294 | }{ | ||
| 295 | \dml.error{Could not find node \dml.listname;\[\1\]} | ||
| 296 | } | ||
| 297 | } | ||
| 298 | } | ||
| 299 | \def{dml.confirm}{x}{ | ||
| 300 | %T.cmd | ||
| 301 | %T.list | ||
| 302 | %T.node | ||
| 303 | %T.subject | ||
| 304 | \dml.mailuser{\dml.listname: confirmation}{ | ||
| 305 | Your command | ||
| 306 | |||
| 307 | \1 | ||
| 308 | |||
| 309 | was processed sucessfully. | ||
| 310 | } | ||
| 311 | } | ||
| 312 | \def{dml.mail}{x}{ | ||
| 313 | %(node) - mail this node to user | ||
| 314 | \db{DML}{ | ||
| 315 | \find.rec{\1}{ | ||
| 316 | [attime:=\if(PROTECT)(TIME){\now}]; | ||
| 317 | \if{\user.allow{\dml.group}(attime)}{ | ||
| 318 | \log{dml: mailing \dml.listname\[[INDEX]\] to (\user.id)}; | ||
| 319 | \mail{\su(AUTHOR){\user.email}}{}{\user.email}{\su(AUTHOR){\user.name}} | ||
| 320 | (TIME){*\dml.listname\[[INDEX]\]* [SUBJECT]}(MIME){\dml.layout{\user.id}(BODY)}; | ||
| 321 | }{ | ||
| 322 | \log{dml: denying \dml.listname\[[INDEX]\] to (\user.id)}; | ||
| 323 | \dml.mailuser{\dml.listname\[[INDEX]\]: not found}{ | ||
| 324 | The node you requested could not be found | ||
| 325 | |||
| 326 | (or may be protected) | ||
| 327 | } | ||
| 328 | } | ||
| 329 | }{ | ||
| 330 | \dml.error{Could not find node \dml.listname;\[\1\]} | ||
| 331 | } | ||
| 332 | } | ||
| 333 | } | ||
| 334 | \def{dml.broadcast}{x}{ | ||
| 335 | %(node) - mail this node to group | ||
| 336 | \db{DML}{ | ||
| 337 | \find.rec{\1}{ | ||
| 338 | \if(!BROADCAST){ | ||
| 339 | \log{dml: broadcasting \dml.listname\[[INDEX]\]} | ||
| 340 | [ | ||
| 341 | femail:=\su(AUTHOR){\user.email}; | ||
| 342 | fname:=\su(AUTHOR){\user.name}; | ||
| 343 | fsubj:="*"++\dml.listname++"["++INDEX++"]* "++SUBJECT; | ||
| 344 | watchers:=\dml.watchers; | ||
| 345 | BROADCAST=count watchers; | ||
| 346 | ]; | ||
| 347 | \forall{i}(watchers){ | ||
| 348 | [ | ||
| 349 | temail:=\su(i){\user.email}; | ||
| 350 | talias:=\su(i){\user.alias}; | ||
| 351 | tname:=\su(i){\user.name}; | ||
| 352 | tpin:=\su(i){\user.pin}; | ||
| 353 | tbody:=\replace(BODY){\recipient.email}(temail); | ||
| 354 | tbody=\replace(tbody){\recipient.alias}(talias); | ||
| 355 | tbody=\replace(tbody){\recipient.name}(tname); | ||
| 356 | tbody=\replace(tbody){\recipient.pin}(tpin); | ||
| 357 | tbody=\replace(tbody){\recipient.id}(i); | ||
| 358 | ]; | ||
| 359 | \mail(femail){\dml.listname <\dml.address>}(temail)(fname) | ||
| 360 | (TIME)(fsubj)(MIME){\dml.layout(i)(tbody)}; | ||
| 361 | \sleep(2); | ||
| 362 | } | ||
| 363 | } | ||
| 364 | } | ||
| 365 | } | ||
| 366 | } | ||
| 367 | \def{dml.addbroad}{x}{ | ||
| 368 | [node:=\dml.addnode{\1}]; | ||
| 369 | \if(node){ | ||
| 370 | \dml.broadcast(node) | ||
| 371 | }{ | ||
| 372 | \dml.error{Could not add to \dml.listname;\[\1\]} | ||
| 373 | } | ||
| 374 | } | ||
| 375 | \def{dml.addsilent}{x}{ | ||
| 376 | [node:=\dml.addnode{\1}]; | ||
| 377 | \if(node){ | ||
| 378 | \dml.confirm{Added \dml.listname\[[node]\] to \dml.listname\[\1\]} | ||
| 379 | }{ | ||
| 380 | \dml.error{Could not add to \dml.listname;\[\1\]} | ||
| 381 | } | ||
| 382 | } | ||
diff --git a/htc/dmled.htc b/htc/dmled.htc new file mode 100644 index 0000000..61929fa --- /dev/null +++ b/htc/dmled.htc | |||
| @@ -0,0 +1,128 @@ | |||
| 1 | \include{dml.htc} | ||
| 2 | \def{dmled.init}{xx}{ | ||
| 3 | %{listname}{address} | ||
| 4 | \dml.init{\1}{\group}{\npwd}{\server\npwd}; | ||
| 5 | \reconst{dml.address}{\2}; | ||
| 6 | \sort{DML}{INDEX}{>} | ||
| 7 | } | ||
| 8 | \def{dmled.page}{}{ | ||
| 9 | \cond{T.find}{} | ||
| 10 | \cond{T.msg}{0} | ||
| 11 | \title{Database Mailing List (\dml.listname)} | ||
| 12 | \db{DML}{ | ||
| 13 | \form{ | ||
| 14 | \table{width=100% bgcolor=#dddddd}{ | ||
| 15 | \tr{valign=top}{ | ||
| 16 | \td{ | ||
| 17 | <select name=dummy size=6> | ||
| 18 | [tf:=\T.find]; | ||
| 19 | \query( | ||
| 20 | (tf eq "" ||SUBJECT cntn tf||AUTHOR cntn tf||BODY cntn tf)&& | ||
| 21 | (!PROTECT||\user.allow(\dml.group)(TIME)) | ||
| 22 | ){ | ||
| 23 | \option{\if(INDEX==\T.msg){ selected }}(INDEX){ | ||
| 24 | [INDEX] - \sub(SUBJECT){0}{30} | ||
| 25 | \su(AUTHOR){\[\user.name\]}; (\time2htc(TIME)) | ||
| 26 | \if(count ATTACH){\[attach\]} | ||
| 27 | } | ||
| 28 | } | ||
| 29 | </select> | ||
| 30 | } | ||
| 31 | \td{ | ||
| 32 | \button{View}<br> | ||
| 33 | \button{Reply}<br> | ||
| 34 | \button{New} | ||
| 35 | } | ||
| 36 | } | ||
| 37 | \tr{valign=top}{ | ||
| 38 | \td{ | ||
| 39 | \input{find}{60}{\T.find} | ||
| 40 | } | ||
| 41 | \td{ | ||
| 42 | \button{Search} | ||
| 43 | } | ||
| 44 | } | ||
| 45 | } | ||
| 46 | } | ||
| 47 | \find.rec{\T.msg}{ | ||
| 48 | \if(!PROTECT||\user.allow(\dml.group)(TIME)){ | ||
| 49 | \table{width=100% bgcolor=#dddddd}{ | ||
| 50 | \tr{ | ||
| 51 | \th{align=left}{[INDEX] - [SUBJECT]} | ||
| 52 | \td{align=right}{ | ||
| 53 | \find.rec(PARENT){ | ||
| 54 | \if(!PROTECT||\user.allow(\dml.group)(TIME)){ | ||
| 55 | \bf{Prev:} | ||
| 56 | \href{\this?msg=[INDEX]}{[INDEX] - \sub(SUBJECT){0}{30}} | ||
| 57 | \su(AUTHOR){\[\user.name\]} | ||
| 58 | } | ||
| 59 | } | ||
| 60 | } | ||
| 61 | } | ||
| 62 | \tr{ | ||
| 63 | \td{align=left}{ | ||
| 64 | \su(AUTHOR){ | ||
| 65 | \user.name \lt;\href{mailto:\user.email}{\user.email};\gt | ||
| 66 | } | ||
| 67 | } | ||
| 68 | \td{align=right}{ | ||
| 69 | \time2htc(TIME) | ||
| 70 | } | ||
| 71 | } | ||
| 72 | \tr{ | ||
| 73 | \td{align=left colspan=2}{ | ||
| 74 | \htmlize(BODY) | ||
| 75 | } | ||
| 76 | } | ||
| 77 | \if(count ATTACH){ | ||
| 78 | \tr{ | ||
| 79 | \td{align=left colspan=2}{ | ||
| 80 | \forall{i}(ATTACH){ | ||
| 81 | \href{\npwd/attach/[i]}(i)\n | ||
| 82 | } | ||
| 83 | } | ||
| 84 | } | ||
| 85 | } | ||
| 86 | \tr{ | ||
| 87 | \td{align=left colspan=2}{ | ||
| 88 | [idx:=INDEX]; | ||
| 89 | \query(PARENT==idx&&(!PROTECT||\user.allow(\dml.group)(TIME))){ | ||
| 90 | \bf{Next:} | ||
| 91 | \href{\this?msg=[INDEX]}{[INDEX] - [SUBJECT]} | ||
| 92 | \su(AUTHOR){\[\user.name\]} | ||
| 93 | <br> | ||
| 94 | } | ||
| 95 | } | ||
| 96 | } | ||
| 97 | } | ||
| 98 | } | ||
| 99 | } | ||
| 100 | } | ||
| 101 | } | ||
| 102 | \def{dmled.onpost}{}{ | ||
| 103 | \switch{\T.cmd} | ||
| 104 | {View}{ | ||
| 105 | \redirect{\server\this?msg=\T.dummy} | ||
| 106 | } | ||
| 107 | {Reply}{ | ||
| 108 | \redirect{\server\this} | ||
| 109 | \db{DML}{ | ||
| 110 | \find.rec{\T.dummy}{ | ||
| 111 | \if(!PROTECT||\user.allow(\dml.group)(TIME)){ | ||
| 112 | \redirect{ | ||
| 113 | mailto:\dml.address?subject=Reply \dml.listname\[[INDEX]\] [SUBJECT] | ||
| 114 | } | ||
| 115 | } | ||
| 116 | } | ||
| 117 | } | ||
| 118 | } | ||
| 119 | {New}{ | ||
| 120 | [node:=\on.glob{T.dummy}{\T.dummy}{1}]; | ||
| 121 | \redirect{mailto:\dml.address?subject=New \dml.listname\[[node]\] (no subject)} | ||
| 122 | } | ||
| 123 | { | ||
| 124 | \on.glob{T.find}{ | ||
| 125 | \redirect{\server\this?find=\encode{\T.find}} | ||
| 126 | } | ||
| 127 | } | ||
| 128 | } | ||
diff --git a/htc/help.htc b/htc/help.htc new file mode 100644 index 0000000..d35d210 --- /dev/null +++ b/htc/help.htc | |||
| @@ -0,0 +1,31 @@ | |||
| 1 | \throw{help: OBSOLETED} | ||
| 2 | \def{list.unary}{}{ | ||
| 3 | \ops.htc{ | ||
| 4 | \order{PRE1}{>} | ||
| 5 | \query(PRE1){ | ||
| 6 | \left(OP){10}[DESC] | ||
| 7 | } | ||
| 8 | } | ||
| 9 | } | ||
| 10 | \def{list.binary}{}{ | ||
| 11 | \ops.htc{ | ||
| 12 | \order{PRE2}{>} | ||
| 13 | \query(PRE2){ | ||
| 14 | \left(OP){10}[DESC] | ||
| 15 | } | ||
| 16 | } | ||
| 17 | } | ||
| 18 | \def{list.mod}{x}{ | ||
| 19 | \tokens{ | ||
| 20 | \query(MOD==\1){ | ||
| 21 | [TOK] | ||
| 22 | } | ||
| 23 | } | ||
| 24 | } | ||
| 25 | \def{list.users}{x}{ | ||
| 26 | \users{\1}{ | ||
| 27 | \query{1}{ | ||
| 28 | \left(ID){4} \left(NAME){38} \left(GID){3} \sub{\time2htc(LAST)}{4}{12} [LASTIN] | ||
| 29 | } | ||
| 30 | } | ||
| 31 | } | ||
diff --git a/htc/htcd.htc b/htc/htcd.htc new file mode 100644 index 0000000..038bf89 --- /dev/null +++ b/htc/htcd.htc | |||
| @@ -0,0 +1,4 @@ | |||
| 1 | \include{latex.htc} | ||
| 2 | \include{html.htc} | ||
| 3 | \include{http.htc} | ||
| 4 | \include{dmled.htc} | ||
diff --git a/htc/html.htc b/htc/html.htc new file mode 100644 index 0000000..bd96870 --- /dev/null +++ b/htc/html.htc | |||
| @@ -0,0 +1,152 @@ | |||
| 1 | \const{icons}{/icons} | ||
| 2 | \const{space}{ } | ||
| 3 | \const{lt}{<} | ||
| 4 | \const{gt}{>} | ||
| 5 | \def{indent}{x}{\for(i:=0)(i<\1)(i+=1){\space}} | ||
| 6 | \def{option}{?xx}{ | ||
| 7 | %<options>{value}{desc} | ||
| 8 | <option\on.arg{0}{ \0} value=\cdata{\1}> | ||
| 9 | \2 | ||
| 10 | } | ||
| 11 | \def{select}{xx*}{ | ||
| 12 | %{name}{selected}<optname><optval>.. | ||
| 13 | <select name=\1> | ||
| 14 | \if(\args>2){ | ||
| 15 | \for(i:=3)(i<=\args)(i+=2){ | ||
| 16 | <option\if(\arg(i) eq \2){ selected} value=\cdata{\arg(i)}> | ||
| 17 | \arg(i+1) | ||
| 18 | } | ||
| 19 | }{ | ||
| 20 | \2 | ||
| 21 | } | ||
| 22 | </select> | ||
| 23 | } | ||
| 24 | \def{button}{?x}{ | ||
| 25 | %[option]{value} | ||
| 26 | <input type=submit name=\on.arg{0}{\0}{cmd} value=\cdata{\1}> | ||
| 27 | } | ||
| 28 | \def{variable}{xx}{ | ||
| 29 | %{name}{value} | ||
| 30 | <input type=hidden name=\1 value=\cdata{\2}> | ||
| 31 | } | ||
| 32 | \def{radio}{xx?}{ | ||
| 33 | %{name}{value}[bool] | ||
| 34 | <input type=radio name=\1 value=\cdata{\2}\if{\0}{ checked}> | ||
| 35 | } | ||
| 36 | \def{target}{x}{} | ||
| 37 | \def{href}{xx}{ | ||
| 38 | %{uri}{name} | ||
| 39 | <a href=\cdata{\1}\target{\1}>\2</a> | ||
| 40 | } | ||
| 41 | \def{iref}{xx}{ | ||
| 42 | %{uri}{image} | ||
| 43 | <a href=\cdata{\1}\target{\1}><img border=0 src=\cdata{\2}></a> | ||
| 44 | } | ||
| 45 | \def{form}{?x}{ | ||
| 46 | %<uri>{body} | ||
| 47 | <form method=post action=/POST\on.arg{0}{\0}{\req.uri}\target{\0}> | ||
| 48 | \1 | ||
| 49 | </form> | ||
| 50 | } | ||
| 51 | \def{form.multi}{?x}{ | ||
| 52 | %{body} | ||
| 53 | <form method=post enctype=multipart/form-data action=/POST\on.arg{0}{\0}{\req.uri}\target{\0}> | ||
| 54 | \1 | ||
| 55 | </form> | ||
| 56 | } | ||
| 57 | \def{input}{xx?}{ | ||
| 58 | %{name}{size}[value] | ||
| 59 | <input type=text name=\1 size=\2\on.arg{0}{ value=\cdata{\0}}> | ||
| 60 | } | ||
| 61 | \def{passwd}{xx?}{ | ||
| 62 | %{name}{size}[value] | ||
| 63 | <input type=password name=\1 size=\2\on.arg{0}{ value=\cdata{\0}}> | ||
| 64 | } | ||
| 65 | \def{check}{xx?}{ | ||
| 66 | %{name}{value}[bool] | ||
| 67 | <input type=checkbox name=\1 value=\cdata{\2}\if{\0}{ checked}> | ||
| 68 | } | ||
| 69 | \def{file}{?xx}{ | ||
| 70 | %{name}{size}[value] | ||
| 71 | <input type=file\on.arg{0}{ accept=\cdata{\0}} name=\1 size=\2> | ||
| 72 | } | ||
| 73 | \def{text}{xxx?}{ | ||
| 74 | %{name}{row}{col}[value] | ||
| 75 | <textarea name=\1 rows=\2 cols=\3> | ||
| 76 | \mask.html{\4} | ||
| 77 | </textarea> | ||
| 78 | } | ||
| 79 | \def{image}{?x}{ | ||
| 80 | %[options]{body} | ||
| 81 | <img\on.arg{0}{ \0} src=\cdata{\1}> | ||
| 82 | } | ||
| 83 | \def{table}{?x}{ | ||
| 84 | %[options]{body} | ||
| 85 | <table\on.arg{0}{ \0}> | ||
| 86 | \1 | ||
| 87 | </table> | ||
| 88 | } | ||
| 89 | \def{th}{?x}{ | ||
| 90 | %[options]{body} | ||
| 91 | <th\on.arg{0}{ \0}> | ||
| 92 | \1 | ||
| 93 | </th> | ||
| 94 | } | ||
| 95 | \def{tr}{?x}{ | ||
| 96 | %[options]{body} | ||
| 97 | <tr\on.arg{0}{ \0}> | ||
| 98 | \1 | ||
| 99 | </tr> | ||
| 100 | } | ||
| 101 | \def{td}{?x}{ | ||
| 102 | %[options]{body} | ||
| 103 | <td\on.arg{0}{ \0}>\on.arg{1}{\1}{\space}</td> | ||
| 104 | } | ||
| 105 | \def{font}{?x}{ | ||
| 106 | %[options]{body} | ||
| 107 | <font\on.arg{0}{ \0}>\1</font> | ||
| 108 | } | ||
| 109 | \def{ul}{?x}{ | ||
| 110 | %[options]{body} | ||
| 111 | <ul\on.arg{0}{ \0}> | ||
| 112 | \1 | ||
| 113 | </ul> | ||
| 114 | } | ||
| 115 | \def{li}{?x}{ | ||
| 116 | %[options]{body} | ||
| 117 | <li\on.arg{0}{ \0}>\1</li> | ||
| 118 | } | ||
| 119 | \def{h1}{?x}{ | ||
| 120 | %[options]{body} | ||
| 121 | <h1\on.arg{0}{ \0}>\1</h1> | ||
| 122 | } | ||
| 123 | \def{h2}{?x}{ | ||
| 124 | %[options]{body} | ||
| 125 | <h2\on.arg{0}{ \0}>\1</h2> | ||
| 126 | } | ||
| 127 | \def{h3}{?x}{ | ||
| 128 | %[options]{body} | ||
| 129 | <h3\on.arg{0}{ \0}>\1</h3> | ||
| 130 | } | ||
| 131 | \def{h4}{?x}{ | ||
| 132 | %[options]{body} | ||
| 133 | <h4\on.arg{0}{ \0}>\1</h4> | ||
| 134 | } | ||
| 135 | \def{h5}{?x}{ | ||
| 136 | %[options]{body} | ||
| 137 | <h5\on.arg{0}{ \0}>\1</h5> | ||
| 138 | } | ||
| 139 | \def{h6}{?x}{ | ||
| 140 | %[options]{body} | ||
| 141 | <h6\on.arg{0}{ \0}>\1</h6> | ||
| 142 | } | ||
| 143 | \def{center}{?x}{ | ||
| 144 | %[options]{body} | ||
| 145 | <center\on.arg{0}{ \0}>\1</center> | ||
| 146 | } | ||
| 147 | \def{body}{?x}{ | ||
| 148 | %[options]{body} | ||
| 149 | <body\on.arg{0}{ \0}> | ||
| 150 | \1 | ||
| 151 | </body> | ||
| 152 | } | ||
diff --git a/htc/http.htc b/htc/http.htc new file mode 100644 index 0000000..c9a8557 --- /dev/null +++ b/htc/http.htc | |||
| @@ -0,0 +1,61 @@ | |||
| 1 | \include{system.htc} | ||
| 2 | \include{tree.htc} | ||
| 3 | \include{layout.htc} | ||
| 4 | \include{upload.htc} | ||
| 5 | \include{posit.htc} | ||
| 6 | \const{server}{http://\HOST\if(\port!=80){:\port}} | ||
| 7 | \const{server.alias}(\HOST left ".") | ||
| 8 | \const{server.admin}{\ADMIN} | ||
| 9 | % | ||
| 10 | % Some special stuff | ||
| 11 | % | ||
| 12 | \def{setcookie}{xx?}{ | ||
| 13 | \resp.cookie{\1}{\2}{ | ||
| 14 | % domain=\HOST\; path=/\if(\0){; expires=\time2http{\0}} | ||
| 15 | % the domain spec above does not work on modern browsers such as firefox | ||
| 16 | % if host is not a fully qualified dns name | ||
| 17 | path=/\if(\0){; expires=\time2http{\0}} | ||
| 18 | } | ||
| 19 | } | ||
| 20 | \def{redirect}{x}{ | ||
| 21 | \if(\req.version gt "HTTP/1.0"){ | ||
| 22 | \resp.status{\HTTP.303} | ||
| 23 | }{ | ||
| 24 | \resp.status{\HTTP.302} | ||
| 25 | } | ||
| 26 | \if(\1 cnt ":"){ | ||
| 27 | \resp.location{\1} | ||
| 28 | }{ | ||
| 29 | \resp.location{\server\1} | ||
| 30 | } | ||
| 31 | } | ||
| 32 | \def{onget}{r}{ | ||
| 33 | \if("GET HEAD" which \req.method){ | ||
| 34 | \1 | ||
| 35 | } | ||
| 36 | } | ||
| 37 | \def{onpost}{r}{ | ||
| 38 | \if(\req.method eq "POST"){ | ||
| 39 | \1 | ||
| 40 | } | ||
| 41 | } | ||
| 42 | % | ||
| 43 | % Cookie allowance | ||
| 44 | % | ||
| 45 | \def{cookie.allow}{x}{ | ||
| 46 | [ok:=1;name:=first \1;val:=rest \1]; | ||
| 47 | \if(name ne ""){ | ||
| 48 | [ok=0]; | ||
| 49 | \for(i:=0)(i<\ncookie)(i+=1){ | ||
| 50 | \if(\cookie[i].name eq name && \cookie[i].val eq val)(ok=1); | ||
| 51 | } | ||
| 52 | }; | ||
| 53 | [ok] | ||
| 54 | } | ||
| 55 | % | ||
| 56 | % CRONTAB | ||
| 57 | % | ||
| 58 | \cron(211){\sync} | ||
| 59 | \cron(120){\tree.update} | ||
| 60 | \cron(300){\tempfile.update} | ||
| 61 | |||
diff --git a/htc/latex.htc b/htc/latex.htc new file mode 100644 index 0000000..5b962bb --- /dev/null +++ b/htc/latex.htc | |||
| @@ -0,0 +1,262 @@ | |||
| 1 | \def{symbol}{x}{<font face=symbol>\1</font>} | ||
| 2 | |||
| 3 | \const{alpha}{\symbol{a}} | ||
| 4 | \const{beta}{\symbol{b}} | ||
| 5 | \const{gamma}{\symbol{g}} | ||
| 6 | \const{delta}{\symbol{d}} | ||
| 7 | \const{epsilon}{\symbol{e}} | ||
| 8 | \const{varepsilon}{\symbol{e}} | ||
| 9 | \const{zeta}{\symbol{z}} | ||
| 10 | \const{eta}{\symbol{h}} | ||
| 11 | \const{theta}{\symbol{q}} | ||
| 12 | \const{vartheta}{\symbol{J}} | ||
| 13 | \const{iota}{\symbol{i}} | ||
| 14 | \const{kappa}{\symbol{k}} | ||
| 15 | \const{lambda}{\symbol{l}} | ||
| 16 | \const{mu}{\symbol{m}} | ||
| 17 | \const{nu}{\symbol{n}} | ||
| 18 | \const{xi}{\symbol{x}} | ||
| 19 | \const{omicron}{\symbol{o}} | ||
| 20 | \const{pi}{\symbol{p}} | ||
| 21 | \const{varpi}{\symbol{v}} | ||
| 22 | \const{rho}{\symbol{r}} | ||
| 23 | \const{varrho}{\symbol{r}} | ||
| 24 | \const{sigma}{\symbol{s}} | ||
| 25 | \const{varsigma}{\symbol{V}} | ||
| 26 | \const{tau}{\symbol{t}} | ||
| 27 | \const{upsilon}{\symbol{u}} | ||
| 28 | \const{phi}{\symbol{f}} | ||
| 29 | \const{varphi}{\symbol{j}} | ||
| 30 | \const{chi}{\symbol{c}} | ||
| 31 | \const{psi}{\symbol{y}} | ||
| 32 | \const{omega}{\symbol{w}} | ||
| 33 | \const{Gamma}{\symbol{G}} | ||
| 34 | \const{Delta}{\symbol{D}} | ||
| 35 | \const{Theta}{\symbol{Q}} | ||
| 36 | \const{Lambda}{\symbol{L}} | ||
| 37 | \const{Xi}{\symbol{X}} | ||
| 38 | \const{Pi}{\symbol{P}} | ||
| 39 | \const{Sigma}{\symbol{S}} | ||
| 40 | \const{Upsilon}{\symbol{¡}} | ||
| 41 | \const{Phi}{\symbol{F}} | ||
| 42 | \const{Psi}{\symbol{Y}} | ||
| 43 | \const{Omega}{\symbol{W}} | ||
| 44 | \const{pm}{\symbol{±}} | ||
| 45 | \const{times}{\symbol{´}} | ||
| 46 | \const{div}{\symbol{¸}} | ||
| 47 | \const{bullet}{\symbol{·}} | ||
| 48 | \const{cdot}{\symbol{×}} | ||
| 49 | \const{varplus}{\symbol{+}} | ||
| 50 | \const{cap}{\symbol{Ç}} | ||
| 51 | \const{cup}{\symbol{È}} | ||
| 52 | \const{vee}{\symbol{Ù}} | ||
| 53 | \const{wedge}{\symbol{Ú}} | ||
| 54 | \const{varminus}{\symbol{-}} | ||
| 55 | \const{diamond}{\symbol{à}} | ||
| 56 | \const{oplus}{\symbol{Å}} | ||
| 57 | \const{otimes}{\symbol{Ä}} | ||
| 58 | \const{leq}{\symbol{£}} | ||
| 59 | \const{subset}{\symbol{Ì}} | ||
| 60 | \const{subseteq}{\symbol{Í}} | ||
| 61 | \const{in}{\symbol{Î}} | ||
| 62 | \const{notin}{\symbol{Ï}} | ||
| 63 | \const{geq}{\symbol{³}} | ||
| 64 | \const{supset}{\symbol{É}} | ||
| 65 | \const{supseteq}{\symbol{Ê}} | ||
| 66 | \const{equiv}{\symbol{º}} | ||
| 67 | \const{sim}{\symbol{~}} | ||
| 68 | \const{approx}{\symbol{»}} | ||
| 69 | \const{cong}{\symbol{@}} | ||
| 70 | \const{neq}{\symbol{¹}} | ||
| 71 | \const{propto}{\symbol{µ}} | ||
| 72 | \const{less}{\symbol{<}} | ||
| 73 | \const{perp}{\symbol{^}} | ||
| 74 | \const{mid}{\symbol{|}} | ||
| 75 | \const{equal}{\symbol{=}} | ||
| 76 | \const{greater}{\symbol{>}} | ||
| 77 | \const{colon}{\symbol{:}} | ||
| 78 | \const{semi}{\symbol{;}} | ||
| 79 | \const{ldots}{\symbol{¼}} | ||
| 80 | \const{leftarrow}{\symbol{¬}} | ||
| 81 | \const{Leftarrow}{\symbol{Ü}} | ||
| 82 | \const{rightarrow}{\symbol{®}} | ||
| 83 | \const{Rightarrow}{\symbol{Þ}} | ||
| 84 | \const{leftrightarrow}{\symbol{«}} | ||
| 85 | \const{Leftrightarrow}{\symbol{Û}} | ||
| 86 | \const{uparrow}{\symbol{¯}} | ||
| 87 | \const{Uparrow}{\symbol{Ý}} | ||
| 88 | \const{downarrow}{\symbol{}} | ||
| 89 | \const{Downarrow}{\symbol{ß}} | ||
| 90 | \const{aleph}{\symbol{À}} | ||
| 91 | \const{wp}{\symbol{Ã}} | ||
| 92 | \const{Re}{\symbol{Â}} | ||
| 93 | \const{Im}{\symbol{Á}} | ||
| 94 | \const{prime}{\symbol{¢}} | ||
| 95 | \const{doubleprime}{\symbol{²}} | ||
| 96 | \const{emptyset}{\symbol{Æ}} | ||
| 97 | \const{nabla}{\symbol{Ñ}} | ||
| 98 | \const{surd}{\symbol{Ö}} | ||
| 99 | \const{angle}{\symbol{Ð}} | ||
| 100 | \const{deg}{\symbol{°}} | ||
| 101 | \const{neg}{\symbol{Ø}} | ||
| 102 | \const{partial}{\symbol{¶}} | ||
| 103 | \const{infty}{\symbol{¥}} | ||
| 104 | \const{clubsuit}{\symbol{§}} | ||
| 105 | \const{diamondsuit}{\symbol{¨}} | ||
| 106 | \const{heartsuit}{\symbol{©}} | ||
| 107 | \const{spadesuit}{\symbol{ª}} | ||
| 108 | \const{apple}{\symbol{ð}} | ||
| 109 | \const{tm}{\symbol{Ô}} | ||
| 110 | \const{vartm}{\symbol{ä}} | ||
| 111 | \const{copyright}{\symbol{Ó}} | ||
| 112 | \const{circledR}{\symbol{Ò}} | ||
| 113 | \const{prod}{\symbol{Õ}} | ||
| 114 | \const{int}{\symbol{ò}} | ||
| 115 | \const{sum}{\symbol{å}} | ||
| 116 | \const{ast}{*} | ||
| 117 | \const{backslash}{ | ||
| 118 | \ | ||
| 119 | } | ||
| 120 | \const{setminus}{ | ||
| 121 | \ | ||
| 122 | } | ||
| 123 | |||
| 124 | \const{`A}{À} | ||
| 125 | \const{'A}{Á} | ||
| 126 | \const{^A}{Â} | ||
| 127 | \const{~A}{Ã} | ||
| 128 | \const{"A}{Ä} | ||
| 129 | \const{AA}{Å} | ||
| 130 | \const{AE}{Æ} | ||
| 131 | \const{`E}{È} | ||
| 132 | \const{'E}{É} | ||
| 133 | \const{^E}{Ê} | ||
| 134 | \const{"E}{Ë} | ||
| 135 | \const{`I}{Ì} | ||
| 136 | \const{'I}{Í} | ||
| 137 | \const{^I}{Î} | ||
| 138 | \const{"I}{Ï} | ||
| 139 | \const{'N}{Ñ} | ||
| 140 | \const{`O}{Ò} | ||
| 141 | \const{'O}{Ó} | ||
| 142 | \const{^O}{Ô} | ||
| 143 | \const{~O}{Õ} | ||
| 144 | \const{"O}{Ö} | ||
| 145 | \const{OO}{Ø} | ||
| 146 | \const{`U}{Ù} | ||
| 147 | \const{'U}{Ú} | ||
| 148 | \const{^U}{Û} | ||
| 149 | \const{"U}{Ü} | ||
| 150 | \const{'Y}{Ý} | ||
| 151 | \const{`a}{à} | ||
| 152 | \const{'a}{á} | ||
| 153 | \const{^a}{â} | ||
| 154 | \const{~a}{ã} | ||
| 155 | \const{"a}{ä} | ||
| 156 | \const{aa}{å} | ||
| 157 | \const{ae}{æ} | ||
| 158 | \const{cc}{ç} | ||
| 159 | \const{`e}{è} | ||
| 160 | \const{'e}{é} | ||
| 161 | \const{^e}{ê} | ||
| 162 | \const{"e}{ë} | ||
| 163 | \const{`i}{ì} | ||
| 164 | \const{'i}{í} | ||
| 165 | \const{^i}{î} | ||
| 166 | \const{"i}{ï} | ||
| 167 | \const{~n}{ñ} | ||
| 168 | \const{`o}{ò} | ||
| 169 | \const{'o}{ó} | ||
| 170 | \const{^o}{ô} | ||
| 171 | \const{~o}{õ} | ||
| 172 | \const{"o}{ö} | ||
| 173 | \const{oo}{ø} | ||
| 174 | \const{`u}{ù} | ||
| 175 | \const{'u}{ú} | ||
| 176 | \const{^u}{û} | ||
| 177 | \const{"u}{ü} | ||
| 178 | \const{'y}{ý} | ||
| 179 | \const{"y}{ÿ} | ||
| 180 | \const{ | ||
| 181 | \ | ||
| 182 | }{ | ||
| 183 | <br> | ||
| 184 | } | ||
| 185 | \const{,}{ } | ||
| 186 | \const{!}{} | ||
| 187 | \const{para}{<p>\n} | ||
| 188 | |||
| 189 | \const{newpage}{\n} | ||
| 190 | \const{det}{det} | ||
| 191 | \const{ln}{ln} | ||
| 192 | \const{lim}{lim} | ||
| 193 | %\const{tilde}{~} | ||
| 194 | \const{tilde}{} | ||
| 195 | \const{protect}{} | ||
| 196 | |||
| 197 | \def{emph}{x}{<em>\1</em>} | ||
| 198 | \def{title}{x}{<h1>\1</h1>} | ||
| 199 | \def{chapter}{x}{<h2>\1</h2>} | ||
| 200 | \def{section}{x}{<h3>\1</h3>} | ||
| 201 | \def{subsection}{x}{<h4>\1</h4>} | ||
| 202 | \def{subsubsection}{x}{<h5>\1</h5>} | ||
| 203 | \def{itemize}{x}{ | ||
| 204 | <ul> | ||
| 205 | \1 | ||
| 206 | </ul> | ||
| 207 | } | ||
| 208 | \def{item}{x}{<li>\1</li>} | ||
| 209 | \const{draft}{} | ||
| 210 | \const{maketitle}{} | ||
| 211 | |||
| 212 | \global{LATEX.CITEN}{1} | ||
| 213 | \def{cite}{x}{ | ||
| 214 | \global{LATEX.CITECUR}( | ||
| 215 | \forall{ii}{\1}{ ,}{ | ||
| 216 | \LATEX.CITEN,\on.glob{LATEX.CITE[ii]}{}{ | ||
| 217 | \global{LATEX.CITE[ii]}{\LATEX.CITEN}\global{LATEX.CITEN}(\LATEX.CITEN+1) | ||
| 218 | } | ||
| 219 | } | ||
| 220 | rleft "," | ||
| 221 | ); | ||
| 222 | $^\LATEX.CITECUR$ | ||
| 223 | } | ||
| 224 | \def{onlinecite}{x}{\cite{\1}} | ||
| 225 | \def{bibitem}{x}{\[\LATEX.CITE[\1]\]} | ||
| 226 | |||
| 227 | \def{author}{x}{} | ||
| 228 | \def{address}{x}{} | ||
| 229 | \def{pacs}{x}{} | ||
| 230 | \def{ref}{x}{} | ||
| 231 | \def{caption}{x}{} | ||
| 232 | \def{abstract}{x}{\bf \1} | ||
| 233 | \def{label}{x}{} | ||
| 234 | \def{frac}{xx}{$\1/\2$} | ||
| 235 | |||
| 236 | \def{document}{r}{ | ||
| 237 | \page{ | ||
| 238 | \1 | ||
| 239 | } | ||
| 240 | } | ||
| 241 | \def{array}{x}{ | ||
| 242 | \table{ | ||
| 243 | \forall{ii}{\1}{<br>}{ | ||
| 244 | \tr{ | ||
| 245 | \forall{jj}(ii){&}{ | ||
| 246 | \td(jj) | ||
| 247 | } | ||
| 248 | } | ||
| 249 | } | ||
| 250 | } | ||
| 251 | } | ||
| 252 | \def{ltable}{x}{ | ||
| 253 | \table{ | ||
| 254 | \forall{ii}{\1}{<br>}{ | ||
| 255 | \tr{ | ||
| 256 | \forall{jj}(ii){&}{ | ||
| 257 | \td(jj) | ||
| 258 | } | ||
| 259 | } | ||
| 260 | } | ||
| 261 | } | ||
| 262 | } | ||
diff --git a/htc/layout.htc b/htc/layout.htc new file mode 100644 index 0000000..b3e7b44 --- /dev/null +++ b/htc/layout.htc | |||
| @@ -0,0 +1,348 @@ | |||
| 1 | \const{HEIGHT.head}{40} | ||
| 2 | \const{HEIGHT.foot}{32} | ||
| 3 | \const{COLOR.private}{#ffffcc} | ||
| 4 | \const{COLOR.public}{#ffffff} | ||
| 5 | \const{COLOR.special}{#cccccc} | ||
| 6 | \const{COLOR.grayed}{#999999} | ||
| 7 | \def{page}{r}{ | ||
| 8 | \if("GET HEAD" which \req.method){ | ||
| 9 | \output{ | ||
| 10 | \body{bgcolor=\if(\group ne ""){\COLOR.private}{\COLOR.public}}{ | ||
| 11 | \1 | ||
| 12 | } | ||
| 13 | } | ||
| 14 | } | ||
| 15 | } | ||
| 16 | \def{show.head}{}{ | ||
| 17 | <head> | ||
| 18 | <title>\server.alias\uri</title> | ||
| 19 | </head> | ||
| 20 | } | ||
| 21 | \def{show.page}{}{ | ||
| 22 | \nif(\req.useragent cnt "Mozilla"){\resp.cont.type.charset{}}; | ||
| 23 | \switch(stat.MIME) | ||
| 24 | {text/x-htc}{ | ||
| 25 | \if(stat.MOD&1){ | ||
| 26 | \parse.public(stat.REFER) | ||
| 27 | }{ | ||
| 28 | \if(stat.MOD&8){ | ||
| 29 | \parse.private(stat.REFER) | ||
| 30 | }{ | ||
| 31 | \parse(stat.REFER) | ||
| 32 | } | ||
| 33 | } | ||
| 34 | } | ||
| 35 | {text/x-htx}{ | ||
| 36 | \show.latex(stat.REFER) | ||
| 37 | } | ||
| 38 | {text/html}{ | ||
| 39 | \resp.cont.type(stat.MIME); | ||
| 40 | \output{\minilang{\load(stat.REFER)}} | ||
| 41 | } | ||
| 42 | } | ||
| 43 | \def{show.rawpage}{}{ | ||
| 44 | \resp.cont.type(stat.MIME); | ||
| 45 | \output{\load(stat.REFER)} | ||
| 46 | } | ||
| 47 | \def{show.srcpage}{}{ | ||
| 48 | \resp.cont.type{text/plain} | ||
| 49 | \nif(\req.useragent cnt "Mozilla"){\resp.cont.type.charset{}}; | ||
| 50 | \output{ | ||
| 51 | \switch(stat.MIME) | ||
| 52 | {text/x-htc}{ | ||
| 53 | \%/SRC\uri HTC/1.2 Last modified \time2http(stat.LASTMOD) | ||
| 54 | } | ||
| 55 | {text/html}{ | ||
| 56 | \%/SRC\uri HTML Last modified \time2http(stat.LASTMOD) | ||
| 57 | } | ||
| 58 | {text/x-htx}{ | ||
| 59 | \%/SRC\uri HTX/1.2 (LaTeX) Last modified \time2http(stat.LASTMOD) | ||
| 60 | } | ||
| 61 | \load(stat.REFER) | ||
| 62 | } | ||
| 63 | } | ||
| 64 | \def{show.banner}{}{ | ||
| 65 | \ldef{shist}{x}{ | ||
| 66 | \find.rec{\1}{ | ||
| 67 | \if(count BANNER){ | ||
| 68 | [ban:=rest BANNER]\run.local{ban} | ||
| 69 | }{ | ||
| 70 | \if(count PARENT){\shist(PARENT)} | ||
| 71 | } | ||
| 72 | } | ||
| 73 | }; | ||
| 74 | \db{TREE}{\shist(stat.URI rleftand "/")} | ||
| 75 | } | ||
| 76 | \def{calc.height}{}{ | ||
| 77 | \ldef{chist}{x}{ | ||
| 78 | \find.rec{\1}{ | ||
| 79 | \if(count BANNER)(first BANNER){\if(count PARENT){\chist(PARENT)}{\HEIGHT.head}} | ||
| 80 | }{ | ||
| 81 | \HEIGHT.head | ||
| 82 | } | ||
| 83 | }; | ||
| 84 | \db{TREE}{\chist(stat.URI rleftand "/")} | ||
| 85 | } | ||
| 86 | \def{page.header}{}{ | ||
| 87 | \ldef{hist}{x}{ | ||
| 88 | \find.rec{\1}{ | ||
| 89 | \if(count PARENT){\hist(PARENT)}; | ||
| 90 | \if(URI eq uri){\run.local{ALIAS}}{\href{\andlang;[URI]}{\run.local{ALIAS}}}> | ||
| 91 | } | ||
| 92 | } | ||
| 93 | \page{ | ||
| 94 | \show.banner | ||
| 95 | \table{width=100% border=0 cellspacing=0 cellpadding=0 bgcolor=\COLOR.special}{ | ||
| 96 | \tr{valign=top align=left}{ | ||
| 97 | \td{width=60%}{ | ||
| 98 | \font{size=3}{ | ||
| 99 | [uri:=stat.URI;dir:=uri rleftand "/";n:=0]; | ||
| 100 | \db{TREE}{ | ||
| 101 | \hist(dir); | ||
| 102 | \query(PARENT eq dir && URI ne "/"){ | ||
| 103 | \if{\user.allow(X.CLEAR){\now}}{ | ||
| 104 | \if(n){|}[n+=1]\if(URI eq uri){ | ||
| 105 | \run.local{ALIAS} | ||
| 106 | }{ | ||
| 107 | \href{\andlang;[URI]}{\run.local{ALIAS}} | ||
| 108 | } | ||
| 109 | } | ||
| 110 | } | ||
| 111 | }\space; | ||
| 112 | } | ||
| 113 | }; | ||
| 114 | \td{width=40% align=right}{ | ||
| 115 | \font{size=3}{ | ||
| 116 | \if{\user.id}{\user.name}{\lang{Anonymous}{Anonym}}, \time2htc{\now} | ||
| 117 | } | ||
| 118 | } | ||
| 119 | } | ||
| 120 | } | ||
| 121 | } | ||
| 122 | } | ||
| 123 | \def{show.icons}{}{} | ||
| 124 | \def{page.footer}{}{ | ||
| 125 | \output{ | ||
| 126 | \body{bgcolor=\COLOR.special}{ | ||
| 127 | \table{width=100% border=0 cellspacing=0 cellpadding=0 bgcolor=\COLOR.special}{ | ||
| 128 | \td{valign=top align=left}{ | ||
| 129 | \iref{mailto:\server.admin}{\icons/mail.gif} | ||
| 130 | \if{\user.id}{ | ||
| 131 | \iref{/LOGOUT\uri\andarg}{\icons/logout.gif} | ||
| 132 | }{ | ||
| 133 | \iref{/LOGIN\uri\andarg}{\icons/login.gif} | ||
| 134 | } | ||
| 135 | \on.clear{ADM}{ | ||
| 136 | \iref{\andlang/HTC/admin.htc}{\icons/adm.gif} | ||
| 137 | } | ||
| 138 | \iref{ | ||
| 139 | \lang{/sv}{/en}[stat.URI] | ||
| 140 | }{ | ||
| 141 | \icons/lang.gif | ||
| 142 | } | ||
| 143 | \if{\user.id}{ | ||
| 144 | \iref{\andlang/HTC/prefs.htc}{\icons/prefs.gif} | ||
| 145 | } | ||
| 146 | \iref{/SRC[stat.URI]}{\icons/source.gif} | ||
| 147 | [acc:=\upload.clear(stat.URI)]\if((first acc) ne "ROOT"){ | ||
| 148 | \on.clear(acc){ | ||
| 149 | \iref{\server/RAW[stat.URI]}{\icons/transfer.gif} | ||
| 150 | } | ||
| 151 | } | ||
| 152 | \show.icons; | ||
| 153 | } | ||
| 154 | \td{valign=center align=right}{ | ||
| 155 | HTCd/1.2 \[\lang{en}{sv}\] \time2htc(stat.LASTMOD) | ||
| 156 | } | ||
| 157 | } | ||
| 158 | } | ||
| 159 | } | ||
| 160 | } | ||
| 161 | \redef{show.register}{}{ | ||
| 162 | \lang{ | ||
| 163 | If your are not a registered user, register first. | ||
| 164 | }{ | ||
| 165 | Om du inte {\"a}r en registrerad anv{\"a}ndare, | ||
| 166 | registrera dig f{\"o}rst. | ||
| 167 | } | ||
| 168 | } | ||
| 169 | \def{page.login}{}{ | ||
| 170 | \cond{T.alias}{} | ||
| 171 | \page{ | ||
| 172 | \h1{\server.alias Login} | ||
| 173 | \if{\user.id}{ | ||
| 174 | \lang{ | ||
| 175 | You are logged in as \user.name; (\user.alias). | ||
| 176 | }{ | ||
| 177 | Du {\"a}r inloggad som \user.name; (\user.alias). | ||
| 178 | } | ||
| 179 | <p> | ||
| 180 | \href{\referer}{\lang{Continue}{Forts{\"a}tt}} | ||
| 181 | }{ | ||
| 182 | \lang{ | ||
| 183 | This server contains information only accessible to registered users. | ||
| 184 | Each registered user receives a user ID and a PIN code. | ||
| 185 | }{ | ||
| 186 | Den h{\"a}r servern inneh{\aa}ller information som bara {\"a}r | ||
| 187 | tillg{\"a}nglig f{\"o}r registrerade anv{\"a}ndare. | ||
| 188 | Varje registrerad anv{\"a}ndare erh{\aa}ller ett anv{\"a}ndar-ID | ||
| 189 | och en PIN-kod. | ||
| 190 | }; | ||
| 191 | <p> | ||
| 192 | \show.register; | ||
| 193 | <p> | ||
| 194 | \lang{ | ||
| 195 | To login, enter your email address and PIN code below. | ||
| 196 | \it{DO NOT} enter your unix password! | ||
| 197 | }{ | ||
| 198 | F{\"o}r att logga in, fyll i din epostadress och PIN kod nedan. | ||
| 199 | An{\"a}nd \it{EJ} ditt unix passord! | ||
| 200 | }; | ||
| 201 | [remcookie:=0;email:=\T.alias]; | ||
| 202 | \for(i:=0)(i<\ncookie)(i+=1){ | ||
| 203 | \if(\cookie[i].name eq "RESEND"){ | ||
| 204 | [remcookie=1;email=\cookie[i].val]; | ||
| 205 | <p> | ||
| 206 | \font{color=red}{ | ||
| 207 | \lang{E-mail has been sent to }{E-post har skickats till }[email] | ||
| 208 | (\lang{provided user exist}{f{\"o}rutsatt anv{\"a}ndaren existerar}) | ||
| 209 | } | ||
| 210 | } | ||
| 211 | }; | ||
| 212 | <p> | ||
| 213 | \form{ | ||
| 214 | \variable{remcookie}(remcookie); | ||
| 215 | \variable{ref}{\referer}; | ||
| 216 | \table{ | ||
| 217 | \tr{ | ||
| 218 | \td{\lang{E-mail (or alias)}{E-post (eller alias)}:} | ||
| 219 | \td{\input{email}{28}(email)} | ||
| 220 | }; | ||
| 221 | \tr{ | ||
| 222 | \td{PIN:} | ||
| 223 | \td{ | ||
| 224 | \passwd{pin}{6} | ||
| 225 | } | ||
| 226 | }; | ||
| 227 | \tr{ | ||
| 228 | \td{colspan=2}{ | ||
| 229 | \check{T.keep}{\endtime} | ||
| 230 | \lang{ | ||
| 231 | Keep me logged in by storing to disk | ||
| 232 | }{ | ||
| 233 | H{\aa}ll mig inloggad genom att spara till disk | ||
| 234 | }; | ||
| 235 | } | ||
| 236 | }; | ||
| 237 | \tr{ | ||
| 238 | \td{colspan=2}{ | ||
| 239 | \button{Login} | ||
| 240 | \button{Forgot my PIN code} | ||
| 241 | \button{Assign a new (4 digit) PIN code} | ||
| 242 | } | ||
| 243 | } | ||
| 244 | } | ||
| 245 | } | ||
| 246 | \h3{\lang{Nota bene}{Observera}} | ||
| 247 | <p> | ||
| 248 | \li{ | ||
| 249 | \lang{ | ||
| 250 | You must allow a COOKIE containing your user ID and | ||
| 251 | PIN code to be set. If you normally do not allow cookies, | ||
| 252 | you need to make an exception in this case, or by some other | ||
| 253 | means arrange for the cookie to be set. | ||
| 254 | If you don't know what a cookie is, you can probably ignore | ||
| 255 | this paragraph. | ||
| 256 | }{ | ||
| 257 | Du m{\aa}ste till{\aa}ta s{\"a}ttning av en COOKIE med | ||
| 258 | ditt anv{\"a}ndar-ID och PIN-kod. Om du normalt inte till{\aa}ter | ||
| 259 | "kakor", m{\aa}ste du antingen g{\"o}ra ett undantag i det | ||
| 260 | h{\"a}r fallet, eller p{\aa} n{\aa}got annat s{\"a}tt | ||
| 261 | se till att kakan blir satt p{\aa} r{\"a}tt s{\"a}tt. | ||
| 262 | Vet du inte vad en kaka {\"a}r, kan du troligtvis bortse | ||
| 263 | fr{\aa}n denna paragraf. | ||
| 264 | } | ||
| 265 | }; | ||
| 266 | <p> | ||
| 267 | \li{ | ||
| 268 | \lang{ | ||
| 269 | If logging in from a 'shared' browser, don't forget to logout | ||
| 270 | properly when you're done. Otherwise, the person after you may | ||
| 271 | enter the server as you. | ||
| 272 | }{ | ||
| 273 | Om du loggar in fr{\aa}n en 'delad' webbl{\"a}sare, gl{\"o}m | ||
| 274 | inte att logga ut dig ordentligt. Annars kan n{\"a}sta person | ||
| 275 | komma in p{\aa} servern som dig. | ||
| 276 | } | ||
| 277 | } | ||
| 278 | } | ||
| 279 | }; | ||
| 280 | \onpost{ | ||
| 281 | \cond{T.keep}{0}; | ||
| 282 | \cond{T.uid}{\getuser{\T.email}}; | ||
| 283 | \switch(first \T.cmd) | ||
| 284 | {Login}{ | ||
| 285 | \log{SetID \[\T.uid.\T.pin\] (\T.keep)}; | ||
| 286 | \setcookie{ID}{\T.uid.\T.pin}{\T.keep}; | ||
| 287 | \if{\T.remcookie}{\setcookie{RESEND}{deleted}{1}}; | ||
| 288 | \redirect{\T.ref}; | ||
| 289 | } | ||
| 290 | {Forgot}{ | ||
| 291 | \su{\T.uid}{ | ||
| 292 | \mail.user{PIN code}{ | ||
| 293 | Your PIN code is \user.pin. | ||
| 294 | |||
| 295 | /Admin | ||
| 296 | } | ||
| 297 | }; | ||
| 298 | \if(\T.email ne ""){\setcookie{RESEND}{\T.email}}; | ||
| 299 | \redirect{\server\this\andarg}; | ||
| 300 | } | ||
| 301 | {Assign}{ | ||
| 302 | \su{\T.uid}{ | ||
| 303 | \if(\user.pin eq \T.pin){ | ||
| 304 | \user.pin.set{\random{4}}\user.update; | ||
| 305 | \mail.user{New PIN code}{ | ||
| 306 | Your new PIN code is \user.pin. | ||
| 307 | |||
| 308 | /Admin | ||
| 309 | } | ||
| 310 | } | ||
| 311 | }; | ||
| 312 | \if(\T.email ne ""){\setcookie{RESEND}{\T.email}}; | ||
| 313 | \redirect{\server\this\andarg}; | ||
| 314 | }{ | ||
| 315 | Don't understand "\T.cmd" | ||
| 316 | } | ||
| 317 | } | ||
| 318 | } | ||
| 319 | \def{page.logout}{}{ | ||
| 320 | \setcookie{ID}{deleted}{1}; | ||
| 321 | \resp.cont.type.charset{}; | ||
| 322 | \redirect{\server/} | ||
| 323 | } | ||
| 324 | \def{layout}{}{ | ||
| 325 | \if{\FRAMES}{ | ||
| 326 | [cacheok=1;stat.X.CACHE=\days{14}]; | ||
| 327 | \output{ | ||
| 328 | \show.head; | ||
| 329 | <frameset rows="\calc.height,*,\HEIGHT.foot" border=0 scrolling=no onload="\killframes"> | ||
| 330 | <frame scrolling=no name=head align=top src="/HEAD\uri\andarg"> | ||
| 331 | <frame scrolling=auto name=body align=left src="/BODY\uri\andarg"> | ||
| 332 | <frame scrolling=no name=foot align=bottom src="/FOOT\uri\andarg"> | ||
| 333 | </frameset> | ||
| 334 | } | ||
| 335 | }{ | ||
| 336 | \resp.cont.type.charset{}; | ||
| 337 | \output{\show.head}; | ||
| 338 | \page.header; | ||
| 339 | \output{<br><br>}; | ||
| 340 | \show.page; | ||
| 341 | \output{<br><br>}; | ||
| 342 | \page.footer | ||
| 343 | } | ||
| 344 | } | ||
| 345 | \def{show.latex}{x}{ | ||
| 346 | \parse.public{\1} | ||
| 347 | } | ||
| 348 | |||
diff --git a/htc/mailer.htc b/htc/mailer.htc new file mode 100644 index 0000000..65f0d98 --- /dev/null +++ b/htc/mailer.htc | |||
| @@ -0,0 +1,53 @@ | |||
| 1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||
| 2 | % maild Mailinglist | ||
| 3 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||
| 4 | \setuser{\getuser{\T.from}} | ||
| 5 | \nif(count \T.node){\reconst{T.node}{1}} | ||
| 6 | \dml.init{demo}{}{}{} | ||
| 7 | \if{\user.id}{ | ||
| 8 | \setlist{\T.list}; | ||
| 9 | \if(count \dml.group){ | ||
| 10 | \on.clear{\dml.group}{ | ||
| 11 | \switch{\T.cmd} | ||
| 12 | {help}{ | ||
| 13 | \dml.help | ||
| 14 | } | ||
| 15 | {who}{ | ||
| 16 | \dml.who{\T.node} | ||
| 17 | } | ||
| 18 | {silent}{ | ||
| 19 | \dml.addsilent{\T.node} | ||
| 20 | } | ||
| 21 | {new}{ | ||
| 22 | \dml.addbroad{\T.node} | ||
| 23 | } | ||
| 24 | {reply}{ | ||
| 25 | \reconst{T.subject}{\dml.resubj{\T.subject}} | ||
| 26 | \dml.addbroad{\T.node} | ||
| 27 | } | ||
| 28 | {open}{ | ||
| 29 | \dml.opennode{\T.node} | ||
| 30 | } | ||
| 31 | {close}{ | ||
| 32 | \dml.closenode{\T.node} | ||
| 33 | } | ||
| 34 | {mail}{ | ||
| 35 | \dml.mail{\T.node} | ||
| 36 | } | ||
| 37 | { | ||
| 38 | \dml.error{\T.list: Bad command (\T.cmd)} | ||
| 39 | } | ||
| 40 | }{ | ||
| 41 | \dml.error{\T.list: User denied (\T.from)} | ||
| 42 | } | ||
| 43 | }{ | ||
| 44 | \if(\T.cmd eq "help"){ | ||
| 45 | \dml.help | ||
| 46 | }{ | ||
| 47 | \dml.error{\T.list: Not found} | ||
| 48 | } | ||
| 49 | } | ||
| 50 | }{ | ||
| 51 | \dml.error{\HOST: Could not find user \T.from} | ||
| 52 | } | ||
| 53 | |||
diff --git a/htc/posit.htc b/htc/posit.htc new file mode 100644 index 0000000..af92038 --- /dev/null +++ b/htc/posit.htc | |||
| @@ -0,0 +1,23 @@ | |||
| 1 | \def{select.posit}{xx}{ | ||
| 2 | \select | ||
| 3 | {\1}{\2} | ||
| 4 | {Temp}{Temporary} | ||
| 5 | {ProfEmerit}{Professor Emeritus} | ||
| 6 | {Prof}{Professor} | ||
| 7 | {AssocProf}{Associate Professor} | ||
| 8 | {AssistProf}{Assistant Professor} | ||
| 9 | {ResAssoc}{Research Associate} | ||
| 10 | {Postdoc}{Post-doc} | ||
| 11 | {Doc}{Docent} | ||
| 12 | {PhD}{PhD} | ||
| 13 | {MD}{MD} | ||
| 14 | {Sec}{Secretary} | ||
| 15 | {Grad}{Graduate Student} | ||
| 16 | {Lic}{Licentiate} | ||
| 17 | {Master}{Master of Science} | ||
| 18 | {Diploma}{Diploma worker} | ||
| 19 | {Stud}{Student} | ||
| 20 | {Psi}{Psychologist} | ||
| 21 | {Prog}{Programmer} | ||
| 22 | {Other}{Other} | ||
| 23 | } | ||
diff --git a/htc/prefs.hdb b/htc/prefs.hdb new file mode 100644 index 0000000..15cf68c --- /dev/null +++ b/htc/prefs.hdb | |||
| Binary files differ | |||
diff --git a/htc/server.htc b/htc/server.htc new file mode 100644 index 0000000..4060556 --- /dev/null +++ b/htc/server.htc | |||
| @@ -0,0 +1,321 @@ | |||
| 1 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||
| 2 | % HTCd/1.2 Server (H. Rydberg, 2001) | ||
| 3 | % Supports methods HEAD, GET, PUT, POST, DELETE | ||
| 4 | %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% | ||
| 5 | % | ||
| 6 | % Useragent setting | ||
| 7 | % | ||
| 8 | \if(count \req.accept.lang){\setlang{\req.accept.lang}} | ||
| 9 | \const{FRAMES}(int(\req.useragent past "Mozilla/")>=2); | ||
| 10 | \if{\FRAMES}{ | ||
| 11 | \redef{target}{x}{ | ||
| 12 | \if( | ||
| 13 | (\1 cnt "//") || | ||
| 14 | ( (\sub{\1}{0}{1} eq "/") && ("HEAD BODY FOOT" which (\1 past "/" left "/"))==0) | ||
| 15 | ){ target=_top} | ||
| 16 | } | ||
| 17 | } | ||
| 18 | \const{killframes}{ | ||
| 19 | \if(int(\req.useragent past "Mozilla/")>2){ | ||
| 20 | if(self!=top) top.location.replace(self.location)}{ | ||
| 21 | if(self!=top) top.location=self.location}} | ||
| 22 | % | ||
| 23 | % Set userid and other cookies | ||
| 24 | % Handle errors directly | ||
| 25 | % | ||
| 26 | [userok:=1;]; | ||
| 27 | \def{statlog}{x}{\resp.status{\HTTP.[\1]}} | ||
| 28 | \for(i:=0)(i<\ncookie)(i+=1){ | ||
| 29 | \switch{\cookie[i].name} | ||
| 30 | {LANG}{ | ||
| 31 | \setlang{\cookie[i].val} | ||
| 32 | } | ||
| 33 | {FRAMES}{ | ||
| 34 | \reconst{FRAMES}(int \cookie[i].val); | ||
| 35 | } | ||
| 36 | {AUTH}{ | ||
| 37 | %MIGRATION to HTCd/1.1 | ||
| 38 | %Just silently remove the cookie and continue | ||
| 39 | \resp.cookie{AUTH}{deleted}{path=/; expires=\time2http{1}} | ||
| 40 | } | ||
| 41 | {ID}{ | ||
| 42 | [uid:=\cookie[i].val left ".";pin:=\cookie[i].val past "."]; | ||
| 43 | \setuser(uid); | ||
| 44 | [MAXFAIL:=\on.clear{EXPERT}{1}{3}]; | ||
| 45 | \if(\user.id && \user.pin eq pin){ | ||
| 46 | \if(\user.fail>0){ | ||
| 47 | \if(\user.fail>=MAXFAIL){ | ||
| 48 | \statlog{409}[userok=0;]; | ||
| 49 | \resp.cont.type.charset{}; | ||
| 50 | \output{ | ||
| 51 | \body{ | ||
| 52 | \h3{Login \lang{Failure}{fel}} | ||
| 53 | \lang{ | ||
| 54 | There has been too many bad logins. | ||
| 55 | Please contact the \href{mailto:\ADMIN}{Server Administrator}. | ||
| 56 | }{ | ||
| 57 | F{\"o}r m{\aa}nga login-fel har gjorts. | ||
| 58 | Var v{\"a}nlig kontakta \href{mailto:\ADMIN}{Serveradministrat{\"o}ren}. | ||
| 59 | } | ||
| 60 | } | ||
| 61 | } | ||
| 62 | \setcookie{ID}{deleted}{1} | ||
| 63 | }{ | ||
| 64 | \mail.user{LOGIN ALERT}{ | ||
| 65 | \lang{ | ||
| 66 | There has been (\user.fail) PIN failures | ||
| 67 | }{ | ||
| 68 | Ett antal (\user.fail) PIN fel har gjorts. | ||
| 69 | } | ||
| 70 | |||
| 71 | \user.lastin; (\gethost{\user.lastin}) | ||
| 72 | \time2htc{\user.last} | ||
| 73 | } | ||
| 74 | \user.fail.set{0}\user.update; | ||
| 75 | } | ||
| 76 | }{ | ||
| 77 | \if(\user.lastin ne \remote.address){ | ||
| 78 | \on.clear{EXPERT}{ | ||
| 79 | \mail.user{HOST ALERT}{ | ||
| 80 | \lang{ | ||
| 81 | A change of access address has occured. | ||
| 82 | }{ | ||
| 83 | Ett byte av access-adress har intr{\"a}ffat. | ||
| 84 | } | ||
| 85 | |||
| 86 | \lang{Current access:}{Nuvarande access:} | ||
| 87 | \remote.address; (\remote.name) | ||
| 88 | \time2htc{\now} | ||
| 89 | |||
| 90 | \lang{Last access:}{Senaste access:} | ||
| 91 | \user.lastin; (\gethost{\user.lastin}) | ||
| 92 | \time2htc{\user.last} | ||
| 93 | } | ||
| 94 | }{ | ||
| 95 | \log{HOST ALERT \user.lastin -> \remote.address} | ||
| 96 | } | ||
| 97 | } | ||
| 98 | } | ||
| 99 | }{ | ||
| 100 | \if{\user.id}{ | ||
| 101 | \user.fail.set(\user.fail+1)\user.update; | ||
| 102 | \if(\user.fail==MAXFAIL){ | ||
| 103 | \mail.root{PIN failure}{ | ||
| 104 | PIN failure (\user.fail) for \user.id: \user.name <\user.email> | ||
| 105 | From: \remote.address:\remote.port; (\remote.name) | ||
| 106 | } | ||
| 107 | } | ||
| 108 | } | ||
| 109 | \statlog{409}[userok=0;]; | ||
| 110 | \resp.cont.type.charset{}; | ||
| 111 | \output{ | ||
| 112 | \body{ | ||
| 113 | \h3{\lang{Bad User}{Felaktig anv{\"a}ndare}} | ||
| 114 | \lang{ | ||
| 115 | Please check your user credentials and press the Back button. | ||
| 116 | }{ | ||
| 117 | Var v{\"a}nlig kontrollera din anv{\"a}ndarinformation | ||
| 118 | och tryck p{\aa} Tillbaka-knappen. | ||
| 119 | } | ||
| 120 | } | ||
| 121 | } | ||
| 122 | \setcookie{ID}{deleted}{1} | ||
| 123 | } | ||
| 124 | } | ||
| 125 | } | ||
| 126 | % | ||
| 127 | % At this point, user is set. | ||
| 128 | % | ||
| 129 | \if(\user.id){\user.last.set{\now}\user.lastin.set{\remote.address}\user.update} | ||
| 130 | % | ||
| 131 | % userok tells whether we should continue or not. | ||
| 132 | % | ||
| 133 | \if(userok){ | ||
| 134 | % | ||
| 135 | % Start by checking special URIs | ||
| 136 | % | ||
| 137 | [muri:=\req.uri;sroute:=muri past "/" left "/"]; | ||
| 138 | \if(sroute eq "POST")(muri=muri past "/" past sroute;sroute=muri past "/" left "/"); | ||
| 139 | \const{this}(muri); | ||
| 140 | \if("LOGIN LOGOUT" which sroute)(muri=muri past "/" past sroute)(sroute=""); | ||
| 141 | \const{referer}{\server;[muri]\andarg} | ||
| 142 | [route:=muri past "/" left "/";]; | ||
| 143 | \if("SRC RAW HEAD FOOT BODY" which route)(muri=muri past "/" past route)(route=""); | ||
| 144 | \seturi(muri); | ||
| 145 | [lroute:=muri past "/" left "/";]; | ||
| 146 | \if("en sv" which lroute){[muri=muri past "/" past lroute]\setlang(lroute)}(lroute=""); | ||
| 147 | \const{andlang}{/\lang{en}{sv}} | ||
| 148 | % | ||
| 149 | % sroute -> LOGIN|LOGOUT|none | ||
| 150 | % route -> SRC|RAW|HEAD|FOOT|BODY|none | ||
| 151 | % lroute -> en|sv|none | ||
| 152 | % this -> req.uri without POST | ||
| 153 | % referer -> complete URL (without POST|LOGIN|LOGOUT) | ||
| 154 | % uri -> directory URI (without SRC|RAW|HEAD|FOOT|BODY) | ||
| 155 | % andlang -> /[lang] | ||
| 156 | % muri -> mappable uri (without en|sv) | ||
| 157 | % | ||
| 158 | % Check method and dispatch | ||
| 159 | % | ||
| 160 | \if(\req.method eq "PUT" || \req.method eq "DELETE"){ | ||
| 161 | % | ||
| 162 | % PUT and DELETE treated together | ||
| 163 | % | ||
| 164 | [wclear:=\upload.clear(muri)]; | ||
| 165 | \if((count sroute)||(count lroute)|| !("SRC RAW" which route)||(wclear eq "ROOT")){ | ||
| 166 | \statlog{405}; | ||
| 167 | \resp.cont.type.charset{}; | ||
| 168 | \output{ | ||
| 169 | \body{ | ||
| 170 | \h3{\lang{Method not allowed}{Metoden ej till{\aa}ten}} | ||
| 171 | \lang{ | ||
| 172 | \req.method is not allowed here. | ||
| 173 | }{ | ||
| 174 | \req.method; {\"a}r ej till{\aa}ten h{\"a}r. | ||
| 175 | } | ||
| 176 | <p> | ||
| 177 | \href{\server}{\lang{Home}{Hem}} | ||
| 178 | } | ||
| 179 | } | ||
| 180 | }{ | ||
| 181 | \if{\user.allow(wclear){\now}}{ | ||
| 182 | \statlog{200}; | ||
| 183 | \if(\req.method eq "DELETE"){\upload.delete(muri)}{\upload.put(muri)} | ||
| 184 | }{ | ||
| 185 | \statlog{409} | ||
| 186 | \resp.cont.type.charset{}; | ||
| 187 | \output{ | ||
| 188 | \body{ | ||
| 189 | \h3{\lang{Conflict}{Konflikt}} | ||
| 190 | \lang{ | ||
| 191 | The request could not be granted. | ||
| 192 | }{ | ||
| 193 | Kommandot kunde ej utf{\"o}ras. | ||
| 194 | } | ||
| 195 | <p> | ||
| 196 | \href{\server}{\lang{Home}{Hem}} | ||
| 197 | } | ||
| 198 | } | ||
| 199 | } | ||
| 200 | } | ||
| 201 | }{ | ||
| 202 | % | ||
| 203 | % HEAD, GET and POST treated together | ||
| 204 | % | ||
| 205 | [fallow:=0;uallow:=0;rallow:=0;callow:=0]; | ||
| 206 | \switch(sroute){LOGIN}{\page.login}{LOGOUT}{\page.logout}{ | ||
| 207 | \staturi(muri){ | ||
| 208 | \if(stat.URI ne muri){ | ||
| 209 | [canonized:={\server\andlang;[stat.URI]\andarg}]; | ||
| 210 | \resp.status{\HTTP.301}; | ||
| 211 | \resp.location(canonized); | ||
| 212 | \resp.cont.type.charset{}; | ||
| 213 | \output{\href(canonized)(canonized)} | ||
| 214 | }{ | ||
| 215 | \if(count stat.ALIAS){\db{TREE}(@<-stat.)}; | ||
| 216 | \setgroup(first stat.X.CLEAR); | ||
| 217 | [ | ||
| 218 | fallow=1; | ||
| 219 | ttime:=\if(stat.MOD&36){\now}(stat.LASTMOD); | ||
| 220 | uallow=\user.allow(stat.X.CLEAR)(ttime); | ||
| 221 | rallow=\remote.allow(stat.X.DOMAIN); | ||
| 222 | callow=\cookie.allow(stat.X.COOKIE); | ||
| 223 | ]; | ||
| 224 | \nif((count stat.REFER) && uallow && rallow && callow)(userok=0){ | ||
| 225 | \statlog{200}[cacheok:=0]; | ||
| 226 | \if("text/x-htc text/x-htx text/html" which stat.MIME){ | ||
| 227 | \if(\req.method eq "POST"){ | ||
| 228 | \show.page; | ||
| 229 | }{ | ||
| 230 | \switch(route) | ||
| 231 | {SRC}{ | ||
| 232 | \show.srcpage | ||
| 233 | } | ||
| 234 | {RAW}{ | ||
| 235 | \show.rawpage | ||
| 236 | } | ||
| 237 | {HEAD}{ | ||
| 238 | \page.header | ||
| 239 | } | ||
| 240 | {FOOT}{ | ||
| 241 | \page.footer | ||
| 242 | } | ||
| 243 | {BODY}{ | ||
| 244 | \show.page; | ||
| 245 | [cacheok=(first \resp.getstatus == 200);] | ||
| 246 | } | ||
| 247 | { | ||
| 248 | \if(count lroute){\layout}{ | ||
| 249 | [canonized:={\server\andlang\uri\andarg}]; | ||
| 250 | \resp.status{\HTTP.301}; | ||
| 251 | \resp.location(canonized); | ||
| 252 | \resp.cont.type.charset{}; | ||
| 253 | \output{\href(canonized)(canonized)} | ||
| 254 | } | ||
| 255 | } | ||
| 256 | } | ||
| 257 | }{ | ||
| 258 | \resp.cont.type(stat.MIME); | ||
| 259 | \output{\load(stat.REFER)}[cacheok=1;] | ||
| 260 | } | ||
| 261 | \if(cacheok&&(count stat.X.CACHE)){ | ||
| 262 | \resp.pragma{} | ||
| 263 | \if(stat.X.CACHE){ | ||
| 264 | \resp.lastmod{\time2http(stat.LASTMOD)} | ||
| 265 | [expire:=\now+stat.X.CACHE; | ||
| 266 | \if(expire<=stat.LASTMOD)(expire=stat.LASTMOD+1)]; | ||
| 267 | \resp.expires{\time2http(expire)} | ||
| 268 | } | ||
| 269 | } | ||
| 270 | } | ||
| 271 | } | ||
| 272 | }(userok=0) | ||
| 273 | } | ||
| 274 | \nif(userok){ | ||
| 275 | \statlog{404}; | ||
| 276 | \resp.cont.type.charset{}; | ||
| 277 | \output{ | ||
| 278 | \body{ | ||
| 279 | \h3{\lang{Not Found}{Ej hittad}} | ||
| 280 | \lang{ | ||
| 281 | The requested uri (\req.uri) could not be found. | ||
| 282 | }{ | ||
| 283 | Den beg{\"a}rda sidan (\req.uri) kunde inte hittas. | ||
| 284 | } | ||
| 285 | \nif{\user.id}{ | ||
| 286 | \if(\req.useragent cnt "Mozilla"){ | ||
| 287 | <p> | ||
| 288 | \lang | ||
| 289 | {The reason \it{may} be that you need need to } | ||
| 290 | {Andledningen \it{kan} vara att du beh{\"o}ver } | ||
| 291 | \href{/LOGIN\req.uri\andarg}{\lang{login}{logga in}} \lang{first}{f{\"o}rst}. | ||
| 292 | }{ | ||
| 293 | <p> | ||
| 294 | \lang{ | ||
| 295 | The reason \it{may} be that your user credentials were improperly set. | ||
| 296 | }{ | ||
| 297 | Anledningen \it{kan} vara att din anv{\"a}ndar information {\"a}r felaktigt satt. | ||
| 298 | } | ||
| 299 | <p> | ||
| 300 | \lang{ | ||
| 301 | Please go back try again. | ||
| 302 | }{ | ||
| 303 | G{\aa} tillbaka och f{\"o}rs{\"o}k igen. | ||
| 304 | } | ||
| 305 | } | ||
| 306 | }{ | ||
| 307 | \if(fallow){ | ||
| 308 | <p> | ||
| 309 | \lang{Reason:}{Orsak:} | ||
| 310 | \nif(uallow){\lang{Bad clearance}{Fel r{\"a}ttigheter}} | ||
| 311 | \nif(rallow){\lang{Bad access address}{Felaktig access-adress}} | ||
| 312 | \nif(callow){\lang{Bad cookie}{Felaktig 'cookie'}} | ||
| 313 | } | ||
| 314 | } | ||
| 315 | <p> | ||
| 316 | \href{\server}{\lang{Home}{Hem}} | ||
| 317 | } | ||
| 318 | } | ||
| 319 | } | ||
| 320 | } | ||
| 321 | } | ||
diff --git a/htc/system.htc b/htc/system.htc new file mode 100644 index 0000000..ecae08e --- /dev/null +++ b/htc/system.htc | |||
| @@ -0,0 +1,35 @@ | |||
| 1 | % | ||
| 2 | % User stuff | ||
| 3 | % | ||
| 4 | \def{mail.root}{xx}{ | ||
| 5 | \log{mail root: \1} | ||
| 6 | \mail{\ROOT}{}{\ROOT}{server root}{\now}{\1}{text/plain}{\2} | ||
| 7 | } | ||
| 8 | \def{mail.admin}{xx}{ | ||
| 9 | \log{mail admin: \1} | ||
| 10 | \mail{\ADMIN}{}{\ADMIN}{server admin}{\now}{\1}{text/plain}{\2} | ||
| 11 | } | ||
| 12 | \def{mail.user}{xx}{ | ||
| 13 | \if{\user.id}{ | ||
| 14 | \log{mail user: \1} | ||
| 15 | \mail{\ADMIN}{}{\user.email}{\HOST}{\now}{\1}{text/plain}{\2} | ||
| 16 | } | ||
| 17 | } | ||
| 18 | % | ||
| 19 | % Modification time handling | ||
| 20 | % | ||
| 21 | \def{statmod}{x}{ | ||
| 22 | [mtime:=\dirmtime{\1}]; | ||
| 23 | \if(mtime>stat.LASTMOD)(stat.LASTMOD=mtime); | ||
| 24 | \1 | ||
| 25 | } | ||
| 26 | \def{statinclude}{x}{ | ||
| 27 | \include{\statmod{\1}} | ||
| 28 | } | ||
| 29 | \def{statopen}{xx?}{ | ||
| 30 | \open{\1}{\statmod{\2}}{\3} | ||
| 31 | } | ||
| 32 | \def{statdb}{x}{ | ||
| 33 | [mtime:=\dbmod{\1}]; | ||
| 34 | \if(mtime>stat.LASTMOD)(stat.LASTMOD=mtime); | ||
| 35 | } | ||
diff --git a/htc/tree.htc b/htc/tree.htc new file mode 100644 index 0000000..8615108 --- /dev/null +++ b/htc/tree.htc | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | \const{HTCEXT}{htc htx html} | ||
| 2 | \const{SKIPDIR}{sys htc SCCS} | ||
| 3 | \def{tree.update}{}{ | ||
| 4 | [xmod:=\now]; | ||
| 5 | \ldef{trav}{x}{ | ||
| 6 | \staturi{\1}{ | ||
| 7 | \if(count stat.ALIAS)(@<-stat.); | ||
| 8 | \forall{it}{\dirent{\1}}{ | ||
| 9 | \if(\dirmod(it)&24576){ | ||
| 10 | \nif(\SKIPDIR which (it past \1)){\trav{[it]/}} | ||
| 11 | }{ | ||
| 12 | \if(\HTCEXT which (it rpast ".")){ | ||
| 13 | \staturi(it){\if(count stat.ALIAS)(@<-stat.)} | ||
| 14 | } | ||
| 15 | } | ||
| 16 | } | ||
| 17 | } | ||
| 18 | }; | ||
| 19 | \db{TREE}{\trav{/}\query(XMOD<xmod){\rem.rec}} | ||
| 20 | } | ||
| 21 | |||
diff --git a/htc/upload.htc b/htc/upload.htc new file mode 100644 index 0000000..ef3491e --- /dev/null +++ b/htc/upload.htc | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | \def{upload.clear}{x}{ | ||
| 2 | \if((\1 rpast "." eq "htc")||(\1 rleftand "/" eq \1)||(\1 cnt "WRITABLE")){ | ||
| 3 | ROOT | ||
| 4 | }{ | ||
| 5 | [path:=(\1 rleftand "/")++"WRITABLE"]\staturi(path)(\load(path) left \n){ROOT} | ||
| 6 | } | ||
| 7 | } | ||
| 8 | \def{upload.delete}{x}{ | ||
| 9 | \log{upload: DELETING \1} | ||
| 10 | \remfile{\1} | ||
| 11 | \output{ | ||
| 12 | \h3{\lang{File Deleted}{Filen raderad}} | ||
| 13 | \lang{ | ||
| 14 | \1 was sucessfully deleted. | ||
| 15 | }{ | ||
| 16 | \1 har raderats. | ||
| 17 | } | ||
| 18 | <p> | ||
| 19 | \href{\server}{\lang{Home}{Hem}} | ||
| 20 | } | ||
| 21 | } | ||
| 22 | \def{upload.put}{x}{ | ||
| 23 | \log{upload: PUTTING \1} | ||
| 24 | \save{\1}{T.body}{417} | ||
| 25 | } | ||
| 26 | |||
diff --git a/htc/users.hdb b/htc/users.hdb new file mode 100644 index 0000000..a55fc11 --- /dev/null +++ b/htc/users.hdb | |||
| Binary files differ | |||
diff --git a/log/htc.log b/log/htc.log new file mode 100644 index 0000000..6bab77c --- /dev/null +++ b/log/htc.log | |||
| @@ -0,0 +1,196 @@ | |||
| 1 | [1155814044][issue_start][bin/ls] | ||
| 2 | [1155814044][issue_end][bin/ls] | ||
| 3 | [1155814190][issue_start][bin/ls] | ||
| 4 | [1155814190][issue_end][bin/ls] | ||
| 5 | [1155814231][issue][bin/ls] | ||
| 6 | [1155814232][finish][bin/ls] | ||
| 7 | [1155814266][issue][ls] | ||
| 8 | [1155814266][finish][ls] | ||
| 9 | [1155817522][issue][ls] | ||
| 10 | [1155817522][finish][ls] | ||
| 11 | [1155817710][issue][/bin/atomlab] | ||
| 12 | [1155817710][finish][/bin/atomlab] | ||
| 13 | [1155817631][issue][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 ] | ||
| 14 | [1155817631][finish][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 ] | ||
| 15 | [1155817631][issue][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 ] | ||
| 16 | [1155817631][finish][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 ] | ||
| 17 | [1155817786][issue][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 ] | ||
| 18 | [1155817786][finish][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 ] | ||
| 19 | [1155817786][issue][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 ] | ||
| 20 | [1155817786][finish][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 ] | ||
| 21 | [1155817860][issue][/bin/atomlab 0 30 0 0.5 11\Pu1\Pd1\Du1\Dd1 11\Pu2\Pd2\Du2\Dd2 000000 000000 000000 000000 ] | ||
| 22 | [1155817860][finish][/bin/atomlab 0 30 0 0.5 11\Pu1\Pd1\Du1\Dd1 11\Pu2\Pd2\Du2\Dd2 000000 000000 000000 000000 ] | ||
| 23 | [1155817860][issue][/bin/atomlab 0 30 0 0.5 11\Pu1\Pd1\Du1\Dd1 11\Pu2\Pd2\Du2\Dd2 000000 000000 000000 000000 ] | ||
| 24 | [1155817860][finish][/bin/atomlab 0 30 0 0.5 11\Pu1\Pd1\Du1\Dd1 11\Pu2\Pd2\Du2\Dd2 000000 000000 000000 000000 ] | ||
| 25 | [1155817979][issue][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 26 | [1155817979][finish][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 27 | [1155817980][issue][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 28 | [1155817980][finish][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 29 | [1155819229][issue][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 30 | [1155819229][finish][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 31 | [1155819229][issue][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 32 | [1155819229][finish][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 33 | [1155820139][issue][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 34 | [1155820139][finish][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 35 | [1155820139][issue][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 36 | [1155820139][finish][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 37 | [1155820175][issue][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 38 | [1155820175][finish][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 39 | [1155820175][issue][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 40 | [1155820175][finish][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 41 | [1155820199][issue][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 42 | [1155820199][finish][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 43 | [1155820199][issue][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 44 | [1155820199][finish][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 45 | [1155820485][issue][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 46 | [1155820485][finish][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 47 | [1155820486][issue][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 48 | [1155820486][finish][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 49 | [1155821390][issue][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 50 | [1155821390][finish][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 51 | [1155821390][issue][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 52 | [1155821390][finish][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 53 | [1155823516][issue][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 54 | [1155823516][finish][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 55 | [1155823516][issue][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 56 | [1155823516][finish][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 57 | [1155823662][issue][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 58 | [1155823662][finish][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 59 | [1155823662][issue][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 60 | [1155823662][finish][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 61 | [1155823701][issue][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 62 | [1155823701][finish][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 63 | [1155823701][issue][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 64 | [1155823701][finish][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 65 | [1155823730][issue][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 66 | [1155823731][finish][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 67 | [1155823731][issue][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 68 | [1155823731][finish][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 69 | [1155824224][issue][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 70 | [1155824224][finish][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 71 | [1155824224][issue][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 72 | [1155824224][finish][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 73 | [1155824322][issue][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 74 | [1155824322][finish][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 75 | [1155824322][issue][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 76 | [1155824322][finish][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 77 | [1155824340][issue][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 78 | [1155824340][finish][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 79 | [1155824340][issue][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 80 | [1155824340][finish][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 81 | [1155824398][issue][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 82 | [1155824398][finish][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 83 | [1155824398][issue][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 84 | [1155824398][finish][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 85 | [1155824457][issue][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 86 | [1155824457][finish][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 87 | [1155824457][issue][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 88 | [1155824457][finish][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 89 | [1155824506][issue][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 90 | [1155824506][finish][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 91 | [1155824506][issue][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 92 | [1155824506][finish][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 93 | [1155824529][issue][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 94 | [1155824529][finish][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 95 | [1155824529][issue][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 96 | [1155824529][finish][/bin/atomlab 0 30 0 0.5 000000 000000 000000 000000 000000 000000 ] | ||
| 97 | [1155826487][issue][/bin/atomlab +0 30 0 0.5 110000110000100000000000000000000000] | ||
| 98 | [1155826487][finish][/bin/atomlab +0 30 0 0.5 110000110000100000000000000000000000] | ||
| 99 | [1155826488][issue][/bin/atomlab +0 30 0 0.5 110000110000100000000000000000000000] | ||
| 100 | [1155826488][finish][/bin/atomlab +0 30 0 0.5 110000110000100000000000000000000000] | ||
| 101 | [1155826529][issue][/bin/atomlab +0 30 0 0.5 110000110000100000000000000000000000] | ||
| 102 | [1155826529][finish][/bin/atomlab +0 30 0 0.5 110000110000100000000000000000000000] | ||
| 103 | [1155826529][issue][/bin/atomlab +0 30 0 0.5 110000110000100000000000000000000000] | ||
| 104 | [1155826529][finish][/bin/atomlab +0 30 0 0.5 110000110000100000000000000000000000] | ||
| 105 | [1155826561][issue][/bin/atomlab +0 30 0 0.5 110000 110000 100000 000000 000000 000000 ] | ||
| 106 | [1155826561][finish][/bin/atomlab +0 30 0 0.5 110000 110000 100000 000000 000000 000000 ] | ||
| 107 | [1155826561][issue][/bin/atomlab +0 30 0 0.5 110000 110000 100000 000000 000000 000000 ] | ||
| 108 | [1155826561][finish][/bin/atomlab +0 30 0 0.5 110000 110000 100000 000000 000000 000000 ] | ||
| 109 | [1155835651][issue][/bin/atomlab +0 30 0 0.5 110000 110000 100000 000000 000000 000000 ] | ||
| 110 | [1155835652][finish][/bin/atomlab +0 30 0 0.5 110000 110000 100000 000000 000000 000000 ] | ||
| 111 | [1155835652][issue][/bin/atomlab +0 30 0 0.5 110000 110000 100000 000000 000000 000000 ] | ||
| 112 | [1155835652][finish][/bin/atomlab +0 30 0 0.5 110000 110000 100000 000000 000000 000000 ] | ||
| 113 | [1155835696][issue][/bin/atomlab +0 30 0 0.5 110000 110000 100000 000000 000000 000000 ] | ||
| 114 | [1155835697][finish][/bin/atomlab +0 30 0 0.5 110000 110000 100000 000000 000000 000000 ] | ||
| 115 | [1155835697][issue][/bin/atomlab +0 30 0 0.5 110000 110000 100000 000000 000000 000000 ] | ||
| 116 | [1155835697][finish][/bin/atomlab +0 30 0 0.5 110000 110000 100000 000000 000000 000000 ] | ||
| 117 | [1155835704][issue][/bin/atomlab +0 30 0 0.5 110000 110000 100000 000000 000000 000000 ] | ||
| 118 | [1155835705][finish][/bin/atomlab +0 30 0 0.5 110000 110000 100000 000000 000000 000000 ] | ||
| 119 | [1155835705][issue][/bin/atomlab +0 30 0 0.5 110000 110000 100000 000000 000000 000000 ] | ||
| 120 | [1155835705][finish][/bin/atomlab +0 30 0 0.5 110000 110000 100000 000000 000000 000000 ] | ||
| 121 | [1155835764][issue][/bin/atomlab +0 30 0 0.5 110000 110000 100000 000000 000000 000000 ] | ||
| 122 | [1155835764][finish][/bin/atomlab +0 30 0 0.5 110000 110000 100000 000000 000000 000000 ] | ||
| 123 | [1155835764][issue][/bin/atomlab +0 30 0 0.5 110000 110000 100000 000000 000000 000000 ] | ||
| 124 | [1155835765][finish][/bin/atomlab +0 30 0 0.5 110000 110000 100000 000000 000000 000000 ] | ||
| 125 | [1155835780][issue][/bin/atomlab +0 30 0 0.5 110000 110000 100000 000000 000000 000000 ] | ||
| 126 | [1155835781][finish][/bin/atomlab +0 30 0 0.5 110000 110000 100000 000000 000000 000000 ] | ||
| 127 | [1155835781][issue][/bin/atomlab +0 30 0 0.5 110000 110000 100000 000000 000000 000000 ] | ||
| 128 | [1155835781][finish][/bin/atomlab +0 30 0 0.5 110000 110000 100000 000000 000000 000000 ] | ||
| 129 | [1155835826][issue][/bin/atomlab +0 30 0 0.5 110000 110000 000000 000000 000000 000000 ] | ||
| 130 | [1155835826][finish][/bin/atomlab +0 30 0 0.5 110000 110000 000000 000000 000000 000000 ] | ||
| 131 | [1155835826][issue][/bin/atomlab +0 30 0 0.5 110000 110000 000000 000000 000000 000000 ] | ||
| 132 | [1155835827][finish][/bin/atomlab +0 30 0 0.5 110000 110000 000000 000000 000000 000000 ] | ||
| 133 | [1155836090][issue][/bin/atomlab +0 30 0 0.5 110000 110000 000000 000000 000000 000000 ] | ||
| 134 | [1155836090][finish][/bin/atomlab +0 30 0 0.5 110000 110000 000000 000000 000000 000000 ] | ||
| 135 | [1155836106][issue][/bin/atomlab +0 30 0 0.5 110000 110000 000000 000000 000000 000000 ] | ||
| 136 | [1155836106][finish][/bin/atomlab +0 30 0 0.5 110000 110000 000000 000000 000000 000000 ] | ||
| 137 | [1155836119][issue][/bin/atomlab +0 30 0 0.5 110000 110000 000000 000000 000000 000000 ] | ||
| 138 | [1155836119][finish][/bin/atomlab +0 30 0 0.5 110000 110000 000000 000000 000000 000000 ] | ||
| 139 | [1155837444][issue][pwd] | ||
| 140 | [1155837444][finish][pwd] | ||
| 141 | [1155837536][issue][/bin/pwd] | ||
| 142 | [1155837536][finish][/bin/pwd] | ||
| 143 | [1155837536][issue][/bin/atomlab +0 30 0 0.5 110000 110000 000000 000000 000000 000000 ] | ||
| 144 | [1155837536][finish][/bin/atomlab +0 30 0 0.5 110000 110000 000000 000000 000000 000000 ] | ||
| 145 | [1155838791][issue][/bin/atomlab +0 30 0 0.5 110000 110000 000000 000000 000000 000000 ] | ||
| 146 | [1155838791][finish][/bin/atomlab +0 30 0 0.5 110000 110000 000000 000000 000000 000000 ] | ||
| 147 | [1155838886][issue][/bin/atomlab +0 30 0 0.5 /tmp/14997479.dat 110000 110000 000000 000000 000000 000000 ] | ||
| 148 | [1155838886][finish][/bin/atomlab +0 30 0 0.5 /tmp/14997479.dat 110000 110000 000000 000000 000000 000000 ] | ||
| 149 | [1155838981][issue][/bin/atomlab +0 30 0 0.5 /tmp/61564197.dat 110000 110000 000000 000000 000000 000000 ] | ||
| 150 | [1155838982][finish][/bin/atomlab +0 30 0 0.5 /tmp/61564197.dat 110000 110000 000000 000000 000000 000000 ] | ||
| 151 | [1155839148][issue][/bin/atomlab +0 30 0 0.5 /tmp/97658647.dat 110000 110000 000000 000000 000000 000000 ] | ||
| 152 | [1155839148][finish][/bin/atomlab +0 30 0 0.5 /tmp/97658647.dat 110000 110000 000000 000000 000000 000000 ] | ||
| 153 | [1155839156][issue][/bin/atomlab +0 30 0 0.5 /tmp/25019895.dat 110000 110000 100000 000000 000000 000000 ] | ||
| 154 | [1155839157][finish][/bin/atomlab +0 30 0 0.5 /tmp/25019895.dat 110000 110000 100000 000000 000000 000000 ] | ||
| 155 | [1155839174][issue][/bin/atomlab +0 30 0 0.5 /tmp/04001429.dat 110000 110000 000000 000000 000000 000000 ] | ||
| 156 | [1155839174][finish][/bin/atomlab +0 30 0 0.5 /tmp/04001429.dat 110000 110000 000000 000000 000000 000000 ] | ||
| 157 | [1155839188][issue][/bin/atomlab +0 30 0 0.5 /tmp/21011582.dat 110000 111100 110000 000000 000000 000000 ] | ||
| 158 | [1155839189][finish][/bin/atomlab +0 30 0 0.5 /tmp/21011582.dat 110000 111100 110000 000000 000000 000000 ] | ||
| 159 | [1155839203][issue][/bin/atomlab +0 30 2 0.5 /tmp/98514482.dat 110000 111100 110000 000000 000000 000000 ] | ||
| 160 | [1155839203][finish][/bin/atomlab +0 30 2 0.5 /tmp/98514482.dat 110000 111100 110000 000000 000000 000000 ] | ||
| 161 | [1155839211][issue][/bin/atomlab +0 300 2 0.5 /tmp/98791952.dat 110000 111100 110000 000000 000000 000000 ] | ||
| 162 | [1155839211][finish][/bin/atomlab +0 300 2 0.5 /tmp/98791952.dat 110000 111100 110000 000000 000000 000000 ] | ||
| 163 | [1155839303][issue][/bin/atomlab +0 300 2 0.5 /tmp/95400431.dat 110000 110000 110000 000000 000000 000000 ] | ||
| 164 | [1155839304][finish][/bin/atomlab +0 300 2 0.5 /tmp/95400431.dat 110000 110000 110000 000000 000000 000000 ] | ||
| 165 | [1155839316][issue][/bin/atomlab +0 300 2 0.5 /tmp/37036482.dat 110000 111000 000000 000000 000000 000000 ] | ||
| 166 | [1155839316][finish][/bin/atomlab +0 300 2 0.5 /tmp/37036482.dat 110000 111000 000000 000000 000000 000000 ] | ||
| 167 | [1155839322][issue][/bin/atomlab +0 300 2 0.5 /tmp/36181661.dat 110000 111100 000000 000000 000000 000000 ] | ||
| 168 | [1155839322][finish][/bin/atomlab +0 300 2 0.5 /tmp/36181661.dat 110000 111100 000000 000000 000000 000000 ] | ||
| 169 | [1155839328][issue][/bin/atomlab +0 300 2 0.5 /tmp/96811697.dat 110000 111100 100000 000000 000000 000000 ] | ||
| 170 | [1155839328][finish][/bin/atomlab +0 300 2 0.5 /tmp/96811697.dat 110000 111100 100000 000000 000000 000000 ] | ||
| 171 | [1155839334][issue][/bin/atomlab +0 300 2 0.5 /tmp/79057097.dat 110000 111100 110000 000000 000000 000000 ] | ||
| 172 | [1155839334][finish][/bin/atomlab +0 300 2 0.5 /tmp/79057097.dat 110000 111100 110000 000000 000000 000000 ] | ||
| 173 | [1155839339][issue][/bin/atomlab +0 300 2 0.5 /tmp/22795676.dat 110000 111100 110000 000000 000000 000000 ] | ||
| 174 | [1155839339][finish][/bin/atomlab +0 300 2 0.5 /tmp/22795676.dat 110000 111100 110000 000000 000000 000000 ] | ||
| 175 | [1155839430][issue][/bin/atomlab +0 300 2 0.5 /tmp/33250873.dat 110000 111100 110000 000000 000000 000000 ] | ||
| 176 | [1155839430][finish][/bin/atomlab +0 300 2 0.5 /tmp/33250873.dat 110000 111100 110000 000000 000000 000000 ] | ||
| 177 | [1155839695][issue][/bin/atomlab +0 300 2 0.5 /tmp/41730823.dat 110000 111100 111100 000000 000000 000000 ] | ||
| 178 | [1155839695][finish][/bin/atomlab +0 300 2 0.5 /tmp/41730823.dat 110000 111100 111100 000000 000000 000000 ] | ||
| 179 | [1155839705][issue][/bin/atomlab +0 300 2 0.5 /tmp/54406437.dat 110000 111100 111111 000000 000000 000000 ] | ||
| 180 | [1155839706][finish][/bin/atomlab +0 300 2 0.5 /tmp/54406437.dat 110000 111100 111111 000000 000000 000000 ] | ||
| 181 | [1155839723][issue][/bin/atomlab +0 300 2 0.5 /tmp/14767493.dat 110000 111100 111111 110000 000000 000000 ] | ||
| 182 | [1155839723][finish][/bin/atomlab +0 300 2 0.5 /tmp/14767493.dat 110000 111100 111111 110000 000000 000000 ] | ||
| 183 | [1155839734][issue][/bin/atomlab +0 300 1 0.5 /tmp/88722595.dat 110000 111100 111111 110000 000000 000000 ] | ||
| 184 | [1155839735][finish][/bin/atomlab +0 300 1 0.5 /tmp/88722595.dat 110000 111100 111111 110000 000000 000000 ] | ||
| 185 | [1155839740][issue][/bin/atomlab +0 300 2 0.5 /tmp/18707132.dat 110000 111100 111111 110000 000000 000000 ] | ||
| 186 | [1155839740][finish][/bin/atomlab +0 300 2 0.5 /tmp/18707132.dat 110000 111100 111111 110000 000000 000000 ] | ||
| 187 | [1155841370][issue][/bin/atomlab +0 30 0 0.5 /tmp/92536126.dat 110000 110000 000000 000000 000000 000000 ] | ||
| 188 | [1155841370][finish][/bin/atomlab +0 30 0 0.5 /tmp/92536126.dat 110000 110000 000000 000000 000000 000000 ] | ||
| 189 | [1155841837][issue][/bin/atomlab +0 30 0 0.5 /tmp/10767244.dat 110000 110000 000000 000000 000000 000000 ] | ||
| 190 | [1155841838][finish][/bin/atomlab +0 30 0 0.5 /tmp/10767244.dat 110000 110000 000000 000000 000000 000000 ] | ||
| 191 | [1155908064][issue][/bin/atomlab +0 30 0 0.5 /tmp/68017247.dat 110000 110000 000000 000000 000000 000000 ] | ||
| 192 | [1155908065][finish][/bin/atomlab +0 30 0 0.5 /tmp/68017247.dat 110000 110000 000000 000000 000000 000000 ] | ||
| 193 | [1156512751][issue][/bin/atomlab +0 30 0 0.5 /tmp/09105047.dat 110000 110000 000000 000000 000000 000000 ] | ||
| 194 | [1156512751][finish][/bin/atomlab +0 30 0 0.5 /tmp/09105047.dat 110000 110000 000000 000000 000000 000000 ] | ||
| 195 | [1156669670][issue][/bin/atomlab +0 30 0 0.5 /tmp/35565718.dat 110000 110000 000000 000000 000000 000000 ] | ||
| 196 | [1156669670][finish][/bin/atomlab +0 30 0 0.5 /tmp/35565718.dat 110000 110000 000000 000000 000000 000000 ] | ||
diff --git a/src/LICENSE b/src/LICENSE new file mode 100644 index 0000000..f6e636c --- /dev/null +++ b/src/LICENSE | |||
| @@ -0,0 +1,356 @@ | |||
| 1 | |||
| 2 | This copyright does not cover server HTC code that use the system | ||
| 3 | by normal system calls - this is merely considered normal use of the | ||
| 4 | system, and does not fall under the heading of "derived work". Also | ||
| 5 | note that the GPL below is copyrighted by the Free Software | ||
| 6 | Foundation, but the instance of code that it refers to (the htcd | ||
| 7 | system) is copyrighted by me. | ||
| 8 | |||
| 9 | Also note that the only valid version of the GPL as far as the kernel | ||
| 10 | is concerned is _this_ particular version of the license (ie v2, not | ||
| 11 | v2.2 or v3.x or whatever), unless explicitly otherwise stated. | ||
| 12 | |||
| 13 | Henrik Rydberg (rydberg@euromail.se) | ||
| 14 | |||
| 15 | ---------------------------------------- | ||
| 16 | |||
| 17 | GNU GENERAL PUBLIC LICENSE | ||
| 18 | Version 2, June 1991 | ||
| 19 | |||
| 20 | Copyright (C) 1989, 1991 Free Software Foundation, Inc. | ||
| 21 | 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 22 | Everyone is permitted to copy and distribute verbatim copies | ||
| 23 | of this license document, but changing it is not allowed. | ||
| 24 | |||
| 25 | Preamble | ||
| 26 | |||
| 27 | The licenses for most software are designed to take away your | ||
| 28 | freedom to share and change it. By contrast, the GNU General Public | ||
| 29 | License is intended to guarantee your freedom to share and change free | ||
| 30 | software--to make sure the software is free for all its users. This | ||
| 31 | General Public License applies to most of the Free Software | ||
| 32 | Foundation's software and to any other program whose authors commit to | ||
| 33 | using it. (Some other Free Software Foundation software is covered by | ||
| 34 | the GNU Library General Public License instead.) You can apply it to | ||
| 35 | your programs, too. | ||
| 36 | |||
| 37 | When we speak of free software, we are referring to freedom, not | ||
| 38 | price. Our General Public Licenses are designed to make sure that you | ||
| 39 | have the freedom to distribute copies of free software (and charge for | ||
| 40 | this service if you wish), that you receive source code or can get it | ||
| 41 | if you want it, that you can change the software or use pieces of it | ||
| 42 | in new free programs; and that you know you can do these things. | ||
| 43 | |||
| 44 | To protect your rights, we need to make restrictions that forbid | ||
| 45 | anyone to deny you these rights or to ask you to surrender the rights. | ||
| 46 | These restrictions translate to certain responsibilities for you if you | ||
| 47 | distribute copies of the software, or if you modify it. | ||
| 48 | |||
| 49 | For example, if you distribute copies of such a program, whether | ||
| 50 | gratis or for a fee, you must give the recipients all the rights that | ||
| 51 | you have. You must make sure that they, too, receive or can get the | ||
| 52 | source code. And you must show them these terms so they know their | ||
| 53 | rights. | ||
| 54 | |||
| 55 | We protect your rights with two steps: (1) copyright the software, and | ||
| 56 | (2) offer you this license which gives you legal permission to copy, | ||
| 57 | distribute and/or modify the software. | ||
| 58 | |||
| 59 | Also, for each author's protection and ours, we want to make certain | ||
| 60 | that everyone understands that there is no warranty for this free | ||
| 61 | software. If the software is modified by someone else and passed on, we | ||
| 62 | want its recipients to know that what they have is not the original, so | ||
| 63 | that any problems introduced by others will not reflect on the original | ||
| 64 | authors' reputations. | ||
| 65 | |||
| 66 | Finally, any free program is threatened constantly by software | ||
| 67 | patents. We wish to avoid the danger that redistributors of a free | ||
| 68 | program will individually obtain patent licenses, in effect making the | ||
| 69 | program proprietary. To prevent this, we have made it clear that any | ||
| 70 | patent must be licensed for everyone's free use or not licensed at all. | ||
| 71 | |||
| 72 | The precise terms and conditions for copying, distribution and | ||
| 73 | modification follow. | ||
| 74 | |||
| 75 | GNU GENERAL PUBLIC LICENSE | ||
| 76 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION | ||
| 77 | |||
| 78 | 0. This License applies to any program or other work which contains | ||
| 79 | a notice placed by the copyright holder saying it may be distributed | ||
| 80 | under the terms of this General Public License. The "Program", below, | ||
| 81 | refers to any such program or work, and a "work based on the Program" | ||
| 82 | means either the Program or any derivative work under copyright law: | ||
| 83 | that is to say, a work containing the Program or a portion of it, | ||
| 84 | either verbatim or with modifications and/or translated into another | ||
| 85 | language. (Hereinafter, translation is included without limitation in | ||
| 86 | the term "modification".) Each licensee is addressed as "you". | ||
| 87 | |||
| 88 | Activities other than copying, distribution and modification are not | ||
| 89 | covered by this License; they are outside its scope. The act of | ||
| 90 | running the Program is not restricted, and the output from the Program | ||
| 91 | is covered only if its contents constitute a work based on the | ||
| 92 | Program (independent of having been made by running the Program). | ||
| 93 | Whether that is true depends on what the Program does. | ||
| 94 | |||
| 95 | 1. You may copy and distribute verbatim copies of the Program's | ||
| 96 | source code as you receive it, in any medium, provided that you | ||
| 97 | conspicuously and appropriately publish on each copy an appropriate | ||
| 98 | copyright notice and disclaimer of warranty; keep intact all the | ||
| 99 | notices that refer to this License and to the absence of any warranty; | ||
| 100 | and give any other recipients of the Program a copy of this License | ||
| 101 | along with the Program. | ||
| 102 | |||
| 103 | You may charge a fee for the physical act of transferring a copy, and | ||
| 104 | you may at your option offer warranty protection in exchange for a fee. | ||
| 105 | |||
| 106 | 2. You may modify your copy or copies of the Program or any portion | ||
| 107 | of it, thus forming a work based on the Program, and copy and | ||
| 108 | distribute such modifications or work under the terms of Section 1 | ||
| 109 | above, provided that you also meet all of these conditions: | ||
| 110 | |||
| 111 | a) You must cause the modified files to carry prominent notices | ||
| 112 | stating that you changed the files and the date of any change. | ||
| 113 | |||
| 114 | b) You must cause any work that you distribute or publish, that in | ||
| 115 | whole or in part contains or is derived from the Program or any | ||
| 116 | part thereof, to be licensed as a whole at no charge to all third | ||
| 117 | parties under the terms of this License. | ||
| 118 | |||
| 119 | c) If the modified program normally reads commands interactively | ||
| 120 | when run, you must cause it, when started running for such | ||
| 121 | interactive use in the most ordinary way, to print or display an | ||
| 122 | announcement including an appropriate copyright notice and a | ||
| 123 | notice that there is no warranty (or else, saying that you provide | ||
| 124 | a warranty) and that users may redistribute the program under | ||
| 125 | these conditions, and telling the user how to view a copy of this | ||
| 126 | License. (Exception: if the Program itself is interactive but | ||
| 127 | does not normally print such an announcement, your work based on | ||
| 128 | the Program is not required to print an announcement.) | ||
| 129 | |||
| 130 | These requirements apply to the modified work as a whole. If | ||
| 131 | identifiable sections of that work are not derived from the Program, | ||
| 132 | and can be reasonably considered independent and separate works in | ||
| 133 | themselves, then this License, and its terms, do not apply to those | ||
| 134 | sections when you distribute them as separate works. But when you | ||
| 135 | distribute the same sections as part of a whole which is a work based | ||
| 136 | on the Program, the distribution of the whole must be on the terms of | ||
| 137 | this License, whose permissions for other licensees extend to the | ||
| 138 | entire whole, and thus to each and every part regardless of who wrote it. | ||
| 139 | |||
| 140 | Thus, it is not the intent of this section to claim rights or contest | ||
| 141 | your rights to work written entirely by you; rather, the intent is to | ||
| 142 | exercise the right to control the distribution of derivative or | ||
| 143 | collective works based on the Program. | ||
| 144 | |||
| 145 | In addition, mere aggregation of another work not based on the Program | ||
| 146 | with the Program (or with a work based on the Program) on a volume of | ||
| 147 | a storage or distribution medium does not bring the other work under | ||
| 148 | the scope of this License. | ||
| 149 | |||
| 150 | 3. You may copy and distribute the Program (or a work based on it, | ||
| 151 | under Section 2) in object code or executable form under the terms of | ||
| 152 | Sections 1 and 2 above provided that you also do one of the following: | ||
| 153 | |||
| 154 | a) Accompany it with the complete corresponding machine-readable | ||
| 155 | source code, which must be distributed under the terms of Sections | ||
| 156 | 1 and 2 above on a medium customarily used for software interchange; or, | ||
| 157 | |||
| 158 | b) Accompany it with a written offer, valid for at least three | ||
| 159 | years, to give any third party, for a charge no more than your | ||
| 160 | cost of physically performing source distribution, a complete | ||
| 161 | machine-readable copy of the corresponding source code, to be | ||
| 162 | distributed under the terms of Sections 1 and 2 above on a medium | ||
| 163 | customarily used for software interchange; or, | ||
| 164 | |||
| 165 | c) Accompany it with the information you received as to the offer | ||
| 166 | to distribute corresponding source code. (This alternative is | ||
| 167 | allowed only for noncommercial distribution and only if you | ||
| 168 | received the program in object code or executable form with such | ||
| 169 | an offer, in accord with Subsection b above.) | ||
| 170 | |||
| 171 | The source code for a work means the preferred form of the work for | ||
| 172 | making modifications to it. For an executable work, complete source | ||
| 173 | code means all the source code for all modules it contains, plus any | ||
| 174 | associated interface definition files, plus the scripts used to | ||
| 175 | control compilation and installation of the executable. However, as a | ||
| 176 | special exception, the source code distributed need not include | ||
| 177 | anything that is normally distributed (in either source or binary | ||
| 178 | form) with the major components (compiler, kernel, and so on) of the | ||
| 179 | operating system on which the executable runs, unless that component | ||
| 180 | itself accompanies the executable. | ||
| 181 | |||
| 182 | If distribution of executable or object code is made by offering | ||
| 183 | access to copy from a designated place, then offering equivalent | ||
| 184 | access to copy the source code from the same place counts as | ||
| 185 | distribution of the source code, even though third parties are not | ||
| 186 | compelled to copy the source along with the object code. | ||
| 187 | |||
| 188 | 4. You may not copy, modify, sublicense, or distribute the Program | ||
| 189 | except as expressly provided under this License. Any attempt | ||
| 190 | otherwise to copy, modify, sublicense or distribute the Program is | ||
| 191 | void, and will automatically terminate your rights under this License. | ||
| 192 | However, parties who have received copies, or rights, from you under | ||
| 193 | this License will not have their licenses terminated so long as such | ||
| 194 | parties remain in full compliance. | ||
| 195 | |||
| 196 | 5. You are not required to accept this License, since you have not | ||
| 197 | signed it. However, nothing else grants you permission to modify or | ||
| 198 | distribute the Program or its derivative works. These actions are | ||
| 199 | prohibited by law if you do not accept this License. Therefore, by | ||
| 200 | modifying or distributing the Program (or any work based on the | ||
| 201 | Program), you indicate your acceptance of this License to do so, and | ||
| 202 | all its terms and conditions for copying, distributing or modifying | ||
| 203 | the Program or works based on it. | ||
| 204 | |||
| 205 | 6. Each time you redistribute the Program (or any work based on the | ||
| 206 | Program), the recipient automatically receives a license from the | ||
| 207 | original licensor to copy, distribute or modify the Program subject to | ||
| 208 | these terms and conditions. You may not impose any further | ||
| 209 | restrictions on the recipients' exercise of the rights granted herein. | ||
| 210 | You are not responsible for enforcing compliance by third parties to | ||
| 211 | this License. | ||
| 212 | |||
| 213 | 7. If, as a consequence of a court judgment or allegation of patent | ||
| 214 | infringement or for any other reason (not limited to patent issues), | ||
| 215 | conditions are imposed on you (whether by court order, agreement or | ||
| 216 | otherwise) that contradict the conditions of this License, they do not | ||
| 217 | excuse you from the conditions of this License. If you cannot | ||
| 218 | distribute so as to satisfy simultaneously your obligations under this | ||
| 219 | License and any other pertinent obligations, then as a consequence you | ||
| 220 | may not distribute the Program at all. For example, if a patent | ||
| 221 | license would not permit royalty-free redistribution of the Program by | ||
| 222 | all those who receive copies directly or indirectly through you, then | ||
| 223 | the only way you could satisfy both it and this License would be to | ||
| 224 | refrain entirely from distribution of the Program. | ||
| 225 | |||
| 226 | If any portion of this section is held invalid or unenforceable under | ||
| 227 | any particular circumstance, the balance of the section is intended to | ||
| 228 | apply and the section as a whole is intended to apply in other | ||
| 229 | circumstances. | ||
| 230 | |||
| 231 | It is not the purpose of this section to induce you to infringe any | ||
| 232 | patents or other property right claims or to contest validity of any | ||
| 233 | such claims; this section has the sole purpose of protecting the | ||
| 234 | integrity of the free software distribution system, which is | ||
| 235 | implemented by public license practices. Many people have made | ||
| 236 | generous contributions to the wide range of software distributed | ||
| 237 | through that system in reliance on consistent application of that | ||
| 238 | system; it is up to the author/donor to decide if he or she is willing | ||
| 239 | to distribute software through any other system and a licensee cannot | ||
| 240 | impose that choice. | ||
| 241 | |||
| 242 | This section is intended to make thoroughly clear what is believed to | ||
| 243 | be a consequence of the rest of this License. | ||
| 244 | |||
| 245 | 8. If the distribution and/or use of the Program is restricted in | ||
| 246 | certain countries either by patents or by copyrighted interfaces, the | ||
| 247 | original copyright holder who places the Program under this License | ||
| 248 | may add an explicit geographical distribution limitation excluding | ||
| 249 | those countries, so that distribution is permitted only in or among | ||
| 250 | countries not thus excluded. In such case, this License incorporates | ||
| 251 | the limitation as if written in the body of this License. | ||
| 252 | |||
| 253 | 9. The Free Software Foundation may publish revised and/or new versions | ||
| 254 | of the General Public License from time to time. Such new versions will | ||
| 255 | be similar in spirit to the present version, but may differ in detail to | ||
| 256 | address new problems or concerns. | ||
| 257 | |||
| 258 | Each version is given a distinguishing version number. If the Program | ||
| 259 | specifies a version number of this License which applies to it and "any | ||
| 260 | later version", you have the option of following the terms and conditions | ||
| 261 | either of that version or of any later version published by the Free | ||
| 262 | Software Foundation. If the Program does not specify a version number of | ||
| 263 | this License, you may choose any version ever published by the Free Software | ||
| 264 | Foundation. | ||
| 265 | |||
| 266 | 10. If you wish to incorporate parts of the Program into other free | ||
| 267 | programs whose distribution conditions are different, write to the author | ||
| 268 | to ask for permission. For software which is copyrighted by the Free | ||
| 269 | Software Foundation, write to the Free Software Foundation; we sometimes | ||
| 270 | make exceptions for this. Our decision will be guided by the two goals | ||
| 271 | of preserving the free status of all derivatives of our free software and | ||
| 272 | of promoting the sharing and reuse of software generally. | ||
| 273 | |||
| 274 | NO WARRANTY | ||
| 275 | |||
| 276 | 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY | ||
| 277 | FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN | ||
| 278 | OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES | ||
| 279 | PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED | ||
| 280 | OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF | ||
| 281 | MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS | ||
| 282 | TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE | ||
| 283 | PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, | ||
| 284 | REPAIR OR CORRECTION. | ||
| 285 | |||
| 286 | 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING | ||
| 287 | WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR | ||
| 288 | REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, | ||
| 289 | INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING | ||
| 290 | OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED | ||
| 291 | TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY | ||
| 292 | YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER | ||
| 293 | PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE | ||
| 294 | POSSIBILITY OF SUCH DAMAGES. | ||
| 295 | |||
| 296 | END OF TERMS AND CONDITIONS | ||
| 297 | |||
| 298 | How to Apply These Terms to Your New Programs | ||
| 299 | |||
| 300 | If you develop a new program, and you want it to be of the greatest | ||
| 301 | possible use to the public, the best way to achieve this is to make it | ||
| 302 | free software which everyone can redistribute and change under these terms. | ||
| 303 | |||
| 304 | To do so, attach the following notices to the program. It is safest | ||
| 305 | to attach them to the start of each source file to most effectively | ||
| 306 | convey the exclusion of warranty; and each file should have at least | ||
| 307 | the "copyright" line and a pointer to where the full notice is found. | ||
| 308 | |||
| 309 | <one line to give the program's name and a brief idea of what it does.> | ||
| 310 | Copyright (C) <year> <name of author> | ||
| 311 | |||
| 312 | This program is free software; you can redistribute it and/or modify | ||
| 313 | it under the terms of the GNU General Public License as published by | ||
| 314 | the Free Software Foundation; either version 2 of the License, or | ||
| 315 | (at your option) any later version. | ||
| 316 | |||
| 317 | This program is distributed in the hope that it will be useful, | ||
| 318 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 319 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 320 | GNU General Public License for more details. | ||
| 321 | |||
| 322 | You should have received a copy of the GNU General Public License | ||
| 323 | along with this program; if not, write to the Free Software | ||
| 324 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 325 | |||
| 326 | |||
| 327 | Also add information on how to contact you by electronic and paper mail. | ||
| 328 | |||
| 329 | If the program is interactive, make it output a short notice like this | ||
| 330 | when it starts in an interactive mode: | ||
| 331 | |||
| 332 | Gnomovision version 69, Copyright (C) year name of author | ||
| 333 | Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. | ||
| 334 | This is free software, and you are welcome to redistribute it | ||
| 335 | under certain conditions; type `show c' for details. | ||
| 336 | |||
| 337 | The hypothetical commands `show w' and `show c' should show the appropriate | ||
| 338 | parts of the General Public License. Of course, the commands you use may | ||
| 339 | be called something other than `show w' and `show c'; they could even be | ||
| 340 | mouse-clicks or menu items--whatever suits your program. | ||
| 341 | |||
| 342 | You should also get your employer (if you work as a programmer) or your | ||
| 343 | school, if any, to sign a "copyright disclaimer" for the program, if | ||
| 344 | necessary. Here is a sample; alter the names: | ||
| 345 | |||
| 346 | Yoyodyne, Inc., hereby disclaims all copyright interest in the program | ||
| 347 | `Gnomovision' (which makes passes at compilers) written by James Hacker. | ||
| 348 | |||
| 349 | <signature of Ty Coon>, 1 April 1989 | ||
| 350 | Ty Coon, President of Vice | ||
| 351 | |||
| 352 | This General Public License does not permit incorporating your program into | ||
| 353 | proprietary programs. If your program is a subroutine library, you may | ||
| 354 | consider it more useful to permit linking proprietary applications with the | ||
| 355 | library. If this is what you want to do, use the GNU Library General | ||
| 356 | Public License instead of this License. | ||
diff --git a/src/hdb/README b/src/hdb/README new file mode 100644 index 0000000..0db7269 --- /dev/null +++ b/src/hdb/README | |||
| @@ -0,0 +1,154 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | HDB/1.2 FILE FORMAT SPECIFICATION Sat Feb 24 18:38:25 MET 2001 | ||
| 21 | |||
| 22 | MT AND MP SAFE | ||
| 23 | |||
| 24 | One single format utilizing memory maps, and which is designed to | ||
| 25 | work safely between processes and within a multi-threading process. | ||
| 26 | To accomplish this, there are two types of locking mechanisms - | ||
| 27 | one inter-process lock in the file header, and one MT lock implemented | ||
| 28 | the usual way. | ||
| 29 | |||
| 30 | The format is robust within each thread, except for changes in the | ||
| 31 | table structure, which generates fatal error_t errors. | ||
| 32 | |||
| 33 | The format includes a finite (32) number of tables, which should not | ||
| 34 | be a real problem. Besides, a possible change is to move the frame | ||
| 35 | pointer to a position inside, so that additional header could be | ||
| 36 | added if needed. | ||
| 37 | |||
| 38 | FILEFORMAT in HDB/1.2 | ||
| 39 | |||
| 40 | BYTES 1.2 NAME DESCRIPTION | ||
| 41 | 32 IDENT Identification header | ||
| 42 | 4 LOCK Inter-process lock | ||
| 43 | 4 MINOR Minor modification state number | ||
| 44 | 4 MAJOR Major modification state number | ||
| 45 | 4 FATAL Fatal modification state number | ||
| 46 | 4 FILESIZE Size of file | ||
| 47 | 4 FILETOP Size of used part | ||
| 48 | 4 TABLES Number of table name strings | ||
| 49 | 4 INDEX Which column is the order column. | ||
| 50 | 32 COMPNAME Comparison name | ||
| 51 | 32*32 TABLENAMES Table names | ||
| 52 | 4 FRAME Start of record data | ||
| 53 | * RECORDS Record list | ||
| 54 | 4 mem amount of memory for this record | ||
| 55 | 4 caps the capacity of this record - 0 means deleted | ||
| 56 | mem-8 data The data follows | ||
| 57 | 0 ZEROS The rest of the file is padded with zeros. | ||
| 58 | |||
| 59 | The records are always staying where they land; a minor change means | ||
| 60 | a change in-place, a major change means a change leading to an index | ||
| 61 | update, which could be a deletion, an insertion. Those are updated at | ||
| 62 | will, and not seen until wanted. A fatal change is a change in the | ||
| 63 | table structure, i.e., an insertion or deletion of a table. Also a | ||
| 64 | table name change counts as fatal. The filesize used to be (earlier | ||
| 65 | versions) a state needing attention as well, but not anymore. | ||
| 66 | |||
| 67 | -- | ||
| 68 | |||
| 69 | HDB/1.11 FILE FORMAT SPECIFICATION Mon Jan 29 03:51:41 MET 2001 | ||
| 70 | |||
| 71 | STATIC/DYNAMIC mapping | ||
| 72 | |||
| 73 | The header field determines whether the mapping is dynamic or static, | ||
| 74 | i.e., static mapping creates a shared mmap and edits the records | ||
| 75 | directly, whereas the dynamic mapping creates a private map and | ||
| 76 | stores the changes on save only. | ||
| 77 | |||
| 78 | The format changed quite a lot after all... | ||
| 79 | |||
| 80 | FILEFORMAT in HDB/1.11 | ||
| 81 | |||
| 82 | BYTES 1.11 NAME DESCRIPTION | ||
| 83 | 32 IDENT Identification header | ||
| 84 | 4 MODNUM Modification number | ||
| 85 | 4 LOCK Soft lock | ||
| 86 | 4 FILESIZE Size of file | ||
| 87 | 4 FILETOP Size of used part | ||
| 88 | 4 FIXED Whether fixed mapping or not | ||
| 89 | 4 TABLES Number of table name strings | ||
| 90 | 4 INDEX Which column is the order column. | ||
| 91 | 32 COMPNAME Comparison name | ||
| 92 | 4 RECORDS Number of records in file. | ||
| 93 | tables | ||
| 94 | 4,* name table name | ||
| 95 | 4,* defaults default string | ||
| 96 | 4 caps default sizes | ||
| 97 | [4],* records TABLES[RECORDS] | ||
| 98 | |||
| 99 | Size info [4] always refers to the stringref-size, but the number of | ||
| 100 | bytes actually written is as follows: for fixed maps, it is tabs[].caps, | ||
| 101 | and for dynamic maps, it is capsize(), which is defined as (n=stringref-size) | ||
| 102 | (4+n)&~3. | ||
| 103 | |||
| 104 | -- | ||
| 105 | |||
| 106 | HDB/1.10 FILE FORMAT SPECIFICATION Thu Jan 25 00:42:49 MET 2001 | ||
| 107 | |||
| 108 | The HDB/1.0 format has been used widely in the software | ||
| 109 | for our group (MST) during the last three years of so. | ||
| 110 | The HDB/1.1 file format is binary compatible with 1.0, | ||
| 111 | and merely consists of a formalization, along with a | ||
| 112 | change in the internal manipulation scheme and a new | ||
| 113 | hdb editor. | ||
| 114 | |||
| 115 | FILE FORMAT IN 1.0 and 1.1 | ||
| 116 | |||
| 117 | BYTES 1.0/1.1 NAME DESCRIPTION | ||
| 118 | 32/variable HEAD Identification header. | ||
| 119 | Used to be exactly 32 bytes, | ||
| 120 | but see no point in that. | ||
| 121 | 4 TABLES Number of table name strings | ||
| 122 | 4 dim bytes in string | ||
| 123 | * data string data | ||
| 124 | 4 DEFAULTS Number of default strings | ||
| 125 | 4 dim bytes in string | ||
| 126 | * data string data | ||
| 127 | 4 ORDERBY Which column is the order column. | ||
| 128 | 4 dim Number of bytes in compname. | ||
| 129 | * data string data | ||
| 130 | 4 RECORDS Number of records in file. | ||
| 131 | 4 tables | ||
| 132 | 4 dim | ||
| 133 | * data | ||
| 134 | 0/variable FOOTER File ends. Simple Footer. | ||
| 135 | |||
| 136 | ADDITIONAL CHANGES BETWEEN 1.0 and 1.1 | ||
| 137 | |||
| 138 | The major difference - and the rationale for 1.1 - is | ||
| 139 | the possiblity to edit files directly, as in mmap. | ||
| 140 | To be able to do this, there is a need to force a minimum | ||
| 141 | size to each field. This is done by padding the data | ||
| 142 | with trailing zeros. This is ok since only string data | ||
| 143 | is stored in the fields, and never binary data. Just think | ||
| 144 | of it; if it was binary data, it would not be replaced | ||
| 145 | by something the same size anyways, so thats forbidden | ||
| 146 | in the direct-editing mode. It makes no difference to | ||
| 147 | the normal operation. | ||
| 148 | |||
| 149 | The default sizes for new fields are taken from the defaults | ||
| 150 | table, which again is completely compatible. The only | ||
| 151 | difference is that the zeros are stored as well, and hence | ||
| 152 | cannot be defined just by the default string, but need an editor | ||
| 153 | that specifies the sizes. | ||
| 154 | |||
diff --git a/src/hdb/buffer.h b/src/hdb/buffer.h new file mode 100644 index 0000000..9383753 --- /dev/null +++ b/src/hdb/buffer.h | |||
| @@ -0,0 +1,38 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef BUFFERH | ||
| 21 | #define BUFFERH | ||
| 22 | |||
| 23 | #include <mt/mstring.h> | ||
| 24 | #include <time.h> | ||
| 25 | |||
| 26 | inline void LoadBuffer(mstring& buffer,const mstring& path) | ||
| 27 | throw(merror_t) | ||
| 28 | { | ||
| 29 | if(buffer.load(path.c_str())<0) THROW("file: Could not load "<<path); | ||
| 30 | } | ||
| 31 | |||
| 32 | inline void SaveBuffer(const sref& buffer,const mstring& path,int prot=0600) | ||
| 33 | throw(merror_t) | ||
| 34 | { | ||
| 35 | if(buffer.save(path,prot)<0) THROW("file: Could not save "<<path); | ||
| 36 | } | ||
| 37 | |||
| 38 | #endif | ||
diff --git a/src/hdb/comp.cc b/src/hdb/comp.cc new file mode 100644 index 0000000..3cb304a --- /dev/null +++ b/src/hdb/comp.cc | |||
| @@ -0,0 +1,78 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <hdb/db.h> | ||
| 21 | using namespace std; | ||
| 22 | |||
| 23 | const mstring compat="(compatibility)"; | ||
| 24 | const int zkey=0; | ||
| 25 | |||
| 26 | OP2_IMPL(lti) {out<<(atoi(L)<atoi(R));} | ||
| 27 | OP2_IMPL(lei) {out<<(atoi(L)<=atoi(R));} | ||
| 28 | OP2_IMPL(gei) {out<<(atoi(L)>=atoi(R));} | ||
| 29 | OP2_IMPL(gti) {out<<(atoi(L)>atoi(R));} | ||
| 30 | |||
| 31 | void dbmap::setup() | ||
| 32 | { | ||
| 33 | MLOCK(mutex); | ||
| 34 | if(M.empty()) { | ||
| 35 | opAddComp(M); | ||
| 36 | OP_ADDN(20,lti,lt.int,compat); | ||
| 37 | OP_ADDN(20,lei,le.int,compat); | ||
| 38 | OP_ADDN(20,gei,ge.int,compat); | ||
| 39 | OP_ADDN(20,gti,gt.int,compat); | ||
| 40 | |||
| 41 | M.add(new op_t("lt.case",20,M.get(sref("lt"))->f2,compat)); | ||
| 42 | M.add(new op_t("gt.case",20,M.get(sref("gt"))->f2,compat)); | ||
| 43 | M.add(new op_t("lt.nocase",20,M.get(sref("ltn"))->f2,compat)); | ||
| 44 | M.add(new op_t("gt.nocase",20,M.get(sref("gtn"))->f2,compat)); | ||
| 45 | } | ||
| 46 | } | ||
| 47 | |||
| 48 | const op_t* dbmap::CompOperator(const sref& s) | ||
| 49 | { | ||
| 50 | if(M.empty()) setup(); | ||
| 51 | const op_t* p=M.get(s); | ||
| 52 | if(!p) THROW("dbmap: could not find operator "<<s); | ||
| 53 | return p; | ||
| 54 | } | ||
| 55 | |||
| 56 | /////////////////////////////////////////////////////////////////// | ||
| 57 | |||
| 58 | void dbmap::Sort(const sref& tab,const sref& cmp) throw(merror_t) | ||
| 59 | { | ||
| 60 | check(); | ||
| 61 | int DO=0; | ||
| 62 | if(cmp.nempty()&&cmp!=compname) { compname=cmp; DO=1; } | ||
| 63 | if(tab.nempty()) { int col=Index(tab); if(col!=index) { index=col; DO=1; } } | ||
| 64 | if(DO) remap_recs(); | ||
| 65 | } | ||
| 66 | |||
| 67 | void dbmap::Order(const sref& tab,const sref& cmp) throw(merror_t) | ||
| 68 | { | ||
| 69 | check(); | ||
| 70 | if(!wok) THROW("db: cannot order - readonly"); | ||
| 71 | Sort(tab,cmp); | ||
| 72 | { | ||
| 73 | HEADLOCK(file); | ||
| 74 | file->head()->setcomp(index,compname); | ||
| 75 | remap_tabs(); | ||
| 76 | } | ||
| 77 | } | ||
| 78 | |||
diff --git a/src/hdb/cvt.cc b/src/hdb/cvt.cc new file mode 100644 index 0000000..4788bf1 --- /dev/null +++ b/src/hdb/cvt.cc | |||
| @@ -0,0 +1,83 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <hdb/db.h> | ||
| 21 | using namespace std; | ||
| 22 | |||
| 23 | const mstring HEAD10="HTC DB File Format version 1.0\n"; | ||
| 24 | const mstring HEAD11="HDB/1.1"; | ||
| 25 | |||
| 26 | static fp_stream merr(stderr); | ||
| 27 | |||
| 28 | static void Read(FILE* fp,mstring& s,int version) { | ||
| 29 | int n; fread(&n,4,1,fp); | ||
| 30 | switch(version) { | ||
| 31 | case 10: | ||
| 32 | s.resize(n); | ||
| 33 | fread(s.data(),1,n,fp); | ||
| 34 | break; | ||
| 35 | case 11: | ||
| 36 | s.resize(n-1); | ||
| 37 | fread(s.data(),1,n,fp); | ||
| 38 | s.resize(strlen(s.data())); | ||
| 39 | if(s.size()>=n) THROW("dbmap: assertion failed on dimension"); | ||
| 40 | break; | ||
| 41 | default: | ||
| 42 | THROW("read: bad HDB version"); | ||
| 43 | break; | ||
| 44 | } | ||
| 45 | } | ||
| 46 | |||
| 47 | void Convert(dbmap& db,const char* path) | ||
| 48 | { | ||
| 49 | FILE* fp=fopen(path,"rb"); | ||
| 50 | char line[1024]; | ||
| 51 | fgets(line,1000,fp); | ||
| 52 | int version=0; | ||
| 53 | if(sref(line)==HEAD10) { fgetc(fp); version=10; } | ||
| 54 | else if(First(sref(line))==HEAD11) { version=11; } | ||
| 55 | if(version==0) THROW("hdbcvt: unknown HDB format"); | ||
| 56 | int tables; | ||
| 57 | mstring s; | ||
| 58 | fread(&tables,4,1,fp); | ||
| 59 | for(int i=0;i<tables;i++) { | ||
| 60 | Read(fp,s,version); | ||
| 61 | db.InsertTable(i,s); | ||
| 62 | } | ||
| 63 | fread(&tables,4,1,fp); | ||
| 64 | if(tables!=db.Tables()) THROW("hdbcvt: bad table num\n"); | ||
| 65 | spile defs(tables); | ||
| 66 | for(int i=0;i<tables;i++) Read(fp,defs[i],version); | ||
| 67 | merr<<"db: NOTE - default values no longer supported\n"; | ||
| 68 | int index; | ||
| 69 | fread(&index,4,1,fp); | ||
| 70 | mstring compname; | ||
| 71 | Read(fp,compname,version); | ||
| 72 | db.Order(db.Table(index),compname); | ||
| 73 | int records; | ||
| 74 | fread(&records,4,1,fp); | ||
| 75 | for(int i=0;i<records;i++) { | ||
| 76 | int n; fread(&n,4,1,fp); | ||
| 77 | if(n!=tables) THROW("hdbcvt: bad table num\n"); | ||
| 78 | spile rec(n); | ||
| 79 | for(int j=0;j<n;j++) Read(fp,rec[j],version); | ||
| 80 | int ok=db.Insert(rec,1); | ||
| 81 | if(ok<0) merr<<"hdbcvt: bad index ["<<rec[index]<<"] - not unique; skipped\n"; | ||
| 82 | } | ||
| 83 | } | ||
diff --git a/src/hdb/db.cc b/src/hdb/db.cc new file mode 100644 index 0000000..0cc9827 --- /dev/null +++ b/src/hdb/db.cc | |||
| @@ -0,0 +1,276 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <hdb/db.h> | ||
| 21 | #include <new> | ||
| 22 | |||
| 23 | filemap* dbmap::flist; | ||
| 24 | mutex_t dbmap::mutex; | ||
| 25 | opmap dbmap::M; | ||
| 26 | |||
| 27 | /////////////////////////////////////////////////////////////////////// | ||
| 28 | |||
| 29 | dbmap::dbmap(): | ||
| 30 | wok(0),fatal(0),index(0), | ||
| 31 | compname(),file(0),tmap(),recs() | ||
| 32 | { | ||
| 33 | minor=0; | ||
| 34 | major=0; | ||
| 35 | } | ||
| 36 | |||
| 37 | dbmap::~dbmap() | ||
| 38 | { | ||
| 39 | Close(); | ||
| 40 | } | ||
| 41 | |||
| 42 | /////////////////////////////////////////////////////////////////////// | ||
| 43 | |||
| 44 | void dbmap::remap_tabs() | ||
| 45 | { | ||
| 46 | fatal=head()->fatal.get(); | ||
| 47 | tmap.clear(); | ||
| 48 | for(int i=0;i<Tables();i++) tmap.add(sref(head()->tabs[i]),i); | ||
| 49 | } | ||
| 50 | |||
| 51 | void dbmap::remap_recs() | ||
| 52 | { | ||
| 53 | major=head()->major.get(); | ||
| 54 | recs.clear(); | ||
| 55 | int p=file->recs(); | ||
| 56 | while(file->size(p)) { | ||
| 57 | record_t* rec=(record_t*)file->at(p); | ||
| 58 | if(rec->caps.get()) | ||
| 59 | recs.push_back(idx_t(rec->at(index),rec)); | ||
| 60 | p+=rec->mem.get(); | ||
| 61 | } | ||
| 62 | recs.sort(CompOperator(compname)); | ||
| 63 | } | ||
| 64 | |||
| 65 | int dbmap::remap() | ||
| 66 | { | ||
| 67 | int state=0; | ||
| 68 | if(fatal!=head()->fatal.get()) { remap_tabs(); state|=4; } | ||
| 69 | if(major!=head()->major.get()) { remap_recs(); state|=2; } | ||
| 70 | if(minor!=head()->minor.get()) { minor=head()->minor.get(); state|=1; } | ||
| 71 | return state; | ||
| 72 | } | ||
| 73 | |||
| 74 | /////////////////////////////////////////////////////////////////////// | ||
| 75 | |||
| 76 | void Open(const mstring& path,int update=0,int prot=0600) throw(merror_t); | ||
| 77 | void Saveas(const mstring& path,int prot=0600) throw(merror_t); | ||
| 78 | void Close(); | ||
| 79 | |||
| 80 | void dbmap::Open(const mstring& path,int update,int prot) throw(merror_t) | ||
| 81 | { | ||
| 82 | Close(); | ||
| 83 | wok=update?1:0; | ||
| 84 | { | ||
| 85 | MLOCK(mutex); | ||
| 86 | for(filemap* p=flist;p;p=p->next) | ||
| 87 | if(p->Pathname()==path&&p->writable()==wok) { (file=p)->pushref(); break; } | ||
| 88 | if(!file) { | ||
| 89 | filemap* fm=new filemap(flist); | ||
| 90 | try { fm->open(path,wok,prot); fm->check(); file=flist=fm; } | ||
| 91 | catch(...) { delete fm; wok=0; throw; } | ||
| 92 | } | ||
| 93 | } | ||
| 94 | index=head()->index.get(); | ||
| 95 | compname=head()->compname; | ||
| 96 | remap_tabs(); | ||
| 97 | remap_recs(); | ||
| 98 | minor=head()->minor.get(); | ||
| 99 | } | ||
| 100 | |||
| 101 | void dbmap::Saveas(const mstring& path,int prot) throw(merror_t) | ||
| 102 | { | ||
| 103 | file->save(path,prot); | ||
| 104 | } | ||
| 105 | |||
| 106 | void dbmap::Close() | ||
| 107 | { | ||
| 108 | wok=0; | ||
| 109 | minor=0; | ||
| 110 | major=0; | ||
| 111 | fatal=0; | ||
| 112 | index=0; | ||
| 113 | compname.clear(); | ||
| 114 | recs.clear(); | ||
| 115 | tmap.clear(); | ||
| 116 | if(file) { | ||
| 117 | MLOCK(mutex); | ||
| 118 | if(file->reference()) file->popref(); | ||
| 119 | else { | ||
| 120 | if(flist==file) flist=file->next; | ||
| 121 | else for(filemap* p=flist;p;p=p->next) | ||
| 122 | if(p->next==file) { p->next=file->next; break; } | ||
| 123 | delete file; | ||
| 124 | } | ||
| 125 | file=0; | ||
| 126 | } | ||
| 127 | } | ||
| 128 | |||
| 129 | void dbmap::Sync() | ||
| 130 | { | ||
| 131 | MLOCK(mutex); | ||
| 132 | for(filemap* p=flist;p;p=p->next) { | ||
| 133 | if(p->writable()) p->sync(); | ||
| 134 | } | ||
| 135 | } | ||
| 136 | |||
| 137 | /////////////////////////////////////////////////////////////////////// | ||
| 138 | |||
| 139 | void dbmap::SetTable(int col,const sref& name) throw(merror_t) | ||
| 140 | { | ||
| 141 | check(); | ||
| 142 | if(!wok) THROW("db: cannot set table - readonly"); | ||
| 143 | if(col<0||col>=Tables()) THROW("db: bad column"); | ||
| 144 | HEADLOCK(file); | ||
| 145 | head()->set(col,name); | ||
| 146 | remap(); | ||
| 147 | } | ||
| 148 | |||
| 149 | void dbmap::InsertTable(int col,const sref& name) throw(merror_t) | ||
| 150 | { | ||
| 151 | check(); | ||
| 152 | if(!wok) THROW("db: cannot insert table - readonly"); | ||
| 153 | if(Tables()+1>file->maxtabs) THROW("db: too many tables"); | ||
| 154 | if(col<0||col>Tables()) THROW("db: bad column"); | ||
| 155 | { | ||
| 156 | HEADLOCK(file); | ||
| 157 | head()->insert(col,name); | ||
| 158 | int p=file->recs(); | ||
| 159 | while(file->size(p)) { | ||
| 160 | record_t* rec=(record_t*)file->at(p); | ||
| 161 | if(rec->caps.get()) rec->insert(col); | ||
| 162 | p+=rec->mem.get(); | ||
| 163 | } | ||
| 164 | head()->major.add(1); | ||
| 165 | } | ||
| 166 | index=head()->index.get(); | ||
| 167 | compname=head()->compname; | ||
| 168 | remap(); | ||
| 169 | } | ||
| 170 | |||
| 171 | void dbmap::RemTable(int col) throw(merror_t) | ||
| 172 | { | ||
| 173 | check(); | ||
| 174 | if(!wok) THROW("db: cannot remove table - readonly"); | ||
| 175 | if(col<0||col>=Tables()) THROW("db: bad column"); | ||
| 176 | if(col==head()->index.get()) THROW("db: cannot remove index table"); | ||
| 177 | { | ||
| 178 | HEADLOCK(file); | ||
| 179 | head()->remove(col); | ||
| 180 | int p=file->recs(); | ||
| 181 | while(file->size(p)) { | ||
| 182 | record_t* rec=(record_t*)file->at(p); | ||
| 183 | if(rec->caps.get()) rec->remove(col); | ||
| 184 | p+=rec->mem.get(); | ||
| 185 | } | ||
| 186 | head()->major.add(1); | ||
| 187 | } | ||
| 188 | index=head()->index.get(); | ||
| 189 | compname=head()->compname; | ||
| 190 | remap(); | ||
| 191 | } | ||
| 192 | |||
| 193 | /////////////////////////////////////////////////////////////////////// | ||
| 194 | |||
| 195 | void dbmap::Get(int row,spile& list) throw(merror_t) | ||
| 196 | { | ||
| 197 | check(); | ||
| 198 | if(row<0||row>=recs.size()) THROW("db: not a valid record"); | ||
| 199 | list.resize(Tables()); | ||
| 200 | recs[row].rec->get(list); | ||
| 201 | } | ||
| 202 | |||
| 203 | void dbmap::Set(int row,int col,const sref& s) throw(merror_t) | ||
| 204 | { | ||
| 205 | check(); | ||
| 206 | if(!wok) THROW("db: cannot set - readonly"); | ||
| 207 | if(row<0||row>=recs.size()) THROW("db: not a valid record"); | ||
| 208 | if(col==index) THROW("db: cannot set index"); | ||
| 209 | HEADLOCK(file); | ||
| 210 | record_t* rec=recs[row].rec; | ||
| 211 | int dim=rec->setreq(col,s); | ||
| 212 | if(dim>rec->caps.get()) { | ||
| 213 | rec=new(file->add(dim)) record_t(*rec); | ||
| 214 | file->rem(recs[row].rec); | ||
| 215 | recs[row].rec=rec; | ||
| 216 | head()->major.add(1); | ||
| 217 | major++; | ||
| 218 | } | ||
| 219 | rec->set(col,s); | ||
| 220 | head()->minor.add(1); | ||
| 221 | minor++; | ||
| 222 | } | ||
| 223 | |||
| 224 | void dbmap::Set(int row,const spile& list) throw(merror_t) | ||
| 225 | { | ||
| 226 | check(); | ||
| 227 | if(!wok) THROW("db: cannot set - readonly"); | ||
| 228 | if(row<0||row>=recs.size()) THROW("db: not a valid record"); | ||
| 229 | if(list.size()!=Tables()) | ||
| 230 | THROW("db: wrong number of tables - "<<list.size()<<" should be "<<Tables()); | ||
| 231 | HEADLOCK(file); | ||
| 232 | record_t* rec=recs[row].rec; | ||
| 233 | if(rec->at(index)!=list[index]) THROW("db: cannot set index"); | ||
| 234 | int dim=record_t::req(list); | ||
| 235 | if(dim>rec->caps.get()) { | ||
| 236 | rec=new(file->add(dim)) record_t(*rec); | ||
| 237 | file->rem(recs[row].rec); | ||
| 238 | recs[row].rec=rec; | ||
| 239 | head()->major.add(1); | ||
| 240 | major++; | ||
| 241 | } | ||
| 242 | rec->set(list); | ||
| 243 | head()->minor.add(1); | ||
| 244 | minor++; | ||
| 245 | } | ||
| 246 | |||
| 247 | /////////////////////////////////////////////////////////////////////// | ||
| 248 | |||
| 249 | void dbmap::Rem(int row) throw(merror_t) | ||
| 250 | { | ||
| 251 | if(!wok) THROW("db: cannot delete - readonly"); | ||
| 252 | if(row<0||row>=recs.size()) THROW("db: not a valid record"); | ||
| 253 | HEADLOCK(file); | ||
| 254 | file->rem(recs[row].rec); | ||
| 255 | recs.erase(recs.begin()+row); | ||
| 256 | head()->major.add(1); | ||
| 257 | major++; | ||
| 258 | } | ||
| 259 | |||
| 260 | int dbmap::Insert(const spile& list,int unique) throw(merror_t) | ||
| 261 | { | ||
| 262 | check(); | ||
| 263 | if(!wok) THROW("db: cannot insert - readonly"); | ||
| 264 | if(index!=head()->index.get()) | ||
| 265 | THROW("db: can only insert under normal order"); | ||
| 266 | HEADLOCK(file); | ||
| 267 | remap(); | ||
| 268 | int row=recs.get(list[index]); | ||
| 269 | if(row<0) { | ||
| 270 | record_t* rec=new(file->add(record_t::req(list))) record_t(list); | ||
| 271 | row=recs.add(rec->at(index),rec); | ||
| 272 | head()->major.add(1); | ||
| 273 | major++; | ||
| 274 | } | ||
| 275 | return row; | ||
| 276 | } | ||
diff --git a/src/hdb/db.h b/src/hdb/db.h new file mode 100644 index 0000000..6621944 --- /dev/null +++ b/src/hdb/db.h | |||
| @@ -0,0 +1,129 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef DBH | ||
| 21 | #define DBH | ||
| 22 | |||
| 23 | #include <hdb/sortable.h> | ||
| 24 | #include <mt/msmap.h> | ||
| 25 | |||
| 26 | //////////////////////////////////////////////////// | ||
| 27 | // | ||
| 28 | // OK for MT and MP | ||
| 29 | // | ||
| 30 | |||
| 31 | class dbmap { | ||
| 32 | public: | ||
| 33 | dbmap(); | ||
| 34 | ~dbmap(); | ||
| 35 | |||
| 36 | filemap::head_t* head() { return file->head(); } | ||
| 37 | const filemap::head_t* head() const { return file->head(); } | ||
| 38 | |||
| 39 | int remap(); | ||
| 40 | |||
| 41 | int size() const { return recs.size(); } | ||
| 42 | int empty() const { return recs.empty(); } | ||
| 43 | |||
| 44 | const sref operator()(int row,int col) const throw(merror_t) { | ||
| 45 | check(); return recs[row].rec->at(col); | ||
| 46 | } | ||
| 47 | const sref at(int row,int col) const throw(merror_t) { | ||
| 48 | check(); return recs[row].rec->at(col); | ||
| 49 | } | ||
| 50 | |||
| 51 | /////////////////////////////////////////////////////// | ||
| 52 | |||
| 53 | void Get(int row,spile& list) throw(merror_t); | ||
| 54 | void Set(int row,int col,const sref& s) throw(merror_t); | ||
| 55 | void Set(int row,const spile& list) throw(merror_t); | ||
| 56 | |||
| 57 | /////////////////////////////////////////////////////// | ||
| 58 | |||
| 59 | void Rem(int row) throw(merror_t); | ||
| 60 | int Insert(const spile& list,int unique) throw(merror_t); | ||
| 61 | |||
| 62 | /////////////////////////////////////////////////////// | ||
| 63 | |||
| 64 | int Tables() const { return head()->tables.get(); } | ||
| 65 | const sref Table(int col) const { check(); return head()->get(col); } | ||
| 66 | |||
| 67 | /////////////////////////////////////////////////////// | ||
| 68 | |||
| 69 | void SetTable(int col,const sref& name) throw(merror_t); | ||
| 70 | void RemTable(int col) throw(merror_t); | ||
| 71 | void InsertTable(int col,const sref& name) throw(merror_t); | ||
| 72 | |||
| 73 | /////////////////////////////////////////////////////// | ||
| 74 | |||
| 75 | int Index() const { return index; } | ||
| 76 | int FindIndex(const sref& tab) const { return tmap.get(tab); } | ||
| 77 | int Index(const sref& tab) const throw(merror_t) { | ||
| 78 | int p=FindIndex(tab); | ||
| 79 | if(p<0) THROW("db: table ["<<tab<<"] does not exist"); | ||
| 80 | return p; | ||
| 81 | } | ||
| 82 | |||
| 83 | /////////////////////////////////////////////////////// | ||
| 84 | |||
| 85 | const mstring& Compname() const { return compname; } | ||
| 86 | |||
| 87 | void Sort(const sref& tab,const sref& cmp) throw(merror_t); | ||
| 88 | void Order(const sref& tab,const sref& cmp) throw(merror_t); | ||
| 89 | |||
| 90 | int Find(const sref& key) const { return recs.get(key); } | ||
| 91 | |||
| 92 | /////////////////////////////////////////////////////// | ||
| 93 | |||
| 94 | void Open(const mstring& path,int update=0,int prot=0600) throw(merror_t); | ||
| 95 | void Saveas(const mstring& path,int prot=0600) throw(merror_t); | ||
| 96 | time_t Lastmod() const { return file->Lastmod(); } | ||
| 97 | void Close(); | ||
| 98 | |||
| 99 | static void Sync(); | ||
| 100 | |||
| 101 | protected: | ||
| 102 | dbmap(const dbmap& db) {} | ||
| 103 | void operator=(const dbmap& db) {} | ||
| 104 | |||
| 105 | void check() const { | ||
| 106 | if(fatal!=head()->fatal.get()) THROW("db: fatal state change") | ||
| 107 | } | ||
| 108 | |||
| 109 | void remap_recs(); | ||
| 110 | void remap_tabs(); | ||
| 111 | |||
| 112 | static void setup(); | ||
| 113 | static const op_t* CompOperator(const sref& s); | ||
| 114 | |||
| 115 | static filemap* flist; | ||
| 116 | static mutex_t mutex; | ||
| 117 | static opmap M; | ||
| 118 | private: | ||
| 119 | int wok,minor,major,fatal,index; | ||
| 120 | mstring compname; | ||
| 121 | filemap* file; | ||
| 122 | rimap tmap; | ||
| 123 | indexmap recs; | ||
| 124 | }; | ||
| 125 | |||
| 126 | void Convert(dbmap& db,const char* path); | ||
| 127 | |||
| 128 | #endif | ||
| 129 | |||
diff --git a/src/hdb/filemap.cc b/src/hdb/filemap.cc new file mode 100644 index 0000000..b40644f --- /dev/null +++ b/src/hdb/filemap.cc | |||
| @@ -0,0 +1,302 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <hdb/filemap.h> | ||
| 21 | #include <mt/split.h> | ||
| 22 | #include <fcntl.h> | ||
| 23 | #include <sys/stat.h> | ||
| 24 | #include <sys/mman.h> | ||
| 25 | #include <new> | ||
| 26 | using namespace std; | ||
| 27 | |||
| 28 | const int PAGESIZE=getpagesize(); | ||
| 29 | const filemap::char32 HEADNAME="HDB/1.2\n"; | ||
| 30 | const filemap::char32 COMPNAME="lt"; | ||
| 31 | const mstring dev_tag="/dev/"; | ||
| 32 | |||
| 33 | const int TIMEOUT=20; | ||
| 34 | |||
| 35 | /////////////////////////////////////////////////// | ||
| 36 | |||
| 37 | filemap::head_t::head_t() | ||
| 38 | { | ||
| 39 | memcpy(ident,HEADNAME,sizeof(char32)); | ||
| 40 | lock.set(0); | ||
| 41 | minor.set(0); | ||
| 42 | major.set(0); | ||
| 43 | fatal.set(0); | ||
| 44 | filesize.set(PAGESIZE); | ||
| 45 | filetop.set(sizeof(head_t)); | ||
| 46 | tables.set(0); | ||
| 47 | index.set(0); | ||
| 48 | memcpy(compname,COMPNAME,sizeof(char32)); | ||
| 49 | memset(tabs,0,maxtabs*sizeof(char32)); | ||
| 50 | frame.set(sizeof(head_t)); | ||
| 51 | } | ||
| 52 | |||
| 53 | filemap::head_t::head_t(const head_t* hd,int mem) | ||
| 54 | { | ||
| 55 | memcpy(ident,HEADNAME,sizeof(char32)); | ||
| 56 | lock.set(0); | ||
| 57 | minor.set(0); | ||
| 58 | major.set(0); | ||
| 59 | fatal.set(0); | ||
| 60 | filetop.set(sizeof(head_t)+mem); | ||
| 61 | filesize.set(PAGESIZE*int((filetop.get()+PAGESIZE)/PAGESIZE)); | ||
| 62 | tables=hd->tables; | ||
| 63 | index=hd->index; | ||
| 64 | memcpy(compname,hd->compname,sizeof(char32)); | ||
| 65 | memset(tabs,0,maxtabs*sizeof(char32)); | ||
| 66 | for(int i=0;i<tables.get();i++) | ||
| 67 | memcpy(tabs[i],hd->tabs[i],sizeof(char32)); | ||
| 68 | frame.set(sizeof(head_t)); | ||
| 69 | } | ||
| 70 | |||
| 71 | void filemap::head_t::setcomp(int idx,const sref& s) | ||
| 72 | { | ||
| 73 | index.set(idx); | ||
| 74 | s.copyto(compname,sizeof(char32)); | ||
| 75 | fatal.add(1); | ||
| 76 | } | ||
| 77 | |||
| 78 | void filemap::head_t::set(int col,const sref& s) | ||
| 79 | { | ||
| 80 | s.copyto(tabs[col],sizeof(char32)); | ||
| 81 | fatal.add(1); | ||
| 82 | } | ||
| 83 | |||
| 84 | void filemap::head_t::insert(int col,const sref& s) | ||
| 85 | { | ||
| 86 | for(int i=maxtabs-1;i>col;i--) | ||
| 87 | memcpy(tabs[i],tabs[i-1],sizeof(char32)); | ||
| 88 | if(index.get()>=col&&index.get()<tables.get()) | ||
| 89 | index.add(1); | ||
| 90 | s.copyto(tabs[col],sizeof(char32)); | ||
| 91 | tables.add(1); | ||
| 92 | fatal.add(1); | ||
| 93 | } | ||
| 94 | |||
| 95 | void filemap::head_t::remove(int col) | ||
| 96 | { | ||
| 97 | if(index.get()!=col) { | ||
| 98 | for(int i=col;i<maxtabs-1;i++) | ||
| 99 | memcpy(tabs[i],tabs[i+1],sizeof(char32)); | ||
| 100 | if(index.get()>col) index.set(index.get()-1); | ||
| 101 | tables.add(-1); | ||
| 102 | fatal.add(1); | ||
| 103 | } | ||
| 104 | } | ||
| 105 | |||
| 106 | /////////////////////////////////////////////////////// | ||
| 107 | |||
| 108 | filemap::chunk_t::chunk_t(chunk_t* p,int fd,int wok,int off,int size) | ||
| 109 | { | ||
| 110 | next=p; | ||
| 111 | end=(begin=off)+size; | ||
| 112 | map=(char*)mmap(0,size,PROT_READ|(wok?PROT_WRITE:0),MAP_SHARED,fd,off); | ||
| 113 | if(map==MAP_FAILED) { map=0; THROW("filemap: could not map chunk") } | ||
| 114 | } | ||
| 115 | |||
| 116 | filemap::chunk_t::~chunk_t() | ||
| 117 | { | ||
| 118 | if(map) munmap(map,end-begin); | ||
| 119 | } | ||
| 120 | |||
| 121 | int filemap::chunk_t::fill(int off) | ||
| 122 | { | ||
| 123 | if(own(off)) { | ||
| 124 | at(off)->mem.set(end-off); | ||
| 125 | at(off)->caps.set(0); | ||
| 126 | return end; | ||
| 127 | } | ||
| 128 | else return off; | ||
| 129 | } | ||
| 130 | |||
| 131 | void filemap::chunk_t::sync() | ||
| 132 | { | ||
| 133 | msync(map,end-begin,MS_SYNC); | ||
| 134 | } | ||
| 135 | |||
| 136 | /////////////////////////////////////////////////////// | ||
| 137 | |||
| 138 | void filemap::remap() | ||
| 139 | { | ||
| 140 | while(mem->end<hd->filesize.get()) { | ||
| 141 | mem=new chunk_t(mem,fd,wok,mem->end,mem->size()<<1); | ||
| 142 | } | ||
| 143 | } | ||
| 144 | |||
| 145 | filemap::rec_t* filemap::add(int n) | ||
| 146 | { | ||
| 147 | int caps=sizeof(rec_t),dim=caps+n; | ||
| 148 | while(caps<dim) caps<<=1; | ||
| 149 | remap(); | ||
| 150 | if(hd->filesize.get()<mem->end) { | ||
| 151 | ftruncate(fd,mem->end); | ||
| 152 | hd->filesize.set(mem->end); | ||
| 153 | } | ||
| 154 | while(hd->filetop.get()+caps>mem->end) { | ||
| 155 | hd->filetop.set(mem->fill(hd->filetop.get())); | ||
| 156 | mem=new chunk_t(mem,fd,wok,mem->end,mem->size()<<1); | ||
| 157 | ftruncate(fd,mem->end); | ||
| 158 | hd->filesize.set(mem->end); | ||
| 159 | } | ||
| 160 | rec_t* rec=at(hd->filetop.get()); | ||
| 161 | hd->filetop.add(caps); | ||
| 162 | rec->mem.set(caps); | ||
| 163 | rec->caps.set(n); | ||
| 164 | return rec; | ||
| 165 | } | ||
| 166 | |||
| 167 | void filemap::rem(rec_t* rec) | ||
| 168 | { | ||
| 169 | rec->caps.set(0); | ||
| 170 | } | ||
| 171 | |||
| 172 | /////////////////////////////////////////////////////// | ||
| 173 | |||
| 174 | filemap::filemap(filemap* p): | ||
| 175 | next(p),fd(-1),wok(0),refs(0),pathname(),hd(0),mem(0),nodelock(0) | ||
| 176 | { | ||
| 177 | memset(&mutex,0,sizeof(mutex_t)); | ||
| 178 | } | ||
| 179 | |||
| 180 | filemap::filemap(filemap* p,const mstring& path,int update,int prot): | ||
| 181 | next(p),fd(-1),wok(0),refs(0),pathname(),hd(0),mem(0),nodelock(0) | ||
| 182 | { | ||
| 183 | memset(&mutex,0,sizeof(mutex_t)); | ||
| 184 | open(path,update,prot); | ||
| 185 | } | ||
| 186 | |||
| 187 | filemap::~filemap() | ||
| 188 | { | ||
| 189 | close(); | ||
| 190 | } | ||
| 191 | |||
| 192 | /////////////////////////////////////////////////////// | ||
| 193 | |||
| 194 | void filemap::open(const mstring& path,int update,int prot) throw(merror_t) | ||
| 195 | { | ||
| 196 | close(); | ||
| 197 | if(update) { | ||
| 198 | if(path.left(5)!=dev_tag) nodelock=new nodelock_t(path); | ||
| 199 | else nodelock=0; | ||
| 200 | wok=1; | ||
| 201 | } | ||
| 202 | else { | ||
| 203 | nodelock=0; | ||
| 204 | wok=0; | ||
| 205 | } | ||
| 206 | fd=::open(path.c_str(),wok?O_RDWR|O_CREAT:O_RDONLY,prot); | ||
| 207 | if(fd<0) THROW("filemap: could not open "<<path); | ||
| 208 | int fsize=lseek(fd,0,SEEK_END); | ||
| 209 | int mapsize=PAGESIZE*int((fsize+PAGESIZE)/PAGESIZE); | ||
| 210 | hd=(head_t*)(mem=new chunk_t(0,fd,wok,0,mapsize))->map; | ||
| 211 | if(fsize<sizeof(head_t)) { | ||
| 212 | if(wok) { ftruncate(fd,fsize=mapsize); new(hd) head_t(); } | ||
| 213 | else THROW("filemap: not a HDB file"); | ||
| 214 | } | ||
| 215 | if(First(sref(hd->ident))!=First(sref(HEADNAME))) THROW("filemap: bad version"); | ||
| 216 | remap(); | ||
| 217 | if(fsize!=hd->filesize.get()) | ||
| 218 | THROW("filemap: "<<path<<" has bad filesize - run hdbfix"); | ||
| 219 | pathname=path; | ||
| 220 | } | ||
| 221 | |||
| 222 | void filemap::check() throw(merror_t) | ||
| 223 | { | ||
| 224 | // Make a consistency test, but NEVER change filetop!!! | ||
| 225 | // Severe loss of data may occur if you do | ||
| 226 | // Use hdbfix in case the db seems corrupted | ||
| 227 | int p=recs(),ft=hd->filetop.get(); | ||
| 228 | while(size(p)) { | ||
| 229 | rec_t* rec=at(p); | ||
| 230 | p+=rec->mem.get(); | ||
| 231 | } | ||
| 232 | if(p<ft) THROW("filemap: "<<pathname<<" is corrupted - run hdbfix"); | ||
| 233 | // OK, at least no data is missing. Usually p==ft, | ||
| 234 | // but since no locking is done here, another process | ||
| 235 | // may make changes that turn p>ft. | ||
| 236 | } | ||
| 237 | |||
| 238 | void filemap::save(const mstring& path,int prot) throw(merror_t) | ||
| 239 | { | ||
| 240 | if(path==pathname) THROW("filemap: cannot overwrite current file"); | ||
| 241 | int mfd=::open(path.c_str(),O_RDWR|O_CREAT|O_TRUNC,prot); | ||
| 242 | if(mfd<0) THROW("filemap: could not open "<<path<<" for writing"); | ||
| 243 | int caps=0,p=recs(); | ||
| 244 | while(size(p)) { | ||
| 245 | rec_t* rec=at(p); | ||
| 246 | if(rec->caps.get()) caps+=rec->mem.get(); | ||
| 247 | p+=rec->mem.get(); | ||
| 248 | } | ||
| 249 | head_t mhd(hd,caps); | ||
| 250 | ::write(mfd,&mhd,sizeof(head_t)); | ||
| 251 | p=recs(); | ||
| 252 | while(size(p)) { | ||
| 253 | rec_t* rec=at(p); | ||
| 254 | if(rec->caps.get()) ::write(mfd,rec,rec->mem.get()); | ||
| 255 | p+=rec->mem.get(); | ||
| 256 | } | ||
| 257 | ftruncate(mfd,mhd.filesize.get()); | ||
| 258 | ::close(mfd); | ||
| 259 | } | ||
| 260 | |||
| 261 | void filemap::close() | ||
| 262 | { | ||
| 263 | while(mem) { chunk_t* p=mem->next; delete mem; mem=p; } | ||
| 264 | hd=0; | ||
| 265 | wok=0; | ||
| 266 | refs=0; | ||
| 267 | if(fd>=0) { ::close(fd); fd=-1; } | ||
| 268 | delete nodelock; nodelock=0; | ||
| 269 | pathname.clear(); | ||
| 270 | } | ||
| 271 | |||
| 272 | void filemap::sync() | ||
| 273 | { | ||
| 274 | for(chunk_t* p=mem;p;p=p->next) p->sync(); | ||
| 275 | } | ||
| 276 | |||
| 277 | /////////////////////////////////////////////////////// | ||
| 278 | |||
| 279 | void filemap::lock() | ||
| 280 | { | ||
| 281 | if(hd) { | ||
| 282 | MLOCK(mutex); | ||
| 283 | if((volatile long&)hd->lock) { | ||
| 284 | time_t end=time(0)+TIMEOUT; | ||
| 285 | while((volatile long&)hd->lock&&time(0)<end); | ||
| 286 | } | ||
| 287 | hd->lock.set(1); | ||
| 288 | } | ||
| 289 | } | ||
| 290 | |||
| 291 | void filemap::unlock() | ||
| 292 | { | ||
| 293 | if(hd) hd->lock.set(0); | ||
| 294 | } | ||
| 295 | |||
| 296 | /////////////////////////////////////////////////////// | ||
| 297 | |||
| 298 | time_t filemap::Lastmod() const | ||
| 299 | { | ||
| 300 | struct stat fs; fstat(fd,&fs); return fs.st_mtime; | ||
| 301 | } | ||
| 302 | |||
diff --git a/src/hdb/filemap.h b/src/hdb/filemap.h new file mode 100644 index 0000000..d6af7eb --- /dev/null +++ b/src/hdb/filemap.h | |||
| @@ -0,0 +1,196 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef FILEMAPH | ||
| 21 | #define FILEMAPH | ||
| 22 | |||
| 23 | #include <mt/mstring.h> | ||
| 24 | #include <mt/lock.h> | ||
| 25 | #include <mt/mlock.h> | ||
| 26 | #include <mt/mlock.h> | ||
| 27 | #include <netinet/in.h> | ||
| 28 | |||
| 29 | ////////////////////////////////////////////// | ||
| 30 | // | ||
| 31 | // NOTE that filemap is MT unsafe: | ||
| 32 | // it needs to be called from dbmap | ||
| 33 | // | ||
| 34 | // The exception is when filelocking; | ||
| 35 | // that's MT safe per filemap, and hence | ||
| 36 | // should not be locked further | ||
| 37 | // | ||
| 38 | |||
| 39 | #define HEADLOCK(fm) headlock_t headlock(fm) | ||
| 40 | |||
| 41 | ////////////////////////////////////////////////////// | ||
| 42 | |||
| 43 | // network byteorder | ||
| 44 | class byte4 { | ||
| 45 | public: | ||
| 46 | byte4() {} // must be uninitialized | ||
| 47 | explicit byte4(int h): n(htonl(h)) {} | ||
| 48 | void set(int h) { n=htonl(h); } | ||
| 49 | void add(int h) { n=htonl(ntohl(n)+h); } | ||
| 50 | int get() const { return ntohl(n); } | ||
| 51 | private: | ||
| 52 | long n; | ||
| 53 | }; | ||
| 54 | |||
| 55 | ////////////////////////////////////////////////////// | ||
| 56 | |||
| 57 | class filemap { | ||
| 58 | public: | ||
| 59 | typedef char char32[32]; | ||
| 60 | static const int maxtabs=32; | ||
| 61 | |||
| 62 | //////////////////////////////////////////////////// | ||
| 63 | |||
| 64 | struct head_t { | ||
| 65 | char32 ident; | ||
| 66 | byte4 lock; | ||
| 67 | byte4 minor; | ||
| 68 | byte4 major; | ||
| 69 | byte4 fatal; | ||
| 70 | byte4 filesize; | ||
| 71 | byte4 filetop; | ||
| 72 | byte4 tables; | ||
| 73 | byte4 index; | ||
| 74 | char32 compname; | ||
| 75 | char32 tabs[maxtabs]; | ||
| 76 | byte4 frame; | ||
| 77 | |||
| 78 | head_t(); | ||
| 79 | head_t(const head_t* hd,int mem); | ||
| 80 | |||
| 81 | void setcomp(int idx, const sref& cp); | ||
| 82 | |||
| 83 | sref get(int col) const { return sref(tabs[col]); } | ||
| 84 | void set(int col,const sref& s); | ||
| 85 | void insert(int col,const sref& s); | ||
| 86 | void remove(int col); | ||
| 87 | }; | ||
| 88 | |||
| 89 | head_t* head() { return hd; } | ||
| 90 | const head_t* head() const { return hd; } | ||
| 91 | |||
| 92 | /////////////////////////////////////////////////////// | ||
| 93 | |||
| 94 | struct rec_t { | ||
| 95 | byte4 mem; | ||
| 96 | byte4 caps; | ||
| 97 | }; | ||
| 98 | |||
| 99 | rec_t* at(int off) { | ||
| 100 | for(chunk_t* p=mem;p;p=p->next) if(p->own(off)) return p->at(off); return 0; | ||
| 101 | } | ||
| 102 | const rec_t* at(int off) const { | ||
| 103 | for(const chunk_t* p=mem;p;p=p->next) if(p->own(off)) return p->at(off); | ||
| 104 | return 0; | ||
| 105 | } | ||
| 106 | |||
| 107 | int recs() const { return hd->frame.get(); } | ||
| 108 | int size(int off) const { | ||
| 109 | if(off<hd->filetop.get()) { | ||
| 110 | for(const chunk_t* p=mem;p;p=p->next) | ||
| 111 | if(p->own(off)) return p->at(off)->mem.get(); | ||
| 112 | } | ||
| 113 | return 0; | ||
| 114 | } | ||
| 115 | |||
| 116 | /////////////////////////////////////////////////////// | ||
| 117 | |||
| 118 | void remap(); | ||
| 119 | |||
| 120 | rec_t* add(int n); | ||
| 121 | void rem(rec_t* rec); | ||
| 122 | |||
| 123 | /////////////////////////////////////////////////////// | ||
| 124 | |||
| 125 | filemap(filemap* p); | ||
| 126 | filemap(filemap* p,const mstring& path,int update=0,int prot=0600); | ||
| 127 | ~filemap(); | ||
| 128 | |||
| 129 | filemap* next; | ||
| 130 | |||
| 131 | /////////////////////////////////////////////////////// | ||
| 132 | |||
| 133 | void open(const mstring& path,int update=0,int prot=0600) throw(merror_t); | ||
| 134 | void save(const mstring& path,int prot=0600) throw(merror_t); | ||
| 135 | void check() throw(merror_t); | ||
| 136 | void close(); | ||
| 137 | void sync(); | ||
| 138 | |||
| 139 | const mstring& Pathname() const { return pathname; } | ||
| 140 | time_t Lastmod() const; | ||
| 141 | |||
| 142 | int reference() const { return refs; } | ||
| 143 | int writable() const { return wok; } | ||
| 144 | |||
| 145 | void pushref() { refs++; } | ||
| 146 | void popref() { refs--; } | ||
| 147 | |||
| 148 | /////////////////////////////////////////////////////// | ||
| 149 | |||
| 150 | void lock(); | ||
| 151 | void unlock(); | ||
| 152 | |||
| 153 | /////////////////////////////////////////////////////// | ||
| 154 | |||
| 155 | protected: | ||
| 156 | struct chunk_t { | ||
| 157 | chunk_t* next; | ||
| 158 | long begin; | ||
| 159 | long end; | ||
| 160 | char* map; | ||
| 161 | |||
| 162 | int size() const { return end-begin; } | ||
| 163 | |||
| 164 | chunk_t(chunk_t* p,int fd,int wok,int off,int size); | ||
| 165 | ~chunk_t(); | ||
| 166 | |||
| 167 | int own(int off) const { return off>=begin&&off<end; } | ||
| 168 | void sync(); | ||
| 169 | |||
| 170 | rec_t* at(int off) { return (rec_t*)(map+(off-begin)); } | ||
| 171 | const rec_t* at(int off) const { return (rec_t*)(map+(off-begin)); } | ||
| 172 | |||
| 173 | int fill(int off); | ||
| 174 | }; | ||
| 175 | private: | ||
| 176 | int fd,wok,refs; | ||
| 177 | mstring pathname; | ||
| 178 | head_t* hd; | ||
| 179 | chunk_t* mem; | ||
| 180 | mutex_t mutex; | ||
| 181 | nodelock_t* nodelock; | ||
| 182 | private: | ||
| 183 | filemap(const filemap&) {} | ||
| 184 | void operator=(const filemap&) {} | ||
| 185 | }; | ||
| 186 | |||
| 187 | ////////////////////////////////////////////////////// | ||
| 188 | |||
| 189 | struct headlock_t { | ||
| 190 | filemap* fm; | ||
| 191 | headlock_t(filemap* f) : fm(f) { fm->lock(); } | ||
| 192 | ~headlock_t() { if(fm) fm->unlock(); } | ||
| 193 | }; | ||
| 194 | |||
| 195 | #endif | ||
| 196 | |||
diff --git a/src/hdb/hdbcvt.cc b/src/hdb/hdbcvt.cc new file mode 100644 index 0000000..ece70f0 --- /dev/null +++ b/src/hdb/hdbcvt.cc | |||
| @@ -0,0 +1,50 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <hdb/db.h> | ||
| 21 | #include <mt/lock.h> | ||
| 22 | |||
| 23 | static fp_stream mout(stdout),merr(stderr); | ||
| 24 | |||
| 25 | main(int argc,char* argv[]) throw(merror_t) try | ||
| 26 | { | ||
| 27 | if(argc<2) { | ||
| 28 | merr<<"Usage: "<<argv[0]<<" <db> [<index> <cp>]\n"; | ||
| 29 | return -1; | ||
| 30 | } | ||
| 31 | mstring newfile=argv[1]; | ||
| 32 | mstring oldfile=newfile+sref(".bak"); | ||
| 33 | rename(newfile.c_str(),oldfile.c_str()); | ||
| 34 | dbmap db; | ||
| 35 | try { | ||
| 36 | db.Open(oldfile); | ||
| 37 | if(argc>3) db.Sort(sref(argv[2]),sref(argv[3])); | ||
| 38 | db.Saveas(newfile); | ||
| 39 | } | ||
| 40 | catch(const merror_t& e) { | ||
| 41 | merr<<"Opened as newfile, old version\n"; | ||
| 42 | db.Open(newfile,1); | ||
| 43 | Convert(db,oldfile.c_str()); | ||
| 44 | } | ||
| 45 | return 0; | ||
| 46 | } | ||
| 47 | catch(const merror_t& e) { | ||
| 48 | merr<<e.desc<<"\n"; | ||
| 49 | return -1; | ||
| 50 | } | ||
diff --git a/src/hdb/hdbfix.cc b/src/hdb/hdbfix.cc new file mode 100644 index 0000000..b82f151 --- /dev/null +++ b/src/hdb/hdbfix.cc | |||
| @@ -0,0 +1,140 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <hdb/db.h> | ||
| 21 | |||
| 22 | static fp_stream mout(stdout),merr(stderr); | ||
| 23 | |||
| 24 | main(int argc,char* argv[]) try | ||
| 25 | { | ||
| 26 | if(argc<2) { | ||
| 27 | mout<<"Usage: "<<argv[0]<<" [-s] <path>\n"; | ||
| 28 | return -1; | ||
| 29 | } | ||
| 30 | mstring path; int silent; | ||
| 31 | if(argc>2) { silent=1; path=argv[2]; } | ||
| 32 | else { silent=0; path=argv[1]; } | ||
| 33 | mstring map; if(map.load(path)<0) THROW("hdbfix: could not open "<<path); | ||
| 34 | filemap::head_t head; | ||
| 35 | mstring version=First(sref(head.ident,sizeof(head.ident))); | ||
| 36 | memcpy(&head,map.data(),sizeof(head)); | ||
| 37 | mstring cver=First(sref(head.ident,sizeof(head.ident))); | ||
| 38 | mstring answer; | ||
| 39 | int save=0; | ||
| 40 | if(version!=cver) { | ||
| 41 | merr<<path<<": Not a "<<version<<" file\n"; | ||
| 42 | return -1; | ||
| 43 | } | ||
| 44 | else { | ||
| 45 | int top=head.frame.get(),last=0; | ||
| 46 | while(top<head.filetop.get()&&top<map.size()) { | ||
| 47 | filemap::rec_t* rec=(filemap::rec_t*)(map.data()+top); | ||
| 48 | if(rec->mem.get()<=0) { | ||
| 49 | if(!silent&&rec->mem.get()<0) | ||
| 50 | mout<<"ending mem: "<<rec->mem.get()<<"\n"; | ||
| 51 | break; | ||
| 52 | } | ||
| 53 | last=top; | ||
| 54 | top+=rec->mem.get(); | ||
| 55 | } | ||
| 56 | if(top==head.filetop.get()&&head.filesize.get()==map.size()) { | ||
| 57 | if(!silent) mout<<path<<": OK\n"; | ||
| 58 | } | ||
| 59 | else { | ||
| 60 | mout<<path<<": CORRUPTED\n"; | ||
| 61 | if(silent) return 0; | ||
| 62 | mout<<"\n"; | ||
| 63 | mout<<"Head info:\n"; | ||
| 64 | mout<<"Size: "<<head.filesize.get()<<"\n"; | ||
| 65 | mout<<"Frame: "<<head.frame.get()<<"\n"; | ||
| 66 | mout<<"Top: "<<head.filetop.get()<<"\n"; | ||
| 67 | mout<<"\n"; | ||
| 68 | |||
| 69 | mout<<"Actual sizes:\n"; | ||
| 70 | mout<<"Size: "<<map.size()<<"\n"; | ||
| 71 | mout<<"Last: "<<last<<"\n"; | ||
| 72 | mout<<"End: "<<top<<"\n"; | ||
| 73 | mout<<"\n"; | ||
| 74 | |||
| 75 | if(map.size()!=head.filesize.get()) { | ||
| 76 | mout<<"Filesizes differ - do you want to set the filesize to " | ||
| 77 | <<head.filesize.get()<<"?\n"; | ||
| 78 | getline(answer,stdin); answer.tolower(); | ||
| 79 | if(*answer=='y') { | ||
| 80 | map.resize(head.filesize.get()); | ||
| 81 | save=1; | ||
| 82 | mout<<"Done.\n"; | ||
| 83 | } | ||
| 84 | else { | ||
| 85 | mout<<"No change - quitting.\n"; | ||
| 86 | return 0; | ||
| 87 | } | ||
| 88 | } | ||
| 89 | |||
| 90 | int nend=0,end=head.filetop.get(); | ||
| 91 | for(int p=head.filetop.get()-4;p>=last;p-=4){ | ||
| 92 | int val=ntohl(*(long*)(map.data()+p)); | ||
| 93 | if(p+val==end) { nend++; end=p; } | ||
| 94 | } | ||
| 95 | int gap=end-top; | ||
| 96 | |||
| 97 | mout<<"GAP DATA\n"; | ||
| 98 | mout<<"==============================\n"; | ||
| 99 | for(int i=top;i<end;i++) { | ||
| 100 | if(cset_printable.test(map[i])) mout.put(map[i]); | ||
| 101 | else mout<<"["<<(int)map[i]<<"]"; | ||
| 102 | } | ||
| 103 | mout<<"\n==============================\n"; | ||
| 104 | mout<<"\n"; | ||
| 105 | |||
| 106 | mout<<"At-end sequence:\n"; | ||
| 107 | mout<<"Start: "<<end<<"\n"; | ||
| 108 | mout<<"Gap: "<<gap<<"\n"; | ||
| 109 | mout<<"\n"; | ||
| 110 | |||
| 111 | if(gap>0) { | ||
| 112 | mout<<"Do you want to mark the gap as deleted?\n"; | ||
| 113 | getline(answer,stdin); answer.tolower(); | ||
| 114 | if(*answer=='y') { | ||
| 115 | filemap::rec_t* rec=(filemap::rec_t*)(map.data()+top); | ||
| 116 | rec->mem.set(gap); | ||
| 117 | rec->caps.set(0); | ||
| 118 | save=1; | ||
| 119 | mout<<"Done.\n"; | ||
| 120 | } | ||
| 121 | else { | ||
| 122 | mout<<"No change - quitting.\n"; | ||
| 123 | return 0; | ||
| 124 | } | ||
| 125 | } | ||
| 126 | } | ||
| 127 | } | ||
| 128 | |||
| 129 | if(save) map.save(path); | ||
| 130 | |||
| 131 | return 0; | ||
| 132 | } | ||
| 133 | catch(const merror_t& e) { | ||
| 134 | merr<<e.desc<<"\n"; | ||
| 135 | return -1; | ||
| 136 | } | ||
| 137 | catch(...) { | ||
| 138 | merr<<"FATAL ERROR\n"; | ||
| 139 | return -1; | ||
| 140 | } | ||
diff --git a/src/hdb/hdbtest.cc b/src/hdb/hdbtest.cc new file mode 100644 index 0000000..89169da --- /dev/null +++ b/src/hdb/hdbtest.cc | |||
| @@ -0,0 +1,153 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <hdb/db.h> | ||
| 21 | |||
| 22 | static fp_stream mout(stdout),merr(stderr); | ||
| 23 | |||
| 24 | main(int argc,char* argv[]) try | ||
| 25 | { | ||
| 26 | if(argc<2) { | ||
| 27 | mout<<"Usage: "<<argv[0]<<" [-s] <path>\n"; | ||
| 28 | return -1; | ||
| 29 | } | ||
| 30 | mstring path; int silent; | ||
| 31 | if(argc>2) { silent=atoi(argv[1]); path=argv[2]; } | ||
| 32 | else { silent=0; path=argv[1]; } | ||
| 33 | mstring map; if(map.load(path)<0) THROW("hdbfix: could not open "<<path); | ||
| 34 | filemap::head_t head; | ||
| 35 | mstring version=First(sref(head.ident,sizeof(head.ident))); | ||
| 36 | memcpy(&head,map.data(),sizeof(head)); | ||
| 37 | mstring cver=First(sref(head.ident,sizeof(head.ident))); | ||
| 38 | mstring answer; | ||
| 39 | int save=0; | ||
| 40 | if(version!=cver) { | ||
| 41 | merr<<path<<": Not a "<<version<<" file\n"; | ||
| 42 | return -1; | ||
| 43 | } | ||
| 44 | else { | ||
| 45 | int top=head.frame.get(),last=0; | ||
| 46 | while(top<head.filetop.get()&&top<map.size()) { | ||
| 47 | filemap::rec_t* rec=(filemap::rec_t*)(map.data()+top); | ||
| 48 | if(rec->mem.get()<=0) break; | ||
| 49 | if(silent) { | ||
| 50 | if(silent==top) { | ||
| 51 | mout<<top<<" *************\n"; | ||
| 52 | for(int i=0;i<65536;i++) { | ||
| 53 | char c=map.data()[top+i]; | ||
| 54 | if(cset_printable.test(c)) mout.put(c); | ||
| 55 | } | ||
| 56 | mout<<"\n\n"; | ||
| 57 | } | ||
| 58 | } | ||
| 59 | else { | ||
| 60 | mout<<top<<" *************\n"; | ||
| 61 | for(int i=0;i<1024;i++) { | ||
| 62 | char c=map.data()[top+i]; | ||
| 63 | if(cset_printable.test(c)) mout.put(c); | ||
| 64 | } | ||
| 65 | mout<<"\n\n"; | ||
| 66 | } | ||
| 67 | last=top; top+=rec->mem.get(); | ||
| 68 | } | ||
| 69 | if(top==head.filetop.get()&&head.filesize.get()==map.size()) { | ||
| 70 | if(!silent) mout<<path<<": OK\n"; | ||
| 71 | } | ||
| 72 | else { | ||
| 73 | mout<<path<<": CORRUPTED\n"; | ||
| 74 | if(silent) return 0; | ||
| 75 | mout<<"\n"; | ||
| 76 | mout<<"Head info:\n"; | ||
| 77 | mout<<"Size: "<<head.filesize.get()<<"\n"; | ||
| 78 | mout<<"Frame: "<<head.frame.get()<<"\n"; | ||
| 79 | mout<<"Top: "<<head.filetop.get()<<"\n"; | ||
| 80 | mout<<"\n"; | ||
| 81 | |||
| 82 | mout<<"Actual sizes:\n"; | ||
| 83 | mout<<"Size: "<<map.size()<<"\n"; | ||
| 84 | mout<<"Last: "<<last<<"\n"; | ||
| 85 | mout<<"End: "<<top<<"\n"; | ||
| 86 | mout<<"\n"; | ||
| 87 | |||
| 88 | if(map.size()!=head.filesize.get()) { | ||
| 89 | mout<<"Filesizes differ - do you want to set the filesize to " | ||
| 90 | <<head.filesize.get()<<"?\n"; | ||
| 91 | getline(answer,stdin); answer.tolower(); | ||
| 92 | if(*answer=='y') { | ||
| 93 | map.resize(head.filesize.get()); | ||
| 94 | save=1; | ||
| 95 | mout<<"Done.\n"; | ||
| 96 | } | ||
| 97 | else { | ||
| 98 | mout<<"No change - quitting.\n"; | ||
| 99 | return 0; | ||
| 100 | } | ||
| 101 | } | ||
| 102 | |||
| 103 | int nend=0,end=head.filetop.get(); | ||
| 104 | for(int p=head.filetop.get()-4;p>=last;p-=4){ | ||
| 105 | unsigned val=*(unsigned*)(map.data()+p); | ||
| 106 | if(p+val==end) { nend++; end=p; } | ||
| 107 | } | ||
| 108 | int gap=end-top; | ||
| 109 | |||
| 110 | mout<<"GAP DATA\n"; | ||
| 111 | mout<<"==============================\n"; | ||
| 112 | for(int i=top;i<end;i++) { | ||
| 113 | if(cset_printable.test(map[i])) mout.put(map[i]); | ||
| 114 | else if(map[i]) mout<<"["<<(int)map[i]<<"]"; | ||
| 115 | } | ||
| 116 | mout<<"\n==============================\n"; | ||
| 117 | mout<<"\n"; | ||
| 118 | |||
| 119 | mout<<"At-end sequence:\n"; | ||
| 120 | mout<<"Start: "<<end<<"\n"; | ||
| 121 | mout<<"Gap: "<<gap<<"\n"; | ||
| 122 | mout<<"\n"; | ||
| 123 | |||
| 124 | if(gap>0) { | ||
| 125 | mout<<"Do you want to mark the gap as deleted?\n"; | ||
| 126 | getline(answer,stdin); answer.tolower(); | ||
| 127 | if(*answer=='y') { | ||
| 128 | filemap::rec_t* rec=(filemap::rec_t*)(map.data()+top); | ||
| 129 | rec->mem.set(gap); | ||
| 130 | rec->caps.set(0); | ||
| 131 | save=1; | ||
| 132 | mout<<"Done.\n"; | ||
| 133 | } | ||
| 134 | else { | ||
| 135 | mout<<"No change - quitting.\n"; | ||
| 136 | return 0; | ||
| 137 | } | ||
| 138 | } | ||
| 139 | } | ||
| 140 | } | ||
| 141 | |||
| 142 | if(save) map.save(path); | ||
| 143 | |||
| 144 | return 0; | ||
| 145 | } | ||
| 146 | catch(const merror_t& e) { | ||
| 147 | merr<<e.desc<<"\n"; | ||
| 148 | return -1; | ||
| 149 | } | ||
| 150 | catch(...) { | ||
| 151 | merr<<"FATAL ERROR\n"; | ||
| 152 | return -1; | ||
| 153 | } | ||
diff --git a/src/hdb/sortable.cc b/src/hdb/sortable.cc new file mode 100644 index 0000000..39adf58 --- /dev/null +++ b/src/hdb/sortable.cc | |||
| @@ -0,0 +1,81 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <hdb/sortable.h> | ||
| 21 | #include <algorithm> | ||
| 22 | using namespace std; | ||
| 23 | |||
| 24 | int int_stream::appc(char c) { return val=c,1; } | ||
| 25 | int int_stream::appi(int i) { return val=i,1; } | ||
| 26 | int int_stream::appf(double f) { return val=(int)f,1; } | ||
| 27 | int int_stream::apps(const sref& s) { return val=atoi(s),s.size(); } | ||
| 28 | |||
| 29 | /////////////////////////////////////////////////// | ||
| 30 | |||
| 31 | record_t::record_t(const spile& list) | ||
| 32 | { | ||
| 33 | pos[0].set(0); | ||
| 34 | for(int i=0;i<list.size();i++) { | ||
| 35 | memcpy(data+pos[i].get(),list[i].data(),list[i].size()); | ||
| 36 | pos[i+1].set(pos[i].get()+list[i].size()); | ||
| 37 | } | ||
| 38 | for(int i=list.size();i<maxtabs;i++) pos[i+1]=pos[i]; | ||
| 39 | } | ||
| 40 | |||
| 41 | void record_t::set(const spile& list) | ||
| 42 | { | ||
| 43 | pos[0].set(0); | ||
| 44 | for(int i=0;i<list.size();i++) { | ||
| 45 | memcpy(data+pos[i].get(),list[i].data(),list[i].size()); | ||
| 46 | pos[i+1].set(pos[i].get()+list[i].size()); | ||
| 47 | } | ||
| 48 | for(int i=list.size();i<maxtabs;i++) pos[i+1]=pos[i]; | ||
| 49 | } | ||
| 50 | |||
| 51 | void record_t::resize(int col,int n) | ||
| 52 | { | ||
| 53 | int delta=n+pos[col].get()-pos[col+1].get(); | ||
| 54 | if(delta) { | ||
| 55 | memmove(data+pos[col+1].get()+delta,data+pos[col+1].get(), | ||
| 56 | pos[maxtabs].get()-pos[col+1].get()); | ||
| 57 | for(int i=col+1;i<=maxtabs;i++) pos[i].add(delta); | ||
| 58 | } | ||
| 59 | } | ||
| 60 | |||
| 61 | /////////////////////////////////////////////////// | ||
| 62 | |||
| 63 | int indexmap::get(const sref& t) const | ||
| 64 | { | ||
| 65 | pair<const_iterator,const_iterator> p=equal_range(begin(),end(),idx_t(t,0),comp); | ||
| 66 | return p.first!=p.second?p.first-begin():-1; | ||
| 67 | } | ||
| 68 | |||
| 69 | int indexmap::add(const sref& t,record_t* rec) | ||
| 70 | { | ||
| 71 | idx_t tmp(t,rec); | ||
| 72 | pair<iterator,iterator> p=equal_range(begin(),end(),tmp,comp); | ||
| 73 | if(p.first!=p.second) return &(*p.first=tmp)-begin(); | ||
| 74 | else return insert(p.second,tmp)-begin(); | ||
| 75 | } | ||
| 76 | |||
| 77 | void indexmap::sort(const op_t* op) | ||
| 78 | { | ||
| 79 | comp.func=op->f2; | ||
| 80 | ::sort(begin(),end(),comp); | ||
| 81 | } | ||
diff --git a/src/hdb/sortable.h b/src/hdb/sortable.h new file mode 100644 index 0000000..7de0aa8 --- /dev/null +++ b/src/hdb/sortable.h | |||
| @@ -0,0 +1,138 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef SORTABLEH | ||
| 21 | #define SORTABLEH | ||
| 22 | |||
| 23 | #include <hdb/filemap.h> | ||
| 24 | #include <ops/express.h> | ||
| 25 | #include <mt/mset.h> | ||
| 26 | |||
| 27 | //////////////////////////////////////////////////// | ||
| 28 | // | ||
| 29 | // NOTE that these classes are not MT safe: | ||
| 30 | // need to be called from dbamp | ||
| 31 | // | ||
| 32 | |||
| 33 | struct record_t : public filemap::rec_t { | ||
| 34 | static const int maxtabs=filemap::maxtabs; | ||
| 35 | static const int recsize=(maxtabs+1)*sizeof(long); | ||
| 36 | |||
| 37 | byte4 pos[maxtabs+1]; | ||
| 38 | char data[sizeof(byte4)]; | ||
| 39 | |||
| 40 | int size() const { return pos[maxtabs].get()-pos[0].get(); } | ||
| 41 | int size(int i) const { return pos[i+1].get()-pos[i].get(); } | ||
| 42 | |||
| 43 | sref at(int i) const { return sref(data+pos[i].get(),size(i)); } | ||
| 44 | |||
| 45 | ///////////////////////////////////////////////// | ||
| 46 | |||
| 47 | record_t(const record_t& rec) { | ||
| 48 | for(int i=0;i<=maxtabs;i++) pos[i]=rec.pos[i]; | ||
| 49 | memcpy(data,rec.data,rec.caps.get()); | ||
| 50 | } | ||
| 51 | record_t(const spile& list); | ||
| 52 | |||
| 53 | ///////////////////////////////////////////////// | ||
| 54 | |||
| 55 | void get(spile& list) const { | ||
| 56 | for(int i=0;i<list.size();i++) list[i]=at(i); | ||
| 57 | } | ||
| 58 | |||
| 59 | ///////////////////////////////////////////////// | ||
| 60 | |||
| 61 | int setreq(int col,const sref& s) const { | ||
| 62 | return recsize+size()+s.size()-size(col); | ||
| 63 | } | ||
| 64 | inline static int req(const spile& list) { | ||
| 65 | int n=0; for(int i=0;i<list.size();i++) n+=list[i].size(); | ||
| 66 | return recsize+n; | ||
| 67 | } | ||
| 68 | |||
| 69 | ///////////////////////////////////////////////// | ||
| 70 | |||
| 71 | void set(int col,const sref& s) { | ||
| 72 | resize(col,s.size()); | ||
| 73 | memcpy(data+pos[col].get(),s.data(),s.size()); | ||
| 74 | } | ||
| 75 | |||
| 76 | void set(const spile& list); | ||
| 77 | |||
| 78 | ///////////////////////////////////////////////// | ||
| 79 | |||
| 80 | void insert(int col) { | ||
| 81 | for(int i=maxtabs;i>col;i--) pos[i]=pos[i-1]; | ||
| 82 | } | ||
| 83 | void remove(int col) { | ||
| 84 | resize(col,0); | ||
| 85 | for(int i=col;i<maxtabs;i++) pos[i]=pos[i+1]; | ||
| 86 | } | ||
| 87 | |||
| 88 | ///////////////////////////////////////////////// | ||
| 89 | |||
| 90 | void resize(int col,int n); | ||
| 91 | |||
| 92 | }; | ||
| 93 | |||
| 94 | //////////////////////////////////////////////////////////////////// | ||
| 95 | |||
| 96 | struct int_stream : public mstream { | ||
| 97 | int val; | ||
| 98 | |||
| 99 | int_stream() : val(0) {} | ||
| 100 | |||
| 101 | int appc(char c); | ||
| 102 | int appi(int i); | ||
| 103 | int appf(double f); | ||
| 104 | int apps(const sref& s); | ||
| 105 | }; | ||
| 106 | |||
| 107 | //////////////////////////////////////////////////////////////////// | ||
| 108 | |||
| 109 | struct idx_t { | ||
| 110 | sref key; record_t* rec; | ||
| 111 | idx_t(const sref& t,record_t* p) : key(t),rec(p) {} | ||
| 112 | }; | ||
| 113 | |||
| 114 | class indexmap : public mrvec<idx_t> { | ||
| 115 | public: | ||
| 116 | typedef mrvec<idx_t>::iterator iterator; | ||
| 117 | typedef mrvec<idx_t>::const_iterator const_iterator; | ||
| 118 | |||
| 119 | struct comp_t { | ||
| 120 | op_t::op2_t func; | ||
| 121 | comp_t() : func(0) {} | ||
| 122 | comp_t(const op_t* op) : func(op->f2) {} | ||
| 123 | bool operator()(const idx_t& a,const idx_t& b) const { | ||
| 124 | int_stream res; | ||
| 125 | op_env env; | ||
| 126 | func(res,env,a.key,b.key); | ||
| 127 | return res.val; | ||
| 128 | } | ||
| 129 | }; | ||
| 130 | |||
| 131 | int get(const sref& t) const; | ||
| 132 | int add(const sref& t,record_t* rec); | ||
| 133 | void sort(const op_t* op); | ||
| 134 | private: | ||
| 135 | comp_t comp; | ||
| 136 | }; | ||
| 137 | |||
| 138 | #endif | ||
diff --git a/src/hdb/test.cc b/src/hdb/test.cc new file mode 100644 index 0000000..b8d335b --- /dev/null +++ b/src/hdb/test.cc | |||
| @@ -0,0 +1,52 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <hdb/db.h> | ||
| 21 | |||
| 22 | static fp_stream merr(stderr); | ||
| 23 | |||
| 24 | main(int argc,char* argv[]) throw(merror_t) try | ||
| 25 | { | ||
| 26 | if(argc<2) { | ||
| 27 | merr<<"Usage: "<<argv[0]<<" <path>\n"; | ||
| 28 | return -1; | ||
| 29 | } | ||
| 30 | dbmap m; | ||
| 31 | m.Open(argv[1]); | ||
| 32 | |||
| 33 | merr<<m.head()->filesize.get()<<"\n"; | ||
| 34 | merr<<m.head()->filetop.get()<<"\n"; | ||
| 35 | merr<<m.head()->frame.get()<<"\n"; | ||
| 36 | |||
| 37 | for(int j=0;j<m.Tables();j++) merr<<m.Table(j)<<" "; | ||
| 38 | merr<<"\n\n"; | ||
| 39 | |||
| 40 | for(int i=0;i<m.size();i++) { | ||
| 41 | //for(int j=0;j<m.Tables();j++) merr<<m(i,j)<<" "; | ||
| 42 | for(int j=0;j<1;j++) merr<<m(i,j)<<" "; | ||
| 43 | |||
| 44 | merr<<"\n"; | ||
| 45 | } | ||
| 46 | |||
| 47 | return 0; | ||
| 48 | } | ||
| 49 | catch(const merror_t& e) { | ||
| 50 | merr<<e.desc<<"\n"; | ||
| 51 | return -1; | ||
| 52 | } | ||
diff --git a/src/hed/edit.cc b/src/hed/edit.cc new file mode 100644 index 0000000..b38b1e9 --- /dev/null +++ b/src/hed/edit.cc | |||
| @@ -0,0 +1,262 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <hed/edit.h> | ||
| 21 | #include <hed/input.h> | ||
| 22 | #include <string.h> | ||
| 23 | #include <malloc.h> | ||
| 24 | |||
| 25 | const mstring end_tag="~"; | ||
| 26 | |||
| 27 | Editor::Line::Line() | ||
| 28 | { | ||
| 29 | line=(char*)malloc(MAXCOLS); | ||
| 30 | line[0]=0; | ||
| 31 | dim=1; | ||
| 32 | } | ||
| 33 | Editor::Line::Line(char* p,int s) | ||
| 34 | { | ||
| 35 | line=(char*)malloc(MAXCOLS); | ||
| 36 | memcpy(line,p,s); | ||
| 37 | dim=s; | ||
| 38 | } | ||
| 39 | Editor::Line::~Line() | ||
| 40 | { | ||
| 41 | delete line; | ||
| 42 | } | ||
| 43 | int Editor::Line::Insert(int pos,char c) | ||
| 44 | { | ||
| 45 | if(pos>=dim) pos=dim-1; | ||
| 46 | if(dim<MAXCOLS) { | ||
| 47 | memmove(line+pos+1,line+pos,dim-pos); | ||
| 48 | line[pos]=c; | ||
| 49 | dim++; | ||
| 50 | return 1; | ||
| 51 | } | ||
| 52 | else return 0; | ||
| 53 | } | ||
| 54 | int Editor::Line::Append(const Line* p) | ||
| 55 | { | ||
| 56 | if(dim-1+p->dim<=MAXCOLS) { | ||
| 57 | memcpy(line+dim-1,p->line,p->dim); | ||
| 58 | dim+=p->dim-1; | ||
| 59 | return 1; | ||
| 60 | } | ||
| 61 | else return 0; | ||
| 62 | } | ||
| 63 | Editor::Line* Editor::Line::Break(int pos) | ||
| 64 | { | ||
| 65 | if(pos>=dim) pos=dim-1; | ||
| 66 | Line* p=new Line(line+pos,dim-pos); | ||
| 67 | line[pos]=0; | ||
| 68 | dim=pos+1; | ||
| 69 | return p; | ||
| 70 | } | ||
| 71 | void Editor::Line::Delete(int pos) | ||
| 72 | { | ||
| 73 | if(dim-1>pos) { | ||
| 74 | memmove(line+pos,line+pos+1,dim-pos-1); | ||
| 75 | dim--; | ||
| 76 | } | ||
| 77 | } | ||
| 78 | |||
| 79 | ///////////////////////////////////////////////////////////////////////// | ||
| 80 | |||
| 81 | Editor::Editor(const mstring& s,int ex) : | ||
| 82 | path(s), | ||
| 83 | from(0),lines(Lines()),atline(0),size(0), | ||
| 84 | tab(0),cols(Columns()),atcol(0),exclusive(ex) | ||
| 85 | { | ||
| 86 | memset(map,0,sizeof(Line*)*MAXLINES); | ||
| 87 | map[0]=new Line(); | ||
| 88 | size=1; | ||
| 89 | caption=path; | ||
| 90 | caption+=sref(" ok (ESC to go back)"); | ||
| 91 | if(!exclusive) caption+=sref(" (readonly)"); | ||
| 92 | } | ||
| 93 | Editor::~Editor() | ||
| 94 | { | ||
| 95 | for(int i=0;i<size;i++) delete map[i]; | ||
| 96 | } | ||
| 97 | |||
| 98 | void Editor::Show() | ||
| 99 | { | ||
| 100 | ClearScreen(); | ||
| 101 | for(int i=from;i<from+lines&&i<size;i++) { | ||
| 102 | if(tab<map[i]->dim) { | ||
| 103 | if(i==size-1) { | ||
| 104 | if(tab<map[i]->dim-1) | ||
| 105 | OutputField(i-from,0,cols,sref(map[i]->line+tab,map[i]->dim-tab-1)); | ||
| 106 | OutputField(i-from,map[i]->dim-tab-1,1,end_tag); | ||
| 107 | } | ||
| 108 | else { | ||
| 109 | OutputField(i-from,0,cols,sref(map[i]->line+tab,map[i]->dim-tab)); | ||
| 110 | } | ||
| 111 | } | ||
| 112 | } | ||
| 113 | Reverse(1); | ||
| 114 | OutputField(lines,0,cols,caption); | ||
| 115 | Reverse(0); | ||
| 116 | MoveCursor(atline-from,atcol-tab); | ||
| 117 | Refresh(); | ||
| 118 | } | ||
| 119 | |||
| 120 | void Editor::Move(int i,int j) | ||
| 121 | { | ||
| 122 | atline+=i; | ||
| 123 | atcol+=j; | ||
| 124 | if(atline<0) atline=0; else if(atline>=size) atline=size-1; | ||
| 125 | if(atline<from) from=atline; else if(atline>=from+lines) from=atline+1-lines; | ||
| 126 | if(atcol<0) atcol=0; else if(atcol>=map[atline]->dim) atcol=map[atline]->dim-1; | ||
| 127 | if(atcol<tab) tab=atcol; else if(atcol>=tab+cols) tab=atcol+1-cols; | ||
| 128 | } | ||
| 129 | |||
| 130 | void Editor::Home() | ||
| 131 | { | ||
| 132 | atline=from=atcol=tab=0; | ||
| 133 | } | ||
| 134 | |||
| 135 | void Editor::Navigate() | ||
| 136 | { | ||
| 137 | int c; | ||
| 138 | while(1) { | ||
| 139 | Show(); | ||
| 140 | switch(c=Input()) { | ||
| 141 | case KK_UP: | ||
| 142 | case 16: | ||
| 143 | Move(-1,0); | ||
| 144 | break; | ||
| 145 | case KK_DOWN: | ||
| 146 | case 14: | ||
| 147 | Move(1,0); | ||
| 148 | break; | ||
| 149 | case KK_LEFT: | ||
| 150 | case 2: | ||
| 151 | Move(0,-1); break; | ||
| 152 | case KK_RIGHT: | ||
| 153 | case 6: | ||
| 154 | Move(0,1); | ||
| 155 | break; | ||
| 156 | case KK_NPAGE: | ||
| 157 | Move(lines/2,0); | ||
| 158 | break; | ||
| 159 | case KK_PPAGE: | ||
| 160 | Move(-lines/2,0); | ||
| 161 | break; | ||
| 162 | case KK_HOME: | ||
| 163 | case 1: | ||
| 164 | Move(0,-map[atline]->dim); | ||
| 165 | break; | ||
| 166 | case KK_END: | ||
| 167 | case 5: | ||
| 168 | Move(0,map[atline]->dim); | ||
| 169 | break; | ||
| 170 | case 127: | ||
| 171 | case 4: | ||
| 172 | if(exclusive) Delete(); | ||
| 173 | break; | ||
| 174 | case 8: | ||
| 175 | if(exclusive) Backspace(); | ||
| 176 | break; | ||
| 177 | case 13: | ||
| 178 | if(exclusive) BreakLine(); | ||
| 179 | break; | ||
| 180 | case KK_F(1): | ||
| 181 | if(exclusive) Insert('å'); | ||
| 182 | break; | ||
| 183 | case KK_F(2): | ||
| 184 | if(exclusive) Insert('ä'); | ||
| 185 | break; | ||
| 186 | case KK_F(3): | ||
| 187 | if(exclusive) Insert('ö'); | ||
| 188 | break; | ||
| 189 | case 9: | ||
| 190 | if(exclusive) Insert('\t'); | ||
| 191 | break; | ||
| 192 | default: | ||
| 193 | if(exclusive) if(c>=32&&c<127) Insert(c); | ||
| 194 | break; | ||
| 195 | case 27: | ||
| 196 | return; | ||
| 197 | } | ||
| 198 | } | ||
| 199 | } | ||
| 200 | |||
| 201 | void Editor::Insert(int c) | ||
| 202 | { | ||
| 203 | if(map[atline]->Insert(atcol,c)) Move(0,1); | ||
| 204 | } | ||
| 205 | |||
| 206 | void Editor::BreakLine() | ||
| 207 | { | ||
| 208 | if(size<MAXLINES) { | ||
| 209 | Line* p=map[atline]->Break(atcol); | ||
| 210 | memmove(map+atline+2,map+atline+1,sizeof(Line*)*(size-atline-1)); | ||
| 211 | map[atline+1]=p; | ||
| 212 | size++; | ||
| 213 | Move(1,-atcol); | ||
| 214 | } | ||
| 215 | } | ||
| 216 | |||
| 217 | void Editor::Delete() | ||
| 218 | { | ||
| 219 | if(map[atline]->dim-1>atcol) { | ||
| 220 | map[atline]->Delete(atcol); | ||
| 221 | } | ||
| 222 | else if(size-1>atline) { | ||
| 223 | delete map[atline]; | ||
| 224 | memmove(map+atline,map+atline+1,sizeof(Line*)*(size-atline-1)); | ||
| 225 | size--; | ||
| 226 | } | ||
| 227 | } | ||
| 228 | |||
| 229 | void Editor::Backspace() | ||
| 230 | { | ||
| 231 | if(atcol>0) { | ||
| 232 | Move(0,-1); | ||
| 233 | map[atline]->Delete(atcol); | ||
| 234 | } | ||
| 235 | else if(atline>0) { | ||
| 236 | int pos=map[atline-1]->dim-1; | ||
| 237 | if(map[atline-1]->Append(map[atline])) { | ||
| 238 | delete map[atline]; | ||
| 239 | memmove(map+atline,map+atline+1,sizeof(Line*)*(size-atline-1)); | ||
| 240 | size--; | ||
| 241 | Move(-1,pos-atcol); | ||
| 242 | } | ||
| 243 | } | ||
| 244 | } | ||
| 245 | |||
| 246 | void Editor::Paste(const mstring& s) | ||
| 247 | { | ||
| 248 | for(int i=0;i<s.size();i++) { | ||
| 249 | if(s[i]=='\n') BreakLine(); | ||
| 250 | else if(s[i]!='\r') Insert(s[i]); | ||
| 251 | } | ||
| 252 | Home(); | ||
| 253 | } | ||
| 254 | |||
| 255 | void Editor::Copy(mstring& s) | ||
| 256 | { | ||
| 257 | s.clear(); | ||
| 258 | for(int i=0;i<size;i++) { | ||
| 259 | s+=sref(map[i]->line,map[i]->dim-1); | ||
| 260 | if(i<size-1) s+='\n'; | ||
| 261 | } | ||
| 262 | } | ||
diff --git a/src/hed/edit.h b/src/hed/edit.h new file mode 100644 index 0000000..e6ae437 --- /dev/null +++ b/src/hed/edit.h | |||
| @@ -0,0 +1,61 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef EDITH | ||
| 21 | #define EDITH | ||
| 22 | |||
| 23 | #include <mt/mstring.h> | ||
| 24 | |||
| 25 | struct Editor { | ||
| 26 | static const int MAXLINES=1024; | ||
| 27 | static const int MAXCOLS=256; | ||
| 28 | struct Line { | ||
| 29 | Line(); | ||
| 30 | Line(char* p,int s); | ||
| 31 | ~Line(); | ||
| 32 | int Insert(int pos,char c); | ||
| 33 | int Append(const Line* p); | ||
| 34 | Line* Break(int pos); | ||
| 35 | void Delete(int pos); | ||
| 36 | char* line; | ||
| 37 | int dim; | ||
| 38 | }; | ||
| 39 | |||
| 40 | Editor(const mstring& path,int ex); | ||
| 41 | ~Editor(); | ||
| 42 | |||
| 43 | void Copy(mstring& s); | ||
| 44 | void Paste(const mstring& s); | ||
| 45 | |||
| 46 | void Show(); | ||
| 47 | void Home(); | ||
| 48 | void Move(int i,int j); | ||
| 49 | void Navigate(); | ||
| 50 | void Insert(int c); | ||
| 51 | void BreakLine(); | ||
| 52 | void Delete(); | ||
| 53 | void Backspace(); | ||
| 54 | |||
| 55 | mstring path,caption; | ||
| 56 | Line* map[MAXLINES]; | ||
| 57 | int from,lines,atline,size; | ||
| 58 | int tab,cols,atcol,exclusive; | ||
| 59 | }; | ||
| 60 | |||
| 61 | #endif | ||
diff --git a/src/hed/hed.cc b/src/hed/hed.cc new file mode 100644 index 0000000..dc469cc --- /dev/null +++ b/src/hed/hed.cc | |||
| @@ -0,0 +1,56 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include "tables.h" | ||
| 21 | #include "input.h" | ||
| 22 | #include <unistd.h> | ||
| 23 | |||
| 24 | static fp_stream merr(stderr); | ||
| 25 | |||
| 26 | main(int argc,char* argv[]) | ||
| 27 | { | ||
| 28 | if(argc<2) { | ||
| 29 | merr<<"Usage: "<<argv[0]<<" <hdb> [exclusive]\n"; | ||
| 30 | return -1; | ||
| 31 | } | ||
| 32 | char* path=argv[1]; | ||
| 33 | int excl=argc>2?atoi(argv[2]):0; | ||
| 34 | mstring err; | ||
| 35 | sleep(1); | ||
| 36 | InitCurses(); | ||
| 37 | Tables tab; | ||
| 38 | try { | ||
| 39 | tab.Open(path,excl); | ||
| 40 | tab.Setup(20); | ||
| 41 | tab.Navigate(); | ||
| 42 | } | ||
| 43 | catch(const merror_t& e) { | ||
| 44 | err=e.desc; | ||
| 45 | } | ||
| 46 | catch(...) { | ||
| 47 | err="hdb: Unexpected error"; | ||
| 48 | } | ||
| 49 | tab.Close(); | ||
| 50 | EndCurses(); | ||
| 51 | if(err.nempty()) { | ||
| 52 | merr<<err<<"\n"; | ||
| 53 | sleep(2); | ||
| 54 | } | ||
| 55 | return 0; | ||
| 56 | } | ||
diff --git a/src/hed/input.cc b/src/hed/input.cc new file mode 100644 index 0000000..4f2b008 --- /dev/null +++ b/src/hed/input.cc | |||
| @@ -0,0 +1,107 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <hed/input.h> | ||
| 21 | #include <mt/mstring.h> | ||
| 22 | #include <unistd.h> | ||
| 23 | #include <poll.h> | ||
| 24 | #include <curses.h> | ||
| 25 | |||
| 26 | int Lines() { return LINES-1; } | ||
| 27 | int Columns() { return COLS-1; } | ||
| 28 | |||
| 29 | void ClearScreen() { erase(); } | ||
| 30 | void MoveCursor(int i,int j) { move(i,j); } | ||
| 31 | |||
| 32 | void InitCurses() | ||
| 33 | { | ||
| 34 | initscr(); | ||
| 35 | nodelay(stdscr,1); | ||
| 36 | raw(); | ||
| 37 | noecho(); | ||
| 38 | nonl(); | ||
| 39 | keypad(stdscr,1); | ||
| 40 | intrflush(stdscr,FALSE); | ||
| 41 | } | ||
| 42 | |||
| 43 | void EndCurses() | ||
| 44 | { | ||
| 45 | endwin(); | ||
| 46 | } | ||
| 47 | |||
| 48 | void OutputField(int row,int col,int field,const sref& in) | ||
| 49 | { | ||
| 50 | mstring tmp=in.left_first_of(cset_newl); | ||
| 51 | int cut=tmp.size()!=in.size(); | ||
| 52 | if(tmp.size()<field) tmp.append(field-tmp.size(),' '); | ||
| 53 | if(cut||in.size()>field) { tmp.resize(field-1); tmp.append(1,'\\'); } | ||
| 54 | mvaddstr(row,col,(char*)tmp.c_str()); | ||
| 55 | } | ||
| 56 | |||
| 57 | void Reverse(int n) | ||
| 58 | { | ||
| 59 | if(n) attron(A_REVERSE); else attroff(A_REVERSE); | ||
| 60 | } | ||
| 61 | void Bold(int n) | ||
| 62 | { | ||
| 63 | if(n) attron(A_BOLD); else attroff(A_BOLD); | ||
| 64 | } | ||
| 65 | |||
| 66 | void Refresh() | ||
| 67 | { | ||
| 68 | refresh(); | ||
| 69 | } | ||
| 70 | |||
| 71 | int RawInput() { | ||
| 72 | int c=getch(); | ||
| 73 | if(c>0) return c; | ||
| 74 | struct pollfd ps={fileno(stdin),POLLIN,0}; | ||
| 75 | poll(&ps,1,1000); | ||
| 76 | return getch(); | ||
| 77 | } | ||
| 78 | |||
| 79 | int Input() { | ||
| 80 | int c=RawInput(); | ||
| 81 | #if 0 | ||
| 82 | if(c==27) { | ||
| 83 | napms(1); | ||
| 84 | int c2=getch(); | ||
| 85 | if(c2!=-1) { | ||
| 86 | switch(c2) { | ||
| 87 | default: return 0; | ||
| 88 | case 91: | ||
| 89 | switch(RawInput()) { | ||
| 90 | default: return 0; | ||
| 91 | case '2': | ||
| 92 | RawInput(); | ||
| 93 | switch(RawInput()) { | ||
| 94 | default: return 0; | ||
| 95 | case 52: return RawInput()==122?KEY_HOME:0; | ||
| 96 | case 54: return RawInput()==122?KEY_PPAGE:0; | ||
| 97 | case 48: return RawInput()==122?KEY_END:0; | ||
| 98 | case 50: return RawInput()==122?KEY_NPAGE:0; | ||
| 99 | } | ||
| 100 | } | ||
| 101 | } | ||
| 102 | } | ||
| 103 | } | ||
| 104 | #endif | ||
| 105 | return c; | ||
| 106 | } | ||
| 107 | |||
diff --git a/src/hed/input.h b/src/hed/input.h new file mode 100644 index 0000000..76071ce --- /dev/null +++ b/src/hed/input.h | |||
| @@ -0,0 +1,52 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <mt/stringref.h> | ||
| 21 | |||
| 22 | #ifndef INPUTH | ||
| 23 | #define INPUTH | ||
| 24 | |||
| 25 | #define KK_DOWN 0402 | ||
| 26 | #define KK_UP 0403 | ||
| 27 | #define KK_LEFT 0404 | ||
| 28 | #define KK_RIGHT 0405 | ||
| 29 | #define KK_HOME 0406 | ||
| 30 | #define KK_F0 0410 | ||
| 31 | #define KK_F(n) (KK_F0+(n)) | ||
| 32 | #define KK_NPAGE 0522 | ||
| 33 | #define KK_PPAGE 0523 | ||
| 34 | #define KK_END 0550 | ||
| 35 | |||
| 36 | int Input(); | ||
| 37 | int RawInput(); | ||
| 38 | |||
| 39 | int Lines(); | ||
| 40 | int Columns(); | ||
| 41 | |||
| 42 | void ClearScreen(); | ||
| 43 | void MoveCursor(int i,int j); | ||
| 44 | void OutputField(int row,int col,int field,const sref& p); | ||
| 45 | void Reverse(int n); | ||
| 46 | void Bold(int n); | ||
| 47 | void Refresh(); | ||
| 48 | |||
| 49 | void InitCurses(); | ||
| 50 | void EndCurses(); | ||
| 51 | |||
| 52 | #endif | ||
diff --git a/src/hed/tables.cc b/src/hed/tables.cc new file mode 100644 index 0000000..c489e6f --- /dev/null +++ b/src/hed/tables.cc | |||
| @@ -0,0 +1,442 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include "tables.h" | ||
| 21 | #include "input.h" | ||
| 22 | #include <string.h> | ||
| 23 | #include <malloc.h> | ||
| 24 | #include <stdio.h> | ||
| 25 | |||
| 26 | const mstring star_tag="*"; | ||
| 27 | |||
| 28 | const int PAD=2; | ||
| 29 | const mstring HELP= | ||
| 30 | "Commands from record page:\n" | ||
| 31 | "\n" | ||
| 32 | "DEL - Delete record\n" | ||
| 33 | "RET - Edit record\n" | ||
| 34 | "n - New record\n" | ||
| 35 | "s - Sort by table\n" | ||
| 36 | "o - Order by table\n" | ||
| 37 | "c - Check for duplicates\n" | ||
| 38 | "f - Filename for map\n" | ||
| 39 | "r - Remove table\n" | ||
| 40 | "a - Add table\n"; | ||
| 41 | |||
| 42 | Tables::Tables() : | ||
| 43 | from(0),lines(Lines()-1),atline(0),writable(0), | ||
| 44 | tab(0),space(10),cols(Columns()),atcol(0), | ||
| 45 | lastfrom(-1),lasttab(-1),lastline(0),lastcol(0) | ||
| 46 | { | ||
| 47 | dispcols=cols/space; | ||
| 48 | } | ||
| 49 | |||
| 50 | Tables::~Tables() | ||
| 51 | { | ||
| 52 | } | ||
| 53 | |||
| 54 | void Tables::Setup(int sp) | ||
| 55 | { | ||
| 56 | space=sp; | ||
| 57 | dispcols=cols/space; | ||
| 58 | Home(); | ||
| 59 | } | ||
| 60 | |||
| 61 | void Tables::Show() | ||
| 62 | { | ||
| 63 | if(db.remap()) { | ||
| 64 | lastfrom=-1; | ||
| 65 | caption.convert("%d, %d, %d, %d", | ||
| 66 | db.head()->filesize.get(), | ||
| 67 | db.head()->fatal.get(), | ||
| 68 | db.head()->major.get(), | ||
| 69 | db.head()->minor.get()); | ||
| 70 | } | ||
| 71 | if(from!=lastfrom||tab!=lasttab) { | ||
| 72 | ClearScreen(); | ||
| 73 | Bold(1); | ||
| 74 | for(int j=tab;j<tab+dispcols&&j<db.Tables();j++) { | ||
| 75 | if(j==db.Index()) { | ||
| 76 | OutputField(0,space*(j-tab),space-PAD-1,db.Table(j)); | ||
| 77 | OutputField(0,space*(j-tab)+space-PAD-1,1,star_tag); | ||
| 78 | } | ||
| 79 | else { | ||
| 80 | OutputField(0,space*(j-tab),space-PAD,db.Table(j)); | ||
| 81 | } | ||
| 82 | } | ||
| 83 | Bold(0); | ||
| 84 | for(int i=from;i<from+lines&&i<=db.size();i++) { | ||
| 85 | for(int j=tab;j<tab+dispcols&&j<=db.Tables();j++) { | ||
| 86 | sref tmp; if(i<db.size()&&j<db.Tables()) tmp=db(i,j); | ||
| 87 | if(i==atline&&j==atcol) Reverse(1); else Reverse(0); | ||
| 88 | OutputField(i+1-from,space*(j-tab),space-PAD,tmp); | ||
| 89 | if(i==atline&&j==atcol) Reverse(0); | ||
| 90 | } | ||
| 91 | } | ||
| 92 | Reverse(1); | ||
| 93 | OutputField(lines+1,1,cols-1,caption); | ||
| 94 | Reverse(0); | ||
| 95 | } | ||
| 96 | else { | ||
| 97 | int i=lastline,j=lastcol; | ||
| 98 | if(i>=0&&i<=db.size()&&j>=0&&j<=db.Tables()) { | ||
| 99 | sref tmp; if(i<db.size()&&j<db.Tables()) tmp=db(i,j); | ||
| 100 | OutputField(i+1-from,space*(j-tab),space-PAD,tmp); | ||
| 101 | } | ||
| 102 | i=atline; j=atcol; | ||
| 103 | if(i>=0&&i<=db.size()&&j>=0&&j<=db.Tables()) { | ||
| 104 | sref tmp; if(i<db.size()&&j<db.Tables()) tmp=db(i,j); | ||
| 105 | Reverse(1); | ||
| 106 | OutputField(i+1-from,space*(j-tab),space-PAD,tmp); | ||
| 107 | Reverse(0); | ||
| 108 | } | ||
| 109 | } | ||
| 110 | MoveCursor(lines+1,0); | ||
| 111 | Refresh(); | ||
| 112 | lastline=atline; | ||
| 113 | lastcol=atcol; | ||
| 114 | lastfrom=from; | ||
| 115 | lasttab=tab; | ||
| 116 | } | ||
| 117 | |||
| 118 | void Tables::Home() | ||
| 119 | { | ||
| 120 | atline=atcol=from=tab=0; | ||
| 121 | } | ||
| 122 | |||
| 123 | void Tables::Move(int i,int j) | ||
| 124 | { | ||
| 125 | atline+=i; | ||
| 126 | if(atline>=db.size()) atline=db.size(); | ||
| 127 | if(atline<0) atline=0; | ||
| 128 | if(atline>=from+lines) from=atline+1-lines; | ||
| 129 | if(atline<from) from=atline; | ||
| 130 | atcol+=j; | ||
| 131 | if(atcol>=db.Tables()) atcol=db.Tables(); | ||
| 132 | if(atcol<0) atcol=0; | ||
| 133 | if(atcol>=tab+dispcols) tab=atcol+1-dispcols; | ||
| 134 | if(atcol<tab) tab=atcol; | ||
| 135 | } | ||
| 136 | |||
| 137 | void Tables::Insert() | ||
| 138 | { | ||
| 139 | if(db.remap()) lastfrom=-1; | ||
| 140 | if(db.Tables()==0) return; | ||
| 141 | mstring tx,key,ttab=db.Table(db.Index()); | ||
| 142 | tx.convert("%s - insert %s",path.c_str(),ttab.c_str()); | ||
| 143 | Editor edit(tx,1); | ||
| 144 | edit.Paste(""); | ||
| 145 | edit.Navigate(); | ||
| 146 | edit.Copy(key); | ||
| 147 | int row=-1; | ||
| 148 | try { | ||
| 149 | spile list(db.Tables()); | ||
| 150 | list[db.Index()]=key; | ||
| 151 | row=db.Insert(list,1); | ||
| 152 | if(row>=0) { | ||
| 153 | caption.convert("%s - added record",path.c_str()); | ||
| 154 | Move(row-atline,0); | ||
| 155 | } | ||
| 156 | else { | ||
| 157 | caption.convert("%s - record nonunique - not added",path.c_str()); | ||
| 158 | Move(0,0); | ||
| 159 | } | ||
| 160 | } | ||
| 161 | catch(const merror_t& e) { | ||
| 162 | caption=e.desc; | ||
| 163 | Move(0,0); | ||
| 164 | } | ||
| 165 | lastfrom=-1; | ||
| 166 | } | ||
| 167 | |||
| 168 | void Tables::Delete() | ||
| 169 | { | ||
| 170 | if(db.remap()) lastfrom=-1; | ||
| 171 | if(atline<db.size()) { | ||
| 172 | db.Rem(atline); | ||
| 173 | Move(0,0); | ||
| 174 | lastfrom=-1; | ||
| 175 | } | ||
| 176 | } | ||
| 177 | |||
| 178 | void Tables::Navigate() | ||
| 179 | { | ||
| 180 | int c; | ||
| 181 | while(1) { | ||
| 182 | Show(); | ||
| 183 | switch(c=Input()) { | ||
| 184 | case KK_UP: | ||
| 185 | case 16: | ||
| 186 | Move(-1,0); | ||
| 187 | break; | ||
| 188 | case KK_DOWN: | ||
| 189 | case 14: | ||
| 190 | Move(1,0); | ||
| 191 | break; | ||
| 192 | case KK_LEFT: | ||
| 193 | case 2: | ||
| 194 | Move(0,-1); break; | ||
| 195 | case KK_RIGHT: | ||
| 196 | case 6: | ||
| 197 | case 9: | ||
| 198 | Move(0,1); | ||
| 199 | break; | ||
| 200 | case KK_NPAGE: | ||
| 201 | Move(lines/2,0); | ||
| 202 | break; | ||
| 203 | case KK_PPAGE: | ||
| 204 | Move(-lines/2,0); | ||
| 205 | break; | ||
| 206 | case KK_HOME: | ||
| 207 | case 1: | ||
| 208 | Move(0,-db.Tables()); | ||
| 209 | break; | ||
| 210 | case KK_END: | ||
| 211 | case 5: | ||
| 212 | Move(0,db.Tables()); | ||
| 213 | break; | ||
| 214 | case 127: | ||
| 215 | case 4: | ||
| 216 | if(writable) Delete(); | ||
| 217 | break; | ||
| 218 | case 13: | ||
| 219 | Edit(); | ||
| 220 | break; | ||
| 221 | case 's': | ||
| 222 | Sort(); | ||
| 223 | break; | ||
| 224 | case 'o': | ||
| 225 | if(writable) Order(); | ||
| 226 | break; | ||
| 227 | case 'c': | ||
| 228 | Check(); | ||
| 229 | break; | ||
| 230 | case 'f': | ||
| 231 | FileName(); | ||
| 232 | break; | ||
| 233 | case 'r': | ||
| 234 | if(writable) RemTable(); | ||
| 235 | break; | ||
| 236 | case 'a': | ||
| 237 | if(writable) AddTable(); | ||
| 238 | break; | ||
| 239 | case 'n': | ||
| 240 | if(writable) Insert(); | ||
| 241 | break; | ||
| 242 | case 27: | ||
| 243 | if(Command()) break; | ||
| 244 | else return; | ||
| 245 | } | ||
| 246 | |||
| 247 | } | ||
| 248 | } | ||
| 249 | |||
| 250 | int Tables::Command() | ||
| 251 | { | ||
| 252 | mstring tmp=caption; | ||
| 253 | caption="q (quit), s (save), h (help)"; | ||
| 254 | lastfrom=-1; | ||
| 255 | Show(); | ||
| 256 | switch(Input()) { | ||
| 257 | case 'q': | ||
| 258 | return 0; | ||
| 259 | case 's': | ||
| 260 | Save(); | ||
| 261 | break; | ||
| 262 | case 'h': | ||
| 263 | Help(); | ||
| 264 | break; | ||
| 265 | default: | ||
| 266 | caption=tmp; | ||
| 267 | break; | ||
| 268 | } | ||
| 269 | lastfrom=-1; | ||
| 270 | return 1; | ||
| 271 | } | ||
| 272 | |||
| 273 | void Tables::Help() | ||
| 274 | { | ||
| 275 | Editor edit("help",0); | ||
| 276 | edit.Paste(HELP); | ||
| 277 | edit.Navigate(); | ||
| 278 | lastfrom=-1; | ||
| 279 | } | ||
| 280 | |||
| 281 | void Tables::Edit() | ||
| 282 | { | ||
| 283 | if(db.remap()) lastfrom=-1; | ||
| 284 | if(atline<db.size()&&atcol<db.Tables()) { | ||
| 285 | mstring tx; | ||
| 286 | tx.convert("%s - (%d,%d)",path.c_str(),atline+1,atcol+1); | ||
| 287 | Editor edit(tx,writable&&atcol!=db.Index()); | ||
| 288 | edit.Paste(db(atline,atcol)); | ||
| 289 | edit.Navigate(); | ||
| 290 | edit.Copy(tx); | ||
| 291 | try { | ||
| 292 | if(writable) db.Set(atline,atcol,tx); | ||
| 293 | caption=path; | ||
| 294 | caption+=sref(" edited."); | ||
| 295 | } | ||
| 296 | catch(const merror_t& e) { | ||
| 297 | caption=e.desc; | ||
| 298 | } | ||
| 299 | catch(...) { | ||
| 300 | } | ||
| 301 | Move(0,0); | ||
| 302 | lastfrom=-1; | ||
| 303 | } | ||
| 304 | } | ||
| 305 | |||
| 306 | void Tables::Sort() | ||
| 307 | { | ||
| 308 | if(db.remap()) lastfrom=-1; | ||
| 309 | if(atline<=db.size()&&atcol<db.Tables()) { | ||
| 310 | mstring tx=db.Compname(); | ||
| 311 | Editor edit("compname",1); | ||
| 312 | edit.Paste(tx); | ||
| 313 | edit.Navigate(); | ||
| 314 | edit.Copy(tx); | ||
| 315 | db.Sort(db.Table(atcol),tx); | ||
| 316 | mstring ttab=db.Table(db.Index()); | ||
| 317 | caption.convert("%s sorted: %s %s",path.c_str(),ttab.c_str(),tx.c_str()); | ||
| 318 | Move(0,0); | ||
| 319 | lastfrom=-1; | ||
| 320 | } | ||
| 321 | } | ||
| 322 | |||
| 323 | void Tables::Order() | ||
| 324 | { | ||
| 325 | if(db.remap()) lastfrom=-1; | ||
| 326 | if(atline<=db.size()&&atcol<db.Tables()) { | ||
| 327 | mstring tx=db.Compname(); | ||
| 328 | Editor edit("compname",1); | ||
| 329 | edit.Paste(tx); | ||
| 330 | edit.Navigate(); | ||
| 331 | edit.Copy(tx); | ||
| 332 | db.Order(db.Table(atcol),tx); | ||
| 333 | mstring ttab=db.Table(db.Index()); | ||
| 334 | caption.convert("%s ordered: %s %s",path.c_str(),ttab.c_str(),tx.c_str()); | ||
| 335 | Move(0,0); | ||
| 336 | lastfrom=-1; | ||
| 337 | } | ||
| 338 | } | ||
| 339 | |||
| 340 | void Tables::Check() | ||
| 341 | { | ||
| 342 | if(db.remap()) lastfrom=-1; | ||
| 343 | int idx=db.Index(); | ||
| 344 | mswrite mm; | ||
| 345 | for(int i=0;i<db.size()-1;i++) { | ||
| 346 | if(db(i,idx)==db(i+1,idx)) mm<<db(i,idx)<<" duplicated\n"; | ||
| 347 | } | ||
| 348 | if(mm.str().empty()) mm<<"Nothing duplicated\n"; | ||
| 349 | Editor edit("check",0); | ||
| 350 | edit.Paste(mm.str()); | ||
| 351 | edit.Navigate(); | ||
| 352 | lastfrom=-1; | ||
| 353 | } | ||
| 354 | |||
| 355 | void Tables::FileName() | ||
| 356 | { | ||
| 357 | if(db.remap()) lastfrom=-1; | ||
| 358 | mstring tx; tx.convert("%s - filename",path.c_str()); | ||
| 359 | Editor edit(tx,1); | ||
| 360 | tx.convert("%s",path.c_str()); | ||
| 361 | edit.Paste(tx); | ||
| 362 | edit.Navigate(); | ||
| 363 | edit.Copy(tx); | ||
| 364 | path=tx; | ||
| 365 | lastfrom=-1; | ||
| 366 | } | ||
| 367 | |||
| 368 | void Tables::AddTable() | ||
| 369 | { | ||
| 370 | if(db.remap()) lastfrom=-1; | ||
| 371 | mstring tx; | ||
| 372 | tx.convert("%s - add table (def: 2nd line)",path.c_str()); | ||
| 373 | Editor edit(tx,1); | ||
| 374 | edit.Paste(""); | ||
| 375 | edit.Navigate(); | ||
| 376 | mstring tb; | ||
| 377 | edit.Copy(tb); | ||
| 378 | sref first,rest=tb; | ||
| 379 | Splitln(first,rest); | ||
| 380 | mstring name=first; | ||
| 381 | Splitln(first,rest); | ||
| 382 | int ok=-db.Tables(); | ||
| 383 | db.InsertTable(atcol,name); | ||
| 384 | ok+=db.Tables(); | ||
| 385 | if(ok) { | ||
| 386 | Move(0,0); | ||
| 387 | caption.convert("%s - added table",path.c_str()); | ||
| 388 | } | ||
| 389 | else caption.convert("%s - not unique - table not added",path.c_str()); | ||
| 390 | lastfrom=-1; | ||
| 391 | } | ||
| 392 | |||
| 393 | void Tables::RemTable() | ||
| 394 | { | ||
| 395 | if(db.remap()) lastfrom=-1; | ||
| 396 | if(atcol<db.Tables()&&atcol!=db.Index()) { | ||
| 397 | db.RemTable(atcol); | ||
| 398 | Move(0,0); | ||
| 399 | caption.convert("%s - removed table",path.c_str()); | ||
| 400 | } | ||
| 401 | else caption.convert("%s - key table - not removed",path.c_str()); | ||
| 402 | lastfrom=-1; | ||
| 403 | } | ||
| 404 | |||
| 405 | void Tables::Open(const mstring& s,int ex) | ||
| 406 | { | ||
| 407 | path=s; | ||
| 408 | writable=ex; | ||
| 409 | db.Open(s,ex); | ||
| 410 | if(ex) db.Saveas(path+sref(".bak")); | ||
| 411 | caption=s; | ||
| 412 | caption+=sref(" loaded"); | ||
| 413 | if(ex) caption+=sref(" (exclusive)"); | ||
| 414 | lastfrom=-1; | ||
| 415 | } | ||
| 416 | |||
| 417 | void Tables::Save() | ||
| 418 | { | ||
| 419 | try { | ||
| 420 | db.Saveas(path); | ||
| 421 | caption=path; | ||
| 422 | caption+=sref(" saved"); | ||
| 423 | } | ||
| 424 | catch(const merror_t& e) { | ||
| 425 | caption=e.desc; | ||
| 426 | } | ||
| 427 | lastfrom=-1; | ||
| 428 | } | ||
| 429 | |||
| 430 | void Tables::Close() | ||
| 431 | { | ||
| 432 | if(writable) { | ||
| 433 | db.Close(); | ||
| 434 | caption=path; | ||
| 435 | caption+=sref(" closed"); | ||
| 436 | } | ||
| 437 | else { | ||
| 438 | caption=path; | ||
| 439 | caption+=sref(" readonly - not closed"); | ||
| 440 | } | ||
| 441 | lastfrom=-1; | ||
| 442 | } | ||
diff --git a/src/hed/tables.h b/src/hed/tables.h new file mode 100644 index 0000000..205ca63 --- /dev/null +++ b/src/hed/tables.h | |||
| @@ -0,0 +1,61 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef TABLESH | ||
| 21 | #define TABLESH | ||
| 22 | |||
| 23 | #include <hed/edit.h> | ||
| 24 | #include <hdb/db.h> | ||
| 25 | |||
| 26 | struct Tables { | ||
| 27 | Tables(); | ||
| 28 | ~Tables(); | ||
| 29 | |||
| 30 | void Open(const mstring& path,int ex=0); | ||
| 31 | void Save(); | ||
| 32 | void Close(); | ||
| 33 | |||
| 34 | void Setup(int sp); | ||
| 35 | |||
| 36 | void Show(); | ||
| 37 | void Home(); | ||
| 38 | void Move(int i,int j); | ||
| 39 | void Navigate(); | ||
| 40 | int Command(); | ||
| 41 | |||
| 42 | void Sort(); | ||
| 43 | void Order(); | ||
| 44 | void Check(); | ||
| 45 | |||
| 46 | void Edit(); | ||
| 47 | void Insert(); | ||
| 48 | void Delete(); | ||
| 49 | void FileName(); | ||
| 50 | void AddTable(); | ||
| 51 | void RemTable(); | ||
| 52 | void Help(); | ||
| 53 | |||
| 54 | dbmap db; | ||
| 55 | mstring path,caption; | ||
| 56 | int from,lines,atline,writable; | ||
| 57 | int tab,space,cols,dispcols,dim,atcol; | ||
| 58 | int lastfrom,lasttab,lastline,lastcol; | ||
| 59 | }; | ||
| 60 | |||
| 61 | #endif | ||
diff --git a/src/hed/test.cc b/src/hed/test.cc new file mode 100644 index 0000000..318334f --- /dev/null +++ b/src/hed/test.cc | |||
| @@ -0,0 +1,33 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include "input.h" | ||
| 21 | #include <stdio.h> | ||
| 22 | |||
| 23 | main(int argc,char* argv[]) | ||
| 24 | { | ||
| 25 | InitCurses(); | ||
| 26 | while(1) { | ||
| 27 | int c=RawInput(); | ||
| 28 | fprintf(stderr,"%d\r\n",c); | ||
| 29 | if(c==27) break; | ||
| 30 | } | ||
| 31 | EndCurses(); | ||
| 32 | return 0; | ||
| 33 | } | ||
diff --git a/src/http/http.h b/src/http/http.h new file mode 100644 index 0000000..8bd4d23 --- /dev/null +++ b/src/http/http.h | |||
| @@ -0,0 +1,144 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef HTTPH | ||
| 21 | #define HTTPH | ||
| 22 | |||
| 23 | #include <http/mime.h> | ||
| 24 | |||
| 25 | /////////////////////////////////////////////////////////////////// | ||
| 26 | |||
| 27 | const mstring http_mime_default="application/octet-stream"; | ||
| 28 | |||
| 29 | const mstring HTTP_V10="HTTP/1.0"; | ||
| 30 | const mstring HTTP_V11="HTTP/1.1"; | ||
| 31 | |||
| 32 | /////////////////////////////////////////////////////////////////// | ||
| 33 | // Request types | ||
| 34 | const mstring HTTP_OPTIONS="OPTIONS"; | ||
| 35 | const mstring HTTP_GET="GET"; | ||
| 36 | const mstring HTTP_HEAD="HEAD"; | ||
| 37 | const mstring HTTP_POST="POST"; | ||
| 38 | const mstring HTTP_PUT="PUT"; | ||
| 39 | const mstring HTTP_DELETE="DELETE"; | ||
| 40 | const mstring HTTP_TRACE="TRACE"; | ||
| 41 | const mstring HTTP_CONNECT="CONNECT"; | ||
| 42 | |||
| 43 | class httpReq : public HTTP { | ||
| 44 | public: | ||
| 45 | httpReq(); | ||
| 46 | httpReq(const sref& msg) { Init(msg); } | ||
| 47 | |||
| 48 | mstring method,uri,arg,version; | ||
| 49 | mstring auth,expect,from,host; | ||
| 50 | mstring if_match,if_mod,if_none,if_range,if_unmod; | ||
| 51 | mstring max_forwards,proxy,range; | ||
| 52 | mstring referer,te,user_agent; | ||
| 53 | sspile cookies; | ||
| 54 | |||
| 55 | void putHead(mstream& out) const; | ||
| 56 | protected: | ||
| 57 | int Special(sref line); | ||
| 58 | int Handle(const sref& name, | ||
| 59 | const sref& rawval, | ||
| 60 | const sref& val, | ||
| 61 | const rrpile& opts); | ||
| 62 | }; | ||
| 63 | |||
| 64 | /////////////////////////////////////////////////////////////////// | ||
| 65 | |||
| 66 | /////////////////////////////////////////////////////////////////// | ||
| 67 | // Informational 1xx | ||
| 68 | const mstring HTTP_100="100 Continue"; | ||
| 69 | const mstring HTTP_101="101 Switching Protocols"; | ||
| 70 | // Successful 2xx | ||
| 71 | const mstring HTTP_200="200 OK"; | ||
| 72 | const mstring HTTP_201="201 Created"; | ||
| 73 | const mstring HTTP_202="202 Accepted"; | ||
| 74 | const mstring HTTP_203="203 Non-Authoritative Information"; | ||
| 75 | const mstring HTTP_204="204 No Content"; | ||
| 76 | const mstring HTTP_205="205 Reset Content"; | ||
| 77 | const mstring HTTP_206="206 Partial Content"; | ||
| 78 | // Redirection 3xx | ||
| 79 | const mstring HTTP_300="300 Multiple Choices"; | ||
| 80 | const mstring HTTP_301="301 Moved Permanently"; | ||
| 81 | const mstring HTTP_302="302 Found"; | ||
| 82 | const mstring HTTP_303="303 See Other"; | ||
| 83 | const mstring HTTP_304="304 Not Modified"; | ||
| 84 | const mstring HTTP_305="305 Use Proxy"; | ||
| 85 | const mstring HTTP_306="306 (Unused)"; | ||
| 86 | const mstring HTTP_307="307 Temporary Redirect"; | ||
| 87 | // Client Error 4xx | ||
| 88 | const mstring HTTP_400="400 Bad Request"; | ||
| 89 | const mstring HTTP_401="401 Unauthorized"; | ||
| 90 | const mstring HTTP_402="402 Payment Required"; | ||
| 91 | const mstring HTTP_403="403 Forbidden"; | ||
| 92 | const mstring HTTP_404="404 Not Found"; | ||
| 93 | const mstring HTTP_405="405 Method Not Allowed"; | ||
| 94 | const mstring HTTP_406="406 Not Acceptable"; | ||
| 95 | const mstring HTTP_407="407 Proxy Authentication Required"; | ||
| 96 | const mstring HTTP_408="408 Request Timeout"; | ||
| 97 | const mstring HTTP_409="409 Conflict"; | ||
| 98 | const mstring HTTP_410="410 Gone"; | ||
| 99 | const mstring HTTP_411="411 Length Required"; | ||
| 100 | const mstring HTTP_412="412 Precondition Failed"; | ||
| 101 | const mstring HTTP_413="413 Request Entity Too Large"; | ||
| 102 | const mstring HTTP_414="414 Request-URI Too Long"; | ||
| 103 | const mstring HTTP_415="415 Unsupported Media Type"; | ||
| 104 | const mstring HTTP_416="416 Requested Range Not Satisfiable"; | ||
| 105 | const mstring HTTP_417="417 Expectation Failed"; | ||
| 106 | // Server Error 5xx | ||
| 107 | const mstring HTTP_500="500 Internal Server Error"; | ||
| 108 | const mstring HTTP_501="501 Not Implemented"; | ||
| 109 | const mstring HTTP_502="502 Bad Gateway"; | ||
| 110 | const mstring HTTP_503="503 Service Unavailable"; | ||
| 111 | const mstring HTTP_504="504 Gateway Timeout"; | ||
| 112 | const mstring HTTP_505="505 HTTP Version Not Supported"; | ||
| 113 | |||
| 114 | struct cookie_t { | ||
| 115 | mstring name,val,options; | ||
| 116 | cookie_t() {} | ||
| 117 | cookie_t(const sref& n,const sref& v) : name(n),val(v) {} | ||
| 118 | cookie_t(const sref& n,const sref& v,const sref& o) : | ||
| 119 | name(n),val(v),options(o) {} | ||
| 120 | }; | ||
| 121 | |||
| 122 | class httpResp : public HTTP { | ||
| 123 | public: | ||
| 124 | httpResp(); | ||
| 125 | httpResp(const sref& msg) { Init(msg); } | ||
| 126 | |||
| 127 | mstring version,status; | ||
| 128 | mstring age,etag,location; | ||
| 129 | mstring proxy_authent,retry,server,vary,authent; | ||
| 130 | msvec<cookie_t> set_cookies; | ||
| 131 | |||
| 132 | void putHead(mstream& out) const; | ||
| 133 | protected: | ||
| 134 | int Special(sref line); | ||
| 135 | int Handle(const sref& name, | ||
| 136 | const sref& rawval, | ||
| 137 | const sref& val, | ||
| 138 | const rrpile& opts); | ||
| 139 | }; | ||
| 140 | |||
| 141 | /////////////////////////////////////////////////////////////////// | ||
| 142 | |||
| 143 | #endif | ||
| 144 | |||
diff --git a/src/http/mime.cc b/src/http/mime.cc new file mode 100644 index 0000000..f6b3412 --- /dev/null +++ b/src/http/mime.cc | |||
| @@ -0,0 +1,92 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <http/mime.h> | ||
| 21 | |||
| 22 | HTTP::HTTP() | ||
| 23 | { | ||
| 24 | connect="close"; | ||
| 25 | pragma="no-cache"; | ||
| 26 | date=httpTime(idate=Now()); | ||
| 27 | } | ||
| 28 | |||
| 29 | int HTTP::Special(sref line) | ||
| 30 | { | ||
| 31 | return 1; | ||
| 32 | } | ||
| 33 | |||
| 34 | int HTTP::Handle(const sref& name, | ||
| 35 | const sref& rawval, | ||
| 36 | const sref& val, | ||
| 37 | const rrpile& opts) | ||
| 38 | { | ||
| 39 | if(Mime::Handle(name,rawval,val,opts)) return 1; | ||
| 40 | else if(eqn(name,cache_tag)) cache=val; | ||
| 41 | else if(eqn(name,connect_tag)) connect=val; | ||
| 42 | else if(eqn(name,date_tag)) date=val; | ||
| 43 | else if(eqn(name,pragma_tag)) pragma=val; | ||
| 44 | else if(eqn(name,trailer_tag)) trailer=val; | ||
| 45 | else if(eqn(name,trans_enc_tag)) trans_enc=val; | ||
| 46 | else if(eqn(name,upgrade_tag)) upgrade=val; | ||
| 47 | else if(eqn(name,via_tag)) via=val; | ||
| 48 | else if(eqn(name,warning_tag)) warning=val; | ||
| 49 | else if(eqn(name,allow_tag)) allow=val; | ||
| 50 | else if(eqn(name,cont_enc_tag)) cont_enc=val; | ||
| 51 | else if(eqn(name,cont_lang_tag)) cont_lang=val; | ||
| 52 | else if(eqn(name,cont_location_tag)) cont_location=val; | ||
| 53 | else if(eqn(name,cont_md5_tag)) cont_md5=val; | ||
| 54 | else if(eqn(name,cont_range_tag)) cont_range=val; | ||
| 55 | else if(eqn(name,expires_tag)) expires=val; | ||
| 56 | else if(eqn(name,lastmod_tag)) lastmod=val; | ||
| 57 | else if(eqn(name,accept_tag)) accept=val; | ||
| 58 | else if(eqn(name,accept_charset_tag)) accept_charset=val; | ||
| 59 | else if(eqn(name,accept_enc_tag)) accept_enc=val; | ||
| 60 | else if(eqn(name,accept_lang_tag)) accept_lang=val; | ||
| 61 | else if(eqn(name,accept_range_tag)) accept_range=val; | ||
| 62 | else return 0; | ||
| 63 | return 1; | ||
| 64 | } | ||
| 65 | |||
| 66 | void HTTP::putHead(mstream& out) const | ||
| 67 | { | ||
| 68 | if(putval(out,cache_tag,cache)) putend(out); | ||
| 69 | if(putval(out,connect_tag,connect)) putend(out); | ||
| 70 | if(putval(out,date_tag,date)) putend(out); | ||
| 71 | if(putval(out,pragma_tag,pragma)) putend(out); | ||
| 72 | if(putval(out,trailer_tag,trailer)) putend(out); | ||
| 73 | if(putval(out,trans_enc_tag,trans_enc)) putend(out); | ||
| 74 | if(putval(out,upgrade_tag,upgrade)) putend(out); | ||
| 75 | if(putval(out,via_tag,via)) putend(out); | ||
| 76 | if(putval(out,warning_tag,warning)) putend(out); | ||
| 77 | if(putval(out,allow_tag,allow)) putend(out); | ||
| 78 | if(putval(out,cont_enc_tag,cont_enc)) putend(out); | ||
| 79 | if(putval(out,cont_lang_tag,cont_lang)) putend(out); | ||
| 80 | if(putval(out,cont_location_tag,cont_location)) putend(out); | ||
| 81 | if(putval(out,cont_md5_tag,cont_md5)) putend(out); | ||
| 82 | if(putval(out,cont_range_tag,cont_range)) putend(out); | ||
| 83 | if(putval(out,expires_tag,expires)) putend(out); | ||
| 84 | if(putval(out,lastmod_tag,lastmod)) putend(out); | ||
| 85 | if(putval(out,accept_tag,accept)) putend(out); | ||
| 86 | if(putval(out,accept_charset_tag,accept_charset)) putend(out); | ||
| 87 | if(putval(out,accept_enc_tag,accept_enc)) putend(out); | ||
| 88 | if(putval(out,accept_lang_tag,accept_lang)) putend(out); | ||
| 89 | if(putval(out,accept_range_tag,accept_range)) putend(out); | ||
| 90 | Mime::putHead(out); | ||
| 91 | } | ||
| 92 | |||
diff --git a/src/http/mime.h b/src/http/mime.h new file mode 100644 index 0000000..85200cc --- /dev/null +++ b/src/http/mime.h | |||
| @@ -0,0 +1,99 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef MIMEHTTPH | ||
| 21 | #define MIMEHTTPH | ||
| 22 | |||
| 23 | #include <mime/mime.h> | ||
| 24 | #include <mt/dates.h> | ||
| 25 | |||
| 26 | // Entity Headers | ||
| 27 | const mstring allow_tag="Allow"; | ||
| 28 | const mstring accept_tag="Accept"; | ||
| 29 | const mstring accept_charset_tag="Accept-Charset"; | ||
| 30 | const mstring accept_enc_tag="Accept-Encoding"; | ||
| 31 | const mstring accept_lang_tag="Accept-Language"; | ||
| 32 | const mstring accept_range_tag="Accept-Ranges"; | ||
| 33 | const mstring cont_enc_tag="Content-Encoding"; | ||
| 34 | const mstring cont_lang_tag="Content-Language"; | ||
| 35 | const mstring cont_location_tag="Content-Location"; | ||
| 36 | const mstring cont_md5_tag="Content-MD5"; | ||
| 37 | const mstring cont_range_tag="Content-Range"; | ||
| 38 | const mstring expires_tag="Expires"; | ||
| 39 | const mstring lastmod_tag="Last-Modified"; | ||
| 40 | // General headers | ||
| 41 | const mstring cache_tag="Cache-Control"; | ||
| 42 | const mstring connect_tag="Connection"; | ||
| 43 | const mstring date_tag="Date"; | ||
| 44 | const mstring pragma_tag="Pragma"; | ||
| 45 | const mstring trailer_tag="Trailer"; | ||
| 46 | const mstring trans_enc_tag="Transfer-Encoding"; | ||
| 47 | const mstring upgrade_tag="Upgrade"; | ||
| 48 | const mstring via_tag="Via"; | ||
| 49 | const mstring warning_tag="Warning"; | ||
| 50 | // Request headers | ||
| 51 | const mstring auth_tag="Authorization"; | ||
| 52 | const mstring expect_tag="Expect"; | ||
| 53 | const mstring host_tag="Host"; | ||
| 54 | const mstring if_match_tag="If-Match"; | ||
| 55 | const mstring if_mod_tag="If-Modified-Since"; | ||
| 56 | const mstring if_none_tag="If-None-Match"; | ||
| 57 | const mstring if_range_tag="If-Range"; | ||
| 58 | const mstring if_unmod_tag="If-Unmodified-Since"; | ||
| 59 | const mstring max_forwards_tag="Max-Forwards"; | ||
| 60 | const mstring proxy_tag="Proxy-Authorization"; | ||
| 61 | const mstring range_tag="Range"; | ||
| 62 | const mstring referer_tag="Referer"; | ||
| 63 | const mstring te_tag="TE"; | ||
| 64 | const mstring user_agent_tag="User-Agent"; | ||
| 65 | const mstring cookie_tag="Cookie"; | ||
| 66 | // Response headers | ||
| 67 | const mstring age_tag="Age"; | ||
| 68 | const mstring etag_tag="ETag"; | ||
| 69 | const mstring location_tag="Location"; | ||
| 70 | const mstring proxy_authent_tag="Proxy-Authenticate"; | ||
| 71 | const mstring retry_tag="Retry-After"; | ||
| 72 | const mstring server_tag="Server"; | ||
| 73 | const mstring vary_tag="Vary"; | ||
| 74 | const mstring authent_tag="WWW-Authenticate"; | ||
| 75 | const mstring set_cookie_tag="Set-Cookie"; | ||
| 76 | |||
| 77 | class HTTP : public Mime { | ||
| 78 | public: | ||
| 79 | HTTP(); | ||
| 80 | HTTP(const sref& msg) { Init(msg); } | ||
| 81 | |||
| 82 | mstring cache,connect,date,pragma; | ||
| 83 | mstring trailer,trans_enc,upgrade,via,warning; | ||
| 84 | mstring allow,cont_enc,cont_lang,cont_location; | ||
| 85 | mstring cont_md5,cont_range,expires,lastmod; | ||
| 86 | mstring accept,accept_charset,accept_enc,accept_lang,accept_range; | ||
| 87 | |||
| 88 | time_t idate; | ||
| 89 | void putHead(mstream& out) const; | ||
| 90 | protected: | ||
| 91 | int Special(sref line); | ||
| 92 | int Handle(const sref& name, | ||
| 93 | const sref& rawval, | ||
| 94 | const sref& val, | ||
| 95 | const rrpile& opts); | ||
| 96 | }; | ||
| 97 | |||
| 98 | #endif | ||
| 99 | |||
diff --git a/src/http/req.cc b/src/http/req.cc new file mode 100644 index 0000000..acb2105 --- /dev/null +++ b/src/http/req.cc | |||
| @@ -0,0 +1,100 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <http/http.h> | ||
| 21 | #include <mime/mailbox.h> | ||
| 22 | |||
| 23 | httpReq::httpReq() | ||
| 24 | { | ||
| 25 | } | ||
| 26 | |||
| 27 | int httpReq::Special(sref line) | ||
| 28 | { | ||
| 29 | sref first,rest=line; | ||
| 30 | Split(first,rest); | ||
| 31 | method=first; | ||
| 32 | Split(first,rest); | ||
| 33 | uri=first; | ||
| 34 | arg.clear(); | ||
| 35 | Split(first,rest); | ||
| 36 | version=first; | ||
| 37 | int pos=uri.find('?'); | ||
| 38 | if(pos>=0) { arg=uri.right(pos+1); uri.resize(pos); } | ||
| 39 | return 1; | ||
| 40 | } | ||
| 41 | |||
| 42 | int httpReq::Handle(const sref& name, | ||
| 43 | const sref& rawval, | ||
| 44 | const sref& val, | ||
| 45 | const rrpile& opts) | ||
| 46 | { | ||
| 47 | if(HTTP::Handle(name,rawval,val,opts)) return 1; | ||
| 48 | else if(eqn(name,auth_tag)) auth=val; | ||
| 49 | else if(eqn(name,expect_tag)) expect=val; | ||
| 50 | else if(eqn(name,from_tag)) from=val; | ||
| 51 | else if(eqn(name,host_tag)) host=val; | ||
| 52 | else if(eqn(name,if_match_tag)) if_match=val; | ||
| 53 | else if(eqn(name,if_mod_tag)) if_mod=val; | ||
| 54 | else if(eqn(name,if_none_tag)) if_none=val; | ||
| 55 | else if(eqn(name,if_range_tag)) if_range=val; | ||
| 56 | else if(eqn(name,if_unmod_tag)) if_unmod=val; | ||
| 57 | else if(eqn(name,max_forwards_tag)) max_forwards=val; | ||
| 58 | else if(eqn(name,proxy_tag)) proxy=val; | ||
| 59 | else if(eqn(name,range_tag)) range=val; | ||
| 60 | else if(eqn(name,referer_tag)) referer=val; | ||
| 61 | else if(eqn(name,te_tag)) te=val; | ||
| 62 | else if(eqn(name,user_agent_tag)) user_agent=val; | ||
| 63 | else if(eqn(name,cookie_tag)) { | ||
| 64 | for(rrpile::const_iterator p=opts.begin();p!=opts.end();p++) | ||
| 65 | cookies.push_back(sstring(p->first,p->second)); | ||
| 66 | } | ||
| 67 | else return 0; | ||
| 68 | return 1; | ||
| 69 | } | ||
| 70 | |||
| 71 | void httpReq::putHead(mstream& out) const | ||
| 72 | { | ||
| 73 | out<<method<<" "<<uri; | ||
| 74 | if(arg.nempty()) out<<"?"<<arg; | ||
| 75 | out<<" "<<version<<CRLF; | ||
| 76 | if(putval(out,auth_tag,auth)) putend(out); | ||
| 77 | if(putval(out,expect_tag,expect)) putend(out); | ||
| 78 | if(putval(out,from_tag,from)) putend(out); | ||
| 79 | if(putval(out,host_tag,host)) putend(out); | ||
| 80 | if(putval(out,if_match_tag,if_match)) putend(out); | ||
| 81 | if(putval(out,if_mod_tag,if_mod)) putend(out); | ||
| 82 | if(putval(out,if_none_tag,if_none)) putend(out); | ||
| 83 | if(putval(out,if_range_tag,if_range)) putend(out); | ||
| 84 | if(putval(out,if_unmod_tag,if_unmod)) putend(out); | ||
| 85 | if(putval(out,max_forwards_tag,max_forwards)) putend(out); | ||
| 86 | if(putval(out,proxy_tag,proxy)) putend(out); | ||
| 87 | if(putval(out,range_tag,range)) putend(out); | ||
| 88 | if(putval(out,referer_tag,referer)) putend(out); | ||
| 89 | if(putval(out,te_tag,te)) putend(out); | ||
| 90 | if(putval(out,user_agent_tag,user_agent)) putend(out); | ||
| 91 | HTTP::putHead(out); | ||
| 92 | if(!cookies.empty()) { | ||
| 93 | out<<cookie_tag<<": "; | ||
| 94 | for(sspile::const_iterator p=cookies.begin();p!=cookies.end();p++) { | ||
| 95 | if(p==cookies.begin()) putopt1(out,p->first,p->second); | ||
| 96 | else putopt(out,p->first,p->second); | ||
| 97 | } | ||
| 98 | putend(out); | ||
| 99 | } | ||
| 100 | } | ||
diff --git a/src/http/resp.cc b/src/http/resp.cc new file mode 100644 index 0000000..aa7ed7b --- /dev/null +++ b/src/http/resp.cc | |||
| @@ -0,0 +1,79 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <http/http.h> | ||
| 21 | |||
| 22 | httpResp::httpResp() | ||
| 23 | { | ||
| 24 | server="HTCd/1.2 MT (Unix)"; | ||
| 25 | version="HTTP/1.1"; | ||
| 26 | status=HTTP_200; | ||
| 27 | mime_version.clear(); | ||
| 28 | //accept="*/*"; | ||
| 29 | //this is non-standard in response headers - now... | ||
| 30 | } | ||
| 31 | |||
| 32 | int httpResp::Special(sref line) | ||
| 33 | { | ||
| 34 | version=First(line); | ||
| 35 | status=Rest(line); | ||
| 36 | return 1; | ||
| 37 | } | ||
| 38 | |||
| 39 | int httpResp::Handle(const sref& name, | ||
| 40 | const sref& rawval, | ||
| 41 | const sref& val, | ||
| 42 | const rrpile& opts) | ||
| 43 | { | ||
| 44 | if(HTTP::Handle(name,rawval,val,opts)) return 1; | ||
| 45 | else if(eqn(name,age_tag)) age=val; | ||
| 46 | else if(eqn(name,etag_tag)) etag=val; | ||
| 47 | else if(eqn(name,location_tag)) location=val; | ||
| 48 | else if(eqn(name,proxy_authent_tag)) proxy_authent=val; | ||
| 49 | else if(eqn(name,retry_tag)) retry=val; | ||
| 50 | else if(eqn(name,server_tag)) server=val; | ||
| 51 | else if(eqn(name,vary_tag)) vary=val; | ||
| 52 | else if(eqn(name,authent_tag)) authent=val; | ||
| 53 | else if(eqn(name,set_cookie_tag)) { | ||
| 54 | for(rrpile::const_iterator p=opts.begin();p!=opts.end();p++) | ||
| 55 | set_cookies.push_back(cookie_t(p->first,p->second)); | ||
| 56 | } | ||
| 57 | else return 0; | ||
| 58 | return 1; | ||
| 59 | } | ||
| 60 | |||
| 61 | void httpResp::putHead(mstream& out) const | ||
| 62 | { | ||
| 63 | out<<version<<" "<<status<<CRLF; | ||
| 64 | if(putval(out,age_tag,age)) putend(out); | ||
| 65 | if(putval(out,etag_tag,etag)) putend(out); | ||
| 66 | if(putval(out,location_tag,location)) putend(out); | ||
| 67 | if(putval(out,proxy_authent_tag,proxy_authent)) putend(out); | ||
| 68 | if(putval(out,retry_tag,retry)) putend(out); | ||
| 69 | if(putval(out,server_tag,server)) putend(out); | ||
| 70 | if(putval(out,vary_tag,vary)) putend(out); | ||
| 71 | if(putval(out,authent_tag,authent)) putend(out); | ||
| 72 | HTTP::putHead(out); | ||
| 73 | for(msvec<cookie_t>::const_iterator p=set_cookies.begin();p!=set_cookies.end();p++) { | ||
| 74 | out<<set_cookie_tag<<": "; | ||
| 75 | putopt1(out,p->name,p->val); | ||
| 76 | if(p->options.nempty()) out<<"; "<<p->options; | ||
| 77 | putend(out); | ||
| 78 | } | ||
| 79 | } | ||
diff --git a/src/http/test.cc b/src/http/test.cc new file mode 100644 index 0000000..59ac5c8 --- /dev/null +++ b/src/http/test.cc | |||
| @@ -0,0 +1,28 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <http/http.h> | ||
| 21 | #include <sys/stat.h> | ||
| 22 | |||
| 23 | static fp_stream mout(stdout),merr(stderr); | ||
| 24 | |||
| 25 | main(int argc,char* argv[]) | ||
| 26 | { | ||
| 27 | return 0; | ||
| 28 | } | ||
diff --git a/src/labat/README b/src/labat/README new file mode 100644 index 0000000..96c3006 --- /dev/null +++ b/src/labat/README | |||
| @@ -0,0 +1,49 @@ | |||
| 1 | |||
| 2 | KORT BESKRIVNING AV 'labat' | ||
| 3 | =========================== | ||
| 4 | |||
| 5 | Indata ('atomctrl.dat') foer Al till 'labat' (Boer vara identisk med | ||
| 6 | tidigare versioner). | ||
| 7 | |||
| 8 | 13 0 | ||
| 9 | 10 40 0.2000 | ||
| 10 | 0.5000 0.00001 0.005 | ||
| 11 | 30 0 0 0 | ||
| 12 | 5 2 0<--------------- 0, 1 & 2 foer respektive: lda, barth-hedin & GGA | ||
| 13 | 100 -84.5000 1 1 0 (knapp finns redan) | ||
| 14 | 200 -16.2450 1 1 0 | ||
| 15 | 210 -5.3356 3 1 0 | ||
| 16 | 300 -0.7812 1 1 0 | ||
| 17 | 310 -0.2312 1 1 0 | ||
| 18 | 100 -84.5000 1 1 0 | ||
| 19 | 200 -16.2450 1 1 0 | ||
| 20 | 210 -5.3356 3 1 0 | ||
| 21 | 300 -0.7812 1 1 0 | ||
| 22 | 310 -0.2312 0 1 0 | ||
| 23 | |||
| 24 | |||
| 25 | Skall ge foeljande resultat: | ||
| 26 | (De utdata filer som finns i biblioteket aer fraan LDA-exemplet nedan) | ||
| 27 | |||
| 28 | LDA | ||
| 29 | |||
| 30 | Total energy starts | ||
| 31 | iter: 22 total ch: 13.00 total en: -241.3129 | ||
| 32 | Coulomb potential | ||
| 33 | NEW ITERATION | ||
| 34 | |||
| 35 | GGA | ||
| 36 | |||
| 37 | Total energy starts | ||
| 38 | iter: 22 total ch: 13.00 total en: -242.3491 | ||
| 39 | Coulomb potential | ||
| 40 | NEW ITERATION | ||
| 41 | Note: the following IEEE floating-point arithmetic exceptions | ||
| 42 | occurred and were never cleared; see ieee_flags(3M): | ||
| 43 | Inexact; Underflow; | ||
| 44 | Sun's implementation of IEEE arithmetic is discussed in | ||
| 45 | the Numerical Computation Guide. | ||
| 46 | |||
| 47 | Inte saa snyggt med flyttalsfelen, men ... | ||
| 48 | |||
| 49 | Utdatafilerna aer de som finns i detta bibliotek (samma som tidigare). \ No newline at end of file | ||
diff --git a/src/labat/adensin.dat b/src/labat/adensin.dat new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/labat/adensin.dat | |||
diff --git a/src/labat/adensout.dat b/src/labat/adensout.dat new file mode 100644 index 0000000..7432734 --- /dev/null +++ b/src/labat/adensout.dat | |||
| @@ -0,0 +1,402 @@ | |||
| 1 | 23 z,ion: 13. 0. jblock,nbl,c: 10 40 0.2000000 | ||
| 2 | -0.1300000E+02 0.0000000E+00 0.0000000E+00 0.1388390E+04 0.0000000E+00 | ||
| 3 | -0.2595549E+05 -0.2603599E+05 -0.2603598E+05 0.1388390E+04 0.5000000E-03 | ||
| 4 | -0.1295549E+05 -0.1300223E+05 -0.1300222E+05 0.1370416E+04 0.1000000E-02 | ||
| 5 | -0.8622160E+04 -0.8657409E+04 -0.8657408E+04 0.1352672E+04 0.1500000E-02 | ||
| 6 | -0.6455499E+04 -0.6484424E+04 -0.6484424E+04 0.1335159E+04 0.2000000E-02 | ||
| 7 | -0.5155505E+04 -0.5180875E+04 -0.5180875E+04 0.1317873E+04 0.2500000E-02 | ||
| 8 | -0.4288846E+04 -0.4311748E+04 -0.4311748E+04 0.1300813E+04 0.3000000E-02 | ||
| 9 | -0.3669807E+04 -0.3690957E+04 -0.3690957E+04 0.1283975E+04 0.3500000E-02 | ||
| 10 | -0.3205532E+04 -0.3225349E+04 -0.3225349E+04 0.1267356E+04 0.4000000E-02 | ||
| 11 | -0.2844432E+04 -0.2863203E+04 -0.2863204E+04 0.1250953E+04 0.4500000E-02 | ||
| 12 | -0.2555556E+04 -0.2573482E+04 -0.2573482E+04 0.1234765E+04 0.5000000E-02 | ||
| 13 | -0.2319206E+04 -0.2336431E+04 -0.2336432E+04 0.1218787E+04 0.5500000E-02 | ||
| 14 | -0.2122252E+04 -0.2138886E+04 -0.2138887E+04 0.1203018E+04 0.6000000E-02 | ||
| 15 | -0.1955601E+04 -0.1971728E+04 -0.1971729E+04 0.1187454E+04 0.6500000E-02 | ||
| 16 | -0.1812762E+04 -0.1828448E+04 -0.1828448E+04 0.1172094E+04 0.7000000E-02 | ||
| 17 | -0.1688971E+04 -0.1704268E+04 -0.1704268E+04 0.1156933E+04 0.7500000E-02 | ||
| 18 | -0.1580658E+04 -0.1595610E+04 -0.1595610E+04 0.1141971E+04 0.8000000E-02 | ||
| 19 | -0.1485089E+04 -0.1499732E+04 -0.1499732E+04 0.1127204E+04 0.8500000E-02 | ||
| 20 | -0.1400144E+04 -0.1414506E+04 -0.1414507E+04 0.1112629E+04 0.9000000E-02 | ||
| 21 | -0.1324143E+04 -0.1338250E+04 -0.1338250E+04 0.1098245E+04 0.9500000E-02 | ||
| 22 | -0.1255747E+04 -0.1269619E+04 -0.1269619E+04 0.1084048E+04 0.1000000E-01 | ||
| 23 | -0.1193866E+04 -0.1207523E+04 -0.1207523E+04 0.1070036E+04 0.1050000E-01 | ||
| 24 | -0.1137615E+04 -0.1151072E+04 -0.1151072E+04 0.1056208E+04 0.1100000E-01 | ||
| 25 | -0.1086258E+04 -0.1099528E+04 -0.1099528E+04 0.1042559E+04 0.1150000E-01 | ||
| 26 | -0.1039185E+04 -0.1052280E+04 -0.1052281E+04 0.1029089E+04 0.1200000E-01 | ||
| 27 | -0.9958791E+03 -0.1008811E+04 -0.1008812E+04 0.1015795E+04 0.1250000E-01 | ||
| 28 | -0.9559090E+03 -0.9686865E+03 -0.9686870E+03 0.1002675E+04 0.1300000E-01 | ||
| 29 | -0.9189016E+03 -0.9315332E+03 -0.9315337E+03 0.9897252E+03 0.1350000E-01 | ||
| 30 | -0.8845416E+03 -0.8970348E+03 -0.8970353E+03 0.9769449E+03 0.1400000E-01 | ||
| 31 | -0.8525533E+03 -0.8649147E+03 -0.8649152E+03 0.9643314E+03 0.1450000E-01 | ||
| 32 | -0.8227014E+03 -0.8349372E+03 -0.8349377E+03 0.9518826E+03 0.1500000E-01 | ||
| 33 | -0.7947774E+03 -0.8068931E+03 -0.8068936E+03 0.9395963E+03 0.1550000E-01 | ||
| 34 | -0.7686024E+03 -0.7806030E+03 -0.7806036E+03 0.9274705E+03 0.1600000E-01 | ||
| 35 | -0.7440157E+03 -0.7559058E+03 -0.7559063E+03 0.9155030E+03 0.1650000E-01 | ||
| 36 | -0.7208790E+03 -0.7326628E+03 -0.7326633E+03 0.9036917E+03 0.1700000E-01 | ||
| 37 | -0.6990662E+03 -0.7107476E+03 -0.7107481E+03 0.8920347E+03 0.1750000E-01 | ||
| 38 | -0.6784689E+03 -0.6900513E+03 -0.6900518E+03 0.8805299E+03 0.1800000E-01 | ||
| 39 | -0.6589867E+03 -0.6704735E+03 -0.6704740E+03 0.8691753E+03 0.1850000E-01 | ||
| 40 | -0.6405335E+03 -0.6519276E+03 -0.6519282E+03 0.8579690E+03 0.1900000E-01 | ||
| 41 | -0.6230283E+03 -0.6343326E+03 -0.6343331E+03 0.8469091E+03 0.1950000E-01 | ||
| 42 | -0.6064018E+03 -0.6176191E+03 -0.6176196E+03 0.8359936E+03 0.2000000E-01 | ||
| 43 | -0.5755291E+03 -0.5865791E+03 -0.5865796E+03 0.8145883E+03 0.2100000E-01 | ||
| 44 | -0.5474761E+03 -0.5583670E+03 -0.5583675E+03 0.7937385E+03 0.2200000E-01 | ||
| 45 | -0.5218688E+03 -0.5326084E+03 -0.5326089E+03 0.7734297E+03 0.2300000E-01 | ||
| 46 | -0.4984078E+03 -0.5090028E+03 -0.5090033E+03 0.7536478E+03 0.2400000E-01 | ||
| 47 | -0.4768298E+03 -0.4872860E+03 -0.4872865E+03 0.7343792E+03 0.2500000E-01 | ||
| 48 | -0.4569235E+03 -0.4672462E+03 -0.4672466E+03 0.7156106E+03 0.2600000E-01 | ||
| 49 | -0.4384975E+03 -0.4486914E+03 -0.4486919E+03 0.6973290E+03 0.2700000E-01 | ||
| 50 | -0.4213989E+03 -0.4314685E+03 -0.4314689E+03 0.6795216E+03 0.2800000E-01 | ||
| 51 | -0.4054850E+03 -0.4154341E+03 -0.4154346E+03 0.6621763E+03 0.2900000E-01 | ||
| 52 | -0.3906428E+03 -0.4004751E+03 -0.4004756E+03 0.6452810E+03 0.3000000E-01 | ||
| 53 | -0.3767633E+03 -0.3864822E+03 -0.3864826E+03 0.6288239E+03 0.3100000E-01 | ||
| 54 | -0.3637615E+03 -0.3733700E+03 -0.3733704E+03 0.6127938E+03 0.3200000E-01 | ||
| 55 | -0.3515527E+03 -0.3610536E+03 -0.3610541E+03 0.5971795E+03 0.3300000E-01 | ||
| 56 | -0.3400718E+03 -0.3494678E+03 -0.3494682E+03 0.5819701E+03 0.3400000E-01 | ||
| 57 | -0.3292517E+03 -0.3385452E+03 -0.3385456E+03 0.5671553E+03 0.3500000E-01 | ||
| 58 | -0.3190419E+03 -0.3282353E+03 -0.3282357E+03 0.5527246E+03 0.3600000E-01 | ||
| 59 | -0.3093885E+03 -0.3184839E+03 -0.3184843E+03 0.5386682E+03 0.3700000E-01 | ||
| 60 | -0.3002519E+03 -0.3092515E+03 -0.3092519E+03 0.5249762E+03 0.3800000E-01 | ||
| 61 | -0.2915882E+03 -0.3004938E+03 -0.3004942E+03 0.5116393E+03 0.3900000E-01 | ||
| 62 | -0.2833661E+03 -0.2921795E+03 -0.2921799E+03 0.4986481E+03 0.4000000E-01 | ||
| 63 | -0.2755491E+03 -0.2842721E+03 -0.2842724E+03 0.4859937E+03 0.4100000E-01 | ||
| 64 | -0.2681122E+03 -0.2767465E+03 -0.2767468E+03 0.4736674E+03 0.4200000E-01 | ||
| 65 | -0.2610252E+03 -0.2695722E+03 -0.2695725E+03 0.4616606E+03 0.4300000E-01 | ||
| 66 | -0.2542678E+03 -0.2627292E+03 -0.2627295E+03 0.4499649E+03 0.4400000E-01 | ||
| 67 | -0.2478145E+03 -0.2561915E+03 -0.2561919E+03 0.4385724E+03 0.4500000E-01 | ||
| 68 | -0.2416489E+03 -0.2499431E+03 -0.2499434E+03 0.4274751E+03 0.4600000E-01 | ||
| 69 | -0.2357492E+03 -0.2439618E+03 -0.2439621E+03 0.4166653E+03 0.4700000E-01 | ||
| 70 | -0.2301022E+03 -0.2382345E+03 -0.2382347E+03 0.4061357E+03 0.4800000E-01 | ||
| 71 | -0.2246890E+03 -0.2327421E+03 -0.2327424E+03 0.3958788E+03 0.4900000E-01 | ||
| 72 | -0.2194988E+03 -0.2274741E+03 -0.2274743E+03 0.3858877E+03 0.5000000E-01 | ||
| 73 | -0.2145153E+03 -0.2224138E+03 -0.2224140E+03 0.3761553E+03 0.5100000E-01 | ||
| 74 | -0.2097297E+03 -0.2175525E+03 -0.2175527E+03 0.3666751E+03 0.5200000E-01 | ||
| 75 | -0.2051276E+03 -0.2128759E+03 -0.2128761E+03 0.3574404E+03 0.5300000E-01 | ||
| 76 | -0.2007019E+03 -0.2083766E+03 -0.2083768E+03 0.3484449E+03 0.5400000E-01 | ||
| 77 | -0.1964400E+03 -0.2040421E+03 -0.2040423E+03 0.3396823E+03 0.5500000E-01 | ||
| 78 | -0.1923359E+03 -0.1998664E+03 -0.1998666E+03 0.3311466E+03 0.5600000E-01 | ||
| 79 | -0.1883786E+03 -0.1958384E+03 -0.1958385E+03 0.3228319E+03 0.5700000E-01 | ||
| 80 | -0.1845630E+03 -0.1919531E+03 -0.1919532E+03 0.3147325E+03 0.5800000E-01 | ||
| 81 | -0.1808793E+03 -0.1882005E+03 -0.1882006E+03 0.3068428E+03 0.5900000E-01 | ||
| 82 | -0.1773235E+03 -0.1845771E+03 -0.1845772E+03 0.2991574E+03 0.6000000E-01 | ||
| 83 | -0.1705632E+03 -0.1776836E+03 -0.1776837E+03 0.2843782E+03 0.6200000E-01 | ||
| 84 | -0.1642440E+03 -0.1712338E+03 -0.1712338E+03 0.2703541E+03 0.6400000E-01 | ||
| 85 | -0.1583165E+03 -0.1651794E+03 -0.1651794E+03 0.2570466E+03 0.6600000E-01 | ||
| 86 | -0.1527544E+03 -0.1594933E+03 -0.1594932E+03 0.2444189E+03 0.6800000E-01 | ||
| 87 | -0.1475181E+03 -0.1541359E+03 -0.1541358E+03 0.2324363E+03 0.7000000E-01 | ||
| 88 | -0.1425878E+03 -0.1490873E+03 -0.1490871E+03 0.2210658E+03 0.7200000E-01 | ||
| 89 | -0.1379313E+03 -0.1443151E+03 -0.1443149E+03 0.2102760E+03 0.7400000E-01 | ||
| 90 | -0.1335335E+03 -0.1398043E+03 -0.1398041E+03 0.2000373E+03 0.7600000E-01 | ||
| 91 | -0.1293678E+03 -0.1355281E+03 -0.1355278E+03 0.1903216E+03 0.7800000E-01 | ||
| 92 | -0.1254229E+03 -0.1314751E+03 -0.1314748E+03 0.1811020E+03 0.8000000E-01 | ||
| 93 | -0.1216763E+03 -0.1276228E+03 -0.1276224E+03 0.1723534E+03 0.8200000E-01 | ||
| 94 | -0.1181193E+03 -0.1239626E+03 -0.1239621E+03 0.1640515E+03 0.8400000E-01 | ||
| 95 | -0.1147332E+03 -0.1204754E+03 -0.1204749E+03 0.1561737E+03 0.8600000E-01 | ||
| 96 | -0.1115112E+03 -0.1171545E+03 -0.1171540E+03 0.1486982E+03 0.8800000E-01 | ||
| 97 | -0.1084373E+03 -0.1139839E+03 -0.1139833E+03 0.1416045E+03 0.9000000E-01 | ||
| 98 | -0.1055064E+03 -0.1109583E+03 -0.1109576E+03 0.1348732E+03 0.9200000E-01 | ||
| 99 | -0.1027046E+03 -0.1080640E+03 -0.1080632E+03 0.1284857E+03 0.9400000E-01 | ||
| 100 | -0.1000279E+03 -0.1052968E+03 -0.1052960E+03 0.1224246E+03 0.9600000E-01 | ||
| 101 | -0.9746453E+02 -0.1026449E+03 -0.1026440E+03 0.1166731E+03 0.9800000E-01 | ||
| 102 | -0.9501135E+02 -0.1001051E+03 -0.1001042E+03 0.1112155E+03 0.1000000E+00 | ||
| 103 | -0.9265802E+02 -0.9766714E+02 -0.9766614E+02 0.1060368E+03 0.1020000E+00 | ||
| 104 | -0.9040218E+02 -0.9532851E+02 -0.9532743E+02 0.1011228E+03 0.1040000E+00 | ||
| 105 | -0.8823479E+02 -0.9308017E+02 -0.9307902E+02 0.9645988E+02 0.1060000E+00 | ||
| 106 | -0.8615402E+02 -0.9092026E+02 -0.9091904E+02 0.9203535E+02 0.1080000E+00 | ||
| 107 | -0.8415194E+02 -0.8884081E+02 -0.8883952E+02 0.8783700E+02 0.1100000E+00 | ||
| 108 | -0.8222714E+02 -0.8684041E+02 -0.8683904E+02 0.8385332E+02 0.1120000E+00 | ||
| 109 | -0.8037265E+02 -0.8491201E+02 -0.8491058E+02 0.8007333E+02 0.1140000E+00 | ||
| 110 | -0.7858737E+02 -0.8305453E+02 -0.8305302E+02 0.7648665E+02 0.1160000E+00 | ||
| 111 | -0.7686513E+02 -0.8126175E+02 -0.8126016E+02 0.7308341E+02 0.1180000E+00 | ||
| 112 | -0.7520512E+02 -0.7953283E+02 -0.7953116E+02 0.6985425E+02 0.1200000E+00 | ||
| 113 | -0.7360184E+02 -0.7786223E+02 -0.7786049E+02 0.6679027E+02 0.1220000E+00 | ||
| 114 | -0.7205467E+02 -0.7624934E+02 -0.7624752E+02 0.6388304E+02 0.1240000E+00 | ||
| 115 | -0.7055874E+02 -0.7468921E+02 -0.7468732E+02 0.6112455E+02 0.1260000E+00 | ||
| 116 | -0.6911358E+02 -0.7318138E+02 -0.7317942E+02 0.5850720E+02 0.1280000E+00 | ||
| 117 | -0.6771482E+02 -0.7172144E+02 -0.7171940E+02 0.5602376E+02 0.1300000E+00 | ||
| 118 | -0.6636214E+02 -0.7030904E+02 -0.7030693E+02 0.5366739E+02 0.1320000E+00 | ||
| 119 | -0.6505161E+02 -0.6894022E+02 -0.6893804E+02 0.5143159E+02 0.1340000E+00 | ||
| 120 | -0.6378303E+02 -0.6761476E+02 -0.6761251E+02 0.4931018E+02 0.1360000E+00 | ||
| 121 | -0.6255284E+02 -0.6632897E+02 -0.6632666E+02 0.4729730E+02 0.1380000E+00 | ||
| 122 | -0.6136093E+02 -0.6508333E+02 -0.6508094E+02 0.4538738E+02 0.1400000E+00 | ||
| 123 | -0.5908087E+02 -0.6269912E+02 -0.6269661E+02 0.4185559E+02 0.1440000E+00 | ||
| 124 | -0.5693497E+02 -0.6045311E+02 -0.6045048E+02 0.3867568E+02 0.1480000E+00 | ||
| 125 | -0.5490706E+02 -0.5833048E+02 -0.5832774E+02 0.3581240E+02 0.1520000E+00 | ||
| 126 | -0.5299250E+02 -0.5632548E+02 -0.5632265E+02 0.3323396E+02 0.1560000E+00 | ||
| 127 | -0.5117801E+02 -0.5442476E+02 -0.5442185E+02 0.3091174E+02 0.1600000E+00 | ||
| 128 | -0.4946011E+02 -0.5262454E+02 -0.5262154E+02 0.2881991E+02 0.1640000E+00 | ||
| 129 | -0.4782780E+02 -0.5091357E+02 -0.5091048E+02 0.2693524E+02 0.1680000E+00 | ||
| 130 | -0.4627845E+02 -0.4928903E+02 -0.4928587E+02 0.2523676E+02 0.1720000E+00 | ||
| 131 | -0.4480284E+02 -0.4774149E+02 -0.4773825E+02 0.2370561E+02 0.1760000E+00 | ||
| 132 | -0.4339903E+02 -0.4626887E+02 -0.4626555E+02 0.2232476E+02 0.1800000E+00 | ||
| 133 | -0.4205917E+02 -0.4486324E+02 -0.4485982E+02 0.2107891E+02 0.1840000E+00 | ||
| 134 | -0.4078187E+02 -0.4352312E+02 -0.4351958E+02 0.1995424E+02 0.1880000E+00 | ||
| 135 | -0.3956040E+02 -0.4224178E+02 -0.4223812E+02 0.1893833E+02 0.1920000E+00 | ||
| 136 | -0.3839376E+02 -0.4101827E+02 -0.4101445E+02 0.1801999E+02 0.1960000E+00 | ||
| 137 | -0.3727616E+02 -0.3984685E+02 -0.3984286E+02 0.1718915E+02 0.2000000E+00 | ||
| 138 | -0.3620690E+02 -0.3872696E+02 -0.3872277E+02 0.1643673E+02 0.2040000E+00 | ||
| 139 | -0.3518093E+02 -0.3765367E+02 -0.3764925E+02 0.1575459E+02 0.2080000E+00 | ||
| 140 | -0.3419781E+02 -0.3662670E+02 -0.3662203E+02 0.1513536E+02 0.2120000E+00 | ||
| 141 | -0.3325310E+02 -0.3564173E+02 -0.3563679E+02 0.1457246E+02 0.2160000E+00 | ||
| 142 | -0.3234658E+02 -0.3469866E+02 -0.3469345E+02 0.1405994E+02 0.2200000E+00 | ||
| 143 | -0.3147428E+02 -0.3379361E+02 -0.3378811E+02 0.1359246E+02 0.2240000E+00 | ||
| 144 | -0.3063618E+02 -0.3292656E+02 -0.3292078E+02 0.1316524E+02 0.2280000E+00 | ||
| 145 | -0.2982870E+02 -0.3209392E+02 -0.3208788E+02 0.1277395E+02 0.2320000E+00 | ||
| 146 | -0.2905197E+02 -0.3129569E+02 -0.3128939E+02 0.1241474E+02 0.2360000E+00 | ||
| 147 | -0.2830276E+02 -0.3052846E+02 -0.3052194E+02 0.1208412E+02 0.2400000E+00 | ||
| 148 | -0.2758130E+02 -0.2979222E+02 -0.2978550E+02 0.1177899E+02 0.2440000E+00 | ||
| 149 | -0.2688467E+02 -0.2908371E+02 -0.2907684E+02 0.1149654E+02 0.2480000E+00 | ||
| 150 | -0.2621319E+02 -0.2840292E+02 -0.2839591E+02 0.1123428E+02 0.2520000E+00 | ||
| 151 | -0.2556417E+02 -0.2774676E+02 -0.2773967E+02 0.1098997E+02 0.2560000E+00 | ||
| 152 | -0.2493803E+02 -0.2711527E+02 -0.2710811E+02 0.1076160E+02 0.2600000E+00 | ||
| 153 | -0.2433227E+02 -0.2650557E+02 -0.2649839E+02 0.1054737E+02 0.2640000E+00 | ||
| 154 | -0.2374739E+02 -0.2591779E+02 -0.2591062E+02 0.1034570E+02 0.2680000E+00 | ||
| 155 | -0.2318108E+02 -0.2534931E+02 -0.2534218E+02 0.1015514E+02 0.2720000E+00 | ||
| 156 | -0.2263386E+02 -0.2480036E+02 -0.2479329E+02 0.9974424E+01 0.2760000E+00 | ||
| 157 | -0.2210359E+02 -0.2426857E+02 -0.2426158E+02 0.9802422E+01 0.2800000E+00 | ||
| 158 | -0.2159086E+02 -0.2375429E+02 -0.2374740E+02 0.9638125E+01 0.2840000E+00 | ||
| 159 | -0.2109364E+02 -0.2325536E+02 -0.2324860E+02 0.9480637E+01 0.2880000E+00 | ||
| 160 | -0.2061255E+02 -0.2277227E+02 -0.2276563E+02 0.9329166E+01 0.2920000E+00 | ||
| 161 | -0.2014569E+02 -0.2230305E+02 -0.2229655E+02 0.9183009E+01 0.2960000E+00 | ||
| 162 | -0.1969372E+02 -0.2184864E+02 -0.2184228E+02 0.9041547E+01 0.3000000E+00 | ||
| 163 | -0.1882853E+02 -0.2097648E+02 -0.2097040E+02 0.8770583E+01 0.3080000E+00 | ||
| 164 | -0.1801631E+02 -0.2015516E+02 -0.2014935E+02 0.8512650E+01 0.3160000E+00 | ||
| 165 | -0.1724865E+02 -0.1937739E+02 -0.1937184E+02 0.8264966E+01 0.3240000E+00 | ||
| 166 | -0.1652664E+02 -0.1864364E+02 -0.1863834E+02 0.8025424E+01 0.3320000E+00 | ||
| 167 | -0.1584281E+02 -0.1794675E+02 -0.1794167E+02 0.7792449E+01 0.3400000E+00 | ||
| 168 | -0.1519858E+02 -0.1728820E+02 -0.1728334E+02 0.7564891E+01 0.3480000E+00 | ||
| 169 | -0.1458727E+02 -0.1666144E+02 -0.1665678E+02 0.7341929E+01 0.3560000E+00 | ||
| 170 | -0.1401053E+02 -0.1606820E+02 -0.1606374E+02 0.7122998E+01 0.3640000E+00 | ||
| 171 | -0.1346233E+02 -0.1550256E+02 -0.1549828E+02 0.6907731E+01 0.3720000E+00 | ||
| 172 | -0.1294447E+02 -0.1496642E+02 -0.1496230E+02 0.6695913E+01 0.3800000E+00 | ||
| 173 | -0.1245148E+02 -0.1445440E+02 -0.1445044E+02 0.6487436E+01 0.3880000E+00 | ||
| 174 | -0.1198522E+02 -0.1396847E+02 -0.1396467E+02 0.6282279E+01 0.3960000E+00 | ||
| 175 | -0.1154073E+02 -0.1350375E+02 -0.1350009E+02 0.6080477E+01 0.4040000E+00 | ||
| 176 | -0.1111990E+02 -0.1306222E+02 -0.1305869E+02 0.5882104E+01 0.4120000E+00 | ||
| 177 | -0.1071819E+02 -0.1263941E+02 -0.1263602E+02 0.5687258E+01 0.4200000E+00 | ||
| 178 | -0.1033748E+02 -0.1223727E+02 -0.1223401E+02 0.5496050E+01 0.4280000E+00 | ||
| 179 | -0.9973640E+01 -0.1185173E+02 -0.1184860E+02 0.5308597E+01 0.4360000E+00 | ||
| 180 | -0.9628498E+01 -0.1148468E+02 -0.1148168E+02 0.5125013E+01 0.4440000E+00 | ||
| 181 | -0.9298274E+01 -0.1113239E+02 -0.1112950E+02 0.4945404E+01 0.4520000E+00 | ||
| 182 | -0.8984746E+01 -0.1079667E+02 -0.1079390E+02 0.4769869E+01 0.4600000E+00 | ||
| 183 | -0.8684450E+01 -0.1047411E+02 -0.1047145E+02 0.4598492E+01 0.4680000E+00 | ||
| 184 | -0.8399097E+01 -0.1016644E+02 -0.1016390E+02 0.4431345E+01 0.4760000E+00 | ||
| 185 | -0.8125514E+01 -0.9870523E+01 -0.9868100E+01 0.4268486E+01 0.4840000E+00 | ||
| 186 | -0.7865330E+01 -0.9588022E+01 -0.9585710E+01 0.4109956E+01 0.4920000E+00 | ||
| 187 | -0.7615641E+01 -0.9316053E+01 -0.9313852E+01 0.3955783E+01 0.5000000E+00 | ||
| 188 | -0.7377991E+01 -0.9056183E+01 -0.9054090E+01 0.3805983E+01 0.5080000E+00 | ||
| 189 | -0.7149719E+01 -0.8805770E+01 -0.8803785E+01 0.3660556E+01 0.5160000E+00 | ||
| 190 | -0.6932283E+01 -0.8566289E+01 -0.8564411E+01 0.3519490E+01 0.5240000E+00 | ||
| 191 | -0.6723244E+01 -0.8335320E+01 -0.8333546E+01 0.3382762E+01 0.5320000E+00 | ||
| 192 | -0.6523973E+01 -0.8114244E+01 -0.8112573E+01 0.3250338E+01 0.5400000E+00 | ||
| 193 | -0.6332238E+01 -0.7900843E+01 -0.7899275E+01 0.3122174E+01 0.5480000E+00 | ||
| 194 | -0.6149320E+01 -0.7696410E+01 -0.7694942E+01 0.2998219E+01 0.5560000E+00 | ||
| 195 | -0.5973176E+01 -0.7498912E+01 -0.7497543E+01 0.2878412E+01 0.5640000E+00 | ||
| 196 | -0.5805002E+01 -0.7309553E+01 -0.7308282E+01 0.2762685E+01 0.5720000E+00 | ||
| 197 | -0.5642928E+01 -0.7126472E+01 -0.7125297E+01 0.2650967E+01 0.5800000E+00 | ||
| 198 | -0.5488069E+01 -0.6950791E+01 -0.6949710E+01 0.2543178E+01 0.5880000E+00 | ||
| 199 | -0.5338712E+01 -0.6780801E+01 -0.6779813E+01 0.2439236E+01 0.5960000E+00 | ||
| 200 | -0.5195893E+01 -0.6617551E+01 -0.6616654E+01 0.2339055E+01 0.6040000E+00 | ||
| 201 | -0.5058045E+01 -0.6459456E+01 -0.6458647E+01 0.2242546E+01 0.6120000E+00 | ||
| 202 | -0.4926129E+01 -0.6307589E+01 -0.6306867E+01 0.2149616E+01 0.6200000E+00 | ||
| 203 | -0.4675622E+01 -0.6017721E+01 -0.6017166E+01 0.1974121E+01 0.6360000E+00 | ||
| 204 | -0.4445670E+01 -0.5749102E+01 -0.5748706E+01 0.1811812E+01 0.6520000E+00 | ||
| 205 | -0.4230526E+01 -0.5496313E+01 -0.5496065E+01 0.1661919E+01 0.6680000E+00 | ||
| 206 | -0.4032409E+01 -0.5261418E+01 -0.5261306E+01 0.1523682E+01 0.6840000E+00 | ||
| 207 | -0.3846543E+01 -0.5039689E+01 -0.5039701E+01 0.1396350E+01 0.7000000E+00 | ||
| 208 | -0.3674838E+01 -0.4833033E+01 -0.4833155E+01 0.1279196E+01 0.7160000E+00 | ||
| 209 | -0.3513323E+01 -0.4637484E+01 -0.4637700E+01 0.1171518E+01 0.7320000E+00 | ||
| 210 | -0.3363636E+01 -0.4454678E+01 -0.4454972E+01 0.1072643E+01 0.7480000E+00 | ||
| 211 | -0.3222470E+01 -0.4281309E+01 -0.4281661E+01 0.9819290E+00 0.7640000E+00 | ||
| 212 | -0.3091222E+01 -0.4118767E+01 -0.4119158E+01 0.8987705E+00 0.7800000E+00 | ||
| 213 | -0.2967138E+01 -0.3964298E+01 -0.3964704E+01 0.8225939E+00 0.7960000E+00 | ||
| 214 | -0.2851403E+01 -0.3819079E+01 -0.3819475E+01 0.7528608E+00 0.8120000E+00 | ||
| 215 | -0.2741725E+01 -0.3680812E+01 -0.3681172E+01 0.6890664E+00 0.8280000E+00 | ||
| 216 | -0.2639104E+01 -0.3550493E+01 -0.3550789E+01 0.6307393E+00 0.8440000E+00 | ||
| 217 | -0.2541630E+01 -0.3426204E+01 -0.3426405E+01 0.5774399E+00 0.8600000E+00 | ||
| 218 | -0.2450147E+01 -0.3308787E+01 -0.3308860E+01 0.5287596E+00 0.8760000E+00 | ||
| 219 | -0.2363061E+01 -0.3196638E+01 -0.3196549E+01 0.4843190E+00 0.8920000E+00 | ||
| 220 | -0.2281084E+01 -0.3090467E+01 -0.3090180E+01 0.4437668E+00 0.9080000E+00 | ||
| 221 | -0.2202882E+01 -0.2988933E+01 -0.2988411E+01 0.4067778E+00 0.9240000E+00 | ||
| 222 | -0.2129056E+01 -0.2892634E+01 -0.2891840E+01 0.3730519E+00 0.9400000E+00 | ||
| 223 | -0.2058489E+01 -0.2800443E+01 -0.2799340E+01 0.3423121E+00 0.9560000E+00 | ||
| 224 | -0.1991689E+01 -0.2712863E+01 -0.2711416E+01 0.3143033E+00 0.9720000E+00 | ||
| 225 | -0.1927716E+01 -0.2628944E+01 -0.2627118E+01 0.2887906E+00 0.9880000E+00 | ||
| 226 | -0.1867000E+01 -0.2549106E+01 -0.2546871E+01 0.2655581E+00 0.1004000E+01 | ||
| 227 | -0.1808751E+01 -0.2472542E+01 -0.2469873E+01 0.2444075E+00 0.1020000E+01 | ||
| 228 | -0.1753332E+01 -0.2399598E+01 -0.2396476E+01 0.2251568E+00 0.1036000E+01 | ||
| 229 | -0.1700075E+01 -0.2329581E+01 -0.2325996E+01 0.2076389E+00 0.1052000E+01 | ||
| 230 | -0.1649290E+01 -0.2262775E+01 -0.2258726E+01 0.1917008E+00 0.1068000E+01 | ||
| 231 | -0.1600410E+01 -0.2198578E+01 -0.2194075E+01 0.1772025E+00 0.1084000E+01 | ||
| 232 | -0.1553701E+01 -0.2137216E+01 -0.2132284E+01 0.1640157E+00 0.1100000E+01 | ||
| 233 | -0.1508678E+01 -0.2078159E+01 -0.2072837E+01 0.1520230E+00 0.1116000E+01 | ||
| 234 | -0.1465571E+01 -0.2021586E+01 -0.2015928E+01 0.1411172E+00 0.1132000E+01 | ||
| 235 | -0.1423964E+01 -0.1967027E+01 -0.1961103E+01 0.1312003E+00 0.1148000E+01 | ||
| 236 | -0.1384055E+01 -0.1914622E+01 -0.1908519E+01 0.1221829E+00 0.1164000E+01 | ||
| 237 | -0.1345487E+01 -0.1863954E+01 -0.1857772E+01 0.1139832E+00 0.1180000E+01 | ||
| 238 | -0.1308434E+01 -0.1815136E+01 -0.1808990E+01 0.1065267E+00 0.1196000E+01 | ||
| 239 | -0.1272584E+01 -0.1767803E+01 -0.1761817E+01 0.9974546E-01 0.1212000E+01 | ||
| 240 | -0.1238091E+01 -0.1722058E+01 -0.1716363E+01 0.9357756E-01 0.1228000E+01 | ||
| 241 | -0.1204683E+01 -0.1677566E+01 -0.1672305E+01 0.8796654E-01 0.1244000E+01 | ||
| 242 | -0.1172496E+01 -0.1634699E+01 -0.1629912E+01 0.8286100E-01 0.1260000E+01 | ||
| 243 | -0.1111034E+01 -0.1552141E+01 -0.1548759E+01 0.7398329E-01 0.1292000E+01 | ||
| 244 | -0.1053781E+01 -0.1473828E+01 -0.1472483E+01 0.6661834E-01 0.1324000E+01 | ||
| 245 | -0.9997888E+00 -0.1400499E+01 -0.1401124E+01 0.6049638E-01 0.1356000E+01 | ||
| 246 | -0.9493000E+00 -0.1332437E+01 -0.1334992E+01 0.5539439E-01 0.1388000E+01 | ||
| 247 | -0.9015512E+00 -0.1269951E+01 -0.1273997E+01 0.5112811E-01 0.1420000E+01 | ||
| 248 | -0.8567650E+00 -0.1213951E+01 -0.1218776E+01 0.4754545E-01 0.1452000E+01 | ||
| 249 | -0.8143093E+00 -0.1164221E+01 -0.1168861E+01 0.4452084E-01 0.1484000E+01 | ||
| 250 | -0.7743937E+00 -0.1120850E+01 -0.1124218E+01 0.4195074E-01 0.1516000E+01 | ||
| 251 | -0.7364808E+00 -0.1082695E+01 -0.1083725E+01 0.3974985E-01 0.1548000E+01 | ||
| 252 | -0.7007718E+00 -0.1049020E+01 -0.1046827E+01 0.3784805E-01 0.1580000E+01 | ||
| 253 | -0.6667987E+00 -0.1018339E+01 -0.1012329E+01 0.3618785E-01 0.1612000E+01 | ||
| 254 | -0.6347570E+00 -0.9899549E+00 -0.9798729E+00 0.3472230E-01 0.1644000E+01 | ||
| 255 | -0.6042310E+00 -0.9628122E+00 -0.9487126E+00 0.3341320E-01 0.1676000E+01 | ||
| 256 | -0.5754114E+00 -0.9367280E+00 -0.9189042E+00 0.3222963E-01 0.1708000E+01 | ||
| 257 | -0.5479233E+00 -0.9111737E+00 -0.8900652E+00 0.3114664E-01 0.1740000E+01 | ||
| 258 | -0.5219526E+00 -0.8863284E+00 -0.8624346E+00 0.3014423E-01 0.1772000E+01 | ||
| 259 | -0.4971574E+00 -0.8619231E+00 -0.8357382E+00 0.2920641E-01 0.1804000E+01 | ||
| 260 | -0.4737188E+00 -0.8382449E+00 -0.8102159E+00 0.2832052E-01 0.1836000E+01 | ||
| 261 | -0.4513220E+00 -0.8150882E+00 -0.7855948E+00 0.2747653E-01 0.1868000E+01 | ||
| 262 | -0.4301432E+00 -0.7927277E+00 -0.7620769E+00 0.2666662E-01 0.1900000E+01 | ||
| 263 | -0.4098909E+00 -0.7709543E+00 -0.7393852E+00 0.2588470E-01 0.1932000E+01 | ||
| 264 | -0.3907354E+00 -0.7500038E+00 -0.7176972E+00 0.2512610E-01 0.1964000E+01 | ||
| 265 | -0.3724062E+00 -0.7296567E+00 -0.6967459E+00 0.2438728E-01 0.1996000E+01 | ||
| 266 | -0.3550673E+00 -0.7101160E+00 -0.6766974E+00 0.2366561E-01 0.2028000E+01 | ||
| 267 | -0.3384670E+00 -0.6911601E+00 -0.6573023E+00 0.2295918E-01 0.2060000E+01 | ||
| 268 | -0.3227623E+00 -0.6729690E+00 -0.6387208E+00 0.2226662E-01 0.2092000E+01 | ||
| 269 | -0.3077190E+00 -0.6553265E+00 -0.6207223E+00 0.2158701E-01 0.2124000E+01 | ||
| 270 | -0.2934872E+00 -0.6383971E+00 -0.6034618E+00 0.2091978E-01 0.2156000E+01 | ||
| 271 | -0.2798485E+00 -0.6219742E+00 -0.5867265E+00 0.2026461E-01 0.2188000E+01 | ||
| 272 | -0.2669456E+00 -0.6062106E+00 -0.5706650E+00 0.1962136E-01 0.2220000E+01 | ||
| 273 | -0.2545754E+00 -0.5909118E+00 -0.5550803E+00 0.1899002E-01 0.2252000E+01 | ||
| 274 | -0.2428730E+00 -0.5762208E+00 -0.5401141E+00 0.1837071E-01 0.2284000E+01 | ||
| 275 | -0.2316495E+00 -0.5619556E+00 -0.5255836E+00 0.1776357E-01 0.2316000E+01 | ||
| 276 | -0.2210324E+00 -0.5482501E+00 -0.5116226E+00 0.1716881E-01 0.2348000E+01 | ||
| 277 | -0.2108462E+00 -0.5349346E+00 -0.4980613E+00 0.1658662E-01 0.2380000E+01 | ||
| 278 | -0.2012111E+00 -0.5221348E+00 -0.4850254E+00 0.1601722E-01 0.2412000E+01 | ||
| 279 | -0.1919639E+00 -0.5096924E+00 -0.4723569E+00 0.1546081E-01 0.2444000E+01 | ||
| 280 | -0.1832175E+00 -0.4977253E+00 -0.4601740E+00 0.1491755E-01 0.2476000E+01 | ||
| 281 | -0.1748207E+00 -0.4860862E+00 -0.4483281E+00 0.1438759E-01 0.2508000E+01 | ||
| 282 | -0.1668792E+00 -0.4748784E+00 -0.4369330E+00 0.1387106E-01 0.2540000E+01 | ||
| 283 | -0.1519300E+00 -0.4533747E+00 -0.4150697E+00 0.1287855E-01 0.2604000E+01 | ||
| 284 | -0.1385606E+00 -0.4334250E+00 -0.3947919E+00 0.1194032E-01 0.2668000E+01 | ||
| 285 | -0.1262177E+00 -0.4144804E+00 -0.3755696E+00 0.1105607E-01 0.2732000E+01 | ||
| 286 | -0.1151813E+00 -0.3968488E+00 -0.3576985E+00 0.1022509E-01 0.2796000E+01 | ||
| 287 | -0.1049818E+00 -0.3800720E+00 -0.3407204E+00 0.9446185E-02 0.2860000E+01 | ||
| 288 | -0.9586293E-01 -0.3644036E+00 -0.3248878E+00 0.8717863E-02 0.2924000E+01 | ||
| 289 | -0.8742742E-01 -0.3494545E+00 -0.3098101E+00 0.8038327E-02 0.2988000E+01 | ||
| 290 | -0.7988579E-01 -0.3354404E+00 -0.2957027E+00 0.7405589E-02 0.3052000E+01 | ||
| 291 | -0.7290285E-01 -0.3220310E+00 -0.2822344E+00 0.6817501E-02 0.3116000E+01 | ||
| 292 | -0.6665946E-01 -0.3094103E+00 -0.2695892E+00 0.6271827E-02 0.3180000E+01 | ||
| 293 | -0.6087338E-01 -0.2972994E+00 -0.2574886E+00 0.5766276E-02 0.3244000E+01 | ||
| 294 | -0.5569926E-01 -0.2858555E+00 -0.2460910E+00 0.5298551E-02 0.3308000E+01 | ||
| 295 | -0.5089992E-01 -0.2748450E+00 -0.2351639E+00 0.4866365E-02 0.3372000E+01 | ||
| 296 | -0.4660712E-01 -0.2644031E+00 -0.2248447E+00 0.4467480E-02 0.3436000E+01 | ||
| 297 | -0.4262181E-01 -0.2543353E+00 -0.2149415E+00 0.4099715E-02 0.3500000E+01 | ||
| 298 | -0.3905594E-01 -0.2447585E+00 -0.2055748E+00 0.3760969E-02 0.3564000E+01 | ||
| 299 | -0.3574266E-01 -0.2355122E+00 -0.1965873E+00 0.3449222E-02 0.3628000E+01 | ||
| 300 | -0.3277686E-01 -0.2266977E+00 -0.1880852E+00 0.3162550E-02 0.3692000E+01 | ||
| 301 | -0.3001881E-01 -0.2181828E+00 -0.1799408E+00 0.2899126E-02 0.3756000E+01 | ||
| 302 | -0.2754880E-01 -0.2100555E+00 -0.1722479E+00 0.2657222E-02 0.3820000E+01 | ||
| 303 | -0.2524987E-01 -0.2022069E+00 -0.1649028E+00 0.2435210E-02 0.3884000E+01 | ||
| 304 | -0.2318989E-01 -0.1947127E+00 -0.1579876E+00 0.2231562E-02 0.3948000E+01 | ||
| 305 | -0.2127099E-01 -0.1874827E+00 -0.1514179E+00 0.2044845E-02 0.4012000E+01 | ||
| 306 | -0.1955048E-01 -0.1805814E+00 -0.1452648E+00 0.1873723E-02 0.4076000E+01 | ||
| 307 | -0.1794647E-01 -0.1739333E+00 -0.1394586E+00 0.1716950E-02 0.4140000E+01 | ||
| 308 | -0.1650734E-01 -0.1675924E+00 -0.1340594E+00 0.1573368E-02 0.4204000E+01 | ||
| 309 | -0.1516454E-01 -0.1614947E+00 -0.1290088E+00 0.1441900E-02 0.4268000E+01 | ||
| 310 | -0.1395892E-01 -0.1556847E+00 -0.1243564E+00 0.1321551E-02 0.4332000E+01 | ||
| 311 | -0.1283309E-01 -0.1501076E+00 -0.1200515E+00 0.1211399E-02 0.4396000E+01 | ||
| 312 | -0.1182151E-01 -0.1447993E+00 -0.1161341E+00 0.1110594E-02 0.4460000E+01 | ||
| 313 | -0.1087613E-01 -0.1397124E+00 -0.1125590E+00 0.1018350E-02 0.4524000E+01 | ||
| 314 | -0.1002603E-01 -0.1348758E+00 -0.1093569E+00 0.9339444E-03 0.4588000E+01 | ||
| 315 | -0.9230932E-02 -0.1302480E+00 -0.1064866E+00 0.8567129E-03 0.4652000E+01 | ||
| 316 | -0.8515411E-02 -0.1258518E+00 -0.1039701E+00 0.7860439E-03 0.4716000E+01 | ||
| 317 | -0.7845663E-02 -0.1216511E+00 -0.1017683E+00 0.7213763E-03 0.4780000E+01 | ||
| 318 | -0.7242465E-02 -0.1176638E+00 -0.9989635E-01 0.6621957E-03 0.4844000E+01 | ||
| 319 | -0.6677425E-02 -0.1138581E+00 -0.9831432E-01 0.6080303E-03 0.4908000E+01 | ||
| 320 | -0.6168124E-02 -0.1102479E+00 -0.9703127E-01 0.5584483E-03 0.4972000E+01 | ||
| 321 | -0.5690686E-02 -0.1068102E+00 -0.9602603E-01 0.5130545E-03 0.5036000E+01 | ||
| 322 | -0.5260000E-02 -0.1034991E+00 -0.9505341E-01 0.4714874E-03 0.5100000E+01 | ||
| 323 | -0.4477611E-02 -0.9738560E-01 -0.9418036E-01 0.3985415E-03 0.5228000E+01 | ||
| 324 | -0.3839408E-02 -0.9208111E-01 -0.9434847E-01 0.3372963E-03 0.5356000E+01 | ||
| 325 | -0.3276214E-02 -0.8712605E-01 -0.9447003E-01 0.2858183E-03 0.5484000E+01 | ||
| 326 | -0.2815384E-02 -0.8275498E-01 -0.9470701E-01 0.2425016E-03 0.5612000E+01 | ||
| 327 | -0.2407649E-02 -0.7880597E-01 -0.9443366E-01 0.2060095E-03 0.5740000E+01 | ||
| 328 | -0.2073021E-02 -0.7530793E-01 -0.9316562E-01 0.1752304E-03 0.5868000E+01 | ||
| 329 | -0.1776219E-02 -0.7218882E-01 -0.9039150E-01 0.1492396E-03 0.5996000E+01 | ||
| 330 | -0.1531937E-02 -0.6944847E-01 -0.8585081E-01 0.1272676E-03 0.6124000E+01 | ||
| 331 | -0.1314767E-02 -0.6703940E-01 -0.7957347E-01 0.1086725E-03 0.6252000E+01 | ||
| 332 | -0.1135546E-02 -0.6495564E-01 -0.7195440E-01 0.9291864E-04 0.6380000E+01 | ||
| 333 | -0.9758780E-03 -0.6316060E-01 -0.6356518E-01 0.7955734E-04 0.6508000E+01 | ||
| 334 | -0.8437878E-03 -0.6164610E-01 -0.5502886E-01 0.6821233E-04 0.6636000E+01 | ||
| 335 | -0.7258824E-03 -0.6038230E-01 -0.4683629E-01 0.5856753E-04 0.6764000E+01 | ||
| 336 | -0.6281358E-03 -0.5936004E-01 -0.3932925E-01 0.5035729E-04 0.6892000E+01 | ||
| 337 | -0.5407396E-03 -0.5855440E-01 -0.3267298E-01 0.4335820E-04 0.7020000E+01 | ||
| 338 | -0.4681628E-03 -0.5795552E-01 -0.2692364E-01 0.3738247E-04 0.7148000E+01 | ||
| 339 | -0.4031804E-03 -0.5754156E-01 -0.2204530E-01 0.3227223E-04 0.7276000E+01 | ||
| 340 | -0.3491509E-03 -0.5730096E-01 -0.1796735E-01 0.2789478E-04 0.7404000E+01 | ||
| 341 | -0.3007215E-03 -0.5721191E-01 -0.1459036E-01 0.2413855E-04 0.7532000E+01 | ||
| 342 | -0.2604263E-03 -0.5725804E-01 -0.1181837E-01 0.2090971E-04 0.7660000E+01 | ||
| 343 | -0.2242786E-03 -0.5741189E-01 -0.9553631E-02 0.1812931E-04 0.7788000E+01 | ||
| 344 | -0.1941961E-03 -0.5764507E-01 -0.7713419E-02 0.1573087E-04 0.7916000E+01 | ||
| 345 | -0.1671959E-03 -0.5791416E-01 -0.6221017E-02 0.1365834E-04 0.8044000E+01 | ||
| 346 | -0.1447322E-03 -0.5816658E-01 -0.5015104E-02 0.1186447E-04 0.8172000E+01 | ||
| 347 | -0.1245648E-03 -0.5832927E-01 -0.4040885E-02 0.1030935E-04 0.8300000E+01 | ||
| 348 | -0.1077970E-03 -0.5831462E-01 -0.3255975E-02 0.8959263E-05 0.8428000E+01 | ||
| 349 | -0.9274227E-04 -0.5801756E-01 -0.2623018E-02 0.7785684E-05 0.8556000E+01 | ||
| 350 | -0.8023715E-04 -0.5733050E-01 -0.2113778E-02 0.6764473E-05 0.8684000E+01 | ||
| 351 | -0.6901030E-04 -0.5615555E-01 -0.1703398E-02 0.5875158E-05 0.8812000E+01 | ||
| 352 | -0.5969468E-04 -0.5442941E-01 -0.1373437E-02 0.5100342E-05 0.8940000E+01 | ||
| 353 | -0.5133223E-04 -0.5213802E-01 -0.1107546E-02 0.4425190E-05 0.9068000E+01 | ||
| 354 | -0.4440046E-04 -0.4932734E-01 -0.8937972E-03 0.3836992E-05 0.9196000E+01 | ||
| 355 | -0.3817843E-04 -0.4609416E-01 -0.7214846E-03 0.3324793E-05 0.9324000E+01 | ||
| 356 | -0.3302527E-04 -0.4256982E-01 -0.5829321E-03 0.2879091E-05 0.9452000E+01 | ||
| 357 | -0.2839972E-04 -0.3889556E-01 -0.4711485E-03 0.2491593E-05 0.9580000E+01 | ||
| 358 | -0.2457111E-04 -0.3520294E-01 -0.3811972E-03 0.2155026E-05 0.9708000E+01 | ||
| 359 | -0.2113409E-04 -0.3160316E-01 -0.3085691E-03 0.1862988E-05 0.9836000E+01 | ||
| 360 | -0.1829022E-04 -0.2817333E-01 -0.2499891E-03 0.1609836E-05 0.9964000E+01 | ||
| 361 | -0.1573666E-04 -0.2497170E-01 -0.2027310E-03 0.1390594E-05 0.1009200E+02 | ||
| 362 | -0.1362402E-04 -0.2210784E-01 -0.1652864E-03 0.1200876E-05 0.1022000E+02 | ||
| 363 | -0.1003603E-04 -0.1699821E-01 -0.1084125E-03 0.8950437E-06 0.1047600E+02 | ||
| 364 | -0.7578580E-05 -0.1282903E-01 -0.7098972E-04 0.6668682E-06 0.1073200E+02 | ||
| 365 | -0.5593245E-05 -0.9722369E-02 -0.4731680E-04 0.4969029E-06 0.1098800E+02 | ||
| 366 | -0.4231523E-05 -0.7312414E-02 -0.3158502E-04 0.3703987E-06 0.1124400E+02 | ||
| 367 | -0.3129260E-05 -0.5490480E-02 -0.2113629E-04 0.2762676E-06 0.1150000E+02 | ||
| 368 | -0.2371758E-05 -0.4114605E-02 -0.1424593E-04 0.2062147E-06 0.1175600E+02 | ||
| 369 | -0.1757350E-05 -0.3081342E-02 -0.9610490E-05 0.1540572E-06 0.1201200E+02 | ||
| 370 | -0.1334218E-05 -0.2306980E-02 -0.6544879E-05 0.1151978E-06 0.1226800E+02 | ||
| 371 | -0.9903398E-06 -0.1727497E-02 -0.4462305E-05 0.8622252E-07 0.1252400E+02 | ||
| 372 | -0.7530195E-06 -0.1294164E-02 -0.3079240E-05 0.6459763E-07 0.1278000E+02 | ||
| 373 | -0.5597898E-06 -0.9701390E-03 -0.2129932E-05 0.4844297E-07 0.1303600E+02 | ||
| 374 | -0.4261723E-06 -0.7278158E-03 -0.1496628E-05 0.3636283E-07 0.1329200E+02 | ||
| 375 | -0.3171916E-06 -0.5464862E-03 -0.1056886E-05 0.2732050E-07 0.1354800E+02 | ||
| 376 | -0.2416965E-06 -0.4107180E-03 -0.7620499E-06 0.2054534E-07 0.1380400E+02 | ||
| 377 | -0.1800252E-06 -0.3089713E-03 -0.5546206E-06 0.1546393E-07 0.1406000E+02 | ||
| 378 | -0.1372363E-06 -0.2326598E-03 -0.4147161E-06 0.1164921E-07 0.1431600E+02 | ||
| 379 | -0.1022343E-06 -0.1753656E-03 -0.3147953E-06 0.8782751E-08 0.1457200E+02 | ||
| 380 | -0.7791838E-07 -0.1323115E-03 -0.2468912E-06 0.6626895E-08 0.1482800E+02 | ||
| 381 | -0.5800449E-07 -0.9992339E-04 -0.1975415E-06 0.5004068E-08 0.1508400E+02 | ||
| 382 | -0.4415836E-07 -0.7553729E-04 -0.1636582E-06 0.3781453E-08 0.1534000E+02 | ||
| 383 | -0.3280884E-07 -0.5715659E-04 -0.1385254E-06 0.2859604E-08 0.1559600E+02 | ||
| 384 | -0.2491523E-07 -0.4329052E-04 -0.1210146E-06 0.2163988E-08 0.1585200E+02 | ||
| 385 | -0.1844174E-07 -0.3281947E-04 -0.1077074E-06 0.1638689E-08 0.1610800E+02 | ||
| 386 | -0.1394203E-07 -0.2490580E-04 -0.9823689E-07 0.1241718E-08 0.1636400E+02 | ||
| 387 | -0.1025218E-07 -0.1891908E-04 -0.9082938E-07 0.9415138E-09 0.1662000E+02 | ||
| 388 | -0.7692438E-08 -0.1438669E-04 -0.8539718E-07 0.7143355E-09 0.1687600E+02 | ||
| 389 | -0.5595531E-08 -0.1095216E-04 -0.8100327E-07 0.5423066E-09 0.1713200E+02 | ||
| 390 | -0.4147089E-08 -0.8347732E-05 -0.7765120E-07 0.4119569E-09 0.1738800E+02 | ||
| 391 | -0.2963576E-08 -0.6371051E-05 -0.7483810E-07 0.3131281E-09 0.1764400E+02 | ||
| 392 | -0.2152832E-08 -0.4869813E-05 -0.7258860E-07 0.2381534E-09 0.1790000E+02 | ||
| 393 | -0.1493862E-08 -0.3728723E-05 -0.7063156E-07 0.1812426E-09 0.1815600E+02 | ||
| 394 | -0.1049466E-08 -0.2860763E-05 -0.6898356E-07 0.1380194E-09 0.1841200E+02 | ||
| 395 | -0.6919968E-09 -0.2200249E-05 -0.6751792E-07 0.1051739E-09 0.1866800E+02 | ||
| 396 | -0.4581243E-09 -0.1696551E-05 -0.6621113E-07 0.8020129E-10 0.1892400E+02 | ||
| 397 | -0.2739404E-09 -0.1314388E-05 -0.6501141E-07 0.6120459E-10 0.1918000E+02 | ||
| 398 | -0.1609299E-09 -0.1017272E-05 -0.6392195E-07 0.4674641E-10 0.1943600E+02 | ||
| 399 | -0.7618943E-10 -0.8068822E-06 -0.6289578E-07 0.3573691E-10 0.1969200E+02 | ||
| 400 | -0.3236183E-10 -0.6020435E-06 -0.6193826E-07 0.2734932E-10 0.1994800E+02 | ||
| 401 | -0.4470313E-11 -0.5522402E-06 -0.6102801E-07 0.2095607E-10 0.2020400E+02 | ||
| 402 | 0.0000000E+00 -0.4950088E-06 -0.6016242E-07 0.1608056E-10 0.2046000E+02 | ||
diff --git a/src/labat/apotin.dat b/src/labat/apotin.dat new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/src/labat/apotin.dat | |||
diff --git a/src/labat/apotout.dat b/src/labat/apotout.dat new file mode 100644 index 0000000..c8b9361 --- /dev/null +++ b/src/labat/apotout.dat | |||
| @@ -0,0 +1,402 @@ | |||
| 1 | 23 z,ion: 13. 0. jblock,nbl,c: 10 40 0.2000000 | ||
| 2 | 0. -13. 0. 1388.3896 | ||
| 3 | 0.0005 -25955.4876 -26035.9849 1388.3896 | ||
| 4 | 0.001 -12955.4904 -13002.2249 1370.4157 | ||
| 5 | 0.0015 -8622.15995 -8657.40852 1352.67242 | ||
| 6 | 0.002 -6455.49896 -6484.42383 1335.15901 | ||
| 7 | 0.0025 -5155.50461 -5180.8752 1317.87344 | ||
| 8 | 0.003 -4288.84631 -4311.74825 1300.81287 | ||
| 9 | 0.0035 -3669.807 -3690.95678 1283.97453 | ||
| 10 | 0.004 -3205.53222 -3225.34899 1267.35557 | ||
| 11 | 0.0045 -2844.43198 -2863.20362 1250.9532 | ||
| 12 | 0.005 -2555.5565 -2573.48224 1234.76462 | ||
| 13 | 0.0055 -2319.20618 -2336.43164 1218.7871 | ||
| 14 | 0.006 -2122.25227 -2138.88651 1203.01789 | ||
| 15 | 0.0065 -1955.60128 -1971.72833 1187.45432 | ||
| 16 | 0.007 -1812.7622 -1828.44808 1172.09372 | ||
| 17 | 0.0075 -1688.97061 -1704.26822 1156.93347 | ||
| 18 | 0.008 -1580.65752 -1595.60984 1141.97097 | ||
| 19 | 0.0085 -1485.0894 -1499.73187 1127.20367 | ||
| 20 | 0.009 -1400.14442 -1414.50662 1112.62903 | ||
| 21 | 0.0095 -1324.14322 -1338.25008 1098.24456 | ||
| 22 | 0.01 -1255.74651 -1269.61925 1084.04779 | ||
| 23 | 0.0105 -1193.86593 -1207.52278 1070.03628 | ||
| 24 | 0.011 -1137.61514 -1151.07185 1056.20763 | ||
| 25 | 0.0115 -1086.25784 -1099.52814 1042.55946 | ||
| 26 | 0.012 -1039.1845 -1052.28042 1029.08944 | ||
| 27 | 0.0125 -995.879101 -1008.81125 1015.79523 | ||
| 28 | 0.013 -955.908974 -968.686775 1002.67457 | ||
| 29 | 0.0135 -918.901619 -931.533454 989.725183 | ||
| 30 | 0.014 -884.541644 -897.03502 976.944851 | ||
| 31 | 0.0145 -852.553298 -864.914965 964.331372 | ||
| 32 | 0.015 -822.701413 -834.937463 951.882574 | ||
| 33 | 0.0155 -794.777386 -806.893339 939.596312 | ||
| 34 | 0.016 -768.602423 -780.603299 927.470469 | ||
| 35 | 0.0165 -744.015705 -755.906084 915.502957 | ||
| 36 | 0.017 -720.878987 -732.66306 903.691711 | ||
| 37 | 0.0175 -699.066205 -710.747819 892.034694 | ||
| 38 | 0.018 -678.468878 -690.051574 880.529897 | ||
| 39 | 0.0185 -658.986714 -670.473757 869.175334 | ||
| 40 | 0.019 -640.533471 -651.927899 857.969045 | ||
| 41 | 0.0195 -623.0283 -634.332869 846.909096 | ||
| 42 | 0.02 -606.401847 -617.619387 835.993579 | ||
| 43 | 0.021 -575.529149 -586.579343 814.58832 | ||
| 44 | 0.022 -547.476089 -558.367253 793.738484 | ||
| 45 | 0.023 -521.868786 -532.608675 773.429655 | ||
| 46 | 0.024 -498.407843 -509.003021 753.647795 | ||
| 47 | 0.025 -476.829838 -487.286223 734.37922 | ||
| 48 | 0.026 -456.92351 -467.246399 715.610606 | ||
| 49 | 0.027 -438.497498 -448.691673 697.328962 | ||
| 50 | 0.028 -421.398897 -431.468693 679.52164 | ||
| 51 | 0.029 -405.485005 -415.434375 662.176315 | ||
| 52 | 0.03 -390.642765 -400.475327 645.280982 | ||
| 53 | 0.031 -376.76332 -386.482402 628.823944 | ||
| 54 | 0.032 -363.761548 -373.37022 612.793809 | ||
| 55 | 0.033 -351.552739 -361.05385 597.179478 | ||
| 56 | 0.034 -340.071808 -349.468005 581.970143 | ||
| 57 | 0.035 -329.251666 -338.545419 567.155272 | ||
| 58 | 0.036 -319.041882 -328.235504 552.724611 | ||
| 59 | 0.037 -309.388483 -318.484145 538.668167 | ||
| 60 | 0.038 -300.251946 -309.251693 524.976213 | ||
| 61 | 0.039 -291.588234 -300.493996 511.639269 | ||
| 62 | 0.04 -283.366067 -292.17967 498.648106 | ||
| 63 | 0.041 -275.549056 -284.272233 485.993731 | ||
| 64 | 0.042 -268.112233 -276.746632 473.66739 | ||
| 65 | 0.043 -261.025184 -269.572375 461.660553 | ||
| 66 | 0.044 -254.267834 -262.729315 449.964914 | ||
| 67 | 0.045 -247.814496 -256.191702 438.572383 | ||
| 68 | 0.046 -241.648926 -249.94323 427.475082 | ||
| 69 | 0.047 -235.749227 -243.961948 416.665337 | ||
| 70 | 0.048 -230.102184 -238.23459 406.135674 | ||
| 71 | 0.049 -224.688965 -232.742278 395.878815 | ||
| 72 | 0.05 -219.498776 -227.474172 385.887672 | ||
| 73 | 0.051 -214.515292 -222.41391 376.155341 | ||
| 74 | 0.052 -209.729663 -217.552602 366.675098 | ||
| 75 | 0.053 -205.127637 -212.875962 357.440396 | ||
| 76 | 0.054 -200.701935 -208.376678 348.444857 | ||
| 77 | 0.055 -196.440033 -204.042195 339.682271 | ||
| 78 | 0.056 -192.335932 -199.866487 331.14659 | ||
| 79 | 0.057 -188.37856 -195.83845 322.831922 | ||
| 80 | 0.058 -184.562965 -191.95313 314.732531 | ||
| 81 | 0.059 -180.879305 -188.200564 306.842829 | ||
| 82 | 0.06 -177.323488 -184.577119 299.157376 | ||
| 83 | 0.062 -170.563242 -177.68364 284.378151 | ||
| 84 | 0.064 -164.243976 -171.233797 270.354108 | ||
| 85 | 0.066 -158.31648 -165.179383 257.04658 | ||
| 86 | 0.068 -152.754381 -159.49325 244.418904 | ||
| 87 | 0.07 -147.518073 -154.13582 232.436292 | ||
| 88 | 0.072 -142.587816 -149.087217 221.065756 | ||
| 89 | 0.074 -137.931267 -144.315012 210.275993 | ||
| 90 | 0.076 -133.533522 -139.804212 200.037321 | ||
| 91 | 0.078 -129.367834 -135.527992 190.321573 | ||
| 92 | 0.08 -125.422866 -131.474943 181.102036 | ||
| 93 | 0.082 -121.676257 -127.622637 172.353361 | ||
| 94 | 0.084 -118.119334 -123.962337 164.051505 | ||
| 95 | 0.086 -114.733219 -120.475109 156.173655 | ||
| 96 | 0.088 -111.511247 -117.154234 148.698169 | ||
| 97 | 0.09 -108.437347 -113.983587 141.604509 | ||
| 98 | 0.092 -105.506378 -110.957984 134.873195 | ||
| 99 | 0.094 -102.704554 -108.063593 128.485738 | ||
| 100 | 0.096 -100.027905 -105.296401 122.424596 | ||
| 101 | 0.098 -97.4645262 -102.644462 116.673124 | ||
| 102 | 0.1 -95.0113453 -100.104668 111.215528 | ||
| 103 | 0.102 -92.6580213 -97.666641 106.036817 | ||
| 104 | 0.104 -90.4021799 -95.3279715 101.122768 | ||
| 105 | 0.106 -88.2347892 -93.0795947 96.4598809 | ||
| 106 | 0.108 -86.1540174 -90.9196464 92.0353461 | ||
| 107 | 0.11 -84.151938 -88.840169 87.8370041 | ||
| 108 | 0.112 -82.2271432 -86.8397243 83.8533162 | ||
| 109 | 0.114 -80.3726458 -84.9112952 80.0733299 | ||
| 110 | 0.116 -78.5873706 -83.0537776 76.4866505 | ||
| 111 | 0.118 -76.8651328 -81.2609577 73.0834112 | ||
| 112 | 0.12 -75.2051194 -79.5319941 69.8542473 | ||
| 113 | 0.122 -73.6018352 -77.8613631 66.7902694 | ||
| 114 | 0.124 -72.0546739 -76.24843 63.8830401 | ||
| 115 | 0.126 -70.5587356 -74.6882666 61.1245496 | ||
| 116 | 0.128 -69.113578 -73.1804017 58.5071955 | ||
| 117 | 0.13 -67.7148172 -71.7204225 56.0237603 | ||
| 118 | 0.132 -66.362141 -70.307988 53.6673935 | ||
| 119 | 0.134 -65.0516147 -68.9391302 51.4315911 | ||
| 120 | 0.136 -63.7830296 -67.6136311 49.3101797 | ||
| 121 | 0.138 -62.5528436 -66.327814 47.2972981 | ||
| 122 | 0.14 -61.3609303 -65.0821349 45.387383 | ||
| 123 | 0.144 -59.0808659 -62.6978646 41.8555907 | ||
| 124 | 0.148 -56.9349658 -60.4517957 38.6756821 | ||
| 125 | 0.152 -54.9070555 -58.3291087 35.8123973 | ||
| 126 | 0.156 -52.9924951 -56.3240681 33.2339623 | ||
| 127 | 0.16 -51.178006 -54.4233072 30.9117391 | ||
| 128 | 0.164 -49.4601134 -52.6230381 28.8199127 | ||
| 129 | 0.168 -47.8277963 -50.9120235 26.9352389 | ||
| 130 | 0.172 -46.2784539 -49.287447 25.2367647 | ||
| 131 | 0.176 -44.802842 -47.7398693 23.7056094 | ||
| 132 | 0.18 -43.3990267 -46.2672108 22.3247649 | ||
| 133 | 0.184 -42.0591742 -44.8615294 21.0789087 | ||
| 134 | 0.188 -40.7818674 -43.5213485 19.954241 | ||
| 135 | 0.192 -39.5604007 -42.2399508 18.9383331 | ||
| 136 | 0.196 -38.3937632 -41.0163602 18.0199949 | ||
| 137 | 0.2 -37.2761582 -39.8448573 17.1891513 | ||
| 138 | 0.204 -36.2068987 -38.7248663 16.4367349 | ||
| 139 | 0.208 -35.1809254 -37.6514634 15.754585 | ||
| 140 | 0.212 -34.1978119 -36.6243676 15.1353604 | ||
| 141 | 0.216 -33.2531013 -35.6392628 14.572457 | ||
| 142 | 0.22 -32.3465793 -34.6960538 14.0599373 | ||
| 143 | 0.224 -31.474284 -33.7908604 13.5924632 | ||
| 144 | 0.228 -30.6361756 -32.9236715 13.165238 | ||
| 145 | 0.232 -29.8287018 -32.0908994 12.7739526 | ||
| 146 | 0.236 -29.0519663 -31.2925408 12.414738 | ||
| 147 | 0.24 -28.3027584 -30.5252037 12.0841211 | ||
| 148 | 0.244 -27.5813012 -29.7888603 11.7789869 | ||
| 149 | 0.248 -26.8846701 -29.0802754 11.4965419 | ||
| 150 | 0.252 -26.2131874 -28.3994151 11.2342835 | ||
| 151 | 0.256 -25.5641709 -27.743215 10.9899705 | ||
| 152 | 0.26 -24.938025 -27.1116894 10.7615981 | ||
| 153 | 0.264 -24.3322739 -26.501982 10.5473736 | ||
| 154 | 0.268 -23.7473903 -25.914208 10.3456962 | ||
| 155 | 0.272 -23.1810754 -25.3457431 10.1551372 | ||
| 156 | 0.276 -22.6338585 -24.7968282 9.97442364 | ||
| 157 | 0.28 -22.1035942 -24.2650724 9.802422 | ||
| 158 | 0.284 -21.5908578 -23.7508434 9.63812469 | ||
| 159 | 0.288 -21.093638 -23.251979 9.48063693 | ||
| 160 | 0.292 -20.6125475 -22.768953 9.32916572 | ||
| 161 | 0.296 -20.145693 -22.2997973 9.18300901 | ||
| 162 | 0.3 -19.6937169 -21.8454622 9.04154678 | ||
| 163 | 0.308 -18.8285251 -20.9734428 8.77058317 | ||
| 164 | 0.316 -18.0163073 -20.1522563 8.51265026 | ||
| 165 | 0.324 -17.2486506 -19.3746181 8.26496577 | ||
| 166 | 0.332 -16.5266385 -18.6409913 8.0254235 | ||
| 167 | 0.34 -15.8428052 -17.9442094 7.79244879 | ||
| 168 | 0.348 -15.1985765 -17.285773 7.56489148 | ||
| 169 | 0.356 -14.5872668 -16.6591098 7.34192906 | ||
| 170 | 0.364 -14.0105277 -16.0659685 7.12299838 | ||
| 171 | 0.372 -13.4623317 -15.5004216 6.90773143 | ||
| 172 | 0.38 -12.944469 -14.9643603 6.69591252 | ||
| 173 | 0.388 -12.4514775 -14.4524224 6.48743584 | ||
| 174 | 0.396 -11.985221 -13.9665684 6.28227942 | ||
| 175 | 0.404 -11.5407318 -13.5019216 6.08047725 | ||
| 176 | 0.412 -11.119898 -13.0604543 5.88210419 | ||
| 177 | 0.42 -10.7181896 -12.637713 5.68725782 | ||
| 178 | 0.428 -10.337483 -12.235643 5.49605039 | ||
| 179 | 0.436 -9.97363998 -11.8501679 5.30859716 | ||
| 180 | 0.444 -9.62849844 -11.4831807 5.12501283 | ||
| 181 | 0.452 -9.29827352 -11.1309458 4.94540415 | ||
| 182 | 0.46 -8.98474556 -10.7952873 4.76986906 | ||
| 183 | 0.468 -8.68445022 -10.4727802 4.59849215 | ||
| 184 | 0.476 -8.39909707 -10.1651686 4.43134544 | ||
| 185 | 0.484 -8.12551375 -9.86931144 4.26848561 | ||
| 186 | 0.492 -7.86533024 -9.58686623 4.10995565 | ||
| 187 | 0.5 -7.61564097 -9.3149522 3.95578333 | ||
| 188 | 0.508 -7.37799103 -9.05513641 3.80598319 | ||
| 189 | 0.516 -7.14971907 -8.8047773 3.66055579 | ||
| 190 | 0.524 -6.93228265 -8.56534991 3.51948982 | ||
| 191 | 0.532 -6.72324432 -8.33443262 3.38276174 | ||
| 192 | 0.54 -6.52397342 -8.11340872 3.2503379 | ||
| 193 | 0.548 -6.33223792 -7.90005883 3.12217443 | ||
| 194 | 0.556 -6.14931982 -7.6956761 2.99821919 | ||
| 195 | 0.564 -5.97317563 -7.49822714 2.8784118 | ||
| 196 | 0.572 -5.80500198 -7.30891749 2.76268542 | ||
| 197 | 0.58 -5.64292843 -7.12588467 2.65096684 | ||
| 198 | 0.588 -5.48806909 -6.95025023 2.54317799 | ||
| 199 | 0.596 -5.3387123 -6.78030731 2.43923614 | ||
| 200 | 0.604 -5.195893 -6.61710268 2.33905514 | ||
| 201 | 0.612 -5.05804527 -6.45905125 2.2425456 | ||
| 202 | 0.62 -4.92612862 -6.30722765 2.14961601 | ||
| 203 | 0.636 -4.67562195 -6.01744374 1.97412109 | ||
| 204 | 0.652 -4.44566994 -5.74890413 1.81181156 | ||
| 205 | 0.668 -4.23052624 -5.49618914 1.66191892 | ||
| 206 | 0.684 -4.03240949 -5.26136188 1.52368165 | ||
| 207 | 0.7 -3.8465426 -5.03969472 1.39634993 | ||
| 208 | 0.716 -3.67483817 -4.833094 1.27919637 | ||
| 209 | 0.732 -3.51332341 -4.63759222 1.17151799 | ||
| 210 | 0.748 -3.36363591 -4.45482501 1.07264259 | ||
| 211 | 0.764 -3.22247032 -4.28148507 0.981929034 | ||
| 212 | 0.78 -3.09122154 -4.11896256 0.898770548 | ||
| 213 | 0.796 -2.96713792 -3.96450079 0.822593918 | ||
| 214 | 0.812 -2.85140313 -3.81927694 0.752860843 | ||
| 215 | 0.828 -2.74172462 -3.6809921 0.689066436 | ||
| 216 | 0.844 -2.63910413 -3.5506409 0.630739347 | ||
| 217 | 0.86 -2.54162963 -3.42630476 0.57743993 | ||
| 218 | 0.876 -2.45014743 -3.30882321 0.528759622 | ||
| 219 | 0.892 -2.36306077 -3.19659337 0.484319004 | ||
| 220 | 0.908 -2.28108404 -3.0903235 0.443766759 | ||
| 221 | 0.924 -2.20288158 -2.98867227 0.406777764 | ||
| 222 | 0.94 -2.12905644 -2.89223684 0.373051862 | ||
| 223 | 0.956 -2.0584891 -2.79989167 0.342312061 | ||
| 224 | 0.972 -1.99168909 -2.71213938 0.314303251 | ||
| 225 | 0.988 -1.9277158 -2.62803134 0.288790558 | ||
| 226 | 1.004 -1.86700047 -2.54798889 0.2655581 | ||
| 227 | 1.02 -1.80875054 -2.47120717 0.244407506 | ||
| 228 | 1.036 -1.75333198 -2.39803675 0.225156752 | ||
| 229 | 1.052 -1.7000747 -2.32778845 0.207638859 | ||
| 230 | 1.068 -1.64929043 -2.26075065 0.191700832 | ||
| 231 | 1.084 -1.60041039 -2.19632655 0.177202523 | ||
| 232 | 1.1 -1.55370134 -2.13474992 0.164015687 | ||
| 233 | 1.116 -1.50867833 -2.07549783 0.152022997 | ||
| 234 | 1.132 -1.46557091 -2.01875707 0.141117213 | ||
| 235 | 1.148 -1.42396353 -1.96406511 0.131200335 | ||
| 236 | 1.164 -1.38405502 -1.91157044 0.122182882 | ||
| 237 | 1.18 -1.34548726 -1.86086279 0.113983169 | ||
| 238 | 1.196 -1.30843378 -1.81206267 0.106526681 | ||
| 239 | 1.212 -1.27258406 -1.76480959 0.099745456 | ||
| 240 | 1.228 -1.2380908 -1.7192104 0.0935775561 | ||
| 241 | 1.244 -1.20468294 -1.67493554 0.0879665378 | ||
| 242 | 1.26 -1.17249605 -1.63230557 0.0828609995 | ||
| 243 | 1.292 -1.1110338 -1.55045023 0.0739832945 | ||
| 244 | 1.324 -1.05378121 -1.47315545 0.0666183437 | ||
| 245 | 1.356 -0.999788814 -1.40081147 0.0604963825 | ||
| 246 | 1.388 -0.949300004 -1.33371461 0.0553943894 | ||
| 247 | 1.42 -0.901551246 -1.27197391 0.0511281129 | ||
| 248 | 1.452 -0.856765003 -1.2163633 0.0475454497 | ||
| 249 | 1.484 -0.814309323 -1.16654104 0.0445208384 | ||
| 250 | 1.516 -0.7743937 -1.12253391 0.0419507429 | ||
| 251 | 1.548 -0.736480777 -1.08320985 0.0397498527 | ||
| 252 | 1.58 -0.700771753 -1.0479237 0.0378480528 | ||
| 253 | 1.612 -0.666798697 -1.01533405 0.03618785 | ||
| 254 | 1.644 -0.634756994 -0.98491388 0.0347222995 | ||
| 255 | 1.676 -0.604231022 -0.955762397 0.0334132007 | ||
| 256 | 1.708 -0.57541142 -0.927816107 0.0322296281 | ||
| 257 | 1.74 -0.547923251 -0.900619444 0.0311466379 | ||
| 258 | 1.772 -0.521952624 -0.874381494 0.0301442262 | ||
| 259 | 1.804 -0.49715736 -0.848830643 0.029206412 | ||
| 260 | 1.836 -0.473718787 -0.824230381 0.0283205168 | ||
| 261 | 1.868 -0.451322038 -0.800341498 0.0274765291 | ||
| 262 | 1.9 -0.430143189 -0.777402298 0.0266666175 | ||
| 263 | 1.932 -0.409890891 -0.755169751 0.0258846952 | ||
| 264 | 1.964 -0.390735421 -0.733850502 0.0251260965 | ||
| 265 | 1.996 -0.372406246 -0.713201294 0.0243872797 | ||
| 266 | 2.028 -0.355067324 -0.693406724 0.0236656139 | ||
| 267 | 2.06 -0.338466953 -0.6742312 0.0229591768 | ||
| 268 | 2.092 -0.322762323 -0.655844908 0.0222666158 | ||
| 269 | 2.124 -0.307719043 -0.638024436 0.0215870105 | ||
| 270 | 2.156 -0.293487193 -0.620929444 0.0209197841 | ||
| 271 | 2.188 -0.27984847 -0.604350316 0.0202646099 | ||
| 272 | 2.22 -0.26694561 -0.588437767 0.019621356 | ||
| 273 | 2.252 -0.254575371 -0.572996059 0.0189900228 | ||
| 274 | 2.284 -0.242873011 -0.558167472 0.0183707096 | ||
| 275 | 2.316 -0.23164945 -0.543769585 0.017763573 | ||
| 276 | 2.348 -0.221032434 -0.529936372 0.0171688084 | ||
| 277 | 2.38 -0.210846222 -0.516497961 0.0165866224 | ||
| 278 | 2.412 -0.201211097 -0.503580143 0.0160172241 | ||
| 279 | 2.444 -0.19196389 -0.491024674 0.0154608071 | ||
| 280 | 2.476 -0.183217543 -0.478949667 0.0149175474 | ||
| 281 | 2.508 -0.174820728 -0.46720714 0.0143875912 | ||
| 282 | 2.54 -0.166879229 -0.4559057 0.0138710569 | ||
| 283 | 2.604 -0.151929988 -0.434222199 0.0128785532 | ||
| 284 | 2.668 -0.138560595 -0.414108452 0.0119403188 | ||
| 285 | 2.732 -0.126217715 -0.395025007 0.0110560748 | ||
| 286 | 2.796 -0.115181289 -0.377273651 0.0102250884 | ||
| 287 | 2.86 -0.104981819 -0.36039622 0.00944618503 | ||
| 288 | 2.924 -0.0958629313 -0.344645705 0.00871786277 | ||
| 289 | 2.988 -0.0874274208 -0.329632317 0.00803832713 | ||
| 290 | 3.052 -0.0798857884 -0.315571534 0.00740558938 | ||
| 291 | 3.116 -0.0729028537 -0.3021327 0.00681750058 | ||
| 292 | 3.18 -0.0666594558 -0.289499771 0.00627182705 | ||
| 293 | 3.244 -0.0608733757 -0.277394018 0.00576627626 | ||
| 294 | 3.308 -0.0556992609 -0.265973254 0.00529855068 | ||
| 295 | 3.372 -0.0508999204 -0.255004458 0.00486636454 | ||
| 296 | 3.436 -0.0466071215 -0.244623904 0.00446747976 | ||
| 297 | 3.5 -0.042621813 -0.234638428 0.00409971514 | ||
| 298 | 3.564 -0.039055943 -0.225166652 0.00376096883 | ||
| 299 | 3.628 -0.0357426604 -0.21604973 0.0034492217 | ||
| 300 | 3.692 -0.0327768615 -0.207391423 0.00316255027 | ||
| 301 | 3.756 -0.030018806 -0.199061826 0.00289912613 | ||
| 302 | 3.82 -0.027548798 -0.191151679 0.0026572223 | ||
| 303 | 3.884 -0.0252498699 -0.18355483 0.00243521024 | ||
| 304 | 3.948 -0.0231898935 -0.176350116 0.00223156185 | ||
| 305 | 4.012 -0.0212709928 -0.169450326 0.00204484511 | ||
| 306 | 4.076 -0.0195504845 -0.162923103 0.00187372338 | ||
| 307 | 4.14 -0.0179464726 -0.156695965 0.00171695032 | ||
| 308 | 4.204 -0.0165073374 -0.150825919 0.00157336764 | ||
| 309 | 4.268 -0.0151645426 -0.145251747 0.00144189977 | ||
| 310 | 4.332 -0.0139589185 -0.140020527 0.00132155074 | ||
| 311 | 4.396 -0.0128330872 -0.135079525 0.00121139894 | ||
| 312 | 4.46 -0.0118215111 -0.130466681 0.00111059354 | ||
| 313 | 4.524 -0.0108761264 -0.126135728 0.00101834962 | ||
| 314 | 4.588 -0.0100260305 -0.122116377 0.000933944425 | ||
| 315 | 4.652 -0.00923093195 -0.118367297 0.000856712853 | ||
| 316 | 4.716 -0.00851541128 -0.114910969 0.000786043851 | ||
| 317 | 4.78 -0.00784566261 -0.111709715 0.000721376309 | ||
| 318 | 4.844 -0.007242465 -0.10878006 0.000662195676 | ||
| 319 | 4.908 -0.00667742537 -0.106086191 0.0006080303 | ||
| 320 | 4.972 -0.00616812367 -0.103639571 0.000558448336 | ||
| 321 | 5.036 -0.00569068627 -0.10141813 0.000513054515 | ||
| 322 | 5.1 -0.00526000025 -0.0992762735 0.000471487394 | ||
| 323 | 5.228 -0.00447761068 -0.095782979 0.000398541493 | ||
| 324 | 5.356 -0.00383940848 -0.0932147911 0.0003372963 | ||
| 325 | 5.484 -0.00327621448 -0.0907980421 0.000285818263 | ||
| 326 | 5.612 -0.0028153837 -0.0887309954 0.000242501611 | ||
| 327 | 5.74 -0.00240764875 -0.0866198114 0.000206009491 | ||
| 328 | 5.868 -0.00207302125 -0.0842367752 0.000175230412 | ||
| 329 | 5.996 -0.00177621909 -0.0812901623 0.000149239647 | ||
| 330 | 6.124 -0.00153193652 -0.0776496372 0.000127267556 | ||
| 331 | 6.252 -0.00131476745 -0.0733064333 0.000108672511 | ||
| 332 | 6.38 -0.00113554625 -0.0684550186 9.29186434E-05 | ||
| 333 | 6.508 -0.00097587795 -0.0633628896 7.95573376E-05 | ||
| 334 | 6.636 -0.000843787789 -0.0583374804 6.82123256E-05 | ||
| 335 | 6.764 -0.00072588243 -0.0536092996 5.85675348E-05 | ||
| 336 | 6.892 -0.000628135765 -0.0493446456 5.03572882E-05 | ||
| 337 | 7.02 -0.000540739576 -0.0456136891 4.33581998E-05 | ||
| 338 | 7.148 -0.000468162817 -0.0424395841 3.73824711E-05 | ||
| 339 | 7.276 -0.000403180398 -0.039793429 3.22722304E-05 | ||
| 340 | 7.404 -0.000349150908 -0.0376341537 2.78947771E-05 | ||
| 341 | 7.532 -0.000300721511 -0.0359011349 2.41385453E-05 | ||
| 342 | 7.66 -0.000260426344 -0.0345382078 2.09097083E-05 | ||
| 343 | 7.788 -0.000224278582 -0.0334827596 1.81293111E-05 | ||
| 344 | 7.916 -0.000194196146 -0.032679244 1.57308675E-05 | ||
| 345 | 8.044 -0.000167195916 -0.032067589 1.36583436E-05 | ||
| 346 | 8.172 -0.000144732221 -0.0315908422 1.18644738E-05 | ||
| 347 | 8.3 -0.000124564766 -0.0311850752 1.03093533E-05 | ||
| 348 | 8.428 -0.000107797002 -0.0307852986 8.95926276E-06 | ||
| 349 | 8.556 -9.27422736E-05 -0.0303202886 7.78568407E-06 | ||
| 350 | 8.684 -8.02371475E-05 -0.0297221369 6.76447296E-06 | ||
| 351 | 8.812 -6.90103045E-05 -0.028929475 5.87515777E-06 | ||
| 352 | 8.94 -5.96946823E-05 -0.0279014228 5.10034163E-06 | ||
| 353 | 9.068 -5.13322329E-05 -0.026622781 4.42518973E-06 | ||
| 354 | 9.196 -4.44004582E-05 -0.0251105685 3.83699167E-06 | ||
| 355 | 9.324 -3.81784313E-05 -0.0234078245 3.32479279E-06 | ||
| 356 | 9.452 -3.30252738E-05 -0.0215763769 2.87909088E-06 | ||
| 357 | 9.58 -2.83997197E-05 -0.0196833543 2.49159314E-06 | ||
| 358 | 9.708 -2.45711067E-05 -0.0177920682 2.15502603E-06 | ||
| 359 | 9.836 -2.11340862E-05 -0.0159558646 1.86298825E-06 | ||
| 360 | 9.964 -1.82902227E-05 -0.0142116609 1.60983627E-06 | ||
| 361 | 10.092 -1.57366592E-05 -0.0125872179 1.39059377E-06 | ||
| 362 | 10.22 -1.36240196E-05 -0.0111365643 1.20087597E-06 | ||
| 363 | 10.476 -1.00360257E-05 -0.00855331294 8.95043669E-07 | ||
| 364 | 10.732 -7.57858023E-06 -0.00645001052 6.66868225E-07 | ||
| 365 | 10.988 -5.59324512E-06 -0.00488484266 4.9690287E-07 | ||
| 366 | 11.244 -4.2315225E-06 -0.0036719993 3.70398737E-07 | ||
| 367 | 11.5 -3.12926032E-06 -0.00275580821 2.76267649E-07 | ||
| 368 | 11.756 -2.37175827E-06 -0.00206442544 2.06214669E-07 | ||
| 369 | 12.012 -1.75734979E-06 -0.00154547605 1.54057202E-07 | ||
| 370 | 12.268 -1.33421838E-06 -0.0011567623 1.15197825E-07 | ||
| 371 | 12.524 -9.90339825E-07 -0.000865979602 8.62225224E-08 | ||
| 372 | 12.78 -7.53019451E-07 -0.000648621482 6.4597635E-08 | ||
| 373 | 13.036 -5.59789793E-07 -0.000486134457 4.8442975E-08 | ||
| 374 | 13.292 -4.26172329E-07 -0.000364656213 3.63628311E-08 | ||
| 375 | 13.548 -3.17191632E-07 -0.000273771529 2.73205026E-08 | ||
| 376 | 13.804 -2.41696471E-07 -0.00020574002 2.05453389E-08 | ||
| 377 | 14.06 -1.80025182E-07 -0.000154762947 1.54639331E-08 | ||
| 378 | 14.316 -1.37236292E-07 -0.000116537277 1.16492103E-08 | ||
| 379 | 14.572 -1.02234269E-07 -8.78401813E-05 8.78275108E-09 | ||
| 380 | 14.828 -7.7918381E-08 -6.62792088E-05 6.62689483E-09 | ||
| 381 | 15.084 -5.80044889E-08 -5.00604659E-05 5.004068E-09 | ||
| 382 | 15.34 -4.41583574E-08 -3.78504749E-05 3.78145267E-09 | ||
| 383 | 15.596 -3.28088435E-08 -2.86475556E-05 2.85960361E-09 | ||
| 384 | 15.852 -2.49152294E-08 -2.17057681E-05 2.16398781E-09 | ||
| 385 | 16.108 -1.84417362E-08 -1.64635883E-05 1.63868893E-09 | ||
| 386 | 16.364 -1.3942026E-08 -1.25020194E-05 1.24171762E-09 | ||
| 387 | 16.62 -1.02521781E-08 -9.50495421E-06 9.41513835E-10 | ||
| 388 | 16.876 -7.69243803E-09 -7.23604132E-06 7.14335481E-10 | ||
| 389 | 17.132 -5.59553062E-09 -5.51657994E-06 5.42306598E-10 | ||
| 390 | 17.388 -4.1470892E-09 -4.2126917E-06 4.11956927E-10 | ||
| 391 | 17.644 -2.96357552E-09 -3.22294475E-06 3.13128071E-10 | ||
| 392 | 17.9 -2.15283223E-09 -2.47120067E-06 2.381534E-10 | ||
| 393 | 18.156 -1.4938624E-09 -1.89967742E-06 1.81242601E-10 | ||
| 394 | 18.412 -1.04946643E-09 -1.46487347E-06 1.38019384E-10 | ||
| 395 | 18.668 -6.91996791E-10 -1.13388331E-06 1.05173916E-10 | ||
| 396 | 18.924 -4.58124333E-10 -8.81381236E-07 8.02012948E-11 | ||
| 397 | 19.18 -2.73940422E-10 -6.89699784E-07 6.12045912E-11 | ||
| 398 | 19.436 -1.6092993E-10 -5.40597174E-07 4.67464071E-11 | ||
| 399 | 19.692 -7.61894269E-11 -4.34889002E-07 3.57369105E-11 | ||
| 400 | 19.948 -3.23618296E-11 -3.31990888E-07 2.7349321E-11 | ||
| 401 | 20.204 -4.47031275E-12 -3.06634084E-07 2.09560724E-11 | ||
| 402 | 20.46 0. -2.77585617E-07 1.60805574E-11 | ||
diff --git a/src/labat/aprtout.dat b/src/labat/aprtout.dat new file mode 100644 index 0000000..e55c256 --- /dev/null +++ b/src/labat/aprtout.dat | |||
| @@ -0,0 +1,1175 @@ | |||
| 1 | |||
| 2 | atom number: 13. ionicity: 0. | ||
| 3 | |||
| 4 | perdew - wang xc | ||
| 5 | |||
| 6 | hermann-skillmann mesh | ||
| 7 | blocks, nbl, c: 10, 40, 0.2000000 | ||
| 8 | first interval, last interval, final r: 0.000500, 0.256000, 20.460000 | ||
| 9 | |||
| 10 | energy eigenvalue threshold, screening parameter, feedback: 0.000010, 0.005000, 0.500 | ||
| 11 | |||
| 12 | |||
| 13 | initial bound state configuration | ||
| 14 | nlm energy occup. val.el. d-band el. | ||
| 15 | 100 -0.8450E+02 1.00 1 0 | ||
| 16 | 200 -0.1625E+02 1.00 1 0 | ||
| 17 | 210 -0.5336E+01 3.00 1 0 | ||
| 18 | 300 -0.7812E+00 1.00 1 0 | ||
| 19 | 310 -0.2312E+00 1.00 1 0 | ||
| 20 | 100 -0.8450E+02 1.00 1 0 | ||
| 21 | 200 -0.1625E+02 1.00 1 0 | ||
| 22 | 210 -0.5336E+01 3.00 1 0 | ||
| 23 | 300 -0.7812E+00 1.00 1 0 | ||
| 24 | 310 -0.2312E+00 0.00 1 0 | ||
| 25 | |||
| 26 | number of valence electrons: 13.0 | ||
| 27 | |||
| 28 | initial potentials | ||
| 29 | |||
| 30 | |||
| 31 | |||
| 32 | |||
| 33 | ********************* iteration: 1 *********************** | ||
| 34 | |||
| 35 | l = 0, 3 bound states | ||
| 36 | l = 1, 1 bound states | ||
| 37 | l = 0, 3 bound states | ||
| 38 | l = 1, 1 bound states | ||
| 39 | |||
| 40 | |||
| 41 | bound states | ||
| 42 | |||
| 43 | 100 energy: -51.97833 iteration loops: 7 | ||
| 44 | 200 energy: -3.47892 iteration loops: 10 | ||
| 45 | 300 energy: -0.08955 iteration loops: 15 | ||
| 46 | 210 energy: -2.09653 iteration loops: 13 | ||
| 47 | 100 energy: -51.97833 iteration loops: 7 | ||
| 48 | 200 energy: -3.47892 iteration loops: 10 | ||
| 49 | 300 energy: -0.08955 iteration loops: 15 | ||
| 50 | 210 energy: -2.09653 iteration loops: 13 | ||
| 51 | |||
| 52 | integr charges: total 12.0000000 valence: 12.0000000 0.0000000 | ||
| 53 | induced moment: 0.00000 | ||
| 54 | |||
| 55 | energy terms | ||
| 56 | energy eigenvalue sum: -0.123673E+03 | ||
| 57 | kin: 0.175039E+03 0.175039E+03 coul: -0.451615E+03 exc: -0.175124E+02 | ||
| 58 | |||
| 59 | total energy: -0.2427229E+03 | ||
| 60 | |||
| 61 | charge and spin density profiles | ||
| 62 | |||
| 63 | valence energy: -0.2423878E+03 | ||
| 64 | 0 | ||
| 65 | potentials vs. distance after 1 iterations | ||
| 66 | |||
| 67 | 0.00050 -0.25944E+05 -0.81015E+02 -0.81015E+02 -0.25978E+05 -0.25978E+05 | ||
| 68 | 0.00100 -0.12948E+05 -0.46840E+02 -0.46840E+02 -0.12967E+05 -0.12967E+05 | ||
| 69 | 0.00150 -0.86168E+04 -0.35293E+02 -0.35293E+02 -0.86307E+04 -0.86307E+04 | ||
| 70 | 0.00200 -0.64512E+04 -0.28887E+02 -0.28887E+02 -0.64625E+04 -0.64625E+04 | ||
| 71 | 0.00250 -0.51519E+04 -0.25299E+02 -0.25299E+02 -0.51618E+04 -0.51618E+04 | ||
| 72 | 0.00300 -0.42858E+04 -0.22804E+02 -0.22804E+02 -0.42947E+04 -0.42947E+04 | ||
| 73 | 0.00350 -0.36672E+04 -0.21035E+02 -0.21035E+02 -0.36755E+04 -0.36755E+04 | ||
| 74 | 0.00400 -0.32033E+04 -0.19689E+02 -0.19689E+02 -0.32111E+04 -0.32111E+04 | ||
| 75 | 0.00450 -0.28425E+04 -0.18635E+02 -0.18635E+02 -0.28499E+04 -0.28499E+04 | ||
| 76 | 0.00500 -0.25539E+04 -0.17782E+02 -0.17782E+02 -0.25610E+04 -0.25610E+04 | ||
| 77 | 0.00550 -0.23178E+04 -0.17076E+02 -0.17076E+02 -0.23246E+04 -0.23246E+04 | ||
| 78 | 0.00600 -0.21210E+04 -0.16480E+02 -0.16480E+02 -0.21277E+04 -0.21277E+04 | ||
| 79 | 0.00650 -0.19546E+04 -0.15970E+02 -0.15970E+02 -0.19611E+04 -0.19611E+04 | ||
| 80 | 0.00700 -0.18119E+04 -0.15526E+02 -0.15526E+02 -0.18183E+04 -0.18183E+04 | ||
| 81 | 0.00750 -0.16883E+04 -0.15135E+02 -0.15135E+02 -0.16945E+04 -0.16945E+04 | ||
| 82 | 0.00800 -0.15801E+04 -0.14788E+02 -0.14788E+02 -0.15862E+04 -0.15862E+04 | ||
| 83 | 0.00850 -0.14847E+04 -0.14477E+02 -0.14477E+02 -0.14907E+04 -0.14907E+04 | ||
| 84 | 0.00900 -0.13998E+04 -0.14196E+02 -0.14196E+02 -0.14058E+04 -0.14058E+04 | ||
| 85 | 0.00950 -0.13239E+04 -0.13940E+02 -0.13940E+02 -0.13298E+04 -0.13298E+04 | ||
| 86 | 0.01000 -0.12556E+04 -0.13705E+02 -0.13705E+02 -0.12615E+04 -0.12615E+04 | ||
| 87 | 0.01050 -0.11939E+04 -0.13489E+02 -0.13489E+02 -0.11996E+04 -0.11996E+04 | ||
| 88 | 0.01100 -0.11377E+04 -0.13289E+02 -0.13289E+02 -0.11434E+04 -0.11434E+04 | ||
| 89 | 0.01150 -0.10864E+04 -0.13102E+02 -0.13102E+02 -0.10921E+04 -0.10921E+04 | ||
| 90 | 0.01200 -0.10394E+04 -0.12928E+02 -0.12928E+02 -0.10451E+04 -0.10451E+04 | ||
| 91 | 0.01250 -0.99622E+03 -0.12764E+02 -0.12764E+02 -0.10018E+04 -0.10018E+04 | ||
| 92 | 0.01300 -0.95632E+03 -0.12610E+02 -0.12610E+02 -0.96186E+03 -0.96186E+03 | ||
| 93 | 0.01350 -0.91938E+03 -0.12465E+02 -0.12465E+02 -0.92489E+03 -0.92489E+03 | ||
| 94 | 0.01400 -0.88509E+03 -0.12327E+02 -0.12327E+02 -0.89056E+03 -0.89056E+03 | ||
| 95 | 0.01450 -0.85317E+03 -0.12195E+02 -0.12195E+02 -0.85860E+03 -0.85860E+03 | ||
| 96 | 0.01500 -0.82337E+03 -0.12070E+02 -0.12070E+02 -0.82878E+03 -0.82878E+03 | ||
| 97 | 0.01550 -0.79551E+03 -0.11951E+02 -0.11951E+02 -0.80089E+03 -0.80089E+03 | ||
| 98 | 0.01600 -0.76939E+03 -0.11836E+02 -0.11836E+02 -0.77474E+03 -0.77474E+03 | ||
| 99 | 0.01650 -0.74485E+03 -0.11727E+02 -0.11727E+02 -0.75018E+03 -0.75018E+03 | ||
| 100 | 0.01700 -0.72177E+03 -0.11621E+02 -0.11621E+02 -0.72706E+03 -0.72706E+03 | ||
| 101 | 0.01750 -0.70000E+03 -0.11519E+02 -0.11519E+02 -0.70527E+03 -0.70527E+03 | ||
| 102 | 0.01800 -0.67945E+03 -0.11421E+02 -0.11421E+02 -0.68470E+03 -0.68470E+03 | ||
| 103 | 0.01850 -0.66002E+03 -0.11327E+02 -0.11327E+02 -0.66524E+03 -0.66524E+03 | ||
| 104 | 0.01900 -0.64161E+03 -0.11235E+02 -0.11235E+02 -0.64680E+03 -0.64680E+03 | ||
| 105 | 0.01950 -0.62414E+03 -0.11146E+02 -0.11146E+02 -0.62932E+03 -0.62932E+03 | ||
| 106 | 0.02000 -0.60756E+03 -0.11060E+02 -0.11060E+02 -0.61271E+03 -0.61271E+03 | ||
| 107 | 0.02100 -0.57676E+03 -0.10894E+02 -0.10894E+02 -0.58187E+03 -0.58187E+03 | ||
| 108 | 0.02200 -0.54877E+03 -0.10737E+02 -0.10737E+02 -0.55384E+03 -0.55384E+03 | ||
| 109 | 0.02300 -0.52323E+03 -0.10588E+02 -0.10588E+02 -0.52826E+03 -0.52826E+03 | ||
| 110 | 0.02400 -0.49983E+03 -0.10445E+02 -0.10445E+02 -0.50482E+03 -0.50482E+03 | ||
| 111 | 0.02500 -0.47831E+03 -0.10308E+02 -0.10308E+02 -0.48326E+03 -0.48326E+03 | ||
| 112 | 0.02600 -0.45845E+03 -0.10177E+02 -0.10177E+02 -0.46337E+03 -0.46337E+03 | ||
| 113 | 0.02700 -0.44008E+03 -0.10050E+02 -0.10050E+02 -0.44495E+03 -0.44495E+03 | ||
| 114 | 0.02800 -0.42302E+03 -0.99279E+01 -0.99279E+01 -0.42786E+03 -0.42786E+03 | ||
| 115 | 0.02900 -0.40715E+03 -0.98095E+01 -0.98095E+01 -0.41195E+03 -0.41195E+03 | ||
| 116 | 0.03000 -0.39234E+03 -0.96948E+01 -0.96948E+01 -0.39711E+03 -0.39711E+03 | ||
| 117 | 0.03100 -0.37850E+03 -0.95835E+01 -0.95835E+01 -0.38323E+03 -0.38323E+03 | ||
| 118 | 0.03200 -0.36553E+03 -0.94752E+01 -0.94752E+01 -0.37023E+03 -0.37023E+03 | ||
| 119 | 0.03300 -0.35335E+03 -0.93697E+01 -0.93697E+01 -0.35801E+03 -0.35801E+03 | ||
| 120 | 0.03400 -0.34190E+03 -0.92669E+01 -0.92669E+01 -0.34653E+03 -0.34653E+03 | ||
| 121 | 0.03500 -0.33111E+03 -0.91665E+01 -0.91665E+01 -0.33570E+03 -0.33570E+03 | ||
| 122 | 0.03600 -0.32092E+03 -0.90685E+01 -0.90685E+01 -0.32548E+03 -0.32548E+03 | ||
| 123 | 0.03700 -0.31129E+03 -0.89726E+01 -0.89726E+01 -0.31581E+03 -0.31581E+03 | ||
| 124 | 0.03800 -0.30217E+03 -0.88787E+01 -0.88787E+01 -0.30666E+03 -0.30666E+03 | ||
| 125 | 0.03900 -0.29353E+03 -0.87868E+01 -0.87868E+01 -0.29798E+03 -0.29798E+03 | ||
| 126 | 0.04000 -0.28532E+03 -0.86967E+01 -0.86967E+01 -0.28974E+03 -0.28974E+03 | ||
| 127 | 0.04100 -0.27752E+03 -0.86083E+01 -0.86083E+01 -0.28191E+03 -0.28191E+03 | ||
| 128 | 0.04200 -0.27010E+03 -0.85215E+01 -0.85215E+01 -0.27445E+03 -0.27445E+03 | ||
| 129 | 0.04300 -0.26302E+03 -0.84363E+01 -0.84363E+01 -0.26734E+03 -0.26734E+03 | ||
| 130 | 0.04400 -0.25627E+03 -0.83525E+01 -0.83525E+01 -0.26056E+03 -0.26056E+03 | ||
| 131 | 0.04500 -0.24983E+03 -0.82702E+01 -0.82702E+01 -0.25408E+03 -0.25408E+03 | ||
| 132 | 0.04600 -0.24367E+03 -0.81892E+01 -0.81892E+01 -0.24789E+03 -0.24789E+03 | ||
| 133 | 0.04700 -0.23778E+03 -0.81096E+01 -0.81096E+01 -0.24197E+03 -0.24197E+03 | ||
| 134 | 0.04800 -0.23214E+03 -0.80312E+01 -0.80312E+01 -0.23629E+03 -0.23629E+03 | ||
| 135 | 0.04900 -0.22673E+03 -0.79540E+01 -0.79540E+01 -0.23085E+03 -0.23085E+03 | ||
| 136 | 0.05000 -0.22155E+03 -0.78779E+01 -0.78779E+01 -0.22563E+03 -0.22563E+03 | ||
| 137 | 0.05100 -0.21657E+03 -0.78030E+01 -0.78030E+01 -0.22062E+03 -0.22062E+03 | ||
| 138 | 0.05200 -0.21179E+03 -0.77291E+01 -0.77291E+01 -0.21581E+03 -0.21581E+03 | ||
| 139 | 0.05300 -0.20719E+03 -0.76563E+01 -0.76563E+01 -0.21117E+03 -0.21117E+03 | ||
| 140 | 0.05400 -0.20276E+03 -0.75845E+01 -0.75845E+01 -0.20672E+03 -0.20672E+03 | ||
| 141 | 0.05500 -0.19850E+03 -0.75137E+01 -0.75137E+01 -0.20242E+03 -0.20242E+03 | ||
| 142 | 0.05600 -0.19440E+03 -0.74438E+01 -0.74438E+01 -0.19829E+03 -0.19829E+03 | ||
| 143 | 0.05700 -0.19044E+03 -0.73749E+01 -0.73749E+01 -0.19430E+03 -0.19430E+03 | ||
| 144 | 0.05800 -0.18662E+03 -0.73068E+01 -0.73068E+01 -0.19045E+03 -0.19045E+03 | ||
| 145 | 0.05900 -0.18294E+03 -0.72396E+01 -0.72396E+01 -0.18673E+03 -0.18673E+03 | ||
| 146 | 0.06000 -0.17938E+03 -0.71736E+01 -0.71736E+01 -0.18314E+03 -0.18314E+03 | ||
| 147 | 0.06200 -0.17261E+03 -0.70436E+01 -0.70436E+01 -0.17631E+03 -0.17631E+03 | ||
| 148 | 0.06400 -0.16628E+03 -0.69162E+01 -0.69162E+01 -0.16992E+03 -0.16992E+03 | ||
| 149 | 0.06600 -0.16035E+03 -0.67924E+01 -0.67924E+01 -0.16392E+03 -0.16392E+03 | ||
| 150 | 0.06800 -0.15477E+03 -0.66713E+01 -0.66713E+01 -0.15828E+03 -0.15828E+03 | ||
| 151 | 0.07000 -0.14952E+03 -0.65531E+01 -0.65531E+01 -0.15298E+03 -0.15298E+03 | ||
| 152 | 0.07200 -0.14458E+03 -0.64375E+01 -0.64375E+01 -0.14797E+03 -0.14797E+03 | ||
| 153 | 0.07400 -0.13991E+03 -0.63245E+01 -0.63245E+01 -0.14324E+03 -0.14324E+03 | ||
| 154 | 0.07600 -0.13549E+03 -0.62141E+01 -0.62141E+01 -0.13877E+03 -0.13877E+03 | ||
| 155 | 0.07800 -0.13131E+03 -0.61061E+01 -0.61061E+01 -0.13453E+03 -0.13453E+03 | ||
| 156 | 0.08000 -0.12735E+03 -0.60004E+01 -0.60004E+01 -0.13051E+03 -0.13051E+03 | ||
| 157 | 0.08200 -0.12359E+03 -0.58971E+01 -0.58971E+01 -0.12669E+03 -0.12669E+03 | ||
| 158 | 0.08400 -0.12001E+03 -0.57959E+01 -0.57959E+01 -0.12306E+03 -0.12306E+03 | ||
| 159 | 0.08600 -0.11661E+03 -0.56970E+01 -0.56970E+01 -0.11960E+03 -0.11960E+03 | ||
| 160 | 0.08800 -0.11337E+03 -0.56001E+01 -0.56001E+01 -0.11631E+03 -0.11631E+03 | ||
| 161 | 0.09000 -0.11028E+03 -0.55053E+01 -0.55053E+01 -0.11316E+03 -0.11316E+03 | ||
| 162 | 0.09200 -0.10733E+03 -0.54126E+01 -0.54126E+01 -0.11016E+03 -0.11016E+03 | ||
| 163 | 0.09400 -0.10451E+03 -0.53218E+01 -0.53218E+01 -0.10729E+03 -0.10729E+03 | ||
| 164 | 0.09600 -0.10181E+03 -0.52330E+01 -0.52330E+01 -0.10455E+03 -0.10455E+03 | ||
| 165 | 0.09800 -0.99229E+02 -0.51460E+01 -0.51460E+01 -0.10192E+03 -0.10192E+03 | ||
| 166 | 0.10000 -0.96757E+02 -0.50609E+01 -0.50609E+01 -0.99396E+02 -0.99396E+02 | ||
| 167 | 0.10200 -0.94386E+02 -0.49776E+01 -0.49776E+01 -0.96978E+02 -0.96978E+02 | ||
| 168 | 0.10400 -0.92112E+02 -0.48961E+01 -0.48961E+01 -0.94657E+02 -0.94657E+02 | ||
| 169 | 0.10600 -0.89927E+02 -0.48164E+01 -0.48164E+01 -0.92427E+02 -0.92427E+02 | ||
| 170 | 0.10800 -0.87828E+02 -0.47384E+01 -0.47384E+01 -0.90283E+02 -0.90283E+02 | ||
| 171 | 0.11000 -0.85809E+02 -0.46621E+01 -0.46621E+01 -0.88221E+02 -0.88221E+02 | ||
| 172 | 0.11200 -0.83867E+02 -0.45874E+01 -0.45874E+01 -0.86236E+02 -0.86236E+02 | ||
| 173 | 0.11400 -0.81996E+02 -0.45144E+01 -0.45144E+01 -0.84324E+02 -0.84324E+02 | ||
| 174 | 0.11600 -0.80194E+02 -0.44430E+01 -0.44430E+01 -0.82481E+02 -0.82481E+02 | ||
| 175 | 0.11800 -0.78456E+02 -0.43732E+01 -0.43732E+01 -0.80703E+02 -0.80703E+02 | ||
| 176 | 0.12000 -0.76780E+02 -0.43049E+01 -0.43049E+01 -0.78987E+02 -0.78987E+02 | ||
| 177 | 0.12200 -0.75162E+02 -0.42382E+01 -0.42382E+01 -0.77331E+02 -0.77331E+02 | ||
| 178 | 0.12400 -0.73600E+02 -0.41730E+01 -0.41730E+01 -0.75731E+02 -0.75731E+02 | ||
| 179 | 0.12600 -0.72089E+02 -0.41092E+01 -0.41092E+01 -0.74185E+02 -0.74185E+02 | ||
| 180 | 0.12800 -0.70630E+02 -0.40469E+01 -0.40469E+01 -0.72689E+02 -0.72689E+02 | ||
| 181 | 0.13000 -0.69217E+02 -0.39861E+01 -0.39861E+01 -0.71242E+02 -0.71242E+02 | ||
| 182 | 0.13200 -0.67851E+02 -0.39266E+01 -0.39266E+01 -0.69842E+02 -0.69842E+02 | ||
| 183 | 0.13400 -0.66528E+02 -0.38685E+01 -0.38685E+01 -0.68486E+02 -0.68486E+02 | ||
| 184 | 0.13600 -0.65246E+02 -0.38118E+01 -0.38118E+01 -0.67172E+02 -0.67172E+02 | ||
| 185 | 0.13800 -0.64004E+02 -0.37563E+01 -0.37563E+01 -0.65898E+02 -0.65898E+02 | ||
| 186 | 0.14000 -0.62800E+02 -0.37027E+01 -0.37027E+01 -0.64664E+02 -0.64664E+02 | ||
| 187 | 0.14400 -0.60498E+02 -0.35986E+01 -0.35986E+01 -0.62303E+02 -0.62303E+02 | ||
| 188 | 0.14800 -0.58330E+02 -0.34985E+01 -0.34985E+01 -0.60079E+02 -0.60079E+02 | ||
| 189 | 0.15200 -0.56283E+02 -0.34037E+01 -0.34037E+01 -0.57980E+02 -0.57980E+02 | ||
| 190 | 0.15600 -0.54350E+02 -0.33131E+01 -0.33131E+01 -0.55996E+02 -0.55996E+02 | ||
| 191 | 0.16000 -0.52519E+02 -0.32267E+01 -0.32267E+01 -0.54118E+02 -0.54118E+02 | ||
| 192 | 0.16400 -0.50786E+02 -0.31442E+01 -0.31442E+01 -0.52339E+02 -0.52339E+02 | ||
| 193 | 0.16800 -0.49140E+02 -0.30654E+01 -0.30654E+01 -0.50651E+02 -0.50651E+02 | ||
| 194 | 0.17200 -0.47577E+02 -0.29900E+01 -0.29900E+01 -0.49048E+02 -0.49048E+02 | ||
| 195 | 0.17600 -0.46090E+02 -0.29178E+01 -0.29178E+01 -0.47523E+02 -0.47523E+02 | ||
| 196 | 0.18000 -0.44676E+02 -0.28487E+01 -0.28487E+01 -0.46072E+02 -0.46072E+02 | ||
| 197 | 0.18400 -0.43327E+02 -0.27823E+01 -0.27823E+01 -0.44689E+02 -0.44689E+02 | ||
| 198 | 0.18800 -0.42041E+02 -0.27188E+01 -0.27188E+01 -0.43370E+02 -0.43370E+02 | ||
| 199 | 0.19200 -0.40812E+02 -0.26578E+01 -0.26578E+01 -0.42111E+02 -0.42111E+02 | ||
| 200 | 0.19600 -0.39638E+02 -0.25995E+01 -0.25995E+01 -0.40908E+02 -0.40908E+02 | ||
| 201 | 0.20000 -0.38515E+02 -0.25437E+01 -0.25437E+01 -0.39758E+02 -0.39758E+02 | ||
| 202 | 0.20400 -0.37441E+02 -0.24906E+01 -0.24906E+01 -0.38657E+02 -0.38657E+02 | ||
| 203 | 0.20800 -0.36411E+02 -0.24402E+01 -0.24402E+01 -0.37603E+02 -0.37603E+02 | ||
| 204 | 0.21200 -0.35424E+02 -0.23927E+01 -0.23927E+01 -0.36594E+02 -0.36594E+02 | ||
| 205 | 0.21600 -0.34476E+02 -0.23481E+01 -0.23481E+01 -0.35626E+02 -0.35626E+02 | ||
| 206 | 0.22000 -0.33567E+02 -0.23066E+01 -0.23066E+01 -0.34697E+02 -0.34697E+02 | ||
| 207 | 0.22400 -0.32693E+02 -0.22684E+01 -0.22684E+01 -0.33807E+02 -0.33807E+02 | ||
| 208 | 0.22800 -0.31853E+02 -0.22336E+01 -0.22336E+01 -0.32952E+02 -0.32952E+02 | ||
| 209 | 0.23200 -0.31044E+02 -0.22023E+01 -0.22023E+01 -0.32130E+02 -0.32130E+02 | ||
| 210 | 0.23600 -0.30267E+02 -0.21745E+01 -0.21745E+01 -0.31341E+02 -0.31341E+02 | ||
| 211 | 0.24000 -0.29517E+02 -0.21503E+01 -0.21503E+01 -0.30583E+02 -0.30583E+02 | ||
| 212 | 0.24400 -0.28795E+02 -0.21295E+01 -0.21295E+01 -0.29853E+02 -0.29853E+02 | ||
| 213 | 0.24800 -0.28099E+02 -0.21120E+01 -0.21120E+01 -0.29151E+02 -0.29151E+02 | ||
| 214 | 0.25200 -0.27427E+02 -0.20977E+01 -0.20977E+01 -0.28476E+02 -0.28476E+02 | ||
| 215 | 0.25600 -0.26779E+02 -0.20862E+01 -0.20862E+01 -0.27825E+02 -0.27825E+02 | ||
| 216 | 0.26000 -0.26153E+02 -0.20772E+01 -0.20772E+01 -0.27199E+02 -0.27199E+02 | ||
| 217 | 0.26400 -0.25548E+02 -0.20703E+01 -0.20703E+01 -0.26594E+02 -0.26594E+02 | ||
| 218 | 0.26800 -0.24964E+02 -0.20653E+01 -0.20653E+01 -0.26011E+02 -0.26011E+02 | ||
| 219 | 0.27200 -0.24399E+02 -0.20618E+01 -0.20618E+01 -0.25448E+02 -0.25448E+02 | ||
| 220 | 0.27600 -0.23853E+02 -0.20594E+01 -0.20594E+01 -0.24904E+02 -0.24904E+02 | ||
| 221 | 0.28000 -0.23323E+02 -0.20578E+01 -0.20578E+01 -0.24377E+02 -0.24377E+02 | ||
| 222 | 0.28400 -0.22812E+02 -0.20568E+01 -0.20568E+01 -0.23869E+02 -0.23869E+02 | ||
| 223 | 0.28800 -0.22316E+02 -0.20560E+01 -0.20560E+01 -0.23376E+02 -0.23376E+02 | ||
| 224 | 0.29200 -0.21835E+02 -0.20553E+01 -0.20553E+01 -0.22899E+02 -0.22899E+02 | ||
| 225 | 0.29600 -0.21369E+02 -0.20546E+01 -0.20546E+01 -0.22437E+02 -0.22437E+02 | ||
| 226 | 0.30000 -0.20918E+02 -0.20540E+01 -0.20540E+01 -0.21989E+02 -0.21989E+02 | ||
| 227 | 0.30800 -0.20055E+02 -0.20510E+01 -0.20510E+01 -0.21132E+02 -0.21132E+02 | ||
| 228 | 0.31600 -0.19244E+02 -0.20458E+01 -0.20458E+01 -0.20324E+02 -0.20324E+02 | ||
| 229 | 0.32400 -0.18477E+02 -0.20397E+01 -0.20397E+01 -0.19562E+02 -0.19562E+02 | ||
| 230 | 0.33200 -0.17755E+02 -0.20319E+01 -0.20319E+01 -0.18842E+02 -0.18842E+02 | ||
| 231 | 0.34000 -0.17071E+02 -0.20226E+01 -0.20226E+01 -0.18161E+02 -0.18161E+02 | ||
| 232 | 0.34800 -0.16426E+02 -0.20120E+01 -0.20120E+01 -0.17515E+02 -0.17515E+02 | ||
| 233 | 0.35600 -0.15813E+02 -0.20003E+01 -0.20003E+01 -0.16903E+02 -0.16903E+02 | ||
| 234 | 0.36400 -0.15234E+02 -0.19875E+01 -0.19875E+01 -0.16323E+02 -0.16323E+02 | ||
| 235 | 0.37200 -0.14684E+02 -0.19737E+01 -0.19737E+01 -0.15771E+02 -0.15771E+02 | ||
| 236 | 0.38000 -0.14162E+02 -0.19590E+01 -0.19590E+01 -0.15246E+02 -0.15246E+02 | ||
| 237 | 0.38800 -0.13666E+02 -0.19435E+01 -0.19435E+01 -0.14747E+02 -0.14747E+02 | ||
| 238 | 0.39600 -0.13194E+02 -0.19273E+01 -0.19273E+01 -0.14271E+02 -0.14271E+02 | ||
| 239 | 0.40400 -0.12745E+02 -0.19104E+01 -0.19104E+01 -0.13817E+02 -0.13817E+02 | ||
| 240 | 0.41200 -0.12318E+02 -0.18930E+01 -0.18930E+01 -0.13385E+02 -0.13385E+02 | ||
| 241 | 0.42000 -0.11911E+02 -0.18750E+01 -0.18750E+01 -0.12971E+02 -0.12971E+02 | ||
| 242 | 0.42800 -0.11523E+02 -0.18567E+01 -0.18567E+01 -0.12576E+02 -0.12576E+02 | ||
| 243 | 0.43600 -0.11152E+02 -0.18379E+01 -0.18379E+01 -0.12199E+02 -0.12199E+02 | ||
| 244 | 0.44400 -0.10799E+02 -0.18189E+01 -0.18189E+01 -0.11838E+02 -0.11838E+02 | ||
| 245 | 0.45200 -0.10460E+02 -0.17996E+01 -0.17996E+01 -0.11492E+02 -0.11492E+02 | ||
| 246 | 0.46000 -0.10138E+02 -0.17800E+01 -0.17800E+01 -0.11161E+02 -0.11161E+02 | ||
| 247 | 0.46800 -0.98287E+01 -0.17604E+01 -0.17604E+01 -0.10843E+02 -0.10843E+02 | ||
| 248 | 0.47600 -0.95335E+01 -0.17406E+01 -0.17406E+01 -0.10538E+02 -0.10538E+02 | ||
| 249 | 0.48400 -0.92504E+01 -0.17207E+01 -0.17207E+01 -0.10246E+02 -0.10246E+02 | ||
| 250 | 0.49200 -0.89798E+01 -0.17007E+01 -0.17007E+01 -0.99654E+01 -0.99654E+01 | ||
| 251 | 0.50000 -0.87199E+01 -0.16807E+01 -0.16807E+01 -0.96956E+01 -0.96956E+01 | ||
| 252 | 0.50800 -0.84713E+01 -0.16607E+01 -0.16607E+01 -0.94366E+01 -0.94366E+01 | ||
| 253 | 0.51600 -0.82323E+01 -0.16407E+01 -0.16407E+01 -0.91873E+01 -0.91873E+01 | ||
| 254 | 0.52400 -0.80034E+01 -0.16207E+01 -0.16207E+01 -0.89476E+01 -0.89476E+01 | ||
| 255 | 0.53200 -0.77833E+01 -0.16008E+01 -0.16008E+01 -0.87167E+01 -0.87167E+01 | ||
| 256 | 0.54000 -0.75722E+01 -0.15809E+01 -0.15809E+01 -0.84945E+01 -0.84945E+01 | ||
| 257 | 0.54800 -0.73690E+01 -0.15611E+01 -0.15611E+01 -0.82803E+01 -0.82803E+01 | ||
| 258 | 0.55600 -0.71741E+01 -0.15414E+01 -0.15414E+01 -0.80739E+01 -0.80739E+01 | ||
| 259 | 0.56400 -0.69862E+01 -0.15218E+01 -0.15218E+01 -0.78748E+01 -0.78748E+01 | ||
| 260 | 0.57200 -0.68059E+01 -0.15023E+01 -0.15023E+01 -0.76828E+01 -0.76828E+01 | ||
| 261 | 0.58000 -0.66319E+01 -0.14829E+01 -0.14829E+01 -0.74974E+01 -0.74974E+01 | ||
| 262 | 0.58800 -0.64648E+01 -0.14637E+01 -0.14637E+01 -0.73186E+01 -0.73186E+01 | ||
| 263 | 0.59600 -0.63034E+01 -0.14445E+01 -0.14445E+01 -0.71457E+01 -0.71457E+01 | ||
| 264 | 0.60400 -0.61483E+01 -0.14256E+01 -0.14256E+01 -0.69788E+01 -0.69788E+01 | ||
| 265 | 0.61200 -0.59985E+01 -0.14067E+01 -0.14067E+01 -0.68172E+01 -0.68172E+01 | ||
| 266 | 0.62000 -0.58543E+01 -0.13881E+01 -0.13881E+01 -0.66613E+01 -0.66613E+01 | ||
| 267 | 0.63600 -0.55801E+01 -0.13513E+01 -0.13513E+01 -0.63639E+01 -0.63639E+01 | ||
| 268 | 0.65200 -0.53257E+01 -0.13151E+01 -0.13151E+01 -0.60858E+01 -0.60858E+01 | ||
| 269 | 0.66800 -0.50874E+01 -0.12797E+01 -0.12797E+01 -0.58244E+01 -0.58244E+01 | ||
| 270 | 0.68400 -0.48655E+01 -0.12449E+01 -0.12449E+01 -0.55793E+01 -0.55793E+01 | ||
| 271 | 0.70000 -0.46572E+01 -0.12109E+01 -0.12109E+01 -0.53483E+01 -0.53483E+01 | ||
| 272 | 0.71600 -0.44628E+01 -0.11777E+01 -0.11777E+01 -0.51311E+01 -0.51311E+01 | ||
| 273 | 0.73200 -0.42798E+01 -0.11452E+01 -0.11452E+01 -0.49260E+01 -0.49260E+01 | ||
| 274 | 0.74800 -0.41085E+01 -0.11134E+01 -0.11134E+01 -0.47328E+01 -0.47328E+01 | ||
| 275 | 0.76400 -0.39469E+01 -0.10825E+01 -0.10825E+01 -0.45499E+01 -0.45499E+01 | ||
| 276 | 0.78000 -0.37954E+01 -0.10523E+01 -0.10523E+01 -0.43772E+01 -0.43772E+01 | ||
| 277 | 0.79600 -0.36521E+01 -0.10229E+01 -0.10229E+01 -0.42135E+01 -0.42135E+01 | ||
| 278 | 0.81200 -0.35174E+01 -0.99421E+00 -0.99421E+00 -0.40585E+01 -0.40585E+01 | ||
| 279 | 0.82800 -0.33897E+01 -0.96629E+00 -0.96629E+00 -0.39114E+01 -0.39114E+01 | ||
| 280 | 0.84400 -0.32694E+01 -0.93913E+00 -0.93913E+00 -0.37718E+01 -0.37718E+01 | ||
| 281 | 0.86000 -0.31553E+01 -0.91271E+00 -0.91271E+00 -0.36391E+01 -0.36391E+01 | ||
| 282 | 0.87600 -0.30474E+01 -0.88702E+00 -0.88702E+00 -0.35130E+01 -0.35130E+01 | ||
| 283 | 0.89200 -0.29449E+01 -0.86206E+00 -0.86206E+00 -0.33929E+01 -0.33929E+01 | ||
| 284 | 0.90800 -0.28478E+01 -0.83782E+00 -0.83782E+00 -0.32786E+01 -0.32786E+01 | ||
| 285 | 0.92400 -0.27554E+01 -0.81428E+00 -0.81428E+00 -0.31696E+01 -0.31696E+01 | ||
| 286 | 0.94000 -0.26677E+01 -0.79146E+00 -0.79146E+00 -0.30658E+01 -0.30658E+01 | ||
| 287 | 0.95600 -0.25840E+01 -0.76932E+00 -0.76932E+00 -0.29666E+01 -0.29666E+01 | ||
| 288 | 0.97200 -0.25045E+01 -0.74788E+00 -0.74788E+00 -0.28719E+01 -0.28719E+01 | ||
| 289 | 0.98800 -0.24286E+01 -0.72712E+00 -0.72712E+00 -0.27814E+01 -0.27814E+01 | ||
| 290 | 1.00400 -0.23563E+01 -0.70703E+00 -0.70703E+00 -0.26949E+01 -0.26949E+01 | ||
| 291 | 1.02000 -0.22870E+01 -0.68762E+00 -0.68762E+00 -0.26122E+01 -0.26122E+01 | ||
| 292 | 1.03600 -0.22211E+01 -0.66888E+00 -0.66888E+00 -0.25330E+01 -0.25330E+01 | ||
| 293 | 1.05200 -0.21578E+01 -0.65080E+00 -0.65080E+00 -0.24572E+01 -0.24572E+01 | ||
| 294 | 1.06800 -0.20974E+01 -0.63338E+00 -0.63338E+00 -0.23846E+01 -0.23846E+01 | ||
| 295 | 1.08400 -0.20394E+01 -0.61661E+00 -0.61661E+00 -0.23150E+01 -0.23150E+01 | ||
| 296 | 1.10000 -0.19840E+01 -0.60048E+00 -0.60048E+00 -0.22483E+01 -0.22483E+01 | ||
| 297 | 1.11600 -0.19307E+01 -0.58499E+00 -0.58499E+00 -0.21843E+01 -0.21843E+01 | ||
| 298 | 1.13200 -0.18797E+01 -0.57014E+00 -0.57014E+00 -0.21230E+01 -0.21230E+01 | ||
| 299 | 1.14800 -0.18306E+01 -0.55590E+00 -0.55590E+00 -0.20641E+01 -0.20641E+01 | ||
| 300 | 1.16400 -0.17835E+01 -0.54226E+00 -0.54226E+00 -0.20076E+01 -0.20076E+01 | ||
| 301 | 1.18000 -0.17381E+01 -0.52922E+00 -0.52922E+00 -0.19532E+01 -0.19532E+01 | ||
| 302 | 1.19600 -0.16946E+01 -0.51674E+00 -0.51674E+00 -0.19011E+01 -0.19011E+01 | ||
| 303 | 1.21200 -0.16526E+01 -0.50481E+00 -0.50481E+00 -0.18509E+01 -0.18509E+01 | ||
| 304 | 1.22800 -0.16122E+01 -0.49341E+00 -0.49341E+00 -0.18027E+01 -0.18027E+01 | ||
| 305 | 1.24400 -0.15732E+01 -0.48250E+00 -0.48250E+00 -0.17564E+01 -0.17564E+01 | ||
| 306 | 1.26000 -0.15356E+01 -0.47209E+00 -0.47209E+00 -0.17117E+01 -0.17117E+01 | ||
| 307 | 1.29200 -0.14644E+01 -0.45255E+00 -0.45255E+00 -0.16273E+01 -0.16273E+01 | ||
| 308 | 1.32400 -0.13981E+01 -0.43437E+00 -0.43437E+00 -0.15489E+01 -0.15489E+01 | ||
| 309 | 1.35600 -0.13360E+01 -0.41732E+00 -0.41732E+00 -0.14757E+01 -0.14757E+01 | ||
| 310 | 1.38800 -0.12781E+01 -0.40112E+00 -0.40112E+00 -0.14073E+01 -0.14073E+01 | ||
| 311 | 1.42000 -0.12237E+01 -0.38551E+00 -0.38551E+00 -0.13431E+01 -0.13431E+01 | ||
| 312 | 1.45200 -0.11728E+01 -0.37036E+00 -0.37036E+00 -0.12828E+01 -0.12828E+01 | ||
| 313 | 1.48400 -0.11248E+01 -0.35566E+00 -0.35566E+00 -0.12260E+01 -0.12260E+01 | ||
| 314 | 1.51600 -0.10797E+01 -0.34154E+00 -0.34154E+00 -0.11726E+01 -0.11726E+01 | ||
| 315 | 1.54800 -0.10372E+01 -0.32826E+00 -0.32826E+00 -0.11224E+01 -0.11224E+01 | ||
| 316 | 1.58000 -0.99714E+00 -0.31620E+00 -0.31620E+00 -0.10754E+01 -0.10754E+01 | ||
| 317 | 1.61200 -0.95925E+00 -0.30571E+00 -0.30571E+00 -0.10316E+01 -0.10316E+01 | ||
| 318 | 1.64400 -0.92348E+00 -0.29709E+00 -0.29709E+00 -0.99096E+00 -0.99096E+00 | ||
| 319 | 1.67600 -0.88958E+00 -0.29045E+00 -0.29045E+00 -0.95336E+00 -0.95336E+00 | ||
| 320 | 1.70800 -0.85751E+00 -0.28573E+00 -0.28573E+00 -0.91865E+00 -0.91865E+00 | ||
| 321 | 1.74000 -0.82706E+00 -0.28270E+00 -0.28270E+00 -0.88654E+00 -0.88654E+00 | ||
| 322 | 1.77200 -0.79820E+00 -0.28100E+00 -0.28100E+00 -0.85677E+00 -0.85677E+00 | ||
| 323 | 1.80400 -0.77075E+00 -0.28024E+00 -0.28024E+00 -0.82900E+00 -0.82900E+00 | ||
| 324 | 1.83600 -0.74470E+00 -0.28005E+00 -0.28005E+00 -0.80296E+00 -0.80296E+00 | ||
| 325 | 1.86800 -0.71989E+00 -0.28012E+00 -0.28012E+00 -0.77839E+00 -0.77839E+00 | ||
| 326 | 1.90000 -0.69630E+00 -0.28023E+00 -0.28023E+00 -0.75510E+00 -0.75510E+00 | ||
| 327 | 1.93200 -0.67380E+00 -0.28023E+00 -0.28023E+00 -0.73292E+00 -0.73292E+00 | ||
| 328 | 1.96400 -0.65238E+00 -0.28002E+00 -0.28002E+00 -0.71175E+00 -0.71175E+00 | ||
| 329 | 1.99600 -0.63192E+00 -0.27957E+00 -0.27957E+00 -0.69148E+00 -0.69148E+00 | ||
| 330 | 2.02800 -0.61243E+00 -0.27888E+00 -0.27888E+00 -0.67208E+00 -0.67208E+00 | ||
| 331 | 2.06000 -0.59378E+00 -0.27795E+00 -0.27795E+00 -0.65345E+00 -0.65345E+00 | ||
| 332 | 2.09200 -0.57600E+00 -0.27681E+00 -0.27681E+00 -0.63559E+00 -0.63559E+00 | ||
| 333 | 2.12400 -0.55897E+00 -0.27548E+00 -0.27548E+00 -0.61843E+00 -0.61843E+00 | ||
| 334 | 2.15600 -0.54270E+00 -0.27398E+00 -0.27398E+00 -0.60196E+00 -0.60196E+00 | ||
| 335 | 2.18800 -0.52711E+00 -0.27234E+00 -0.27234E+00 -0.58612E+00 -0.58612E+00 | ||
| 336 | 2.22000 -0.51221E+00 -0.27058E+00 -0.27058E+00 -0.57092E+00 -0.57092E+00 | ||
| 337 | 2.25200 -0.49791E+00 -0.26871E+00 -0.26871E+00 -0.55628E+00 -0.55628E+00 | ||
| 338 | 2.28400 -0.48423E+00 -0.26675E+00 -0.26675E+00 -0.54222E+00 -0.54222E+00 | ||
| 339 | 2.31600 -0.47109E+00 -0.26472E+00 -0.26472E+00 -0.52867E+00 -0.52867E+00 | ||
| 340 | 2.34800 -0.45851E+00 -0.26261E+00 -0.26261E+00 -0.51565E+00 -0.51565E+00 | ||
| 341 | 2.38000 -0.44641E+00 -0.26046E+00 -0.26046E+00 -0.50309E+00 -0.50309E+00 | ||
| 342 | 2.41200 -0.43482E+00 -0.25825E+00 -0.25825E+00 -0.49101E+00 -0.49101E+00 | ||
| 343 | 2.44400 -0.42366E+00 -0.25601E+00 -0.25601E+00 -0.47936E+00 -0.47936E+00 | ||
| 344 | 2.47600 -0.41296E+00 -0.25372E+00 -0.25372E+00 -0.46813E+00 -0.46813E+00 | ||
| 345 | 2.50800 -0.40266E+00 -0.25142E+00 -0.25142E+00 -0.45729E+00 -0.45729E+00 | ||
| 346 | 2.54000 -0.39277E+00 -0.24909E+00 -0.24909E+00 -0.44685E+00 -0.44685E+00 | ||
| 347 | 2.60400 -0.37405E+00 -0.24437E+00 -0.24437E+00 -0.42701E+00 -0.42701E+00 | ||
| 348 | 2.66800 -0.35677E+00 -0.23959E+00 -0.23959E+00 -0.40851E+00 -0.40851E+00 | ||
| 349 | 2.73200 -0.34067E+00 -0.23480E+00 -0.23480E+00 -0.39120E+00 -0.39120E+00 | ||
| 350 | 2.79600 -0.32577E+00 -0.23000E+00 -0.23000E+00 -0.37502E+00 -0.37502E+00 | ||
| 351 | 2.86000 -0.31184E+00 -0.22521E+00 -0.22521E+00 -0.35983E+00 -0.35983E+00 | ||
| 352 | 2.92400 -0.29892E+00 -0.22044E+00 -0.22044E+00 -0.34559E+00 -0.34559E+00 | ||
| 353 | 2.98800 -0.28681E+00 -0.21570E+00 -0.21570E+00 -0.33218E+00 -0.33218E+00 | ||
| 354 | 3.05200 -0.27555E+00 -0.21100E+00 -0.21100E+00 -0.31958E+00 -0.31958E+00 | ||
| 355 | 3.11600 -0.26497E+00 -0.20634E+00 -0.20634E+00 -0.30767E+00 -0.30767E+00 | ||
| 356 | 3.18000 -0.25511E+00 -0.20173E+00 -0.20173E+00 -0.29645E+00 -0.29645E+00 | ||
| 357 | 3.24400 -0.24582E+00 -0.19717E+00 -0.19717E+00 -0.28582E+00 -0.28582E+00 | ||
| 358 | 3.30800 -0.23714E+00 -0.19267E+00 -0.19267E+00 -0.27578E+00 -0.27578E+00 | ||
| 359 | 3.37200 -0.22896E+00 -0.18822E+00 -0.18822E+00 -0.26625E+00 -0.26625E+00 | ||
| 360 | 3.43600 -0.22128E+00 -0.18383E+00 -0.18383E+00 -0.25721E+00 -0.25721E+00 | ||
| 361 | 3.50000 -0.21403E+00 -0.17950E+00 -0.17950E+00 -0.24862E+00 -0.24862E+00 | ||
| 362 | 3.56400 -0.20723E+00 -0.17522E+00 -0.17522E+00 -0.24045E+00 -0.24045E+00 | ||
| 363 | 3.62800 -0.20078E+00 -0.17101E+00 -0.17101E+00 -0.23266E+00 -0.23266E+00 | ||
| 364 | 3.69200 -0.19471E+00 -0.16685E+00 -0.16685E+00 -0.22525E+00 -0.22525E+00 | ||
| 365 | 3.75600 -0.18895E+00 -0.16275E+00 -0.16275E+00 -0.21816E+00 -0.21816E+00 | ||
| 366 | 3.82000 -0.18352E+00 -0.15871E+00 -0.15871E+00 -0.21140E+00 -0.21140E+00 | ||
| 367 | 3.88400 -0.17836E+00 -0.15473E+00 -0.15473E+00 -0.20493E+00 -0.20493E+00 | ||
| 368 | 3.94800 -0.17348E+00 -0.15082E+00 -0.15082E+00 -0.19874E+00 -0.19874E+00 | ||
| 369 | 4.01200 -0.16884E+00 -0.14696E+00 -0.14696E+00 -0.19281E+00 -0.19281E+00 | ||
| 370 | 4.07600 -0.16444E+00 -0.14317E+00 -0.14317E+00 -0.18713E+00 -0.18713E+00 | ||
| 371 | 4.14000 -0.16024E+00 -0.13944E+00 -0.13944E+00 -0.18167E+00 -0.18167E+00 | ||
| 372 | 4.20400 -0.15626E+00 -0.13577E+00 -0.13577E+00 -0.17644E+00 -0.17644E+00 | ||
| 373 | 4.26800 -0.15246E+00 -0.13218E+00 -0.13218E+00 -0.17141E+00 -0.17141E+00 | ||
| 374 | 4.33200 -0.14885E+00 -0.12865E+00 -0.12865E+00 -0.16658E+00 -0.16658E+00 | ||
| 375 | 4.39600 -0.14539E+00 -0.12519E+00 -0.12519E+00 -0.16193E+00 -0.16193E+00 | ||
| 376 | 4.46000 -0.14210E+00 -0.12180E+00 -0.12180E+00 -0.15746E+00 -0.15746E+00 | ||
| 377 | 4.52400 -0.13894E+00 -0.11848E+00 -0.11848E+00 -0.15316E+00 -0.15316E+00 | ||
| 378 | 4.58800 -0.13593E+00 -0.11524E+00 -0.11524E+00 -0.14903E+00 -0.14903E+00 | ||
| 379 | 4.65200 -0.13305E+00 -0.11208E+00 -0.11208E+00 -0.14504E+00 -0.14504E+00 | ||
| 380 | 4.71600 -0.13029E+00 -0.10899E+00 -0.10899E+00 -0.14122E+00 -0.14122E+00 | ||
| 381 | 4.78000 -0.12764E+00 -0.10599E+00 -0.10599E+00 -0.13753E+00 -0.13753E+00 | ||
| 382 | 4.84400 -0.12510E+00 -0.10306E+00 -0.10306E+00 -0.13398E+00 -0.13398E+00 | ||
| 383 | 4.90800 -0.12266E+00 -0.10022E+00 -0.10022E+00 -0.13056E+00 -0.13056E+00 | ||
| 384 | 4.97200 -0.12032E+00 -0.97466E-01 -0.97466E-01 -0.12727E+00 -0.12727E+00 | ||
| 385 | 5.03600 -0.11807E+00 -0.94796E-01 -0.94796E-01 -0.12411E+00 -0.12411E+00 | ||
| 386 | 5.10000 -0.11590E+00 -0.92179E-01 -0.92179E-01 -0.12105E+00 -0.12105E+00 | ||
| 387 | 5.22800 -0.11180E+00 -0.87227E-01 -0.87227E-01 -0.11528E+00 -0.11528E+00 | ||
| 388 | 5.35600 -0.10801E+00 -0.82769E-01 -0.82769E-01 -0.11002E+00 -0.11002E+00 | ||
| 389 | 5.48400 -0.10446E+00 -0.78553E-01 -0.78553E-01 -0.10511E+00 -0.10511E+00 | ||
| 390 | 5.61200 -0.10116E+00 -0.74745E-01 -0.74745E-01 -0.10062E+00 -0.10062E+00 | ||
| 391 | 5.74000 -0.98065E-01 -0.71291E-01 -0.71291E-01 -0.96482E-01 -0.96482E-01 | ||
| 392 | 5.86800 -0.95170E-01 -0.68216E-01 -0.68216E-01 -0.92711E-01 -0.92711E-01 | ||
| 393 | 5.99600 -0.92443E-01 -0.65512E-01 -0.65512E-01 -0.89276E-01 -0.89276E-01 | ||
| 394 | 6.12400 -0.89883E-01 -0.63184E-01 -0.63184E-01 -0.86170E-01 -0.86170E-01 | ||
| 395 | 6.25200 -0.87463E-01 -0.61228E-01 -0.61228E-01 -0.83374E-01 -0.83374E-01 | ||
| 396 | 6.38000 -0.85182E-01 -0.59642E-01 -0.59642E-01 -0.80880E-01 -0.80880E-01 | ||
| 397 | 6.50800 -0.83019E-01 -0.58416E-01 -0.58416E-01 -0.78668E-01 -0.78668E-01 | ||
| 398 | 6.63600 -0.80972E-01 -0.57536E-01 -0.57536E-01 -0.76728E-01 -0.76728E-01 | ||
| 399 | 6.76400 -0.79026E-01 -0.56982E-01 -0.56982E-01 -0.75036E-01 -0.75036E-01 | ||
| 400 | 6.89200 -0.77178E-01 -0.56723E-01 -0.56723E-01 -0.73573E-01 -0.73573E-01 | ||
| 401 | 7.02000 -0.75417E-01 -0.56719E-01 -0.56719E-01 -0.72311E-01 -0.72311E-01 | ||
| 402 | 7.14800 -0.73740E-01 -0.56920E-01 -0.56920E-01 -0.71221E-01 -0.71221E-01 | ||
| 403 | 7.27600 -0.72138E-01 -0.57265E-01 -0.57265E-01 -0.70266E-01 -0.70266E-01 | ||
| 404 | 7.40400 -0.70608E-01 -0.57687E-01 -0.57687E-01 -0.69407E-01 -0.69407E-01 | ||
| 405 | 7.53200 -0.69144E-01 -0.58111E-01 -0.58111E-01 -0.68603E-01 -0.68603E-01 | ||
| 406 | 7.66000 -0.67742E-01 -0.58459E-01 -0.58459E-01 -0.67811E-01 -0.67811E-01 | ||
| 407 | 7.78800 -0.66397E-01 -0.58657E-01 -0.58657E-01 -0.66990E-01 -0.66990E-01 | ||
| 408 | 7.91600 -0.65107E-01 -0.58635E-01 -0.58635E-01 -0.66104E-01 -0.66104E-01 | ||
| 409 | 8.04400 -0.63867E-01 -0.58337E-01 -0.58337E-01 -0.65119E-01 -0.65119E-01 | ||
| 410 | 8.17200 -0.62676E-01 -0.57718E-01 -0.57718E-01 -0.64012E-01 -0.64012E-01 | ||
| 411 | 8.30000 -0.61529E-01 -0.56754E-01 -0.56754E-01 -0.62766E-01 -0.62766E-01 | ||
| 412 | 8.42800 -0.60424E-01 -0.55435E-01 -0.55435E-01 -0.61377E-01 -0.61377E-01 | ||
| 413 | 8.55600 -0.59359E-01 -0.53772E-01 -0.53772E-01 -0.59846E-01 -0.59846E-01 | ||
| 414 | 8.68400 -0.58332E-01 -0.51790E-01 -0.51790E-01 -0.58185E-01 -0.58185E-01 | ||
| 415 | 8.81200 -0.57341E-01 -0.49529E-01 -0.49529E-01 -0.56411E-01 -0.56411E-01 | ||
| 416 | 8.94000 -0.56383E-01 -0.47038E-01 -0.47038E-01 -0.54548E-01 -0.54548E-01 | ||
| 417 | 9.06800 -0.55457E-01 -0.44369E-01 -0.44369E-01 -0.52620E-01 -0.52620E-01 | ||
| 418 | 9.19600 -0.54562E-01 -0.41581E-01 -0.41581E-01 -0.50655E-01 -0.50655E-01 | ||
| 419 | 9.32400 -0.53695E-01 -0.38728E-01 -0.38728E-01 -0.48679E-01 -0.48679E-01 | ||
| 420 | 9.45200 -0.52856E-01 -0.35862E-01 -0.35862E-01 -0.46717E-01 -0.46717E-01 | ||
| 421 | 9.58000 -0.52042E-01 -0.33028E-01 -0.33028E-01 -0.44790E-01 -0.44790E-01 | ||
| 422 | 9.70800 -0.51254E-01 -0.30266E-01 -0.30266E-01 -0.42917E-01 -0.42917E-01 | ||
| 423 | 9.83600 -0.50489E-01 -0.27608E-01 -0.27608E-01 -0.41113E-01 -0.41113E-01 | ||
| 424 | 9.96400 -0.49746E-01 -0.25075E-01 -0.25075E-01 -0.39388E-01 -0.39388E-01 | ||
| 425 | 10.09200 -0.49025E-01 -0.22687E-01 -0.22687E-01 -0.37750E-01 -0.37750E-01 | ||
| 426 | 10.22000 -0.48325E-01 -0.20526E-01 -0.20526E-01 -0.36241E-01 -0.36241E-01 | ||
| 427 | 10.47600 -0.46982E-01 -0.16523E-01 -0.16523E-01 -0.33423E-01 -0.33423E-01 | ||
| 428 | 10.73200 -0.45712E-01 -0.13072E-01 -0.13072E-01 -0.30931E-01 -0.30931E-01 | ||
| 429 | 10.98800 -0.44508E-01 -0.10367E-01 -0.10367E-01 -0.28859E-01 -0.28859E-01 | ||
| 430 | 11.24400 -0.43365E-01 -0.81480E-02 -0.81480E-02 -0.27071E-01 -0.27071E-01 | ||
| 431 | 11.50000 -0.42278E-01 -0.63810E-02 -0.63810E-02 -0.25547E-01 -0.25547E-01 | ||
| 432 | 11.75600 -0.41244E-01 -0.49785E-02 -0.49785E-02 -0.24241E-01 -0.24241E-01 | ||
| 433 | 12.01200 -0.40258E-01 -0.38752E-02 -0.38752E-02 -0.23116E-01 -0.23116E-01 | ||
| 434 | 12.26800 -0.39317E-01 -0.30111E-02 -0.30111E-02 -0.22140E-01 -0.22140E-01 | ||
| 435 | 12.52400 -0.38418E-01 -0.23370E-02 -0.23370E-02 -0.21287E-01 -0.21287E-01 | ||
| 436 | 12.78000 -0.37559E-01 -0.18126E-02 -0.18126E-02 -0.20534E-01 -0.20534E-01 | ||
| 437 | 13.03600 -0.36735E-01 -0.14055E-02 -0.14055E-02 -0.19863E-01 -0.19863E-01 | ||
| 438 | 13.29200 -0.35947E-01 -0.10897E-02 -0.10897E-02 -0.19259E-01 -0.19259E-01 | ||
| 439 | 13.54800 -0.35190E-01 -0.84505E-03 -0.84505E-03 -0.18711E-01 -0.18711E-01 | ||
| 440 | 13.80400 -0.34463E-01 -0.65552E-03 -0.65552E-03 -0.18209E-01 -0.18209E-01 | ||
| 441 | 14.06000 -0.33765E-01 -0.50871E-03 -0.50871E-03 -0.17746E-01 -0.17746E-01 | ||
| 442 | 14.31600 -0.33093E-01 -0.39498E-03 -0.39498E-03 -0.17316E-01 -0.17316E-01 | ||
| 443 | 14.57200 -0.32446E-01 -0.30685E-03 -0.30685E-03 -0.16915E-01 -0.16915E-01 | ||
| 444 | 14.82800 -0.31824E-01 -0.23853E-03 -0.23853E-03 -0.16538E-01 -0.16538E-01 | ||
| 445 | 15.08400 -0.31223E-01 -0.18554E-03 -0.18554E-03 -0.16181E-01 -0.16181E-01 | ||
| 446 | 15.34000 -0.30644E-01 -0.14441E-03 -0.14441E-03 -0.15844E-01 -0.15844E-01 | ||
| 447 | 15.59600 -0.30085E-01 -0.11247E-03 -0.11247E-03 -0.15523E-01 -0.15523E-01 | ||
| 448 | 15.85200 -0.29545E-01 -0.87651E-04 -0.87651E-04 -0.15217E-01 -0.15217E-01 | ||
| 449 | 16.10800 -0.29024E-01 -0.68351E-04 -0.68351E-04 -0.14925E-01 -0.14925E-01 | ||
| 450 | 16.36400 -0.28519E-01 -0.53333E-04 -0.53333E-04 -0.14645E-01 -0.14645E-01 | ||
| 451 | 16.62000 -0.28031E-01 -0.41639E-04 -0.41639E-04 -0.14375E-01 -0.14375E-01 | ||
| 452 | 16.87600 -0.27558E-01 -0.32528E-04 -0.32528E-04 -0.14117E-01 -0.14117E-01 | ||
| 453 | 17.13200 -0.27100E-01 -0.25424E-04 -0.25424E-04 -0.13867E-01 -0.13867E-01 | ||
| 454 | 17.38800 -0.26656E-01 -0.19882E-04 -0.19882E-04 -0.13627E-01 -0.13627E-01 | ||
| 455 | 17.64400 -0.26226E-01 -0.15556E-04 -0.15556E-04 -0.13395E-01 -0.13395E-01 | ||
| 456 | 17.90000 -0.25808E-01 -0.12176E-04 -0.12176E-04 -0.13171E-01 -0.13171E-01 | ||
| 457 | 18.15600 -0.25403E-01 -0.95354E-05 -0.95354E-05 -0.12954E-01 -0.12954E-01 | ||
| 458 | 18.41200 -0.25009E-01 -0.74700E-05 -0.74700E-05 -0.12744E-01 -0.12744E-01 | ||
| 459 | 18.66800 -0.24627E-01 -0.58546E-05 -0.58546E-05 -0.12541E-01 -0.12541E-01 | ||
| 460 | 18.92400 -0.24255E-01 -0.45881E-05 -0.45881E-05 -0.12344E-01 -0.12344E-01 | ||
| 461 | 19.18000 -0.23894E-01 -0.36023E-05 -0.36023E-05 -0.12153E-01 -0.12153E-01 | ||
| 462 | 19.43600 -0.23543E-01 -0.28114E-05 -0.28114E-05 -0.11967E-01 -0.11967E-01 | ||
| 463 | 19.69200 -0.23201E-01 -0.22450E-05 -0.22450E-05 -0.11787E-01 -0.11787E-01 | ||
| 464 | 19.94800 -0.22868E-01 -0.16590E-05 -0.16590E-05 -0.11612E-01 -0.11612E-01 | ||
| 465 | 20.20400 -0.22544E-01 -0.15366E-05 -0.15366E-05 -0.11442E-01 -0.11442E-01 | ||
| 466 | 20.46000 -0.22228E-01 -0.13842E-05 -0.13842E-05 -0.11277E-01 -0.11277E-01 | ||
| 467 | |||
| 468 | |||
| 469 | |||
| 470 | ********************* iteration: 2 *********************** | ||
| 471 | |||
| 472 | l = 0, 5 bound states | ||
| 473 | l = 1, 3 bound states | ||
| 474 | l = 2, 1 bound states | ||
| 475 | l = 0, 5 bound states | ||
| 476 | l = 1, 3 bound states | ||
| 477 | l = 2, 1 bound states | ||
| 478 | |||
| 479 | |||
| 480 | bound states | ||
| 481 | |||
| 482 | 100 energy: -54.47671 iteration loops: 6 | ||
| 483 | 200 energy: -4.17535 iteration loops: 11 | ||
| 484 | 300 energy: -0.29422 iteration loops: 12 | ||
| 485 | 210 energy: -2.79007 iteration loops: 8 | ||
| 486 | 310 energy: -0.11055 iteration loops: 9 | ||
| 487 | 100 energy: -54.47671 iteration loops: 6 | ||
| 488 | 200 energy: -4.17535 iteration loops: 11 | ||
| 489 | 300 energy: -0.29422 iteration loops: 12 | ||
| 490 | 210 energy: -2.79007 iteration loops: 8 | ||
| 491 | |||
| 492 | integr charges: total 13.0000001 valence: 13.0000001 0.0000000 | ||
| 493 | induced moment: 1.00000 | ||
| 494 | |||
| 495 | energy terms | ||
| 496 | energy eigenvalue sum: -0.134744E+03 | ||
| 497 | kin: 0.187132E+03 0.186409E+03 coul: -0.468433E+03 exc: -0.184789E+02 | ||
| 498 | |||
| 499 | total energy: -0.2481140E+03 | ||
| 500 | valence energy: -0.2422917E+03 | ||
| 501 | |||
| 502 | |||
| 503 | |||
| 504 | ********************* iteration: 3 *********************** | ||
| 505 | |||
| 506 | l = 0, 5 bound states | ||
| 507 | l = 1, 3 bound states | ||
| 508 | l = 2, 1 bound states | ||
| 509 | l = 0, 5 bound states | ||
| 510 | l = 1, 3 bound states | ||
| 511 | l = 2, 1 bound states | ||
| 512 | |||
| 513 | |||
| 514 | bound states | ||
| 515 | |||
| 516 | 100 energy: -55.36892 iteration loops: 5 | ||
| 517 | 200 energy: -4.29777 iteration loops: 5 | ||
| 518 | 300 energy: -0.36089 iteration loops: 7 | ||
| 519 | 210 energy: -2.91215 iteration loops: 6 | ||
| 520 | 310 energy: -0.16411 iteration loops: 8 | ||
| 521 | 100 energy: -55.36808 iteration loops: 5 | ||
| 522 | 200 energy: -4.29667 iteration loops: 5 | ||
| 523 | 300 energy: -0.34758 iteration loops: 7 | ||
| 524 | 210 energy: -2.91076 iteration loops: 6 | ||
| 525 | |||
| 526 | integr charges: total 13.0000001 valence: 13.0000001 0.0000000 | ||
| 527 | induced moment: 1.00000 | ||
| 528 | |||
| 529 | energy terms | ||
| 530 | energy eigenvalue sum: -0.137673E+03 | ||
| 531 | kin: 0.190704E+03 0.189800E+03 coul: -0.470290E+03 exc: -0.186975E+02 | ||
| 532 | |||
| 533 | total energy: -0.2461560E+03 | ||
| 534 | valence energy: -0.2469787E+03 | ||
| 535 | |||
| 536 | |||
| 537 | |||
| 538 | ********************* iteration: 4 *********************** | ||
| 539 | |||
| 540 | l = 0, 5 bound states | ||
| 541 | l = 1, 3 bound states | ||
| 542 | l = 2, 1 bound states | ||
| 543 | l = 0, 4 bound states | ||
| 544 | l = 1, 3 bound states | ||
| 545 | |||
| 546 | |||
| 547 | bound states | ||
| 548 | |||
| 549 | 100 energy: -55.55097 iteration loops: 4 | ||
| 550 | 200 energy: -4.20776 iteration loops: 4 | ||
| 551 | 300 energy: -0.35526 iteration loops: 7 | ||
| 552 | 210 energy: -2.81804 iteration loops: 5 | ||
| 553 | 310 energy: -0.15966 iteration loops: 6 | ||
| 554 | 100 energy: -55.54955 iteration loops: 4 | ||
| 555 | 200 energy: -4.20596 iteration loops: 4 | ||
| 556 | 300 energy: -0.33342 iteration loops: 6 | ||
| 557 | 210 energy: -2.81575 iteration loops: 5 | ||
| 558 | |||
| 559 | integr charges: total 13.0000001 valence: 13.0000001 0.0000000 | ||
| 560 | induced moment: 1.00000 | ||
| 561 | |||
| 562 | energy terms | ||
| 563 | energy eigenvalue sum: -0.137264E+03 | ||
| 564 | kin: 0.190734E+03 0.189832E+03 coul: -0.468741E+03 exc: -0.186828E+02 | ||
| 565 | |||
| 566 | total energy: -0.2441225E+03 | ||
| 567 | valence energy: -0.2463262E+03 | ||
| 568 | |||
| 569 | |||
| 570 | |||
| 571 | ********************* iteration: 5 *********************** | ||
| 572 | |||
| 573 | l = 0, 4 bound states | ||
| 574 | l = 1, 3 bound states | ||
| 575 | l = 0, 4 bound states | ||
| 576 | l = 1, 2 bound states | ||
| 577 | |||
| 578 | |||
| 579 | bound states | ||
| 580 | |||
| 581 | 100 energy: -55.51177 iteration loops: 4 | ||
| 582 | 200 energy: -4.09189 iteration loops: 5 | ||
| 583 | 300 energy: -0.33274 iteration loops: 6 | ||
| 584 | 210 energy: -2.69809 iteration loops: 6 | ||
| 585 | 310 energy: -0.14172 iteration loops: 8 | ||
| 586 | 100 energy: -55.51008 iteration loops: 4 | ||
| 587 | 200 energy: -4.08978 iteration loops: 5 | ||
| 588 | 300 energy: -0.30655 iteration loops: 5 | ||
| 589 | 210 energy: -2.69538 iteration loops: 6 | ||
| 590 | |||
| 591 | integr charges: total 13.0000001 valence: 13.0000001 0.0000000 | ||
| 592 | induced moment: 1.00000 | ||
| 593 | |||
| 594 | energy terms | ||
| 595 | energy eigenvalue sum: -0.136165E+03 | ||
| 596 | kin: 0.189870E+03 0.189016E+03 coul: -0.466985E+03 exc: -0.186108E+02 | ||
| 597 | |||
| 598 | total energy: -0.2428752E+03 | ||
| 599 | valence energy: -0.2445257E+03 | ||
| 600 | |||
| 601 | |||
| 602 | |||
| 603 | ********************* iteration: 6 *********************** | ||
| 604 | |||
| 605 | l = 0, 4 bound states | ||
| 606 | l = 1, 3 bound states | ||
| 607 | l = 0, 4 bound states | ||
| 608 | l = 1, 2 bound states | ||
| 609 | |||
| 610 | |||
| 611 | bound states | ||
| 612 | |||
| 613 | 100 energy: -55.45132 iteration loops: 4 | ||
| 614 | 200 energy: -4.01239 iteration loops: 4 | ||
| 615 | 300 energy: -0.31424 iteration loops: 5 | ||
| 616 | 210 energy: -2.61641 iteration loops: 5 | ||
| 617 | 310 energy: -0.12716 iteration loops: 9 | ||
| 618 | 100 energy: -55.44954 iteration loops: 4 | ||
| 619 | 200 energy: -4.01021 iteration loops: 4 | ||
| 620 | 300 energy: -0.28628 iteration loops: 5 | ||
| 621 | 210 energy: -2.61358 iteration loops: 5 | ||
| 622 | |||
| 623 | integr charges: total 13.0000001 valence: 13.0000001 0.0000000 | ||
| 624 | induced moment: 1.00000 | ||
| 625 | |||
| 626 | energy terms | ||
| 627 | energy eigenvalue sum: -0.135341E+03 | ||
| 628 | kin: 0.189155E+03 0.188346E+03 coul: -0.465936E+03 exc: -0.185527E+02 | ||
| 629 | |||
| 630 | total energy: -0.2423289E+03 | ||
| 631 | valence energy: -0.2431501E+03 | ||
| 632 | |||
| 633 | |||
| 634 | |||
| 635 | ********************* iteration: 7 *********************** | ||
| 636 | |||
| 637 | l = 0, 4 bound states | ||
| 638 | l = 1, 3 bound states | ||
| 639 | l = 0, 4 bound states | ||
| 640 | l = 1, 2 bound states | ||
| 641 | |||
| 642 | |||
| 643 | bound states | ||
| 644 | |||
| 645 | 100 energy: -55.42092 iteration loops: 3 | ||
| 646 | 200 energy: -3.97283 iteration loops: 5 | ||
| 647 | 300 energy: -0.30360 iteration loops: 5 | ||
| 648 | 210 energy: -2.57639 iteration loops: 5 | ||
| 649 | 310 energy: -0.11875 iteration loops: 5 | ||
| 650 | 100 energy: -55.41915 iteration loops: 3 | ||
| 651 | 200 energy: -3.97066 iteration loops: 5 | ||
| 652 | 300 energy: -0.27518 iteration loops: 5 | ||
| 653 | 210 energy: -2.57357 iteration loops: 5 | ||
| 654 | |||
| 655 | integr charges: total 13.0000001 valence: 13.0000001 0.0000000 | ||
| 656 | induced moment: 1.00000 | ||
| 657 | |||
| 658 | energy terms | ||
| 659 | energy eigenvalue sum: -0.134931E+03 | ||
| 660 | kin: 0.188797E+03 0.188014E+03 coul: -0.465552E+03 exc: -0.185233E+02 | ||
| 661 | |||
| 662 | total energy: -0.2421949E+03 | ||
| 663 | valence energy: -0.2424598E+03 | ||
| 664 | |||
| 665 | |||
| 666 | |||
| 667 | ********************* iteration: 8 *********************** | ||
| 668 | |||
| 669 | l = 0, 4 bound states | ||
| 670 | l = 1, 2 bound states | ||
| 671 | l = 0, 4 bound states | ||
| 672 | l = 1, 2 bound states | ||
| 673 | |||
| 674 | |||
| 675 | bound states | ||
| 676 | |||
| 677 | 100 energy: -55.41596 iteration loops: 3 | ||
| 678 | 200 energy: -3.95882 iteration loops: 5 | ||
| 679 | 300 energy: -0.29885 iteration loops: 5 | ||
| 680 | 210 energy: -2.56284 iteration loops: 4 | ||
| 681 | 310 energy: -0.11484 iteration loops: 5 | ||
| 682 | 100 energy: -55.41421 iteration loops: 3 | ||
| 683 | 200 energy: -3.95669 iteration loops: 5 | ||
| 684 | 300 energy: -0.27046 iteration loops: 5 | ||
| 685 | 210 energy: -2.56007 iteration loops: 4 | ||
| 686 | |||
| 687 | integr charges: total 13.0000001 valence: 13.0000001 0.0000000 | ||
| 688 | induced moment: 1.00000 | ||
| 689 | |||
| 690 | energy terms | ||
| 691 | energy eigenvalue sum: -0.134799E+03 | ||
| 692 | kin: 0.188694E+03 0.187922E+03 coul: -0.465531E+03 exc: -0.185148E+02 | ||
| 693 | |||
| 694 | total energy: -0.2422287E+03 | ||
| 695 | valence energy: -0.2422434E+03 | ||
| 696 | |||
| 697 | |||
| 698 | |||
| 699 | ********************* iteration: 9 *********************** | ||
| 700 | |||
| 701 | l = 0, 4 bound states | ||
| 702 | l = 1, 2 bound states | ||
| 703 | l = 0, 4 bound states | ||
| 704 | l = 1, 2 bound states | ||
| 705 | |||
| 706 | |||
| 707 | bound states | ||
| 708 | |||
| 709 | 100 energy: -55.42156 iteration loops: 4 | ||
| 710 | 200 energy: -3.95653 iteration loops: 4 | ||
| 711 | 300 energy: -0.29725 iteration loops: 5 | ||
| 712 | 210 energy: -2.56125 iteration loops: 4 | ||
| 713 | 310 energy: -0.11332 iteration loops: 5 | ||
| 714 | 100 energy: -55.41983 iteration loops: 4 | ||
| 715 | 200 energy: -3.95443 iteration loops: 4 | ||
| 716 | 300 energy: -0.26899 iteration loops: 5 | ||
| 717 | 210 energy: -2.55852 iteration loops: 4 | ||
| 718 | |||
| 719 | integr charges: total 13.0000001 valence: 13.0000001 0.0000000 | ||
| 720 | induced moment: 1.00000 | ||
| 721 | |||
| 722 | energy terms | ||
| 723 | energy eigenvalue sum: -0.134791E+03 | ||
| 724 | kin: 0.188705E+03 0.187936E+03 coul: -0.465626E+03 exc: -0.185158E+02 | ||
| 725 | |||
| 726 | total energy: -0.2422928E+03 | ||
| 727 | valence energy: -0.2422437E+03 | ||
| 728 | |||
| 729 | |||
| 730 | |||
| 731 | ********************* iteration: 10 *********************** | ||
| 732 | |||
| 733 | l = 0, 4 bound states | ||
| 734 | l = 1, 2 bound states | ||
| 735 | l = 0, 4 bound states | ||
| 736 | l = 1, 2 bound states | ||
| 737 | |||
| 738 | |||
| 739 | bound states | ||
| 740 | |||
| 741 | 100 energy: -55.42793 iteration loops: 4 | ||
| 742 | 200 energy: -3.95770 iteration loops: 4 | ||
| 743 | 300 energy: -0.29690 iteration loops: 4 | ||
| 744 | 210 energy: -2.56301 iteration loops: 4 | ||
| 745 | 310 energy: -0.11279 iteration loops: 5 | ||
| 746 | 100 energy: -55.42622 iteration loops: 4 | ||
| 747 | 200 energy: -3.95562 iteration loops: 4 | ||
| 748 | 300 energy: -0.26872 iteration loops: 4 | ||
| 749 | 210 energy: -2.56031 iteration loops: 4 | ||
| 750 | |||
| 751 | integr charges: total 13.0000001 valence: 13.0000001 0.0000000 | ||
| 752 | induced moment: 1.00000 | ||
| 753 | |||
| 754 | energy terms | ||
| 755 | energy eigenvalue sum: -0.134816E+03 | ||
| 756 | kin: 0.188741E+03 0.187972E+03 coul: -0.465715E+03 exc: -0.185191E+02 | ||
| 757 | |||
| 758 | total energy: -0.2423368E+03 | ||
| 759 | valence energy: -0.2422989E+03 | ||
| 760 | |||
| 761 | |||
| 762 | |||
| 763 | ********************* iteration: 11 *********************** | ||
| 764 | |||
| 765 | l = 0, 4 bound states | ||
| 766 | l = 1, 2 bound states | ||
| 767 | l = 0, 4 bound states | ||
| 768 | l = 1, 2 bound states | ||
| 769 | |||
| 770 | |||
| 771 | bound states | ||
| 772 | |||
| 773 | 100 energy: -55.43163 iteration loops: 3 | ||
| 774 | 200 energy: -3.95890 iteration loops: 4 | ||
| 775 | 300 energy: -0.29685 iteration loops: 4 | ||
| 776 | 210 energy: -2.56458 iteration loops: 3 | ||
| 777 | 310 energy: -0.11256 iteration loops: 5 | ||
| 778 | 100 energy: -55.42992 iteration loops: 3 | ||
| 779 | 200 energy: -3.95682 iteration loops: 4 | ||
| 780 | 300 energy: -0.26871 iteration loops: 4 | ||
| 781 | 210 energy: -2.56189 iteration loops: 3 | ||
| 782 | |||
| 783 | integr charges: total 13.0000001 valence: 13.0000001 0.0000000 | ||
| 784 | induced moment: 1.00000 | ||
| 785 | |||
| 786 | energy terms | ||
| 787 | energy eigenvalue sum: -0.134835E+03 | ||
| 788 | kin: 0.188768E+03 0.187998E+03 coul: -0.465764E+03 exc: -0.185217E+02 | ||
| 789 | |||
| 790 | total energy: -0.2423554E+03 | ||
| 791 | valence energy: -0.2423421E+03 | ||
| 792 | |||
| 793 | |||
| 794 | |||
| 795 | ********************* iteration: 12 *********************** | ||
| 796 | |||
| 797 | l = 0, 4 bound states | ||
| 798 | l = 1, 2 bound states | ||
| 799 | l = 0, 4 bound states | ||
| 800 | l = 1, 2 bound states | ||
| 801 | |||
| 802 | |||
| 803 | bound states | ||
| 804 | |||
| 805 | 100 energy: -55.43277 iteration loops: 3 | ||
| 806 | 200 energy: -3.95934 iteration loops: 4 | ||
| 807 | 300 energy: -0.29679 iteration loops: 4 | ||
| 808 | 210 energy: -2.56521 iteration loops: 3 | ||
| 809 | 310 energy: -0.11238 iteration loops: 5 | ||
| 810 | 100 energy: -55.43107 iteration loops: 3 | ||
| 811 | 200 energy: -3.95727 iteration loops: 4 | ||
| 812 | 300 energy: -0.26864 iteration loops: 4 | ||
| 813 | 210 energy: -2.56252 iteration loops: 3 | ||
| 814 | |||
| 815 | integr charges: total 13.0000001 valence: 13.0000001 0.0000000 | ||
| 816 | induced moment: 1.00000 | ||
| 817 | |||
| 818 | energy terms | ||
| 819 | energy eigenvalue sum: -0.134841E+03 | ||
| 820 | kin: 0.188779E+03 0.188008E+03 coul: -0.465781E+03 exc: -0.185229E+02 | ||
| 821 | |||
| 822 | total energy: -0.2423586E+03 | ||
| 823 | valence energy: -0.2423610E+03 | ||
| 824 | |||
| 825 | |||
| 826 | |||
| 827 | ********************* iteration: 13 *********************** | ||
| 828 | |||
| 829 | l = 0, 4 bound states | ||
| 830 | l = 1, 2 bound states | ||
| 831 | l = 0, 4 bound states | ||
| 832 | l = 1, 2 bound states | ||
| 833 | |||
| 834 | |||
| 835 | bound states | ||
| 836 | |||
| 837 | 100 energy: -55.43252 iteration loops: 3 | ||
| 838 | 200 energy: -3.95924 iteration loops: 3 | ||
| 839 | 300 energy: -0.29667 iteration loops: 4 | ||
| 840 | 210 energy: -2.56520 iteration loops: 3 | ||
| 841 | 310 energy: -0.11222 iteration loops: 4 | ||
| 842 | 100 energy: -55.43081 iteration loops: 3 | ||
| 843 | 200 energy: -3.95717 iteration loops: 3 | ||
| 844 | 300 energy: -0.26851 iteration loops: 4 | ||
| 845 | 210 energy: -2.56251 iteration loops: 3 | ||
| 846 | |||
| 847 | integr charges: total 13.0000001 valence: 13.0000001 0.0000000 | ||
| 848 | induced moment: 1.00000 | ||
| 849 | |||
| 850 | energy terms | ||
| 851 | energy eigenvalue sum: -0.134840E+03 | ||
| 852 | kin: 0.188780E+03 0.188009E+03 coul: -0.465781E+03 exc: -0.185232E+02 | ||
| 853 | |||
| 854 | total energy: -0.2423557E+03 | ||
| 855 | valence energy: -0.2423635E+03 | ||
| 856 | |||
| 857 | |||
| 858 | |||
| 859 | ********************* iteration: 14 *********************** | ||
| 860 | |||
| 861 | l = 0, 4 bound states | ||
| 862 | l = 1, 2 bound states | ||
| 863 | l = 0, 4 bound states | ||
| 864 | l = 1, 2 bound states | ||
| 865 | |||
| 866 | |||
| 867 | bound states | ||
| 868 | |||
| 869 | 100 energy: -55.43184 iteration loops: 4 | ||
| 870 | 200 energy: -3.95896 iteration loops: 4 | ||
| 871 | 300 energy: -0.29655 iteration loops: 4 | ||
| 872 | 210 energy: -2.56494 iteration loops: 3 | ||
| 873 | 310 energy: -0.11208 iteration loops: 4 | ||
| 874 | 100 energy: -55.43013 iteration loops: 4 | ||
| 875 | 200 energy: -3.95688 iteration loops: 4 | ||
| 876 | 300 energy: -0.26838 iteration loops: 4 | ||
| 877 | 210 energy: -2.56225 iteration loops: 3 | ||
| 878 | |||
| 879 | integr charges: total 13.0000001 valence: 13.0000001 0.0000000 | ||
| 880 | induced moment: 1.00000 | ||
| 881 | |||
| 882 | energy terms | ||
| 883 | energy eigenvalue sum: -0.134836E+03 | ||
| 884 | kin: 0.188777E+03 0.188007E+03 coul: -0.465777E+03 exc: -0.185231E+02 | ||
| 885 | |||
| 886 | total energy: -0.2423522E+03 | ||
| 887 | valence energy: -0.2423593E+03 | ||
| 888 | |||
| 889 | |||
| 890 | |||
| 891 | ********************* iteration: 15 *********************** | ||
| 892 | |||
| 893 | l = 0, 4 bound states | ||
| 894 | l = 1, 2 bound states | ||
| 895 | l = 0, 4 bound states | ||
| 896 | l = 1, 2 bound states | ||
| 897 | |||
| 898 | |||
| 899 | bound states | ||
| 900 | |||
| 901 | 100 energy: -55.43124 iteration loops: 3 | ||
| 902 | 200 energy: -3.95870 iteration loops: 4 | ||
| 903 | 300 energy: -0.29644 iteration loops: 4 | ||
| 904 | 210 energy: -2.56469 iteration loops: 3 | ||
| 905 | 310 energy: -0.11199 iteration loops: 4 | ||
| 906 | 100 energy: -55.42953 iteration loops: 3 | ||
| 907 | 200 energy: -3.95663 iteration loops: 4 | ||
| 908 | 300 energy: -0.26827 iteration loops: 4 | ||
| 909 | 210 energy: -2.56199 iteration loops: 3 | ||
| 910 | |||
| 911 | integr charges: total 13.0000001 valence: 13.0000001 0.0000000 | ||
| 912 | induced moment: 1.00000 | ||
| 913 | |||
| 914 | energy terms | ||
| 915 | energy eigenvalue sum: -0.134833E+03 | ||
| 916 | kin: 0.188774E+03 0.188004E+03 coul: -0.465772E+03 exc: -0.185230E+02 | ||
| 917 | |||
| 918 | total energy: -0.2423499E+03 | ||
| 919 | valence energy: -0.2423544E+03 | ||
| 920 | |||
| 921 | |||
| 922 | |||
| 923 | ********************* iteration: 16 *********************** | ||
| 924 | |||
| 925 | l = 0, 4 bound states | ||
| 926 | l = 1, 2 bound states | ||
| 927 | l = 0, 4 bound states | ||
| 928 | l = 1, 2 bound states | ||
| 929 | |||
| 930 | |||
| 931 | bound states | ||
| 932 | |||
| 933 | 100 energy: -55.43086 iteration loops: 3 | ||
| 934 | 200 energy: -3.95854 iteration loops: 3 | ||
| 935 | 300 energy: -0.29638 iteration loops: 4 | ||
| 936 | 210 energy: -2.56452 iteration loops: 3 | ||
| 937 | 310 energy: -0.11193 iteration loops: 4 | ||
| 938 | 100 energy: -55.42915 iteration loops: 3 | ||
| 939 | 200 energy: -3.95646 iteration loops: 3 | ||
| 940 | 300 energy: -0.26820 iteration loops: 4 | ||
| 941 | 210 energy: -2.56183 iteration loops: 3 | ||
| 942 | |||
| 943 | integr charges: total 13.0000001 valence: 13.0000001 0.0000000 | ||
| 944 | induced moment: 1.00000 | ||
| 945 | |||
| 946 | energy terms | ||
| 947 | energy eigenvalue sum: -0.134831E+03 | ||
| 948 | kin: 0.188772E+03 0.188002E+03 coul: -0.465769E+03 exc: -0.185228E+02 | ||
| 949 | |||
| 950 | total energy: -0.2423489E+03 | ||
| 951 | valence energy: -0.2423511E+03 | ||
| 952 | |||
| 953 | |||
| 954 | |||
| 955 | ********************* iteration: 17 *********************** | ||
| 956 | |||
| 957 | l = 0, 4 bound states | ||
| 958 | l = 1, 2 bound states | ||
| 959 | l = 0, 4 bound states | ||
| 960 | l = 1, 2 bound states | ||
| 961 | |||
| 962 | |||
| 963 | bound states | ||
| 964 | |||
| 965 | 100 energy: -55.43068 iteration loops: 2 | ||
| 966 | 200 energy: -3.95846 iteration loops: 3 | ||
| 967 | 300 energy: -0.29634 iteration loops: 4 | ||
| 968 | 210 energy: -2.56445 iteration loops: 3 | ||
| 969 | 310 energy: -0.11190 iteration loops: 4 | ||
| 970 | 100 energy: -55.42897 iteration loops: 2 | ||
| 971 | 200 energy: -3.95639 iteration loops: 3 | ||
| 972 | 300 energy: -0.26817 iteration loops: 4 | ||
| 973 | 210 energy: -2.56176 iteration loops: 3 | ||
| 974 | |||
| 975 | integr charges: total 13.0000001 valence: 13.0000001 0.0000000 | ||
| 976 | induced moment: 1.00000 | ||
| 977 | |||
| 978 | energy terms | ||
| 979 | energy eigenvalue sum: -0.134830E+03 | ||
| 980 | kin: 0.188771E+03 0.188001E+03 coul: -0.465769E+03 exc: -0.185228E+02 | ||
| 981 | |||
| 982 | total energy: -0.2423487E+03 | ||
| 983 | valence energy: -0.2423495E+03 | ||
| 984 | |||
| 985 | |||
| 986 | |||
| 987 | ********************* iteration: 18 *********************** | ||
| 988 | |||
| 989 | l = 0, 4 bound states | ||
| 990 | l = 1, 2 bound states | ||
| 991 | l = 0, 4 bound states | ||
| 992 | l = 1, 2 bound states | ||
| 993 | |||
| 994 | |||
| 995 | bound states | ||
| 996 | |||
| 997 | 100 energy: -55.43062 iteration loops: 2 | ||
| 998 | 200 energy: -3.95843 iteration loops: 3 | ||
| 999 | 300 energy: -0.29633 iteration loops: 4 | ||
| 1000 | 210 energy: -2.56442 iteration loops: 3 | ||
| 1001 | 310 energy: -0.11188 iteration loops: 4 | ||
| 1002 | 100 energy: -55.42891 iteration loops: 2 | ||
| 1003 | 200 energy: -3.95636 iteration loops: 3 | ||
| 1004 | 300 energy: -0.26815 iteration loops: 4 | ||
| 1005 | 210 energy: -2.56173 iteration loops: 3 | ||
| 1006 | |||
| 1007 | integr charges: total 13.0000001 valence: 13.0000001 0.0000000 | ||
| 1008 | induced moment: 1.00000 | ||
| 1009 | |||
| 1010 | energy terms | ||
| 1011 | energy eigenvalue sum: -0.134829E+03 | ||
| 1012 | kin: 0.188771E+03 0.188001E+03 coul: -0.465769E+03 exc: -0.185228E+02 | ||
| 1013 | |||
| 1014 | total energy: -0.2423488E+03 | ||
| 1015 | valence energy: -0.2423489E+03 | ||
| 1016 | |||
| 1017 | |||
| 1018 | |||
| 1019 | ********************* iteration: 19 *********************** | ||
| 1020 | |||
| 1021 | l = 0, 4 bound states | ||
| 1022 | l = 1, 2 bound states | ||
| 1023 | l = 0, 4 bound states | ||
| 1024 | l = 1, 2 bound states | ||
| 1025 | |||
| 1026 | |||
| 1027 | bound states | ||
| 1028 | |||
| 1029 | 100 energy: -55.43060 iteration loops: 2 | ||
| 1030 | 200 energy: -3.95843 iteration loops: 3 | ||
| 1031 | 300 energy: -0.29632 iteration loops: 3 | ||
| 1032 | 210 energy: -2.56442 iteration loops: 3 | ||
| 1033 | 310 energy: -0.11188 iteration loops: 4 | ||
| 1034 | 100 energy: -55.42889 iteration loops: 2 | ||
| 1035 | 200 energy: -3.95636 iteration loops: 3 | ||
| 1036 | 300 energy: -0.26814 iteration loops: 3 | ||
| 1037 | 210 energy: -2.56173 iteration loops: 3 | ||
| 1038 | |||
| 1039 | integr charges: total 13.0000001 valence: 13.0000001 0.0000000 | ||
| 1040 | induced moment: 1.00000 | ||
| 1041 | |||
| 1042 | energy terms | ||
| 1043 | energy eigenvalue sum: -0.134829E+03 | ||
| 1044 | kin: 0.188771E+03 0.188001E+03 coul: -0.465769E+03 exc: -0.185228E+02 | ||
| 1045 | |||
| 1046 | total energy: -0.2423489E+03 | ||
| 1047 | valence energy: -0.2423488E+03 | ||
| 1048 | |||
| 1049 | |||
| 1050 | |||
| 1051 | ********************* iteration: 20 *********************** | ||
| 1052 | |||
| 1053 | l = 0, 4 bound states | ||
| 1054 | l = 1, 2 bound states | ||
| 1055 | l = 0, 4 bound states | ||
| 1056 | l = 1, 2 bound states | ||
| 1057 | |||
| 1058 | |||
| 1059 | bound states | ||
| 1060 | |||
| 1061 | 100 energy: -55.43060 iteration loops: 2 | ||
| 1062 | 200 energy: -3.95844 iteration loops: 3 | ||
| 1063 | 300 energy: -0.29632 iteration loops: 3 | ||
| 1064 | 210 energy: -2.56443 iteration loops: 3 | ||
| 1065 | 310 energy: -0.11188 iteration loops: 3 | ||
| 1066 | 100 energy: -55.42889 iteration loops: 2 | ||
| 1067 | 200 energy: -3.95636 iteration loops: 3 | ||
| 1068 | 300 energy: -0.26814 iteration loops: 3 | ||
| 1069 | 210 energy: -2.56174 iteration loops: 3 | ||
| 1070 | |||
| 1071 | integr charges: total 13.0000001 valence: 13.0000001 0.0000000 | ||
| 1072 | induced moment: 1.00000 | ||
| 1073 | |||
| 1074 | energy terms | ||
| 1075 | energy eigenvalue sum: -0.134829E+03 | ||
| 1076 | kin: 0.188771E+03 0.188000E+03 coul: -0.465768E+03 exc: -0.185228E+02 | ||
| 1077 | |||
| 1078 | total energy: -0.2423490E+03 | ||
| 1079 | valence energy: -0.2423489E+03 | ||
| 1080 | |||
| 1081 | |||
| 1082 | |||
| 1083 | ********************* iteration: 21 *********************** | ||
| 1084 | |||
| 1085 | l = 0, 4 bound states | ||
| 1086 | l = 1, 2 bound states | ||
| 1087 | l = 0, 4 bound states | ||
| 1088 | l = 1, 2 bound states | ||
| 1089 | |||
| 1090 | |||
| 1091 | bound states | ||
| 1092 | |||
| 1093 | 100 energy: -55.43061 iteration loops: 7 | ||
| 1094 | 200 energy: -3.95844 iteration loops: 3 | ||
| 1095 | 300 energy: -0.29632 iteration loops: 3 | ||
| 1096 | 210 energy: -2.56443 iteration loops: 3 | ||
| 1097 | 310 energy: -0.11188 iteration loops: 3 | ||
| 1098 | 100 energy: -55.42890 iteration loops: 2 | ||
| 1099 | 200 energy: -3.95637 iteration loops: 3 | ||
| 1100 | 300 energy: -0.26814 iteration loops: 3 | ||
| 1101 | 210 energy: -2.56174 iteration loops: 3 | ||
| 1102 | |||
| 1103 | integr charges: total 13.0000001 valence: 13.0000001 0.0000000 | ||
| 1104 | induced moment: 1.00000 | ||
| 1105 | |||
| 1106 | energy terms | ||
| 1107 | energy eigenvalue sum: -0.134829E+03 | ||
| 1108 | kin: 0.188771E+03 0.188000E+03 coul: -0.465769E+03 exc: -0.185228E+02 | ||
| 1109 | |||
| 1110 | total energy: -0.2423491E+03 | ||
| 1111 | valence energy: -0.2423490E+03 | ||
| 1112 | |||
| 1113 | |||
| 1114 | |||
| 1115 | ********************* iteration: 22 *********************** | ||
| 1116 | |||
| 1117 | l = 0, 4 bound states | ||
| 1118 | l = 1, 2 bound states | ||
| 1119 | l = 0, 4 bound states | ||
| 1120 | l = 1, 2 bound states | ||
| 1121 | |||
| 1122 | |||
| 1123 | bound states | ||
| 1124 | |||
| 1125 | 100 energy: -55.43061 iteration loops: 2 | ||
| 1126 | 200 energy: -3.95844 iteration loops: 3 | ||
| 1127 | 300 energy: -0.29632 iteration loops: 3 | ||
| 1128 | 210 energy: -2.56444 iteration loops: 3 | ||
| 1129 | 310 energy: -0.11188 iteration loops: 3 | ||
| 1130 | 100 energy: -55.42890 iteration loops: 2 | ||
| 1131 | 200 energy: -3.95637 iteration loops: 3 | ||
| 1132 | 300 energy: -0.26815 iteration loops: 3 | ||
| 1133 | 210 energy: -2.56174 iteration loops: 3 | ||
| 1134 | |||
| 1135 | integr charges: total 13.0000001 valence: 13.0000001 0.0000000 | ||
| 1136 | induced moment: 1.00000 | ||
| 1137 | |||
| 1138 | energy terms | ||
| 1139 | energy eigenvalue sum: -0.134829E+03 | ||
| 1140 | kin: 0.188771E+03 0.188000E+03 coul: -0.465769E+03 exc: -0.185228E+02 | ||
| 1141 | |||
| 1142 | total energy: -0.2423491E+03 | ||
| 1143 | valence energy: -0.2423491E+03 | ||
| 1144 | |||
| 1145 | |||
| 1146 | |||
| 1147 | ********************* iteration: 23 *********************** | ||
| 1148 | |||
| 1149 | l = 0, 4 bound states | ||
| 1150 | l = 1, 2 bound states | ||
| 1151 | l = 0, 4 bound states | ||
| 1152 | l = 1, 2 bound states | ||
| 1153 | |||
| 1154 | |||
| 1155 | bound states | ||
| 1156 | |||
| 1157 | 100 energy: -55.43061 iteration loops: 2 | ||
| 1158 | 200 energy: -3.95844 iteration loops: 3 | ||
| 1159 | 300 energy: -0.29632 iteration loops: 3 | ||
| 1160 | 210 energy: -2.56444 iteration loops: 3 | ||
| 1161 | 310 energy: -0.11188 iteration loops: 3 | ||
| 1162 | 100 energy: -55.42890 iteration loops: 2 | ||
| 1163 | 200 energy: -3.95637 iteration loops: 3 | ||
| 1164 | 300 energy: -0.26815 iteration loops: 3 | ||
| 1165 | 210 energy: -2.56174 iteration loops: 3 | ||
| 1166 | |||
| 1167 | integr charges: total 13.0000001 valence: 13.0000001 0.0000000 | ||
| 1168 | induced moment: 1.00000 | ||
| 1169 | |||
| 1170 | energy terms | ||
| 1171 | energy eigenvalue sum: -0.134829E+03 | ||
| 1172 | kin: 0.188771E+03 0.188000E+03 coul: -0.465769E+03 exc: -0.185228E+02 | ||
| 1173 | |||
| 1174 | total energy: -0.2423491E+03 | ||
| 1175 | valence energy: -0.2423491E+03 | ||
diff --git a/src/labat/atomctrl.dat b/src/labat/atomctrl.dat new file mode 100644 index 0000000..6fa2eee --- /dev/null +++ b/src/labat/atomctrl.dat | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | 13 0 | ||
| 2 | 10 40 0.2000 | ||
| 3 | 0.5000 0.00001 0.005 | ||
| 4 | 30 0 1 0 | ||
| 5 | 5 2 2 | ||
| 6 | 100 -84.5000 1 1 0 | ||
| 7 | 200 -16.2450 1 1 0 | ||
| 8 | 210 -5.3356 3 1 0 | ||
| 9 | 300 -0.7812 1 1 0 | ||
| 10 | 310 -0.2312 1 1 0 | ||
| 11 | 100 -84.5000 1 1 0 | ||
| 12 | 200 -16.2450 1 1 0 | ||
| 13 | 210 -5.3356 3 1 0 | ||
| 14 | 300 -0.7812 1 1 0 | ||
| 15 | 310 -0.2312 0 1 0 | ||
diff --git a/src/labat/atomdens.dat b/src/labat/atomdens.dat new file mode 100644 index 0000000..65d8de7 --- /dev/null +++ b/src/labat/atomdens.dat | |||
| @@ -0,0 +1,401 @@ | |||
| 1 | 0.000000000000E+00 0.000000000000E+00 0.000000000000E+00 | ||
| 2 | 0.500000000000E-03 0.436175457142E-02 0.000000000000E+00 | ||
| 3 | 0.100000000000E-02 0.172211515283E-01 0.000000000000E+00 | ||
| 4 | 0.150000000000E-02 0.382459117112E-01 0.000000000000E+00 | ||
| 5 | 0.200000000000E-02 0.671124120455E-01 0.000000000000E+00 | ||
| 6 | 0.250000000000E-02 0.103505537733E+00 0.000000000000E+00 | ||
| 7 | 0.300000000000E-02 0.147118470048E+00 0.000000000000E+00 | ||
| 8 | 0.350000000000E-02 0.197652522367E+00 0.000000000000E+00 | ||
| 9 | 0.400000000000E-02 0.254816957219E+00 0.000000000000E+00 | ||
| 10 | 0.450000000000E-02 0.318328815746E+00 0.000000000000E+00 | ||
| 11 | 0.500000000000E-02 0.387912747299E+00 0.000000000000E+00 | ||
| 12 | 0.550000000000E-02 0.463300842732E+00 0.000000000000E+00 | ||
| 13 | 0.600000000000E-02 0.544232471462E+00 0.000000000000E+00 | ||
| 14 | 0.650000000000E-02 0.630454120441E+00 0.000000000000E+00 | ||
| 15 | 0.700000000000E-02 0.721719237721E+00 0.000000000000E+00 | ||
| 16 | 0.750000000000E-02 0.817788077185E+00 0.000000000000E+00 | ||
| 17 | 0.800000000000E-02 0.918427548340E+00 0.000000000000E+00 | ||
| 18 | 0.850000000000E-02 0.102341106664E+01 0.000000000000E+00 | ||
| 19 | 0.900000000000E-02 0.113251840931E+01 0.000000000000E+00 | ||
| 20 | 0.950000000000E-02 0.124553557108E+01 0.000000000000E+00 | ||
| 21 | 0.100000000000E-01 0.136225462590E+01 0.000000000000E+00 | ||
| 22 | 0.105000000000E-01 0.148247358782E+01 0.000000000000E+00 | ||
| 23 | 0.110000000000E-01 0.160599627846E+01 0.000000000000E+00 | ||
| 24 | 0.115000000000E-01 0.173263219287E+01 0.000000000000E+00 | ||
| 25 | 0.120000000000E-01 0.186219637254E+01 0.000000000000E+00 | ||
| 26 | 0.125000000000E-01 0.199450927612E+01 0.000000000000E+00 | ||
| 27 | 0.130000000000E-01 0.212939665777E+01 0.000000000000E+00 | ||
| 28 | 0.135000000000E-01 0.226668944255E+01 0.000000000000E+00 | ||
| 29 | 0.140000000000E-01 0.240622360993E+01 0.000000000000E+00 | ||
| 30 | 0.145000000000E-01 0.254784007371E+01 0.000000000000E+00 | ||
| 31 | 0.150000000000E-01 0.269138457059E+01 0.000000000000E+00 | ||
| 32 | 0.155000000000E-01 0.283670754435E+01 0.000000000000E+00 | ||
| 33 | 0.160000000000E-01 0.298366403931E+01 0.000000000000E+00 | ||
| 34 | 0.165000000000E-01 0.313211358875E+01 0.000000000000E+00 | ||
| 35 | 0.170000000000E-01 0.328192011295E+01 0.000000000000E+00 | ||
| 36 | 0.175000000000E-01 0.343295181175E+01 0.000000000000E+00 | ||
| 37 | 0.180000000000E-01 0.358508106710E+01 0.000000000000E+00 | ||
| 38 | 0.185000000000E-01 0.373818433947E+01 0.000000000000E+00 | ||
| 39 | 0.190000000000E-01 0.389214207482E+01 0.000000000000E+00 | ||
| 40 | 0.195000000000E-01 0.404683860473E+01 0.000000000000E+00 | ||
| 41 | 0.200000000000E-01 0.420216205770E+01 0.000000000000E+00 | ||
| 42 | 0.210000000000E-01 0.451426066096E+01 0.000000000000E+00 | ||
| 43 | 0.220000000000E-01 0.482761538713E+01 0.000000000000E+00 | ||
| 44 | 0.230000000000E-01 0.514145874839E+01 0.000000000000E+00 | ||
| 45 | 0.240000000000E-01 0.545507568127E+01 0.000000000000E+00 | ||
| 46 | 0.250000000000E-01 0.576780090940E+01 0.000000000000E+00 | ||
| 47 | 0.260000000000E-01 0.607901658509E+01 0.000000000000E+00 | ||
| 48 | 0.270000000000E-01 0.638814985059E+01 0.000000000000E+00 | ||
| 49 | 0.280000000000E-01 0.669467068676E+01 0.000000000000E+00 | ||
| 50 | 0.290000000000E-01 0.699808966255E+01 0.000000000000E+00 | ||
| 51 | 0.300000000000E-01 0.729795597458E+01 0.000000000000E+00 | ||
| 52 | 0.310000000000E-01 0.759385537159E+01 0.000000000000E+00 | ||
| 53 | 0.320000000000E-01 0.788540837030E+01 0.000000000000E+00 | ||
| 54 | 0.330000000000E-01 0.817226834232E+01 0.000000000000E+00 | ||
| 55 | 0.340000000000E-01 0.845411989252E+01 0.000000000000E+00 | ||
| 56 | 0.350000000000E-01 0.873067709677E+01 0.000000000000E+00 | ||
| 57 | 0.360000000000E-01 0.900168202993E+01 0.000000000000E+00 | ||
| 58 | 0.370000000000E-01 0.926690314354E+01 0.000000000000E+00 | ||
| 59 | 0.380000000000E-01 0.952613393144E+01 0.000000000000E+00 | ||
| 60 | 0.390000000000E-01 0.977919143729E+01 0.000000000000E+00 | ||
| 61 | 0.400000000000E-01 0.100259150466E+02 0.000000000000E+00 | ||
| 62 | 0.410000000000E-01 0.102661651144E+02 0.000000000000E+00 | ||
| 63 | 0.420000000000E-01 0.104998218739E+02 0.000000000000E+00 | ||
| 64 | 0.430000000000E-01 0.107267841749E+02 0.000000000000E+00 | ||
| 65 | 0.440000000000E-01 0.109469684991E+02 0.000000000000E+00 | ||
| 66 | 0.450000000000E-01 0.111603078023E+02 0.000000000000E+00 | ||
| 67 | 0.460000000000E-01 0.113667506265E+02 0.000000000000E+00 | ||
| 68 | 0.470000000000E-01 0.115662600379E+02 0.000000000000E+00 | ||
| 69 | 0.480000000000E-01 0.117588128282E+02 0.000000000000E+00 | ||
| 70 | 0.490000000000E-01 0.119443985413E+02 0.000000000000E+00 | ||
| 71 | 0.500000000000E-01 0.121230187558E+02 0.000000000000E+00 | ||
| 72 | 0.510000000000E-01 0.122946861934E+02 0.000000000000E+00 | ||
| 73 | 0.520000000000E-01 0.124594240762E+02 0.000000000000E+00 | ||
| 74 | 0.530000000000E-01 0.126172653109E+02 0.000000000000E+00 | ||
| 75 | 0.540000000000E-01 0.127682519135E+02 0.000000000000E+00 | ||
| 76 | 0.550000000000E-01 0.129124342637E+02 0.000000000000E+00 | ||
| 77 | 0.560000000000E-01 0.130498705915E+02 0.000000000000E+00 | ||
| 78 | 0.570000000000E-01 0.131806262959E+02 0.000000000000E+00 | ||
| 79 | 0.580000000000E-01 0.133047734887E+02 0.000000000000E+00 | ||
| 80 | 0.590000000000E-01 0.134223903716E+02 0.000000000000E+00 | ||
| 81 | 0.600000000000E-01 0.135335608332E+02 0.000000000000E+00 | ||
| 82 | 0.620000000000E-01 0.137369231858E+02 0.000000000000E+00 | ||
| 83 | 0.640000000000E-01 0.139156271828E+02 0.000000000000E+00 | ||
| 84 | 0.660000000000E-01 0.140705011276E+02 0.000000000000E+00 | ||
| 85 | 0.680000000000E-01 0.142024242737E+02 0.000000000000E+00 | ||
| 86 | 0.700000000000E-01 0.143123149024E+02 0.000000000000E+00 | ||
| 87 | 0.720000000000E-01 0.144011220159E+02 0.000000000000E+00 | ||
| 88 | 0.740000000000E-01 0.144698156068E+02 0.000000000000E+00 | ||
| 89 | 0.760000000000E-01 0.145193802486E+02 0.000000000000E+00 | ||
| 90 | 0.780000000000E-01 0.145508072765E+02 0.000000000000E+00 | ||
| 91 | 0.800000000000E-01 0.145650899292E+02 0.000000000000E+00 | ||
| 92 | 0.820000000000E-01 0.145632171303E+02 0.000000000000E+00 | ||
| 93 | 0.840000000000E-01 0.145461698998E+02 0.000000000000E+00 | ||
| 94 | 0.860000000000E-01 0.145149164697E+02 0.000000000000E+00 | ||
| 95 | 0.880000000000E-01 0.144704097293E+02 0.000000000000E+00 | ||
| 96 | 0.900000000000E-01 0.144135834483E+02 0.000000000000E+00 | ||
| 97 | 0.920000000000E-01 0.143453505597E+02 0.000000000000E+00 | ||
| 98 | 0.940000000000E-01 0.142666002980E+02 0.000000000000E+00 | ||
| 99 | 0.960000000000E-01 0.141781971550E+02 0.000000000000E+00 | ||
| 100 | 0.980000000000E-01 0.140809787718E+02 0.000000000000E+00 | ||
| 101 | 0.100000000000E+00 0.139757554301E+02 0.000000000000E+00 | ||
| 102 | 0.102000000000E+00 0.138633085605E+02 0.000000000000E+00 | ||
| 103 | 0.104000000000E+00 0.137443906570E+02 0.000000000000E+00 | ||
| 104 | 0.106000000000E+00 0.136197242856E+02 0.000000000000E+00 | ||
| 105 | 0.108000000000E+00 0.134900023280E+02 0.000000000000E+00 | ||
| 106 | 0.110000000000E+00 0.133558873940E+02 0.000000000000E+00 | ||
| 107 | 0.112000000000E+00 0.132180123169E+02 0.000000000000E+00 | ||
| 108 | 0.114000000000E+00 0.130769798879E+02 0.000000000000E+00 | ||
| 109 | 0.116000000000E+00 0.129333635406E+02 0.000000000000E+00 | ||
| 110 | 0.118000000000E+00 0.127877073393E+02 0.000000000000E+00 | ||
| 111 | 0.120000000000E+00 0.126405268000E+02 0.000000000000E+00 | ||
| 112 | 0.122000000000E+00 0.124923090764E+02 0.000000000000E+00 | ||
| 113 | 0.124000000000E+00 0.123435138760E+02 0.000000000000E+00 | ||
| 114 | 0.126000000000E+00 0.121945737962E+02 0.000000000000E+00 | ||
| 115 | 0.128000000000E+00 0.120458953010E+02 0.000000000000E+00 | ||
| 116 | 0.130000000000E+00 0.118978591688E+02 0.000000000000E+00 | ||
| 117 | 0.132000000000E+00 0.117508215028E+02 0.000000000000E+00 | ||
| 118 | 0.134000000000E+00 0.116051142588E+02 0.000000000000E+00 | ||
| 119 | 0.136000000000E+00 0.114610462665E+02 0.000000000000E+00 | ||
| 120 | 0.138000000000E+00 0.113189038105E+02 0.000000000000E+00 | ||
| 121 | 0.140000000000E+00 0.111789516517E+02 0.000000000000E+00 | ||
| 122 | 0.144000000000E+00 0.109065733402E+02 0.000000000000E+00 | ||
| 123 | 0.148000000000E+00 0.106456277689E+02 0.000000000000E+00 | ||
| 124 | 0.152000000000E+00 0.103975360123E+02 0.000000000000E+00 | ||
| 125 | 0.156000000000E+00 0.101634506611E+02 0.000000000000E+00 | ||
| 126 | 0.160000000000E+00 0.994427827634E+01 0.000000000000E+00 | ||
| 127 | 0.164000000000E+00 0.974070118733E+01 0.000000000000E+00 | ||
| 128 | 0.168000000000E+00 0.955320856633E+01 0.000000000000E+00 | ||
| 129 | 0.172000000000E+00 0.938210818041E+01 0.000000000000E+00 | ||
| 130 | 0.176000000000E+00 0.922754822873E+01 0.000000000000E+00 | ||
| 131 | 0.180000000000E+00 0.908953714697E+01 0.000000000000E+00 | ||
| 132 | 0.184000000000E+00 0.896795938169E+01 0.000000000000E+00 | ||
| 133 | 0.188000000000E+00 0.886259238863E+01 0.000000000000E+00 | ||
| 134 | 0.192000000000E+00 0.877312004143E+01 0.000000000000E+00 | ||
| 135 | 0.196000000000E+00 0.869914699278E+01 0.000000000000E+00 | ||
| 136 | 0.200000000000E+00 0.864020983888E+01 0.000000000000E+00 | ||
| 137 | 0.204000000000E+00 0.859578907906E+01 0.000000000000E+00 | ||
| 138 | 0.208000000000E+00 0.856531822751E+01 0.000000000000E+00 | ||
| 139 | 0.212000000000E+00 0.854819364215E+01 0.000000000000E+00 | ||
| 140 | 0.216000000000E+00 0.854378181368E+01 0.000000000000E+00 | ||
| 141 | 0.220000000000E+00 0.855142734840E+01 0.000000000000E+00 | ||
| 142 | 0.224000000000E+00 0.857045868213E+01 0.000000000000E+00 | ||
| 143 | 0.228000000000E+00 0.860019450042E+01 0.000000000000E+00 | ||
| 144 | 0.232000000000E+00 0.863994812524E+01 0.000000000000E+00 | ||
| 145 | 0.236000000000E+00 0.868903264105E+01 0.000000000000E+00 | ||
| 146 | 0.240000000000E+00 0.874676418673E+01 0.000000000000E+00 | ||
| 147 | 0.244000000000E+00 0.881246602644E+01 0.000000000000E+00 | ||
| 148 | 0.248000000000E+00 0.888547094821E+01 0.000000000000E+00 | ||
| 149 | 0.252000000000E+00 0.896512447677E+01 0.000000000000E+00 | ||
| 150 | 0.256000000000E+00 0.905078653868E+01 0.000000000000E+00 | ||
| 151 | 0.260000000000E+00 0.914183396801E+01 0.000000000000E+00 | ||
| 152 | 0.264000000000E+00 0.923766155756E+01 0.000000000000E+00 | ||
| 153 | 0.268000000000E+00 0.933768397142E+01 0.000000000000E+00 | ||
| 154 | 0.272000000000E+00 0.944133627734E+01 0.000000000000E+00 | ||
| 155 | 0.276000000000E+00 0.954807536204E+01 0.000000000000E+00 | ||
| 156 | 0.280000000000E+00 0.965738003028E+01 0.000000000000E+00 | ||
| 157 | 0.284000000000E+00 0.976875200893E+01 0.000000000000E+00 | ||
| 158 | 0.288000000000E+00 0.988171569009E+01 0.000000000000E+00 | ||
| 159 | 0.292000000000E+00 0.999581879582E+01 0.000000000000E+00 | ||
| 160 | 0.296000000000E+00 0.101106318394E+02 0.000000000000E+00 | ||
| 161 | 0.300000000000E+00 0.102257485032E+02 0.000000000000E+00 | ||
| 162 | 0.308000000000E+00 0.104553787146E+02 0.000000000000E+00 | ||
| 163 | 0.316000000000E+00 0.106819076813E+02 0.000000000000E+00 | ||
| 164 | 0.324000000000E+00 0.109028727525E+02 0.000000000000E+00 | ||
| 165 | 0.332000000000E+00 0.111161395682E+02 0.000000000000E+00 | ||
| 166 | 0.340000000000E+00 0.113198756191E+02 0.000000000000E+00 | ||
| 167 | 0.348000000000E+00 0.115125374106E+02 0.000000000000E+00 | ||
| 168 | 0.356000000000E+00 0.116928409854E+02 0.000000000000E+00 | ||
| 169 | 0.364000000000E+00 0.118597484360E+02 0.000000000000E+00 | ||
| 170 | 0.372000000000E+00 0.120124387908E+02 0.000000000000E+00 | ||
| 171 | 0.380000000000E+00 0.121502951670E+02 0.000000000000E+00 | ||
| 172 | 0.388000000000E+00 0.122728772544E+02 0.000000000000E+00 | ||
| 173 | 0.396000000000E+00 0.123799099143E+02 0.000000000000E+00 | ||
| 174 | 0.404000000000E+00 0.124712579462E+02 0.000000000000E+00 | ||
| 175 | 0.412000000000E+00 0.125469165365E+02 0.000000000000E+00 | ||
| 176 | 0.420000000000E+00 0.126069886327E+02 0.000000000000E+00 | ||
| 177 | 0.428000000000E+00 0.126516773497E+02 0.000000000000E+00 | ||
| 178 | 0.436000000000E+00 0.126812660217E+02 0.000000000000E+00 | ||
| 179 | 0.444000000000E+00 0.126961124851E+02 0.000000000000E+00 | ||
| 180 | 0.452000000000E+00 0.126966317145E+02 0.000000000000E+00 | ||
| 181 | 0.460000000000E+00 0.126832917988E+02 0.000000000000E+00 | ||
| 182 | 0.468000000000E+00 0.126565989792E+02 0.000000000000E+00 | ||
| 183 | 0.476000000000E+00 0.126170950873E+02 0.000000000000E+00 | ||
| 184 | 0.484000000000E+00 0.125653447612E+02 0.000000000000E+00 | ||
| 185 | 0.492000000000E+00 0.125019341037E+02 0.000000000000E+00 | ||
| 186 | 0.500000000000E+00 0.124274598383E+02 0.000000000000E+00 | ||
| 187 | 0.508000000000E+00 0.123425289558E+02 0.000000000000E+00 | ||
| 188 | 0.516000000000E+00 0.122477495743E+02 0.000000000000E+00 | ||
| 189 | 0.524000000000E+00 0.121437313636E+02 0.000000000000E+00 | ||
| 190 | 0.532000000000E+00 0.120310778864E+02 0.000000000000E+00 | ||
| 191 | 0.540000000000E+00 0.119103876158E+02 0.000000000000E+00 | ||
| 192 | 0.548000000000E+00 0.117822475537E+02 0.000000000000E+00 | ||
| 193 | 0.556000000000E+00 0.116472346836E+02 0.000000000000E+00 | ||
| 194 | 0.564000000000E+00 0.115059106819E+02 0.000000000000E+00 | ||
| 195 | 0.572000000000E+00 0.113588236758E+02 0.000000000000E+00 | ||
| 196 | 0.580000000000E+00 0.112065038847E+02 0.000000000000E+00 | ||
| 197 | 0.588000000000E+00 0.110494655756E+02 0.000000000000E+00 | ||
| 198 | 0.596000000000E+00 0.108882034917E+02 0.000000000000E+00 | ||
| 199 | 0.604000000000E+00 0.107231949218E+02 0.000000000000E+00 | ||
| 200 | 0.612000000000E+00 0.105548967853E+02 0.000000000000E+00 | ||
| 201 | 0.620000000000E+00 0.103837477718E+02 0.000000000000E+00 | ||
| 202 | 0.636000000000E+00 0.100345496045E+02 0.000000000000E+00 | ||
| 203 | 0.652000000000E+00 0.967872344891E+01 0.000000000000E+00 | ||
| 204 | 0.668000000000E+00 0.931907101425E+01 0.000000000000E+00 | ||
| 205 | 0.684000000000E+00 0.895810820401E+01 0.000000000000E+00 | ||
| 206 | 0.700000000000E+00 0.859805485680E+01 0.000000000000E+00 | ||
| 207 | 0.716000000000E+00 0.824087119330E+01 0.000000000000E+00 | ||
| 208 | 0.732000000000E+00 0.788825582818E+01 0.000000000000E+00 | ||
| 209 | 0.748000000000E+00 0.754167995457E+01 0.000000000000E+00 | ||
| 210 | 0.764000000000E+00 0.720239080394E+01 0.000000000000E+00 | ||
| 211 | 0.780000000000E+00 0.687144226797E+01 0.000000000000E+00 | ||
| 212 | 0.796000000000E+00 0.654970128574E+01 0.000000000000E+00 | ||
| 213 | 0.812000000000E+00 0.623787449324E+01 0.000000000000E+00 | ||
| 214 | 0.828000000000E+00 0.593651588253E+01 0.000000000000E+00 | ||
| 215 | 0.844000000000E+00 0.564604949937E+01 0.000000000000E+00 | ||
| 216 | 0.860000000000E+00 0.536677735057E+01 0.000000000000E+00 | ||
| 217 | 0.876000000000E+00 0.509889842178E+01 0.000000000000E+00 | ||
| 218 | 0.892000000000E+00 0.484251621275E+01 0.000000000000E+00 | ||
| 219 | 0.908000000000E+00 0.459765446156E+01 0.000000000000E+00 | ||
| 220 | 0.924000000000E+00 0.436426397342E+01 0.000000000000E+00 | ||
| 221 | 0.940000000000E+00 0.414223547405E+01 0.000000000000E+00 | ||
| 222 | 0.956000000000E+00 0.393140557927E+01 0.000000000000E+00 | ||
| 223 | 0.972000000000E+00 0.373156719441E+01 0.000000000000E+00 | ||
| 224 | 0.988000000000E+00 0.354247458632E+01 0.000000000000E+00 | ||
| 225 | 0.100400000000E+01 0.336385171559E+01 0.000000000000E+00 | ||
| 226 | 0.102000000000E+01 0.319539644101E+01 0.000000000000E+00 | ||
| 227 | 0.103600000000E+01 0.303678712977E+01 0.000000000000E+00 | ||
| 228 | 0.105200000000E+01 0.288768606201E+01 0.000000000000E+00 | ||
| 229 | 0.106800000000E+01 0.274774461904E+01 0.000000000000E+00 | ||
| 230 | 0.108400000000E+01 0.261660597359E+01 0.000000000000E+00 | ||
| 231 | 0.110000000000E+01 0.249390911171E+01 0.000000000000E+00 | ||
| 232 | 0.111600000000E+01 0.237929089981E+01 0.000000000000E+00 | ||
| 233 | 0.113200000000E+01 0.227238915565E+01 0.000000000000E+00 | ||
| 234 | 0.114800000000E+01 0.217284418122E+01 0.000000000000E+00 | ||
| 235 | 0.116400000000E+01 0.208030106234E+01 0.000000000000E+00 | ||
| 236 | 0.118000000000E+01 0.199441075044E+01 0.000000000000E+00 | ||
| 237 | 0.119600000000E+01 0.191483173901E+01 0.000000000000E+00 | ||
| 238 | 0.121200000000E+01 0.184123076936E+01 0.000000000000E+00 | ||
| 239 | 0.122800000000E+01 0.177328400445E+01 0.000000000000E+00 | ||
| 240 | 0.124400000000E+01 0.171067742461E+01 0.000000000000E+00 | ||
| 241 | 0.126000000000E+01 0.165310759694E+01 0.000000000000E+00 | ||
| 242 | 0.129200000000E+01 0.155191724116E+01 0.000000000000E+00 | ||
| 243 | 0.132400000000E+01 0.146750525512E+01 0.000000000000E+00 | ||
| 244 | 0.135600000000E+01 0.139784381401E+01 0.000000000000E+00 | ||
| 245 | 0.138800000000E+01 0.134107966092E+01 0.000000000000E+00 | ||
| 246 | 0.142000000000E+01 0.129552654599E+01 0.000000000000E+00 | ||
| 247 | 0.145200000000E+01 0.125965628032E+01 0.000000000000E+00 | ||
| 248 | 0.148400000000E+01 0.123208593666E+01 0.000000000000E+00 | ||
| 249 | 0.151600000000E+01 0.121156835897E+01 0.000000000000E+00 | ||
| 250 | 0.154800000000E+01 0.119698112083E+01 0.000000000000E+00 | ||
| 251 | 0.158000000000E+01 0.118731944043E+01 0.000000000000E+00 | ||
| 252 | 0.161200000000E+01 0.118168771367E+01 0.000000000000E+00 | ||
| 253 | 0.164400000000E+01 0.117929367566E+01 0.000000000000E+00 | ||
| 254 | 0.167600000000E+01 0.117944032275E+01 0.000000000000E+00 | ||
| 255 | 0.170800000000E+01 0.118151949160E+01 0.000000000000E+00 | ||
| 256 | 0.174000000000E+01 0.118500323242E+01 0.000000000000E+00 | ||
| 257 | 0.177200000000E+01 0.118943698637E+01 0.000000000000E+00 | ||
| 258 | 0.180400000000E+01 0.119443119513E+01 0.000000000000E+00 | ||
| 259 | 0.183600000000E+01 0.119965506433E+01 0.000000000000E+00 | ||
| 260 | 0.186800000000E+01 0.120482918576E+01 0.000000000000E+00 | ||
| 261 | 0.190000000000E+01 0.120972037857E+01 0.000000000000E+00 | ||
| 262 | 0.193200000000E+01 0.121413551639E+01 0.000000000000E+00 | ||
| 263 | 0.196400000000E+01 0.121791745169E+01 0.000000000000E+00 | ||
| 264 | 0.199600000000E+01 0.122093993025E+01 0.000000000000E+00 | ||
| 265 | 0.202800000000E+01 0.122310443309E+01 0.000000000000E+00 | ||
| 266 | 0.206000000000E+01 0.122433599445E+01 0.000000000000E+00 | ||
| 267 | 0.209200000000E+01 0.122458078315E+01 0.000000000000E+00 | ||
| 268 | 0.212400000000E+01 0.122380265919E+01 0.000000000000E+00 | ||
| 269 | 0.215600000000E+01 0.122198134504E+01 0.000000000000E+00 | ||
| 270 | 0.218800000000E+01 0.121910958787E+01 0.000000000000E+00 | ||
| 271 | 0.222000000000E+01 0.121519180101E+01 0.000000000000E+00 | ||
| 272 | 0.225200000000E+01 0.121024172586E+01 0.000000000000E+00 | ||
| 273 | 0.228400000000E+01 0.120428144770E+01 0.000000000000E+00 | ||
| 274 | 0.231600000000E+01 0.119733947184E+01 0.000000000000E+00 | ||
| 275 | 0.234800000000E+01 0.118945003633E+01 0.000000000000E+00 | ||
| 276 | 0.238000000000E+01 0.118065153236E+01 0.000000000000E+00 | ||
| 277 | 0.241200000000E+01 0.117098605097E+01 0.000000000000E+00 | ||
| 278 | 0.244400000000E+01 0.116049808940E+01 0.000000000000E+00 | ||
| 279 | 0.247600000000E+01 0.114923428069E+01 0.000000000000E+00 | ||
| 280 | 0.250800000000E+01 0.113724233640E+01 0.000000000000E+00 | ||
| 281 | 0.254000000000E+01 0.112457091994E+01 0.000000000000E+00 | ||
| 282 | 0.260400000000E+01 0.109738470182E+01 0.000000000000E+00 | ||
| 283 | 0.266800000000E+01 0.106806439154E+01 0.000000000000E+00 | ||
| 284 | 0.273200000000E+01 0.103698439917E+01 0.000000000000E+00 | ||
| 285 | 0.279600000000E+01 0.100450307329E+01 0.000000000000E+00 | ||
| 286 | 0.286000000000E+01 0.970953381730E+00 0.000000000000E+00 | ||
| 287 | 0.292400000000E+01 0.936644159167E+00 0.000000000000E+00 | ||
| 288 | 0.298800000000E+01 0.901855019638E+00 0.000000000000E+00 | ||
| 289 | 0.305200000000E+01 0.866839215964E+00 0.000000000000E+00 | ||
| 290 | 0.311600000000E+01 0.831821125455E+00 0.000000000000E+00 | ||
| 291 | 0.318000000000E+01 0.796999736132E+00 0.000000000000E+00 | ||
| 292 | 0.324400000000E+01 0.762547673700E+00 0.000000000000E+00 | ||
| 293 | 0.330800000000E+01 0.728614749752E+00 0.000000000000E+00 | ||
| 294 | 0.337200000000E+01 0.695327865933E+00 0.000000000000E+00 | ||
| 295 | 0.343600000000E+01 0.662794304433E+00 0.000000000000E+00 | ||
| 296 | 0.350000000000E+01 0.631102113379E+00 0.000000000000E+00 | ||
| 297 | 0.356400000000E+01 0.600323008499E+00 0.000000000000E+00 | ||
| 298 | 0.362800000000E+01 0.570512981599E+00 0.000000000000E+00 | ||
| 299 | 0.369200000000E+01 0.541714781818E+00 0.000000000000E+00 | ||
| 300 | 0.375600000000E+01 0.513958604532E+00 0.000000000000E+00 | ||
| 301 | 0.382000000000E+01 0.487264171106E+00 0.000000000000E+00 | ||
| 302 | 0.388400000000E+01 0.461641419373E+00 0.000000000000E+00 | ||
| 303 | 0.394800000000E+01 0.437092224312E+00 0.000000000000E+00 | ||
| 304 | 0.401200000000E+01 0.413611047722E+00 0.000000000000E+00 | ||
| 305 | 0.407600000000E+01 0.391186347874E+00 0.000000000000E+00 | ||
| 306 | 0.414000000000E+01 0.369801165599E+00 0.000000000000E+00 | ||
| 307 | 0.420400000000E+01 0.349434267039E+00 0.000000000000E+00 | ||
| 308 | 0.426800000000E+01 0.330060656641E+00 0.000000000000E+00 | ||
| 309 | 0.433200000000E+01 0.311652491038E+00 0.000000000000E+00 | ||
| 310 | 0.439600000000E+01 0.294179509305E+00 0.000000000000E+00 | ||
| 311 | 0.446000000000E+01 0.277609755909E+00 0.000000000000E+00 | ||
| 312 | 0.452400000000E+01 0.261909928620E+00 0.000000000000E+00 | ||
| 313 | 0.458800000000E+01 0.247045937393E+00 0.000000000000E+00 | ||
| 314 | 0.465200000000E+01 0.232983174510E+00 0.000000000000E+00 | ||
| 315 | 0.471600000000E+01 0.219686935923E+00 0.000000000000E+00 | ||
| 316 | 0.478000000000E+01 0.207122620601E+00 0.000000000000E+00 | ||
| 317 | 0.484400000000E+01 0.195256038533E+00 0.000000000000E+00 | ||
| 318 | 0.490800000000E+01 0.184053548124E+00 0.000000000000E+00 | ||
| 319 | 0.497200000000E+01 0.173482273608E+00 0.000000000000E+00 | ||
| 320 | 0.503600000000E+01 0.163510189161E+00 0.000000000000E+00 | ||
| 321 | 0.510000000000E+01 0.154106267371E+00 0.000000000000E+00 | ||
| 322 | 0.522800000000E+01 0.136884591654E+00 0.000000000000E+00 | ||
| 323 | 0.535600000000E+01 0.121591321367E+00 0.000000000000E+00 | ||
| 324 | 0.548400000000E+01 0.108017651918E+00 0.000000000000E+00 | ||
| 325 | 0.561200000000E+01 0.959753749055E-01 0.000000000000E+00 | ||
| 326 | 0.574000000000E+01 0.852944707494E-01 0.000000000000E+00 | ||
| 327 | 0.586800000000E+01 0.758227542149E-01 0.000000000000E+00 | ||
| 328 | 0.599600000000E+01 0.674244363565E-01 0.000000000000E+00 | ||
| 329 | 0.612400000000E+01 0.599788218697E-01 0.000000000000E+00 | ||
| 330 | 0.625200000000E+01 0.533786398769E-01 0.000000000000E+00 | ||
| 331 | 0.638000000000E+01 0.475284971489E-01 0.000000000000E+00 | ||
| 332 | 0.650800000000E+01 0.423433479881E-01 0.000000000000E+00 | ||
| 333 | 0.663600000000E+01 0.377472637261E-01 0.000000000000E+00 | ||
| 334 | 0.676400000000E+01 0.336723948963E-01 0.000000000000E+00 | ||
| 335 | 0.689200000000E+01 0.300581838419E-01 0.000000000000E+00 | ||
| 336 | 0.702000000000E+01 0.268506826101E-01 0.000000000000E+00 | ||
| 337 | 0.714800000000E+01 0.240019738064E-01 0.000000000000E+00 | ||
| 338 | 0.727600000000E+01 0.214696134695E-01 0.000000000000E+00 | ||
| 339 | 0.740400000000E+01 0.192161145818E-01 0.000000000000E+00 | ||
| 340 | 0.753200000000E+01 0.172084431025E-01 0.000000000000E+00 | ||
| 341 | 0.766000000000E+01 0.154175504525E-01 0.000000000000E+00 | ||
| 342 | 0.778800000000E+01 0.138179319918E-01 0.000000000000E+00 | ||
| 343 | 0.791600000000E+01 0.123872273736E-01 0.000000000000E+00 | ||
| 344 | 0.804400000000E+01 0.111058555610E-01 0.000000000000E+00 | ||
| 345 | 0.817200000000E+01 0.995669175697E-02 0.000000000000E+00 | ||
| 346 | 0.830000000000E+01 0.892477900357E-02 0.000000000000E+00 | ||
| 347 | 0.842800000000E+01 0.799707541516E-02 0.000000000000E+00 | ||
| 348 | 0.855600000000E+01 0.716222883183E-02 0.000000000000E+00 | ||
| 349 | 0.868400000000E+01 0.641037533463E-02 0.000000000000E+00 | ||
| 350 | 0.881200000000E+01 0.573295290543E-02 0.000000000000E+00 | ||
| 351 | 0.894000000000E+01 0.512252596993E-02 0.000000000000E+00 | ||
| 352 | 0.906800000000E+01 0.457261653329E-02 0.000000000000E+00 | ||
| 353 | 0.919600000000E+01 0.407754389913E-02 0.000000000000E+00 | ||
| 354 | 0.932400000000E+01 0.363227714481E-02 0.000000000000E+00 | ||
| 355 | 0.945200000000E+01 0.323230745826E-02 0.000000000000E+00 | ||
| 356 | 0.958000000000E+01 0.287354503590E-02 0.000000000000E+00 | ||
| 357 | 0.970800000000E+01 0.255224239652E-02 0.000000000000E+00 | ||
| 358 | 0.983600000000E+01 0.226494165840E-02 0.000000000000E+00 | ||
| 359 | 0.996400000000E+01 0.200844067852E-02 0.000000000000E+00 | ||
| 360 | 0.100920000000E+02 0.177977305756E-02 0.000000000000E+00 | ||
| 361 | 0.102200000000E+02 0.157619451435E-02 0.000000000000E+00 | ||
| 362 | 0.104760000000E+02 0.123436917698E-02 0.000000000000E+00 | ||
| 363 | 0.107320000000E+02 0.965186451268E-03 0.000000000000E+00 | ||
| 364 | 0.109880000000E+02 0.753908554242E-03 0.000000000000E+00 | ||
| 365 | 0.112440000000E+02 0.588465538491E-03 0.000000000000E+00 | ||
| 366 | 0.115000000000E+02 0.459129900109E-03 0.000000000000E+00 | ||
| 367 | 0.117560000000E+02 0.358136490652E-03 0.000000000000E+00 | ||
| 368 | 0.120120000000E+02 0.279333173696E-03 0.000000000000E+00 | ||
| 369 | 0.122680000000E+02 0.217872128786E-03 0.000000000000E+00 | ||
| 370 | 0.125240000000E+02 0.169948253475E-03 0.000000000000E+00 | ||
| 371 | 0.127800000000E+02 0.132583106199E-03 0.000000000000E+00 | ||
| 372 | 0.130360000000E+02 0.103449732933E-03 0.000000000000E+00 | ||
| 373 | 0.132920000000E+02 0.807324659074E-04 0.000000000000E+00 | ||
| 374 | 0.135480000000E+02 0.630157231199E-04 0.000000000000E+00 | ||
| 375 | 0.138040000000E+02 0.491963718127E-04 0.000000000000E+00 | ||
| 376 | 0.140600000000E+02 0.384149672470E-04 0.000000000000E+00 | ||
| 377 | 0.143160000000E+02 0.300019668906E-04 0.000000000000E+00 | ||
| 378 | 0.145720000000E+02 0.234357449754E-04 0.000000000000E+00 | ||
| 379 | 0.148280000000E+02 0.183098631066E-04 0.000000000000E+00 | ||
| 380 | 0.150840000000E+02 0.143075777290E-04 0.000000000000E+00 | ||
| 381 | 0.153400000000E+02 0.111819939178E-04 0.000000000000E+00 | ||
| 382 | 0.155960000000E+02 0.874061827897E-05 0.000000000000E+00 | ||
| 383 | 0.158520000000E+02 0.683333638838E-05 0.000000000000E+00 | ||
| 384 | 0.161080000000E+02 0.534305478230E-05 0.000000000000E+00 | ||
| 385 | 0.163640000000E+02 0.417841576076E-05 0.000000000000E+00 | ||
| 386 | 0.166200000000E+02 0.326812462090E-05 0.000000000000E+00 | ||
| 387 | 0.168760000000E+02 0.255653132983E-05 0.000000000000E+00 | ||
| 388 | 0.171320000000E+02 0.200018830515E-05 0.000000000000E+00 | ||
| 389 | 0.173880000000E+02 0.156516791554E-05 0.000000000000E+00 | ||
| 390 | 0.176440000000E+02 0.122497144447E-05 0.000000000000E+00 | ||
| 391 | 0.179000000000E+02 0.958898661647E-06 0.000000000000E+00 | ||
| 392 | 0.181560000000E+02 0.750776203914E-06 0.000000000000E+00 | ||
| 393 | 0.184120000000E+02 0.587965550136E-06 0.000000000000E+00 | ||
| 394 | 0.186680000000E+02 0.460588927040E-06 0.000000000000E+00 | ||
| 395 | 0.189240000000E+02 0.360925130814E-06 0.000000000000E+00 | ||
| 396 | 0.191800000000E+02 0.282937864443E-06 0.000000000000E+00 | ||
| 397 | 0.194360000000E+02 0.221907449552E-06 0.000000000000E+00 | ||
| 398 | 0.196920000000E+02 0.174143200666E-06 0.000000000000E+00 | ||
| 399 | 0.199480000000E+02 0.136758752860E-06 0.000000000000E+00 | ||
| 400 | 0.202040000000E+02 0.107496536977E-06 0.000000000000E+00 | ||
| 401 | 0.204600000000E+02 0.845906225812E-07 0.000000000000E+00 | ||
diff --git a/src/labat/atomlab.cc b/src/labat/atomlab.cc new file mode 100644 index 0000000..504a0d9 --- /dev/null +++ b/src/labat/atomlab.cc | |||
| @@ -0,0 +1,187 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <mt/config.h> | ||
| 21 | #include <fstream> | ||
| 22 | #include <iostream> | ||
| 23 | #include <unistd.h> | ||
| 24 | #include <fcntl.h> | ||
| 25 | #include <signal.h> | ||
| 26 | #include <sys/stat.h> | ||
| 27 | using namespace std; | ||
| 28 | |||
| 29 | const mstring LABAT=htchome()+sref("/bin/labat"); | ||
| 30 | |||
| 31 | const int SLOTS=8; | ||
| 32 | const int RUNLIMIT=600; | ||
| 33 | static int SLOT; | ||
| 34 | |||
| 35 | extern "C" { | ||
| 36 | static void FreeSlot(int dummy) | ||
| 37 | { | ||
| 38 | static int ok=0; | ||
| 39 | static char buf[256]; | ||
| 40 | if(!ok) { | ||
| 41 | ok=1; | ||
| 42 | sprintf(buf,"rm -rf /tmp/labat%d/",SLOT); | ||
| 43 | system(buf); | ||
| 44 | } | ||
| 45 | } | ||
| 46 | } | ||
| 47 | |||
| 48 | static int AllocSlot() | ||
| 49 | { | ||
| 50 | struct stat FS; | ||
| 51 | char buf[256]; | ||
| 52 | for(SLOT=0;SLOT<SLOTS;SLOT++) { | ||
| 53 | sprintf(buf,"/tmp/labat%d/",SLOT); | ||
| 54 | if(stat(buf,&FS)!=0) { | ||
| 55 | signal(SIGTERM,FreeSlot); | ||
| 56 | signal(SIGINT,FreeSlot); | ||
| 57 | signal(SIGPIPE,FreeSlot); | ||
| 58 | sprintf(buf,"mkdir /tmp/labat%d/",SLOT); | ||
| 59 | system(buf); | ||
| 60 | return 1; | ||
| 61 | } | ||
| 62 | } | ||
| 63 | return 0; | ||
| 64 | } | ||
| 65 | |||
| 66 | /////////////////////////////////////////////////////////////////////////////// | ||
| 67 | |||
| 68 | struct CTLBasis { | ||
| 69 | int n,l,occ; | ||
| 70 | float e; | ||
| 71 | void SetEnergy(int Z) { | ||
| 72 | e=-0.5*float(Z*Z)/float(0.1+n*n*n+l*(l+1)*(l+2)); | ||
| 73 | } | ||
| 74 | }; | ||
| 75 | |||
| 76 | struct CTLData { | ||
| 77 | int atomz,its,basisn,exc; | ||
| 78 | float mix; | ||
| 79 | CTLBasis left[24],right[24]; | ||
| 80 | }; | ||
| 81 | |||
| 82 | static ostream& operator<<(ostream& out,const CTLData& ctl) | ||
| 83 | { | ||
| 84 | out<<ctl.atomz<<" "<<0<<"\n"; | ||
| 85 | out<<10<<" "<<40<<" "<<0.2<<"\n"; // Hermann-Skillman mesh | ||
| 86 | out<<ctl.mix<<" 0.00001 0.005\n"; // mix,error,? | ||
| 87 | out<<ctl.its<<" "<<0<<" "<<1<<" "<<0<<"\n"; // its ? step ? | ||
| 88 | out<<ctl.basisn<<" "<<2<<" "<<ctl.exc<<"\n"; // exc (C-A, B-H, GGA) | ||
| 89 | for(int i=0;i<ctl.basisn;i++) { | ||
| 90 | out<<ctl.left[i].n<<ctl.left[i].l<<0<<" "<<ctl.left[i].e | ||
| 91 | <<" "<<ctl.left[i].occ<<" "<<1<<" "<<0<<"\n"; | ||
| 92 | } | ||
| 93 | for(int i=0;i<ctl.basisn;i++) { | ||
| 94 | out<<ctl.right[i].n<<ctl.right[i].l<<0<<" "<<ctl.right[i].e | ||
| 95 | <<" "<<ctl.right[i].occ<<" "<<1<<" "<<0<<"\n"; | ||
| 96 | } | ||
| 97 | return out; | ||
| 98 | } | ||
| 99 | |||
| 100 | static void SetupLabat(mstring& resfile,int argc,char* argv[]) | ||
| 101 | { | ||
| 102 | CTLData ctl; | ||
| 103 | ctl.atomz=atoi(argv[1]); | ||
| 104 | ctl.its=atoi(argv[2]); | ||
| 105 | ctl.exc=atoi(argv[3]); | ||
| 106 | ctl.mix=atof(argv[4]); | ||
| 107 | resfile=argv[5]; | ||
| 108 | ctl.basisn=0; | ||
| 109 | int nl,nr,elecs=0; | ||
| 110 | for(int i=0;i<6;i++) { | ||
| 111 | for(int k=0;k<3;k++) { | ||
| 112 | nl=int(argv[6+i][2*k]-'0'); | ||
| 113 | nr=int(argv[6+i][2*k+1]-'0'); | ||
| 114 | if(nl>0||nr>0) { | ||
| 115 | ctl.left[ctl.basisn].n=i+1; | ||
| 116 | ctl.left[ctl.basisn].l=k; | ||
| 117 | ctl.left[ctl.basisn].occ=nl; | ||
| 118 | ctl.left[ctl.basisn].SetEnergy(ctl.atomz); | ||
| 119 | ctl.right[ctl.basisn].n=i+1; | ||
| 120 | ctl.right[ctl.basisn].l=k; | ||
| 121 | ctl.right[ctl.basisn].occ=nr; | ||
| 122 | ctl.right[ctl.basisn].SetEnergy(ctl.atomz); | ||
| 123 | ctl.basisn++; | ||
| 124 | } | ||
| 125 | elecs+=nl+nr; | ||
| 126 | } | ||
| 127 | } | ||
| 128 | ctl.atomz+=elecs; | ||
| 129 | char buf[1024]; | ||
| 130 | sprintf(buf,"/tmp/labat%d/atomctrl.dat",SLOT); | ||
| 131 | ofstream os(buf); | ||
| 132 | os<<ctl; | ||
| 133 | cout<<"Atomnumber: "<<ctl.atomz<<" Electrons: "<<elecs<<"<BR>\n"; | ||
| 134 | cout<<"NOTE: if the program does >="<<ctl.its | ||
| 135 | <<" iterations, you must increase the number\n"; | ||
| 136 | cout<<"of iterations and re-run, to assure convergence.<BR>\n"; | ||
| 137 | cout<<"Also note that there is currently a maximum time limit of "<< | ||
| 138 | RUNLIMIT<<" seconds.<BR>\n"; | ||
| 139 | } | ||
| 140 | |||
| 141 | static void RunLabat() | ||
| 142 | { | ||
| 143 | char buf[1024]; | ||
| 144 | sprintf(buf,"cd /tmp/labat%d/\nulimit -t %d\n%s",SLOT,RUNLIMIT,LABAT.c_str()); | ||
| 145 | system(buf); | ||
| 146 | } | ||
| 147 | |||
| 148 | static void SaveLabat(const mstring& resfile) | ||
| 149 | { | ||
| 150 | const char* docroot=getenv("DOCROOT"); | ||
| 151 | if(docroot&&resfile.size()) { | ||
| 152 | char buf[1024]; | ||
| 153 | sprintf(buf,"cp -rfp /tmp/labat%d/atomdens.dat %s/%s", | ||
| 154 | SLOT,docroot,resfile.c_str()); | ||
| 155 | system(buf); | ||
| 156 | cout<<"<p>\n" | ||
| 157 | <<"Here you may download the density profile.\n" | ||
| 158 | <<"Example: Save the file as 'dens.dat', and load it from\n" | ||
| 159 | <<"matlab with 'load dens.dat'.\n" | ||
| 160 | <<"Then you can look at it with 'plot(dens(:,1),dens(:,2))'.\n" | ||
| 161 | <<"<p>\n"<<"<a href="<<resfile.c_str()<<">Get atomic density</a>\n"; | ||
| 162 | } | ||
| 163 | } | ||
| 164 | |||
| 165 | main(int argc,char* argv[]) | ||
| 166 | { | ||
| 167 | if(argc<12) { | ||
| 168 | cerr<<"Usage: "<<argv[0]<<" <ion> <its> <exc> <mix> <resfile> <ssppdd>x6\n"; | ||
| 169 | exit(-1); | ||
| 170 | } | ||
| 171 | mstring resfile; | ||
| 172 | char buf[1024]; | ||
| 173 | if(AllocSlot()) { | ||
| 174 | cout<<"<h4>Running</h4>\n" | ||
| 175 | <<"<PRE>\n"; | ||
| 176 | cout.flush(); | ||
| 177 | SetupLabat(resfile,argc,argv); | ||
| 178 | RunLabat(); | ||
| 179 | cout<<"</PRE>\n" | ||
| 180 | <<"<h4>Done</h4>\n"; | ||
| 181 | SaveLabat(resfile); | ||
| 182 | FreeSlot(0); | ||
| 183 | } | ||
| 184 | else { | ||
| 185 | cout<<"No vacant slots at the moment. Try again later.\n"; | ||
| 186 | } | ||
| 187 | } | ||
diff --git a/src/labat/deriv.f b/src/labat/deriv.f new file mode 100644 index 0000000..b440070 --- /dev/null +++ b/src/labat/deriv.f | |||
| @@ -0,0 +1,65 @@ | |||
| 1 | function deriv(r,x,x2,spin,i,imin,imax) | ||
| 2 | c deriv calculates the derivative of x with respect to r, at | ||
| 3 | c position r(i). | ||
| 4 | c input r : radial coordinate (array) | ||
| 5 | c input x : function to be derivated (array) | ||
| 6 | c input x2 : second derivative of x (array) | ||
| 7 | c input spin : -1 if spin-down, 1 if spin-up, 0 otherwise | ||
| 8 | c input i : counter, i.e. current position = r(i) | ||
| 9 | c input imin : min value of i | ||
| 10 | c input imax : max value of i | ||
| 11 | implicit logical (a-z) | ||
| 12 | double precision deriv,r,x,x2 | ||
| 13 | double precision h,d,dforw,dback,dforup,dfordn,dbacup,dbacdn | ||
| 14 | integer spin,i,imin,imax | ||
| 15 | dimension r(561),x(2,561),x2(2,561) | ||
| 16 | if (i.eq.imin) then | ||
| 17 | h = (r(i+1)-r(i))/2.d0 | ||
| 18 | if (spin.eq.-1) then | ||
| 19 | d = x(2,i) | ||
| 20 | call splint(r,x,x2,-1,imin,imax,r(i)+h,dforw) | ||
| 21 | elseif (spin.eq.1) then | ||
| 22 | d = x(1,i) | ||
| 23 | call splint(r,x,x2,1,imin,imax,r(i)+h,dforw) | ||
| 24 | else | ||
| 25 | d = (x(1,i) + x(2,i)) | ||
| 26 | call splint(r,x,x2,1,imin,imax,r(i)+h,dforup) | ||
| 27 | call splint(r,x,x2,-1,imin,imax,r(i)+h,dfordn) | ||
| 28 | dforw = dforup + dfordn | ||
| 29 | endif | ||
| 30 | deriv = (dforw-d)/h | ||
| 31 | elseif (i.eq.imax) then | ||
| 32 | h = (r(i)-r(i-1))/2.d0 | ||
| 33 | if (spin.eq.-1) then | ||
| 34 | call splint(r,x,x2,-1,imin,imax,r(i)-h,dback) | ||
| 35 | d = x(2,i) | ||
| 36 | elseif (spin.eq.1) then | ||
| 37 | call splint(r,x,x2,1,imin,imax,r(i)-h,dback) | ||
| 38 | d = x(1,i) | ||
| 39 | else | ||
| 40 | call splint(r,x,x2,1,imin,imax,r(i)-h,dbacup) | ||
| 41 | call splint(r,x,x2,-1,imin,imax,r(i)-h,dbacdn) | ||
| 42 | dback = dbacup + dbacdn | ||
| 43 | d = x(1,i) + x(2,i) | ||
| 44 | endif | ||
| 45 | deriv = (d-dback)/h | ||
| 46 | else | ||
| 47 | h = (r(i)-r(i-1))/2.d0 | ||
| 48 | if (spin.eq.-1) then | ||
| 49 | call splint(r,x,x2,-1,imin,imax,r(i)+h,dforw) | ||
| 50 | call splint(r,x,x2,-1,imin,imax,r(i)-h,dback) | ||
| 51 | elseif (spin.eq.1) then | ||
| 52 | call splint(r,x,x2,1,imin,imax,r(i)+h,dforw) | ||
| 53 | call splint(r,x,x2,1,imin,imax,r(i)-h,dback) | ||
| 54 | else | ||
| 55 | call splint(r,x,x2,-1,imin,imax,r(i)+h,dfordn) | ||
| 56 | call splint(r,x,x2,-1,imin,imax,r(i)-h,dbacdn) | ||
| 57 | call splint(r,x,x2,1,imin,imax,r(i)+h,dforup) | ||
| 58 | call splint(r,x,x2,1,imin,imax,r(i)-h,dbacup) | ||
| 59 | dback = dbacup + dbacdn | ||
| 60 | dforw = dforup + dfordn | ||
| 61 | endif | ||
| 62 | deriv = (dforw-dback)/(2.d0*h) | ||
| 63 | endif | ||
| 64 | return | ||
| 65 | end | ||
diff --git a/src/labat/exchen.f b/src/labat/exchen.f new file mode 100644 index 0000000..a3d1112 --- /dev/null +++ b/src/labat/exchen.f | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | subroutine exchen(d,s,ex) | ||
| 2 | c gga91 exchange energy for a spin-unpolarized electronic system | ||
| 3 | c input d : density | ||
| 4 | c input s : abs(grad d)/(2*kf*d) | ||
| 5 | c output ex : exchange energy per electron | ||
| 6 | implicit double precision (a-h,o-z) | ||
| 7 | data a1,a2,a3,a4/0.19645d0,0.27430d0,0.15084d0,100.d0/ | ||
| 8 | data ax,a,b1/-0.7385588d0,7.7956d0,0.004d0/ | ||
| 9 | data thrd/0.333333333333d0/ | ||
| 10 | fac = ax*d**thrd | ||
| 11 | s2 = s*s | ||
| 12 | s4 = s2*s2 | ||
| 13 | p0 = 1.d0/dsqrt(1.d0+a*a*s2) | ||
| 14 | p1 = dlog(a*s+1.d0/p0) | ||
| 15 | p2 = dexp(-a4*s2) | ||
| 16 | p3 = 1.d0/(1.d0+a1*s*p1+b1*s4) | ||
| 17 | p4 = 1.d0+a1*s*p1+(a2-a3*p2)*s2 | ||
| 18 | f = p3*p4 | ||
| 19 | ex = fac*f | ||
| 20 | return | ||
| 21 | end | ||
diff --git a/src/labat/exchpt.f b/src/labat/exchpt.f new file mode 100644 index 0000000..b44f49e --- /dev/null +++ b/src/labat/exchpt.f | |||
| @@ -0,0 +1,33 @@ | |||
| 1 | subroutine exchpt(d,s,u,v,vx) | ||
| 2 | c gga91 exchange potential for a spin-unpolarized electronic system | ||
| 3 | c input d : density | ||
| 4 | c input s : abs(grad d)/(2*kf*d) | ||
| 5 | c input u : (grad d)*grad(abs(grad d))/(d**2 * (2*kf)**3) | ||
| 6 | c input v : (laplacian d)/(d*(2*kf)**2) | ||
| 7 | c output vx : exchange potential per electron | ||
| 8 | implicit double precision (a-h,o-z) | ||
| 9 | data a1,a2,a3,a4/0.19645d0,0.27430d0,0.15084d0,100.d0/ | ||
| 10 | data ax,a,b1/-0.7385588d0,7.7956d0,0.004d0/ | ||
| 11 | data thrd,thrd4/0.333333333333d0,1.33333333333d0/ | ||
| 12 | fac = ax*d**thrd | ||
| 13 | s2 = s*s | ||
| 14 | s3 = s2*s | ||
| 15 | s4 = s2*s2 | ||
| 16 | p0 = 1.d0/dsqrt(1.d0+a*a*s2) | ||
| 17 | p1 = dlog(a*s+1.d0/p0) | ||
| 18 | p2 = dexp(-a4*s2) | ||
| 19 | p3 = 1.d0/(1.d0+a1*s*p1+b1*s4) | ||
| 20 | p4 = 1.d0+a1*s*p1+(a2-a3*p2)*s2 | ||
| 21 | f = p3*p4 | ||
| 22 | p5 = b1*s2-(a2-a3*p2) | ||
| 23 | p6 = a1*s*(p1+a*s*p0) | ||
| 24 | p7 = 2.d0*(a2-a3*p2)+2.d0*a3*a4*s2*p2-4.d0*b1*s2*f | ||
| 25 | fs = p3*(p3*p5*p6+p7) | ||
| 26 | p8 = 2.d0*s*(b1-a3*a4*p2) | ||
| 27 | p9 = a1*p1+a*a1*s*p0*(3.d0-a*a*s2*p0*p0) | ||
| 28 | p10 = 4.d0*a3*a4*s*p2*(2.d0-a4*s2)-8.d0*b1*s*f-4.d0*b1*s3*fs | ||
| 29 | p11 = -p3*p3*(a1*p1+a*a1*s*p0+4.d0*b1*s3) | ||
| 30 | fss = p3*p3*(p5*p9+p6*p8)+2.d0*p3*p5*p6*p11+p3*p10+p7*p11 | ||
| 31 | vx = fac*(thrd4*f-(u-thrd4*s3)*fss-v*fs) | ||
| 32 | return | ||
| 33 | end | ||
diff --git a/src/labat/gcor.f b/src/labat/gcor.f new file mode 100644 index 0000000..afdc739 --- /dev/null +++ b/src/labat/gcor.f | |||
| @@ -0,0 +1,15 @@ | |||
| 1 | subroutine gcor(a,a1,b1,b2,b3,b4,p,rs,gg,ggrs) | ||
| 2 | c called by subroutines ldaec and ldauc | ||
| 3 | implicit double precision (a-h,o-z) | ||
| 4 | p1 = p + 1.d0 | ||
| 5 | q0 = -2.d0*a*(1.d0+a1*rs) | ||
| 6 | rs12 = dsqrt(rs) | ||
| 7 | rs32 = rs12**3 | ||
| 8 | rsp = rs**p | ||
| 9 | q1 = 2.d0*a*(b1*rs12+b2*rs+b3*rs32+b4*rs*rsp) | ||
| 10 | q2 = dlog(1.d0+1.d0/q1) | ||
| 11 | gg = q0*q2 | ||
| 12 | q3 = a*(b1/rs12+2.d0*b2+3.d0*b3*rs12+2.d0*b4*p1*rsp) | ||
| 13 | ggrs = -2.d0*a*a1*q2-q0*q3/(q1**2+q1) | ||
| 14 | return | ||
| 15 | end | ||
diff --git a/src/labat/gga.f b/src/labat/gga.f new file mode 100644 index 0000000..083fdad --- /dev/null +++ b/src/labat/gga.f | |||
| @@ -0,0 +1,45 @@ | |||
| 1 | c***************************************************************** | ||
| 2 | c***************************************************************** | ||
| 3 | c***************************************************************** | ||
| 4 | c GGA | ||
| 5 | c The Generalized Gradient Approximation | ||
| 6 | |||
| 7 | c GGA is a way to improve the local spin density approximation | ||
| 8 | c by adding nonlocal gradients in the evaluation of the exchange- | ||
| 9 | c correlation energy and potential. These functions and subroutines | ||
| 10 | c are based on programs made by John Perdew, Tulane University, | ||
| 11 | c New Orleans, Louisiana, USA. Email: PY03APF%music.tcs.tulane.edu | ||
| 12 | c The modifications necessary to fit them to the atom program was | ||
| 13 | c made by Tomas Holmquist 1993 (so now you know who to blame). | ||
| 14 | c Email: tomash@fy.chalmers.se | ||
| 15 | c A more thorough description of the GGA used may be found in | ||
| 16 | c J.P. Perdew et al, Phys. Rev. B (46) 1992 pp. 6671-6687. | ||
| 17 | |||
| 18 | c The GGA package is: | ||
| 19 | |||
| 20 | c function deriv | ||
| 21 | c subroutine grad | ||
| 22 | c subroutine grabgr | ||
| 23 | c subroutine laplac | ||
| 24 | c subroutine spline | ||
| 25 | c subroutine splint | ||
| 26 | c subroutine ggaexc | ||
| 27 | c subroutine exchen | ||
| 28 | c subroutine ldaec | ||
| 29 | c subroutine gcor | ||
| 30 | c subroutine ggaec | ||
| 31 | c subroutine ggauxc | ||
| 32 | c subroutine exchpt | ||
| 33 | c subroutine ldauc | ||
| 34 | c subroutine ggauc | ||
| 35 | |||
| 36 | c The grad, grabgr, and laplace subroutines uses the function deriv | ||
| 37 | c to calculate different derivatives with respect to the radial | ||
| 38 | c coordinate r. Spline and splint calculates the cubic spline | ||
| 39 | c interpolation which is used in function deriv. | ||
| 40 | c The two main subprograms, ggaexc and ggauxc, calculates | ||
| 41 | c the exchange-correlation energy and potential respectively. | ||
| 42 | c The other subroutines are modified versions of Perdew's program. | ||
| 43 | |||
| 44 | c***************************************************************** | ||
| 45 | c***************************************************************** | ||
diff --git a/src/labat/ggaec.f b/src/labat/ggaec.f new file mode 100644 index 0000000..3177859 --- /dev/null +++ b/src/labat/ggaec.f | |||
| @@ -0,0 +1,43 @@ | |||
| 1 | subroutine ggaec(rs,zet,t,ec,h) | ||
| 2 | c called by subroutine ggaexc | ||
| 3 | c gga91 correlation | ||
| 4 | c input rs : seitz radius | ||
| 5 | c input zet : relative spin polarization | ||
| 6 | c input t : abs(grad d)/(d*2.*ks*g) | ||
| 7 | c input : correlation energy per electron (ec) | ||
| 8 | c output h : nonlocal part of correlation energy per electron | ||
| 9 | implicit double precision (a-h,o-z) | ||
| 10 | data xnu,cc0,cx,alf/15.75592d0,0.004235d0,-0.001667212d0,0.09d0/ | ||
| 11 | data c1,c2,c3,c4/0.002568d0,0.023266d0,7.389d-6,8.723d0/ | ||
| 12 | data c5,c6,a4/0.472d0,7.389d-2,100.d0/ | ||
| 13 | data thrd2/0.666666666667d0/ | ||
| 14 | pi = 4.d0*datan(1.d0) | ||
| 15 | fk = 1.91915829d0/rs | ||
| 16 | sk = dsqrt(4.d0*fk/pi) | ||
| 17 | g = ((1.d0+zet)**thrd2+(1.d0-zet)**thrd2)/2.d0 | ||
| 18 | bet = xnu*cc0 | ||
| 19 | delt = 2.d0*alf/bet | ||
| 20 | g3 = g**3 | ||
| 21 | g4 = g3*g | ||
| 22 | pon = -delt*ec/(g3*bet) | ||
| 23 | b = delt/(dexp(pon)-1.d0) | ||
| 24 | b2 = b*b | ||
| 25 | t2 = t*t | ||
| 26 | t4 = t2*t2 | ||
| 27 | rs2 = rs*rs | ||
| 28 | rs3 = rs2*rs | ||
| 29 | q4 = 1.d0+b*t2 | ||
| 30 | q5 = 1.d0+b*t2+b2*t4 | ||
| 31 | q6 = c1+c2*rs+c3*rs2 | ||
| 32 | q7 = 1.d0+c4*rs+c5*rs2+c6*rs3 | ||
| 33 | cc = -cx + q6/q7 | ||
| 34 | r0 = (sk/fk)**2 | ||
| 35 | r1 = a4*r0*g4 | ||
| 36 | coeff = cc-cc0-3.d0*cx/7.d0 | ||
| 37 | r2 = xnu*coeff*g3 | ||
| 38 | r3 = dexp(-r1*t2) | ||
| 39 | h0 = g3*(bet/delt)*dlog(1.d0+delt*q4*t2/q5) | ||
| 40 | h1 = r3*r2*t2 | ||
| 41 | h = h0 + h1 | ||
| 42 | return | ||
| 43 | end | ||
diff --git a/src/labat/ggaexc.f b/src/labat/ggaexc.f new file mode 100644 index 0000000..135b42e --- /dev/null +++ b/src/labat/ggaexc.f | |||
| @@ -0,0 +1,76 @@ | |||
| 1 | subroutine ggaexc(r,db,i,imin,imax,doned,exc) | ||
| 2 | c ggaexc calculates the exchange-correlation energy | ||
| 3 | c input r : position coordinate (array) | ||
| 4 | c input db : spin up and down density. (array) | ||
| 5 | c input i : counter, i.e. present position = r(i) | ||
| 6 | c input imin : min value of i | ||
| 7 | c input imax : max value of i | ||
| 8 | c in/output doned : true if density is splined | ||
| 9 | c output exc : exchange-correlation energy | ||
| 10 | implicit logical (a-z) | ||
| 11 | logical doned | ||
| 12 | double precision r,db,gradd,gradup,graddn,fk,fkup,fkdn,sk,g | ||
| 13 | double precision sup,sdn,t,exc,ec | ||
| 14 | double precision onethi,twothi,pi,conkf,d,zet,rs,exup,exdn | ||
| 15 | double precision ex,eclda,ecgga | ||
| 16 | integer i,imin,imax | ||
| 17 | dimension r(561),db(2,561) | ||
| 18 | dimension gradd(561),gradup(561),graddn(561),fk(561),fkup(561) | ||
| 19 | dimension fkdn(561),sk(561),g(561),sup(561),sdn(561),t(561) | ||
| 20 | common/gga/gradd,gradup,graddn,fkup,fkdn,sk,g,sup,sdn,t | ||
| 21 | onethi = 1.d0/3.d0 | ||
| 22 | twothi = 2.d0/3.d0 | ||
| 23 | pi = 4.d0*datan(1.d0) | ||
| 24 | conkf = (3.d0*pi**2)**onethi | ||
| 25 | d = db(1,i) + db(2,i) | ||
| 26 | call grad(r,db,i,imin,imax,doned,gradd(i),gradup(i),graddn(i)) | ||
| 27 | |||
| 28 | c calculate the exchange energy, first spin up, then spin down | ||
| 29 | |||
| 30 | if (db(1,i).gt.1.d-100) then | ||
| 31 | fkup(i) = conkf*(2.d0*db(1,i))**onethi | ||
| 32 | sup(i) = dabs(gradup(i))/(2.d0*fkup(i)*db(1,i)) | ||
| 33 | call exchen(2.d0*db(1,i),sup(i),exup) | ||
| 34 | else | ||
| 35 | fkup(i) = 0.d0 | ||
| 36 | sup(i) = 0.d0 | ||
| 37 | exup = 0.d0 | ||
| 38 | endif | ||
| 39 | if (db(2,i).gt.1.d-100) then | ||
| 40 | fkdn(i) = conkf*(2.d0*db(2,i))**onethi | ||
| 41 | sdn(i) = dabs(graddn(i))/(2.d0*fkdn(i)*db(2,i)) | ||
| 42 | call exchen(2.d0*db(2,i),sdn(i),exdn) | ||
| 43 | else | ||
| 44 | fkdn(i) = 0.d0 | ||
| 45 | sdn(i) = 0.d0 | ||
| 46 | exdn = 0.d0 | ||
| 47 | endif | ||
| 48 | if (d.gt.1d-100) then | ||
| 49 | ex = (exup*db(1,i) + exdn*db(2,i))/d | ||
| 50 | else | ||
| 51 | ex = 0.d0 | ||
| 52 | endif | ||
| 53 | |||
| 54 | c exchange energy done, now calculate the correlation energy | ||
| 55 | |||
| 56 | fk(i) = conkf*d**onethi | ||
| 57 | sk(i) = dsqrt(4.d0*fk(i)/pi) | ||
| 58 | if (d.gt.1.d-100) then | ||
| 59 | zet = (db(1,i) - db(2,i))/d | ||
| 60 | else | ||
| 61 | zet = 0.d0 | ||
| 62 | endif | ||
| 63 | g(i) = ((1.d0+zet)**twothi+(1.d0-zet)**twothi)/2.d0 | ||
| 64 | if (d.gt.1.d-18) then | ||
| 65 | rs = (3.d0/(4.d0*pi*d))**onethi | ||
| 66 | t(i) = dabs(gradd(i))/(d*2*sk(i)*g(i)) | ||
| 67 | call ldaec(rs,zet,eclda) | ||
| 68 | call ggaec(rs,zet,t(i),eclda,ecgga) | ||
| 69 | ec = eclda + ecgga | ||
| 70 | else | ||
| 71 | ec = 0.d0 | ||
| 72 | endif | ||
| 73 | exc = ex + ec | ||
| 74 | |||
| 75 | return | ||
| 76 | end | ||
diff --git a/src/labat/ggauc.f b/src/labat/ggauc.f new file mode 100644 index 0000000..f3adcf5 --- /dev/null +++ b/src/labat/ggauc.f | |||
| @@ -0,0 +1,96 @@ | |||
| 1 | subroutine ggauc(rs,zet,t,uu,vv,ww,ec,ecrs,eczet,dvcup,dvcdn) | ||
| 2 | c gga91 correlation | ||
| 3 | c input rs : seitz radius | ||
| 4 | c input zet : relative spin polarization | ||
| 5 | c input t : abs(grad d)/(d*2.*ks*g) | ||
| 6 | c input uu : (grad d)*grad(abs(grad d))/(d**2 * (2*ks*g)**3) | ||
| 7 | c input vv : (laplacian d)/(d * (2*ks*g)**2) | ||
| 8 | c input ww : (grad d)*(grad zet)/(d * (2*ks*g)**2 | ||
| 9 | c input ec : correlation energy | ||
| 10 | c input ecrs : derivative of ec with respect to rs | ||
| 11 | c input eczet : derivative of ec with respect to zet | ||
| 12 | c output dvcup,dvcdn : nonlocal parts of correlation potentials | ||
| 13 | implicit double precision (a-h,o-z) | ||
| 14 | data xnu,cc0,cx,alf/15.75592d0,0.004235d0,-0.001667212d0,0.09d0/ | ||
| 15 | data c1,c2,c3,c4/0.002568d0,0.023266d0,7.389d-6,8.723d0/ | ||
| 16 | data c5,c6,a4/0.472d0,7.389d-2,100.d0/ | ||
| 17 | data thrdm,thrd2/-0.333333333333d0,0.666666666667d0/ | ||
| 18 | pi = 4.d0*datan(1.d0) | ||
| 19 | fk = 1.91915829d0/rs | ||
| 20 | sk = dsqrt(4.d0*fk/pi) | ||
| 21 | g = ((1.d0+zet)**thrd2+(1.d0-zet)**thrd2)/2.d0 | ||
| 22 | bet = xnu*cc0 | ||
| 23 | delt = 2.d0*alf/bet | ||
| 24 | g3 = g**3 | ||
| 25 | g4 = g3*g | ||
| 26 | pon = -delt*ec/(g3*bet) | ||
| 27 | b = delt/(dexp(pon)-1.d0) | ||
| 28 | b2 = b*b | ||
| 29 | t2 = t*t | ||
| 30 | t4 = t2*t2 | ||
| 31 | t6 = t4*t2 | ||
| 32 | rs2 = rs*rs | ||
| 33 | rs3 = rs2*rs | ||
| 34 | q4 = 1.d0+b*t2 | ||
| 35 | q5 = 1.d0+b*t2+b2*t4 | ||
| 36 | q6 = c1+c2*rs+c3*rs2 | ||
| 37 | q7 = 1.d0+c4*rs+c5*rs2+c6*rs3 | ||
| 38 | cc = -cx + q6/q7 | ||
| 39 | r0 = (sk/fk)**2 | ||
| 40 | r1 = a4*r0*g4 | ||
| 41 | coeff = cc-cc0-3.d0*cx/7.d0 | ||
| 42 | r2 = xnu*coeff*g3 | ||
| 43 | r3 = dexp(-r1*t2) | ||
| 44 | h0 = g3*(bet/delt)*dlog(1.d0+delt*q4*t2/q5) | ||
| 45 | h1 = r3*r2*t2 | ||
| 46 | h = h0+h1 | ||
| 47 | c energy done. now the potential: | ||
| 48 | ccrs = (c2+2.*c3*rs)/q7 - q6*(c4+2.*c5*rs+3.*c6*rs2)/q7**2 | ||
| 49 | rsthrd = rs/3.d0 | ||
| 50 | r4 = rsthrd*ccrs/coeff | ||
| 51 | c========================================================= | ||
| 52 | c fix made by Tomas Holmquist | ||
| 53 | if ((zet.eq.1.d0).or.(zet.eq.-1.d0)) then | ||
| 54 | gz = 0.d0 | ||
| 55 | else | ||
| 56 | gz = ((1.d0+zet)**thrdm - (1.d0-zet)**thrdm)/3.d0 | ||
| 57 | endif | ||
| 58 | c========================================================= | ||
| 59 | fac = delt/b+1.d0 | ||
| 60 | bg = -3.d0*b2*ec*fac/(bet*g4) | ||
| 61 | bec = b2*fac/(bet*g3) | ||
| 62 | q8 = q5*q5+delt*q4*q5*t2 | ||
| 63 | q9 = 1.d0+2.d0*b*t2 | ||
| 64 | h0b = -bet*g3*b*t6*(2.d0+b*t2)/q8 | ||
| 65 | h0rs = -rsthrd*h0b*bec*ecrs | ||
| 66 | fact0 = 2.d0*delt-6.d0*b | ||
| 67 | fact1 = q5*q9+q4*q9*q9 | ||
| 68 | h0bt = 2.d0*bet*g3*t4*((q4*q5*fact0-delt*fact1)/q8)/q8 | ||
| 69 | h0rst = rsthrd*t2*h0bt*bec*ecrs | ||
| 70 | h0z = 3.d0*gz*h0/g + h0b*(bg*gz+bec*eczet) | ||
| 71 | h0t = 2.*bet*g3*q9/q8 | ||
| 72 | h0zt = 3.d0*gz*h0t/g+h0bt*(bg*gz+bec*eczet) | ||
| 73 | fact2 = q4*q5+b*t2*(q4*q9+q5) | ||
| 74 | fact3 = 2.d0*b*q5*q9+delt*fact2 | ||
| 75 | h0tt = 4.d0*bet*g3*t*(2.d0*b/q8-(q9*fact3/q8)/q8) | ||
| 76 | h1rs = r3*r2*t2*(-r4+r1*t2/3.d0) | ||
| 77 | fact4 = 2.d0-r1*t2 | ||
| 78 | h1rst = r3*r2*t2*(2.d0*r4*(1.d0-r1*t2)-thrd2*r1*t2*fact4) | ||
| 79 | h1z = gz*r3*r2*t2*(3.d0-4.d0*r1*t2)/g | ||
| 80 | h1t = 2.d0*r3*r2*(1.d0-r1*t2) | ||
| 81 | h1zt = 2.d0*gz*r3*r2*(3.d0-11.d0*r1*t2+4.d0*r1*r1*t4)/g | ||
| 82 | h1tt = 4.d0*r3*r2*r1*t*(-2.d0+r1*t2) | ||
| 83 | hrs = h0rs+h1rs | ||
| 84 | hrst = h0rst+h1rst | ||
| 85 | ht = h0t+h1t | ||
| 86 | htt = h0tt+h1tt | ||
| 87 | hz = h0z+h1z | ||
| 88 | hzt = h0zt+h1zt | ||
| 89 | comm = h+hrs+hrst+t2*ht/6.d0+7.d0*t2*t*htt/6.d0 | ||
| 90 | pref = hz-gz*t2*ht/g | ||
| 91 | fact5 = gz*(2.d0*ht+t*htt)/g | ||
| 92 | comm = comm-pref*zet-uu*htt-vv*ht-ww*(hzt-fact5) | ||
| 93 | dvcup = comm + pref | ||
| 94 | dvcdn = comm - pref | ||
| 95 | return | ||
| 96 | end | ||
diff --git a/src/labat/ggauxc.f b/src/labat/ggauxc.f new file mode 100644 index 0000000..d5fcb61 --- /dev/null +++ b/src/labat/ggauxc.f | |||
| @@ -0,0 +1,82 @@ | |||
| 1 | subroutine ggauxc(r,db,zet,i,imin,imax,donela,donegr,donez, | ||
| 2 | j uxcup,uxcdn) | ||
| 3 | c ggauxc calculates the exchange-correlation potential by taking | ||
| 4 | c the functional derivative of the energy with respect to the density | ||
| 5 | c input r : position coordinate (array) | ||
| 6 | c input db : spin up and down density. (array) | ||
| 7 | c input zet : relative spin polarization (array) | ||
| 8 | c input i : counter, i.e. present position = r(i) | ||
| 9 | c input imin : min value of i | ||
| 10 | c input imax : max value of i | ||
| 11 | c in/output donela : true if r^2*grad(density) is splined | ||
| 12 | c in/output donegr : true if abs(grad(density)) is splined | ||
| 13 | c in/output donez : true if zet is splined | ||
| 14 | c output uxcup : spin-up exchange-correlation potential | ||
| 15 | c output uxcdn : spin-down exchange-correlation potential | ||
| 16 | implicit logical (a-z) | ||
| 17 | double precision r,db,zet,uxcup,uxcdn,gradd,gradup,graddn | ||
| 18 | double precision fkup,fkdn,sk,g,sup,sdn,t,tempz,z2,gradz | ||
| 19 | double precision onethi,pi,d,rs,lapld,laplup,lapldn,deriv | ||
| 20 | double precision gagd,gagup,gagdn,uu,vv,ww,uup,vup,udn,vdn | ||
| 21 | double precision uclcup,uclcdn,ucgaup,ucgadn,uxup,uxdn | ||
| 22 | double precision ucup,ucdn,ec,ecrs,eczet | ||
| 23 | integer i,imin,imax,j | ||
| 24 | logical donela,donegr,donez | ||
| 25 | common/gga/gradd,gradup,graddn,fkup,fkdn,sk,g,sup,sdn,t | ||
| 26 | common/ggaz/tempz,z2 | ||
| 27 | dimension r(561),db(2,561),zet(561),tempz(2,561),z2(2,561) | ||
| 28 | dimension gradd(561),gradup(561),graddn(561),fkup(561) | ||
| 29 | dimension fkdn(561),sk(561),g(561),sup(561),sdn(561),t(561) | ||
| 30 | onethi = 1.d0/3.d0 | ||
| 31 | pi = 4.d0*datan(1.d0) | ||
| 32 | call laplac(r,gradup,graddn,i,imin,imax,donela,lapld,laplup, | ||
| 33 | j lapldn) | ||
| 34 | call grabgr(r,gradup,graddn,i,imin,imax,donegr,gagd,gagup,gagdn) | ||
| 35 | |||
| 36 | c calculate the exchange potential | ||
| 37 | if (db(1,i).gt.1.d-100) then | ||
| 38 | uup = gradup(i)*gagup/(db(1,i)**2*(2.d0*fkup(i))**3) | ||
| 39 | vup = laplup/(db(1,i)*(2.d0*fkup(i))**2) | ||
| 40 | call exchpt(2.d0*db(1,i),sup(i),uup,vup,uxup) | ||
| 41 | else | ||
| 42 | uxup = 0.d0 | ||
| 43 | endif | ||
| 44 | if (db(2,i).gt.1.d-100) then | ||
| 45 | udn = graddn(i)*gagdn/(db(2,i)**2*(2.d0*fkdn(i))**3) | ||
| 46 | vdn = lapldn/(db(2,i)*(2.d0*fkdn(i))**2) | ||
| 47 | call exchpt(2.d0*db(2,i),sdn(i),udn,vdn,uxdn) | ||
| 48 | else | ||
| 49 | uxdn = 0.d0 | ||
| 50 | endif | ||
| 51 | |||
| 52 | c exchange potential done, now calculate the correlation potential | ||
| 53 | |||
| 54 | if (.not.donez) then | ||
| 55 | do 10 j = imin,imax | ||
| 56 | tempz(1,j) = zet(j) | ||
| 57 | 10 continue | ||
| 58 | call spline(r,imin+1,imax,tempz,z2) | ||
| 59 | donez = .true. | ||
| 60 | endif | ||
| 61 | gradz = deriv(r,tempz,z2,1,i,imin,imax) | ||
| 62 | d = db(1,i) + db(2,i) | ||
| 63 | if (d.gt.1.d-18) then | ||
| 64 | rs = (3.d0/(4.d0*pi*d))**onethi | ||
| 65 | uu = gradd(i)*gagd/(d**2*(2.d0*sk(i)*g(i))**3) | ||
| 66 | vv = lapld/(d*(2.d0*sk(i)*g(i))**2) | ||
| 67 | ww = gradd(i)*gradz/(d*(2.d0*sk(i)*g(i))**2) | ||
| 68 | call ldauc(rs,zet(i),ec,ecrs,eczet,uclcup,uclcdn) | ||
| 69 | call ggauc(rs,zet(i),t(i),uu,vv,ww,ec,ecrs,eczet,ucgaup, | ||
| 70 | j ucgadn) | ||
| 71 | ucup = uclcup + ucgaup | ||
| 72 | ucdn = uclcdn + ucgadn | ||
| 73 | else | ||
| 74 | ucdn = 0.d0 | ||
| 75 | ucup = 0.d0 | ||
| 76 | endif | ||
| 77 | uxcup = uxup + ucup | ||
| 78 | uxcdn = uxdn + ucdn | ||
| 79 | |||
| 80 | return | ||
| 81 | end | ||
| 82 | |||
diff --git a/src/labat/grabgr.f b/src/labat/grabgr.f new file mode 100644 index 0000000..1ed039c --- /dev/null +++ b/src/labat/grabgr.f | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | subroutine grabgr(r,gradup,graddn,i,imin,imax,done,gagd,gagup, | ||
| 2 | j gagdn) | ||
| 3 | c calculates grad(abs(grad(density))) | ||
| 4 | c input r : radial coordinate (array) | ||
| 5 | c input gradup : grad(density), spin up (array) | ||
| 6 | c input graddn : grad(density), spin down (array) | ||
| 7 | c input i : counter, i.e. current position = r(i) | ||
| 8 | c input imin : min value of i | ||
| 9 | c input imax : max value of i | ||
| 10 | c in/output done : true if abs(grad(density)) is splined | ||
| 11 | c output gagd : grad(abs(grad(density))) | ||
| 12 | c output gagup,gagdn : grad(abs(grad(density))), spin up and down | ||
| 13 | implicit logical (a-z) | ||
| 14 | logical done | ||
| 15 | double precision r,gradup,graddn,gagd,gagup,gagdn,temp,gag2,deriv | ||
| 16 | integer i,imin,imax,j | ||
| 17 | common/ggagag/temp,gag2 | ||
| 18 | dimension r(561),gradup(561),graddn(561) | ||
| 19 | dimension temp(2,561),gag2(2,561) | ||
| 20 | if (.not.done) then | ||
| 21 | do 10 j = imin,imax | ||
| 22 | temp(1,j) = dabs(gradup(j)) | ||
| 23 | temp(2,j) = dabs(graddn(j)) | ||
| 24 | 10 continue | ||
| 25 | call spline(r,imin+1,imax,temp,gag2) | ||
| 26 | done = .true. | ||
| 27 | endif | ||
| 28 | gagup = deriv(r,temp,gag2,1,i,imin,imax) | ||
| 29 | gagdn = deriv(r,temp,gag2,-1,i,imin,imax) | ||
| 30 | gagd = gagup + gagdn | ||
| 31 | return | ||
| 32 | end | ||
diff --git a/src/labat/grad.f b/src/labat/grad.f new file mode 100644 index 0000000..845ed5a --- /dev/null +++ b/src/labat/grad.f | |||
| @@ -0,0 +1,26 @@ | |||
| 1 | subroutine grad(r,db,i,imin,imax,done,gradd,gradup,graddn) | ||
| 2 | c grad calculates the derivative of db with respect to r, at | ||
| 3 | c position r(i). | ||
| 4 | c input r : radial coordinate (array) | ||
| 5 | c input db : spin-up and down densities (array) | ||
| 6 | c input i : counter, i.e. current position = r(i) | ||
| 7 | c input imin : min value of i | ||
| 8 | c input imax : max value of i | ||
| 9 | c in/output done : true if density is splined | ||
| 10 | c output gradd : grad(density) | ||
| 11 | c output gradup,graddn : grad(density), spin up and down | ||
| 12 | implicit logical (a-z) | ||
| 13 | logical done | ||
| 14 | double precision r,db,gradd,gradup,graddn,db2,deriv | ||
| 15 | integer i,imin,imax | ||
| 16 | dimension r(561),db(2,561),db2(2,561) | ||
| 17 | common/ggagra/db2 | ||
| 18 | if (.not.done) then | ||
| 19 | call spline(r,imin+1,imax,db,db2) | ||
| 20 | done = .true. | ||
| 21 | endif | ||
| 22 | gradup = deriv(r,db,db2,1,i,imin,imax) | ||
| 23 | graddn = deriv(r,db,db2,-1,i,imin,imax) | ||
| 24 | gradd = gradup + graddn | ||
| 25 | return | ||
| 26 | end | ||
diff --git a/src/labat/labat.f b/src/labat/labat.f new file mode 100644 index 0000000..da1f7fe --- /dev/null +++ b/src/labat/labat.f | |||
| @@ -0,0 +1,587 @@ | |||
| 1 | program atom | ||
| 2 | implicit double precision (a-h,o-z) | ||
| 3 | dimension dval(2,561),nval(2,7,10),ddval(2,561),ndval(2,7,10) | ||
| 4 | dimension dcore(2,561),vhv(561),fpu(561) | ||
| 5 | c | ||
| 6 | c free atom program by m.p. summer 1985 (valence energy and core | ||
| 7 | c density are calculated) | ||
| 8 | c | ||
| 9 | c GGA implemented by T. Holmquist and U. Yxklinten. | ||
| 10 | c | ||
| 11 | c files used: | ||
| 12 | c 6: terminal output | ||
| 13 | c 22: density and potential output | ||
| 14 | c 33: density and potential input | ||
| 15 | c 44: potential and density double prec. output | ||
| 16 | c 46: potential and density double prec. input | ||
| 17 | c 55: control input | ||
| 18 | c 66: printer output | ||
| 19 | c 77: density (total and core) output (J.H.) | ||
| 20 | c | ||
| 21 | dimension r(561),veff(2,561),vc(561),vcold(561),vv(561) | ||
| 22 | dimension gr(561),lm(2),rnocc(2,7,10),ux1(561),ux2(561) | ||
| 23 | dimension u(561),roo(561),spl(561),nb(7) | ||
| 24 | dimension db(2,561),v(561),vold(2,561) | ||
| 25 | dimension snlo(561),wj(301),ekin(2) | ||
| 26 | dimension ebound(2,7,10),nbound(2,7),de(2,7,10) | ||
| 27 | dimension apu(561),bpu(561),cpu(561),dpu(561),nlp(2,7,10) | ||
| 28 | dimension epu(561) | ||
| 29 | c=================================================================== | ||
| 30 | c gga | ||
| 31 | dimension excgga(561),uxcup(561),uxcdn(561) | ||
| 32 | logical doned,donela,donegr,donez,donec | ||
| 33 | c gga | ||
| 34 | c=================================================================== | ||
| 35 | common/sc/gr,r,snlo,nbl | ||
| 36 | common/mess/wj,dx,nblock,jblock | ||
| 37 | common/pot/v | ||
| 38 | frs(x)=(3.d0/(4.d0*pi*x))**(1.d0/3.d0) | ||
| 39 | pi=4.d0*datan(1.d0) | ||
| 40 | pi2=pi/2.d0 | ||
| 41 | a=(4.d0/9.d0/pi)**(1.d0/3.d0) | ||
| 42 | c | ||
| 43 | open(22,file='adensout.dat',status='unknown') | ||
| 44 | open(33,file='adensin.dat',status='unknown') | ||
| 45 | open(44,file='apotout.dat',status='unknown') | ||
| 46 | open(46,file='apotin.dat',status='unknown') | ||
| 47 | open(55,file='atomctrl.dat',status='old') | ||
| 48 | open(66,file='aprtout.dat',status='unknown') | ||
| 49 | open(77,file='atomdens.dat',status='unknown') | ||
| 50 | write(6,*) '=== Its ===== Energy (Ha) ======' | ||
| 51 | call flush(6) | ||
| 52 | read(55,*)z,zion | ||
| 53 | c z : atomic number | ||
| 54 | c zion : ionicity | ||
| 55 | c | ||
| 56 | write(66,2) z,zion | ||
| 57 | 2 format(/' atom number:',f5.0,' ionicity:',f5.0) | ||
| 58 | sf=4.d0*pi | ||
| 59 | read(55,*)jblock,nbl,c | ||
| 60 | c parameters of the hermann-skillmann mesh | ||
| 61 | read(55,*)fback,thresh,qsc | ||
| 62 | C fback : feedback | ||
| 63 | c thresh : error allowed for the bound state eigenenergy | ||
| 64 | c e.g. 0.00001 | ||
| 65 | c qsc : parameter for the screened green's function (0.005) | ||
| 66 | read(55,*)itmax,inopt,ipr,iout | ||
| 67 | c itmax : max. no. of iterations | ||
| 68 | c iopt : =0 starting potential generated; =1 starting potential | ||
| 69 | c read in; =2 starting potential read in from unit 46. | ||
| 70 | c (double precision format) | ||
| 71 | c ipr, iout : print out parameters | ||
| 72 | c | ||
| 73 | c set up the herman-skillman mesh | ||
| 74 | c | ||
| 75 | nblock=jblock | ||
| 76 | mesh=nblock*nbl+1 | ||
| 77 | n=mesh | ||
| 78 | mest=mesh | ||
| 79 | dx=c*0.0025d0 | ||
| 80 | en0=-0.01d0 | ||
| 81 | i=1 | ||
| 82 | r(i)=0.d0 | ||
| 83 | deltax=dx | ||
| 84 | do 251 j=1,nblock | ||
| 85 | do 241 jk=1,nbl | ||
| 86 | i=i+1 | ||
| 87 | 241 r(i)=r(i-1)+deltax | ||
| 88 | deltax=2.d0*deltax | ||
| 89 | 251 continue | ||
| 90 | c | ||
| 91 | read(55,*)ne,iys,ixc | ||
| 92 | c ne: no. bound states | ||
| 93 | c iys: =1 for spin compensated; =2 spin polarized | ||
| 94 | c ixc: = 1 b-h xc; =0 c-a xc | ||
| 95 | if(ixc.eq.1)write(66,2149) | ||
| 96 | if(ixc.eq.0)write(66,2148) | ||
| 97 | if(ixc.eq.2)write(66,2147) | ||
| 98 | 2149 format(/' von barth - hedin xc') | ||
| 99 | 2148 format(/' ceperley - alder xc') | ||
| 100 | 2147 format(/' perdew - wang xc') | ||
| 101 | dxx=r(n)-r(n-1) | ||
| 102 | write(66,5)jblock,nbl,c | ||
| 103 | write(66,5849)dx,dxx,r(n) | ||
| 104 | 5 format(/' hermann-skillmann mesh',/,' blocks, nbl, c:',2(i5,','), | ||
| 105 | j f10.7) | ||
| 106 | 5849 format(' first interval, last interval, final r:',2(f10.6,','), | ||
| 107 | j f10.6) | ||
| 108 | write(66,2312) thresh,qsc,fback | ||
| 109 | 2312 format(/' energy eigenvalue threshold, screening parameter, ', | ||
| 110 | j 'feedback:',2(f12.6,','),f6.3) | ||
| 111 | write(66,9) | ||
| 112 | do 5273 i=1,7 | ||
| 113 | 5273 nb(i)=0 | ||
| 114 | lmax=0 | ||
| 115 | 9 format(//' initial bound state configuration',/, | ||
| 116 | j ' nlm energy occup. val.el. d-band el.') | ||
| 117 | zv=0.d0 | ||
| 118 | do 5595 ispin=1,iys | ||
| 119 | do 5595 ii=1,ne | ||
| 120 | read(55,*)nnlz,eb0,rnoc,nv,ndv | ||
| 121 | c | ||
| 122 | c nnlz : e.g. 100 | ||
| 123 | c eb0 : energy eigenvalue guess | ||
| 124 | c rnoc : occupation number | ||
| 125 | c nv : =1 when orbital is a valence orbital; =0 for core orbitals | ||
| 126 | c ndv : =1 when orbital is a d-valence orbital; =0 for other orbitals | ||
| 127 | c | ||
| 128 | nnn=nnlz/100 | ||
| 129 | lll=(nnlz-nnn*100)/10 | ||
| 130 | nnn=nnn-lll | ||
| 131 | if(nnn.gt.nb(lll+1))nb(lll+1)=nnn | ||
| 132 | if(lll.gt.lmax)lmax=lll | ||
| 133 | rnocc(ispin,lll+1,nnn)=rnoc | ||
| 134 | nval(ispin,lll+1,nnn)=nv | ||
| 135 | ndval(ispin,lll+1,nnn)=ndv | ||
| 136 | if(iys.eq.1)nval(2,lll+1,nnn)=nv | ||
| 137 | if(iys.eq.1)ndval(2,lll+1,nnn)=ndv | ||
| 138 | if(iys.eq.1)rnocc(2,lll+1,nnn)=rnoc | ||
| 139 | if(iys.eq.1)rnoc=rnoc*2 | ||
| 140 | write(66,19)nnlz,eb0,rnoc,nv,ndv | ||
| 141 | zv=zv+rnoc*(nv+ndv) | ||
| 142 | 5595 ebound(ispin,lll+1,nnn)=eb0 | ||
| 143 | write(66,5120)zv | ||
| 144 | 5120 format(/' number of valence electrons: ',f5.1) | ||
| 145 | 19 format(i6,e12.4,f7.2,i7,i10) | ||
| 146 | nb1=nbl+1 | ||
| 147 | iter=0 | ||
| 148 | itr=itmax-iout | ||
| 149 | c | ||
| 150 | 16 format(7(f12.5,1x)) | ||
| 151 | 17 format(/' charge and spin density profiles '/) | ||
| 152 | 18 format(1h0/' potentials vs. distance after ',i3,' iterations'/) | ||
| 153 | c | ||
| 154 | c tabulate screened green's function | ||
| 155 | do 10 i=1,n | ||
| 156 | 10 gr(i)=exp(-qsc*r(i)) | ||
| 157 | c | ||
| 158 | c integration weigths | ||
| 159 | do 121 i=1,nb1 | ||
| 160 | 121 wj(i)=(3.d0+(-1.d0)**i)/3.d0 | ||
| 161 | wj(1)=1.d0/3.d0 | ||
| 162 | wj(nb1)=1.d0/3.d0 | ||
| 163 | c | ||
| 164 | c initial values of the potentials | ||
| 165 | if(inopt.eq.1) goto 302 | ||
| 166 | if(inopt.eq.2) goto 306 | ||
| 167 | c | ||
| 168 | itt=0 | ||
| 169 | c thomas-fermi potential | ||
| 170 | do 30 i=2,n | ||
| 171 | x=r(i)/0.88534135d0*z**(1.d0/3.d0) | ||
| 172 | xx=sqrt(x) | ||
| 173 | vc(i)=-z/r(i)/(1.+0.02747d0*xx+1.243d0*x-0.1486d0*x*xx | ||
| 174 | j+0.2302d0*x*x+0.007298d0*x*x*xx+0.006944d0*x*x*x) | ||
| 175 | do 30 ispin=1,2 | ||
| 176 | 30 veff(ispin,i)=vc(i) | ||
| 177 | goto 311 | ||
| 178 | c read in an old potential for the input | ||
| 179 | 302 read(33,2645)itt | ||
| 180 | 2645 format(i3) | ||
| 181 | 1645 format(i3,' z,ion:',2f4.0,' jblock,nbl,c:',2i5,f10.7) | ||
| 182 | do 303 i=1,n | ||
| 183 | 303 read(33,907) vc(i),veff(1,i),veff(2,i),du1,du2 | ||
| 184 | goto 311 | ||
| 185 | 306 read(46,2645) itt | ||
| 186 | do 304 i = 1, n | ||
| 187 | read(46,*) du1, vc(i), vve, du2 | ||
| 188 | veff(1,i) = vve | ||
| 189 | veff(2,i) = vve | ||
| 190 | 304 continue | ||
| 191 | 311 do 312 i=1,n | ||
| 192 | vcold(i)=vc(i) | ||
| 193 | do 312 ispin=1,2 | ||
| 194 | 312 vold(ispin,i)=veff(ispin,i) | ||
| 195 | 5555 format(e15.8) | ||
| 196 | 7771 format(/' initial potentials'/) | ||
| 197 | 7773 format(5f13.5) | ||
| 198 | if(iout.lt.-1)go to 1437 | ||
| 199 | write(66,7771) | ||
| 200 | do 7772 i=2,n,ipr | ||
| 201 | 7772 write(66,7773) r(i),vc(i),veff(1,i),veff(2,i) | ||
| 202 | 1437 eold=0.d0 | ||
| 203 | etot=-1.d0 | ||
| 204 | itec=0 | ||
| 205 | c | ||
| 206 | c iteration | ||
| 207 | c | ||
| 208 | 100 iter=iter+1 | ||
| 209 | c write(6,*) 'NEW ITERATION' | ||
| 210 | c call flush(6) | ||
| 211 | c convergency check | ||
| 212 | if(abs(etot-eold).lt.5.d-5)itec=itec+1 | ||
| 213 | if(abs(etot-eold).lt.5.d-5.and.itec.eq.1)itmax=iter | ||
| 214 | eold=etot | ||
| 215 | if(iter-itmax)999,999,400 | ||
| 216 | 999 itt=itt+1 | ||
| 217 | write(66,6147)itt | ||
| 218 | do 117 i=1,n | ||
| 219 | dval(2,i)=0.d0 | ||
| 220 | ddval(2,i)=0.d0 | ||
| 221 | dcore(1,i)=0.d0 | ||
| 222 | dcore(2,i)=0.d0 | ||
| 223 | dval(1,i)=0.d0 | ||
| 224 | 117 ddval(1,i)=0.d0 | ||
| 225 | 6147 format(///' ********************* iteration:', | ||
| 226 | 1 i4,' ***********************'/) | ||
| 227 | do 917 ispin=1,iys | ||
| 228 | do 116 i=1,n | ||
| 229 | vv(i)=veff(ispin,i) | ||
| 230 | v(i)=2*vv(i) | ||
| 231 | 116 db(ispin,i)=0.d0 | ||
| 232 | lm(ispin)=-1 | ||
| 233 | do 807 i=0,4 | ||
| 234 | ik=i | ||
| 235 | if(i)817,817,818 | ||
| 236 | 817 do 819 jj=1,4 | ||
| 237 | 819 u(jj)=r(jj)-z*r(jj)**2 | ||
| 238 | go to 822 | ||
| 239 | 818 do 821 jj=1,4 | ||
| 240 | 821 u(jj)=r(jj)**(i+1) | ||
| 241 | 822 call schrhs(vv,0.d0,ik,u) | ||
| 242 | merkki=1 | ||
| 243 | c determine the number of bound states | ||
| 244 | ncross=0 | ||
| 245 | do 826 ii=2,n | ||
| 246 | if(merkki)823,823,824 | ||
| 247 | 823 if(u(ii))826,826,825 | ||
| 248 | 824 if(u(ii))825,826,826 | ||
| 249 | 825 merkki=-merkki | ||
| 250 | ncross=ncross+1 | ||
| 251 | 826 continue | ||
| 252 | dlo=(u(n)-u(n-1))*u(n) | ||
| 253 | if(dlo.ge.0)nbound(ispin,i+1)=ncross | ||
| 254 | if(dlo.lt.0)nbound(ispin,i+1)=ncross+1 | ||
| 255 | if(nbound(ispin,i+1).eq.0)go to 827 | ||
| 256 | lm(ispin)=i | ||
| 257 | write(66,678)i,nbound(ispin,i+1) | ||
| 258 | nbound(ispin,i+1)=min0(nbound(ispin,i+1),nb(i+1)) | ||
| 259 | 678 format(' l = ',i4,',',i4,' bound states ') | ||
| 260 | 807 continue | ||
| 261 | 827 if(lm(ispin).lt.0.and.ispin.eq.2)go to 674 | ||
| 262 | if(lm(ispin).lt.0.and.ispin.eq.1)go to 917 | ||
| 263 | lm(ispin)=min0(lm(ispin),lmax) | ||
| 264 | lmm=lm(ispin) | ||
| 265 | do 918 i=0,lmm | ||
| 266 | nii=min0(nbound(ispin,i+1),8) | ||
| 267 | ik=i | ||
| 268 | do 918 ii=1,nii | ||
| 269 | if(rnocc(ispin,i+1,ii).lt.0.1d0)go to 918 | ||
| 270 | nn=i+ii | ||
| 271 | en=2.d0*ebound(ispin,i+1,ii) | ||
| 272 | if(en.ge.0.d0)en=en0 | ||
| 273 | en1=en | ||
| 274 | dde=de(ispin,i+1,ii) | ||
| 275 | if(iter.le.2)dde=0.d0 | ||
| 276 | c determine the bound state energy and eigenfunction | ||
| 277 | call scheq(z,en,ik,nn,mest,mesh,c,thresh,iflag,npr,dde) | ||
| 278 | c scheq operates in rydberg units | ||
| 279 | if(iter.ge.2)de(ispin,i+1,ii)=abs(en-en1) | ||
| 280 | if(iflag.eq.1) goto 400 | ||
| 281 | 163 ebound(ispin,i+1,ii)=en/2.d0 | ||
| 282 | nlp(ispin,i+1,ii)=npr | ||
| 283 | do 9188 ji=1,n | ||
| 284 | dval(ispin,ji)=dval(ispin,ji)+rnocc(ispin,i+1,ii)*snlo(ji)**2/sf | ||
| 285 | j*nval(ispin,i+1,ii) | ||
| 286 | ddval(ispin,ji)=ddval(ispin,ji)+rnocc(ispin,i+1,ii)*snlo(ji)**2/ | ||
| 287 | j sf*ndval(ispin,i+1,ii) | ||
| 288 | dcore(ispin,ji)=dcore(ispin,ji)+rnocc(ispin,i+1,ii)*snlo(ji)**2/ | ||
| 289 | j sf*(1-ndval(ispin,i+1,ii))*(1-nval(ispin,i+1,ii)) | ||
| 290 | 9188 db(ispin,ji)=db(ispin,ji)+rnocc(ispin,i+1,ii)*snlo(ji)**2/sf | ||
| 291 | 918 continue | ||
| 292 | do 919 ji=2,n | ||
| 293 | dcore(ispin,ji)=dcore(ispin,ji)/r(ji)**2 | ||
| 294 | 919 db(ispin,ji)=db(ispin,ji)/r(ji)**2 | ||
| 295 | db(ispin,1)=db(ispin,2) | ||
| 296 | dcore(ispin,1)=dcore(ispin,2) | ||
| 297 | do 5739 ji=2,n | ||
| 298 | ddval(ispin,ji)=ddval(ispin,ji)/r(ji)**2 | ||
| 299 | 5739 dval(ispin,ji)=dval(ispin,ji)/r(ji)**2 | ||
| 300 | dval(ispin,1)=dval(ispin,2) | ||
| 301 | ddval(ispin,1)=ddval(ispin,2) | ||
| 302 | 917 continue | ||
| 303 | if(iys.eq.2)go to 923 | ||
| 304 | do 921 i=1,n | ||
| 305 | dval(2,i)=dval(1,i) | ||
| 306 | ddval(2,i)=ddval(1,i) | ||
| 307 | dcore(2,i)=dcore(1,i) | ||
| 308 | 921 db(2,i)=db(1,i) | ||
| 309 | lmm=lm(1) | ||
| 310 | lm(2)=lm(1) | ||
| 311 | do 922 i=0,lmm | ||
| 312 | nii=nbound(1,i+1) | ||
| 313 | nbound(2,i+1)=nii | ||
| 314 | do 922 ii=1,nii | ||
| 315 | 922 ebound(2,i+1,ii)=ebound(1,i+1,ii) | ||
| 316 | 923 continue | ||
| 317 | 8 format(' ',i6,' energy: ',f12.5,' iteration loops: ',i4) | ||
| 318 | c | ||
| 319 | c total bound state energy | ||
| 320 | c | ||
| 321 | c write(6,*) 'Total energy starts' | ||
| 322 | c call flush(6) | ||
| 323 | 661 eb=0.d0 | ||
| 324 | ebv=0.d0 | ||
| 325 | write(66,7496) | ||
| 326 | 7496 format(//' bound states'/) | ||
| 327 | do 673 ispin=1,2 | ||
| 328 | lmm=lm(ispin) | ||
| 329 | do 673 i=0,lmm | ||
| 330 | nii=nbound(ispin,i+1) | ||
| 331 | do 673 j=1,nii | ||
| 332 | nn=i+j | ||
| 333 | nnlz=100*nn+10*i | ||
| 334 | eb=eb+ebound(ispin,i+1,j)*rnocc(ispin,i+1,j) | ||
| 335 | ebv=ebv+ebound(ispin,i+1,j)*rnocc(ispin,i+1,j)* | ||
| 336 | j (nval(ispin,i+1,j)+ndval(ispin,i+1,j)) | ||
| 337 | if(rnocc(ispin,i+1,j).lt.0.1d0) go to 673 | ||
| 338 | write(66,8) nnlz,ebound(ispin,i+1,j),nlp(ispin,i+1,j) | ||
| 339 | 673 continue | ||
| 340 | go to 679 | ||
| 341 | 674 write(66,676) | ||
| 342 | 676 format('0no bound states') | ||
| 343 | 679 continue | ||
| 344 | c | ||
| 345 | c total charge and spin densities | ||
| 346 | c computing energy integrals | ||
| 347 | c | ||
| 348 | 506 continue | ||
| 349 | c========================================= | ||
| 350 | c gga | ||
| 351 | c set the "done" controle variables to false in the beginning of | ||
| 352 | c each iteration | ||
| 353 | |||
| 354 | if (ixc.eq.2) then | ||
| 355 | doned = .false. | ||
| 356 | donela = .false. | ||
| 357 | donegr = .false. | ||
| 358 | donez = .false. | ||
| 359 | donec = .false. | ||
| 360 | endif | ||
| 361 | c gga | ||
| 362 | c======================================== | ||
| 363 | do 660 i=2,n | ||
| 364 | roo(i)=db(1,i)+db(2,i) | ||
| 365 | rr=roo(i) | ||
| 366 | c When db = (0,0) then the spin-polarization, spl = 0, and not 0/0. | ||
| 367 | if (rr.gt.0.0000000001) then | ||
| 368 | spl(i)=(db(1,i)-db(2,i))/rr | ||
| 369 | else | ||
| 370 | spl(i)=0.0 | ||
| 371 | endif | ||
| 372 | x1=r(i)**2 | ||
| 373 | apu(i)=x1*veff(1,i)*db(1,i)*sf | ||
| 374 | bpu(i)=x1*veff(2,i)*db(2,i)*sf | ||
| 375 | if (ixc.eq.2) then | ||
| 376 | c================================================================ | ||
| 377 | c gga | ||
| 378 | c calculate the gga exchange-correlation energy | ||
| 379 | |||
| 380 | call ggaexc(r,db,i,1,n,doned,excgga(i)) | ||
| 381 | cpu(i) = x1*rr*excgga(i)*sf | ||
| 382 | c gga | ||
| 383 | c================================================================ | ||
| 384 | else | ||
| 385 | cpu(i)=x1*rr*exc(rr,spl(i),ixc)*sf | ||
| 386 | endif | ||
| 387 | dpu(i)=x1*spl(i)*rr*sf | ||
| 388 | 660 continue | ||
| 389 | 26 format(' induced moment: ',f10.5) | ||
| 390 | call simpsh(apu,v1) | ||
| 391 | call simpsh(bpu,v2) | ||
| 392 | call simpsh(cpu,eexc) | ||
| 393 | call simpsh(dpu,smom) | ||
| 394 | c | ||
| 395 | c compute coulomb energy | ||
| 396 | c | ||
| 397 | cz=z | ||
| 398 | do 683 i=1,n | ||
| 399 | bpu(i)=roo(i)*r(i)**2*sf | ||
| 400 | dpu(i)=(dval(1,i)+dval(2,i))*r(i)**2*sf | ||
| 401 | apu(i)=(ddval(1,i)+ddval(2,i))*r(i)**2*sf | ||
| 402 | cpu(i)=roo(i)*(r(i)**2*vc(i)-z*r(i))*sf/2.d0 | ||
| 403 | 683 continue | ||
| 404 | call simpsh(dpu,sum1) | ||
| 405 | call simpsh(apu,sum3) | ||
| 406 | call simpsh(bpu,sum2) | ||
| 407 | call simpsh(cpu,ec) | ||
| 408 | 24 format(' kin: ',2(e14.6,1x),' coul: ',e14.6,' exc: ',e14.6) | ||
| 409 | 25 format(/' total energy: ',e15.7) | ||
| 410 | write(66,192) sum2,sum1,sum3 | ||
| 411 | write(66,26) smom | ||
| 412 | ekin(1)=-v1 | ||
| 413 | ekin(2)=-v2 | ||
| 414 | etot=ekin(1)+ekin(2)+eb+ec+eexc | ||
| 415 | write(66,7453) | ||
| 416 | 7453 format(/' energy terms') | ||
| 417 | write(66,622)eb | ||
| 418 | 622 format(' energy eigenvalue sum: ',e14.6) | ||
| 419 | write(66,24) ekin(1),ekin(2),ec,eexc | ||
| 420 | write(66,25) etot | ||
| 421 | c write(6,2573) itt,sum2,etot | ||
| 422 | c call flush(6) | ||
| 423 | c2573 format(' iter:',i4,' total ch:',f6.2,' total en:',f15.7) | ||
| 424 | write(6,2573) itt,etot | ||
| 425 | call flush(6) | ||
| 426 | 2573 format(' ',i4,' ',f15.5) | ||
| 427 | |||
| 428 | if(iter.ne.1 .and. iter.lt.itr) goto 167 | ||
| 429 | if(iout.lt.0)go to 167 | ||
| 430 | write(66,17) | ||
| 431 | 192 format(/' integr charges: total ',f10.7,' valence: ',2f10.7) | ||
| 432 | do 166 i=1,n,ipr | ||
| 433 | r22=r(i)*r(i) | ||
| 434 | db1=db(1,i) | ||
| 435 | db2=db(2,i) | ||
| 436 | dr=db1+db2 | ||
| 437 | dcc=dcore(1,i)+dcore(2,i) | ||
| 438 | dvv=dval(1,i)+dval(2,i)+ddval(1,i)+ddval(2,i) | ||
| 439 | ddb=db1-db2 | ||
| 440 | c166 write(66,1624) r(i),db1,db2,dval(i),ddval(i),dr,ddb | ||
| 441 | 166 write(66,1624) r(i),db1,db2,dr,dcc,dvv | ||
| 442 | c | ||
| 443 | c | ||
| 444 | c compute coulomb potential | ||
| 445 | c | ||
| 446 | 167 do 55 i=2,n | ||
| 447 | 55 vc(i)=r(i)*vc(i)+zion | ||
| 448 | c write(6,*) 'Coulomb potential' | ||
| 449 | c call flush(6) | ||
| 450 | zi=z-zion | ||
| 451 | vc(1)=-zi | ||
| 452 | call scrhs(roo,vc,zi,qsc,n) | ||
| 453 | do 50 i=2,n | ||
| 454 | 50 vc(i)=(vc(i)-zion)/r(i) | ||
| 455 | c | ||
| 456 | c set up the total potential | ||
| 457 | c | ||
| 458 | do 60 i=2,n | ||
| 459 | dr=roo(i) | ||
| 460 | vc(i)=(1.d0-fback)*vcold(i)+fback*vc(i) | ||
| 461 | vcold(i)=vc(i) | ||
| 462 | if (ixc.eq.2) then | ||
| 463 | c================================================================ | ||
| 464 | c gga | ||
| 465 | c calculate the gga exchange-correlation potential | ||
| 466 | |||
| 467 | call ggauxc(r,db,spl,i,1,n,donela,donegr,donez, | ||
| 468 | j uxcup(i),uxcdn(i)) | ||
| 469 | ux1(i) = uxcup(i) | ||
| 470 | ux2(i) = uxcdn(i) | ||
| 471 | c gga | ||
| 472 | c================================================================ | ||
| 473 | else | ||
| 474 | ux1(i)=uxc(dr,spl(i),1,ixc) | ||
| 475 | ux2(i)=uxc(dr,spl(i),2,ixc) | ||
| 476 | endif | ||
| 477 | 6848 veff(1,i)=vc(i)+ux1(i) | ||
| 478 | veff(2,i)=vc(i)+ux2(i) | ||
| 479 | do 60 ispin=1,2 | ||
| 480 | veff(ispin,i)=(1.d0-fback)*vold(ispin,i)+fback*veff(ispin,i) | ||
| 481 | 60 vold(ispin,i)=veff(ispin,i) | ||
| 482 | c calculate the valence energy | ||
| 483 | do 5100 i=2,mesh | ||
| 484 | do 5110 j=1,mesh | ||
| 485 | apu(j)=0.d0 | ||
| 486 | if(i.le.j)apu(j)=(dval(1,j)+dval(2,j)+ddval(1,j)+ddval(2,j))* | ||
| 487 | j (r(j)**2/r(i)-r(j)) | ||
| 488 | 5110 continue | ||
| 489 | call simpsh(apu,vp) | ||
| 490 | 5100 vhv(i)=-vp*4.d0*pi+zv/r(i) | ||
| 491 | do 5130 i=1,mesh | ||
| 492 | x1=r(i)**2 | ||
| 493 | rr=db(1,i)+db(2,i) | ||
| 494 | spt=0.d0 | ||
| 495 | if(rr.gt.1.d-10)spt=(db(1,i)-db(2,i))/rr | ||
| 496 | rrv=dval(1,i)+dval(2,i)+ddval(1,i)+ddval(2,i) | ||
| 497 | spv=0.d0 | ||
| 498 | if(rrv.gt.1.d-10)spv=(dval(1,i)-dval(2,i)+ddval(1,i)-ddval(2,i)) | ||
| 499 | j /rrv | ||
| 500 | rrc=dcore(1,i)+dcore(2,i) | ||
| 501 | spc=0.d0 | ||
| 502 | if(rrc.gt.1.d-10)spc=(dcore(1,i)-dcore(2,i))/rrc | ||
| 503 | apu(i)=-0.5d0*x1*sf*rrv*vhv(i) | ||
| 504 | if (ixc.eq.2) then | ||
| 505 | c============================================================= | ||
| 506 | c gga | ||
| 507 | c calculate the gga exchange-correlation energy for core electrons | ||
| 508 | |||
| 509 | if (rrc.lt.1.d-100) then | ||
| 510 | excgac = 0.d0 | ||
| 511 | else | ||
| 512 | call ggaexc(r,dcore,i,1,n,donec,excgac) | ||
| 513 | endif | ||
| 514 | bpu(i)=x1*rr*excgga(i)*sf | ||
| 515 | cpu(i)=-x1*rrc*excgac*sf | ||
| 516 | fpu(i)=(dcore(1,i)+dcore(2,i))*excgga(i)*x1*sf | ||
| 517 | dpu(i)=(-(dval(1,i)+ddval(1,i))*uxcup(i) | ||
| 518 | j -(dval(2,i)+ddval(2,i))*uxcdn(i))*sf*x1 | ||
| 519 | c gga | ||
| 520 | c================================================================== | ||
| 521 | else | ||
| 522 | bpu(i)=x1*rr*exc(rr,spt,ixc)*sf | ||
| 523 | cpu(i)=-x1*rrc*exc(rrc,spc,ixc)*sf | ||
| 524 | fpu(i)=(dcore(1,i)+dcore(2,i))*exc(rr,spt,ixc)*x1*sf | ||
| 525 | dpu(i)=(-(dval(1,i)+ddval(1,i))*uxc(rr,spt,1,ixc) | ||
| 526 | j -(dval(2,i)+ddval(2,i))*uxc(rr,spt,2,ixc))*sf*x1 | ||
| 527 | endif | ||
| 528 | epu(i)=apu(i)+bpu(i)+cpu(i)+dpu(i)+fpu(i) | ||
| 529 | 5130 continue | ||
| 530 | c call simpsh(apu,ec) | ||
| 531 | c call simpsh(bpu,eext) | ||
| 532 | c call simpsh(fpu,eexx) | ||
| 533 | c call simpsh(cpu,eexc) | ||
| 534 | c call simpsh(dpu,eexv) | ||
| 535 | c etv=ebv+ec+eext+eexc+eexv | ||
| 536 | call simpsh(epu,etv) | ||
| 537 | etv = etv + ebv | ||
| 538 | write(66,5140)etv | ||
| 539 | 5140 format(' valence energy:',e15.7) | ||
| 540 | if(iter.ne.1 .and. iter.lt.itr) go to 100 | ||
| 541 | if(iout.lt.0)go to 100 | ||
| 542 | write(66,18) itt | ||
| 543 | do 75 i=2,n,ipr | ||
| 544 | dr=roo(i) | ||
| 545 | 75 write(66,1624) r(i),vc(i),ux1(i),ux2(i),veff(1,i),veff(2,i) | ||
| 546 | 1624 format(1x,f12.5,6e14.5) | ||
| 547 | goto 100 | ||
| 548 | 400 continue | ||
| 549 | c | ||
| 550 | c | ||
| 551 | c | ||
| 552 | do 1140 i=2,mesh | ||
| 553 | do 1130 j=1,mesh | ||
| 554 | apu(j)=0.d0 | ||
| 555 | if(i.le.j)apu(j)=(db(1,j)+db(2,j))*(r(j)**2/r(i)-r(j)) | ||
| 556 | 1130 continue | ||
| 557 | call simpsh(apu,vp) | ||
| 558 | 1140 vc(i)=-vp*sf | ||
| 559 | write(22,1645)itt,z,zion,jblock,nbl,c | ||
| 560 | write(44,1645)itt,z,zion,jblock,nbl,c | ||
| 561 | do 900 i=1,n | ||
| 562 | dd=db(1,i)+db(2,i) | ||
| 563 | dc=dcore(1,i)+dcore(2,i) | ||
| 564 | dddc = dd + dc | ||
| 565 | dv1=dval(1,i)+dval(2,i) | ||
| 566 | ddv1=ddval(1,i)+ddval(2,i) | ||
| 567 | vve = 0.5d00*(veff(1,i) + veff(2,i)) | ||
| 568 | write(44,*) r(i), vc(i), vve, dddc | ||
| 569 | c The line below writes total and core densities to atomdens.dat (J.H.) | ||
| 570 | write(77,906) r(i), 4*pi*dd*r(i)*r(i), 4*pi*dc*r(i)*r(i) | ||
| 571 | write(22,907)vc(i),veff(1,i),veff(2,i),dddc,r(i) | ||
| 572 | 900 continue | ||
| 573 | 907 format(6e15.7) | ||
| 574 | c900 write(22,906)vc(i),veff(1,i),veff(2,i),dd,dc | ||
| 575 | c900 write(22,906)vc(i),veff(1,i),veff(2,i),dd,dv1,ddv1 | ||
| 576 | 906 format(6e20.12) | ||
| 577 | write(6,*) '================================' | ||
| 578 | call flush(6) | ||
| 579 | c ieeer=ieee_flags('clear','exception','all',ieeeout) | ||
| 580 | close(6) | ||
| 581 | close(22) | ||
| 582 | close(33) | ||
| 583 | close(55) | ||
| 584 | close(66) | ||
| 585 | close(77) | ||
| 586 | stop | ||
| 587 | end | ||
diff --git a/src/labat/laplac.f b/src/labat/laplac.f new file mode 100644 index 0000000..9a7dfd9 --- /dev/null +++ b/src/labat/laplac.f | |||
| @@ -0,0 +1,41 @@ | |||
| 1 | subroutine laplac(r,gradup,graddn,i,imin,imax,done, | ||
| 2 | j lapl,laplup,lapldn) | ||
| 3 | c calculates laplace(density), i.e. (del^2)(density) | ||
| 4 | c spherical coordinates => (del^2)phi = 1/r^2*d/dr[r^2*d(phi)/dr] | ||
| 5 | c input r : radial coordinate (array) | ||
| 6 | c input gradup : grad(density), spin up (array) | ||
| 7 | c input graddn : grad(density), spin down (array) | ||
| 8 | c input i : counter, i.e. current position = r(i) | ||
| 9 | c input imin : min value of i | ||
| 10 | c input imax : max value of i | ||
| 11 | c in/output done : true if r^2*grad(density) is splined | ||
| 12 | c output lapl : laplace(density) | ||
| 13 | c output laplup,lapldn : laplace(density), spin up and down | ||
| 14 | implicit logical (a-z) | ||
| 15 | logical done | ||
| 16 | double precision r,gradup,graddn,lapl,laplup,lapldn,lapl2,temp | ||
| 17 | double precision rj2,r2,deriv | ||
| 18 | integer i,imin,imax,j | ||
| 19 | common/ggalap/temp,lapl2 | ||
| 20 | dimension r(561),gradup(561),graddn(561) | ||
| 21 | dimension lapl2(2,561),temp(2,561) | ||
| 22 | if (.not.done) then | ||
| 23 | do 10 j = imin,imax | ||
| 24 | rj2 = r(j)**2 | ||
| 25 | temp(1,j) = rj2*gradup(j) | ||
| 26 | temp(2,j) = rj2*graddn(j) | ||
| 27 | 10 continue | ||
| 28 | call spline(r,imin+1,imax,temp,lapl2) | ||
| 29 | done = .true. | ||
| 30 | endif | ||
| 31 | if (i.eq.imin) then | ||
| 32 | call laplac2(r,gradup,graddn,i+1,imin,imax,done,lapl,laplup, | ||
| 33 | j lapldn) | ||
| 34 | else | ||
| 35 | r2 = r(i)**2 | ||
| 36 | laplup = (deriv(r,temp,lapl2,1,i,imin,imax))/r2 | ||
| 37 | lapldn = (deriv(r,temp,lapl2,-1,i,imin,imax))/r2 | ||
| 38 | lapl = laplup + lapldn | ||
| 39 | endif | ||
| 40 | return | ||
| 41 | end | ||
diff --git a/src/labat/laplac2.f b/src/labat/laplac2.f new file mode 100644 index 0000000..f2cce8b --- /dev/null +++ b/src/labat/laplac2.f | |||
| @@ -0,0 +1,11 @@ | |||
| 1 | subroutine laplac2(r,gradup,graddn,i,imin,imax,done, | ||
| 2 | j lapl,laplup,lapldn) | ||
| 3 | implicit logical (a-z) | ||
| 4 | logical done | ||
| 5 | double precision r,gradup,graddn,lapl,laplup,lapldn | ||
| 6 | integer i,imin,imax | ||
| 7 | dimension r(561),gradup(561),graddn(561) | ||
| 8 | call laplac(r,gradup,graddn,i+1,imin,imax,done,lapl,laplup, | ||
| 9 | j lapldn) | ||
| 10 | return | ||
| 11 | end | ||
diff --git a/src/labat/ldaec.f b/src/labat/ldaec.f new file mode 100644 index 0000000..01e18ca --- /dev/null +++ b/src/labat/ldaec.f | |||
| @@ -0,0 +1,21 @@ | |||
| 1 | subroutine ldaec(rs,zet,ec) | ||
| 2 | c uniform-gas correlation of perdew and wang 1991 | ||
| 3 | c calculates the local correlation energy within the lda approx. | ||
| 4 | c input rs : seitz radius | ||
| 5 | c input zet : relative spin polarization | ||
| 6 | c output ec : correlation energy per electron | ||
| 7 | implicit double precision (a-h,o-z) | ||
| 8 | data gam,fzz/0.5198421d0,1.709921d0/ | ||
| 9 | data thrd4/1.333333333333d0/ | ||
| 10 | f = ((1.d0+zet)**thrd4+(1.d0-zet)**thrd4-2.d0)/gam | ||
| 11 | call gcor(0.0310907d0,0.21370d0,7.5957d0,3.5876d0,1.6382d0, | ||
| 12 | 1 0.49294d0,1.00d0,rs,eu,eurs) | ||
| 13 | call gcor(0.01554535d0,0.20548d0,14.1189d0,6.1977d0,3.3662d0, | ||
| 14 | 1 0.62517d0,1.00d0,rs,ep,eprs) | ||
| 15 | call gcor(0.0168869d0,0.11125d0,10.357d0,3.6231d0,0.88026d0, | ||
| 16 | 1 0.49671d0,1.00d0,rs,alfm,alfrsm) | ||
| 17 | c alfm is minus the spin stiffness alfc | ||
| 18 | z4 = zet**4 | ||
| 19 | ec = eu*(1.d0-f*z4)+ep*f*z4-alfm*f*(1.d0-z4)/fzz | ||
| 20 | return | ||
| 21 | end | ||
diff --git a/src/labat/ldauc.f b/src/labat/ldauc.f new file mode 100644 index 0000000..4285c9a --- /dev/null +++ b/src/labat/ldauc.f | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | subroutine ldauc(rs,zet,ec,ecrs,eczet,vcup,vcdn) | ||
| 2 | c uniform-gas correlation of perdew and wang 1991 | ||
| 3 | c calculates the local correlation potential within the lda approx. | ||
| 4 | c input rs : seitz radius | ||
| 5 | c input zet : relative spin polarization | ||
| 6 | c output ec : correlation energy | ||
| 7 | c output ecrs : derivative of ec with respect to rs | ||
| 8 | c output eczet : derivative of ec with respect to zet | ||
| 9 | c output vcup, vcdn : up- and down-spin potentials | ||
| 10 | implicit double precision (a-h,o-z) | ||
| 11 | data gam,fzz/0.5198421d0,1.709921d0/ | ||
| 12 | data thrd,thrd4/0.333333333333d0,1.333333333333d0/ | ||
| 13 | f = ((1.d0+zet)**thrd4+(1.d0-zet)**thrd4-2.d0)/gam | ||
| 14 | call gcor(0.0310907d0,0.21370d0,7.5957d0,3.5876d0,1.6382d0, | ||
| 15 | 1 0.49294d0,1.00d0,rs,eu,eurs) | ||
| 16 | call gcor(0.01554535d0,0.20548d0,14.1189d0,6.1977d0,3.3662d0, | ||
| 17 | 1 0.62517d0,1.00d0,rs,ep,eprs) | ||
| 18 | call gcor(0.0168869d0,0.11125d0,10.357d0,3.6231d0,0.88026d0, | ||
| 19 | 1 0.49671d0,1.00d0,rs,alfm,alfrsm) | ||
| 20 | c alfm is minus the spin stiffness alfc | ||
| 21 | z4 = zet**4 | ||
| 22 | ec = eu*(1.d0-f*z4)+ep*f*z4-alfm*f*(1.d0-z4)/fzz | ||
| 23 | c energy done. now the potential: | ||
| 24 | ecrs = eurs*(1.d0-f*z4)+eprs*f*z4-alfrsm*f*(1.d0-z4)/fzz | ||
| 25 | fz = thrd4*((1.d0+zet)**thrd-(1.d0-zet)**thrd)/gam | ||
| 26 | eczet = 4.d0*(zet**3)*f*(ep-eu+alfm/fzz)+fz*(z4*ep-z4*eu | ||
| 27 | 1 -(1.d0-z4)*alfm/fzz) | ||
| 28 | comm = ec -rs*ecrs/3.d0-zet*eczet | ||
| 29 | vcup = comm + eczet | ||
| 30 | vcdn = comm - eczet | ||
| 31 | return | ||
| 32 | end | ||
diff --git a/src/labat/resten.f b/src/labat/resten.f new file mode 100644 index 0000000..8314dad --- /dev/null +++ b/src/labat/resten.f | |||
| @@ -0,0 +1,634 @@ | |||
| 1 | c ********************************************************************* | ||
| 2 | subroutine scheq(zz,en,lambda,nofl,kkk,mess,scf,thresh,iflag,npr | ||
| 3 | 1,de) | ||
| 4 | implicit double precision (a-h,o-z) | ||
| 5 | c subroutine scheq | ||
| 6 | c compute energy eigenvalue and wave function | ||
| 7 | c originally written by sherwood skillman | ||
| 8 | c rca laboratories, princeton, new jersey, spring 1961 | ||
| 9 | c modified by frank herman, summer 1961 | ||
| 10 | c further modified by richard kortum and paul kelly, lockheed | ||
| 11 | c research laboratories, palo alto, california, summer 1962 | ||
| 12 | c further modified by r.m. nieminen, otaniemi,spring 1978 | ||
| 13 | c and last but not least modified by m.p. winter 1979 | ||
| 14 | dimension qq(561),p(5),q(5),t(5),d(5) | ||
| 15 | common/sc/gr(561),r(561),snlo(561),nbl | ||
| 16 | common/pot/v(561) | ||
| 17 | imp=1 | ||
| 18 | nb1=nbl+1 | ||
| 19 | nmb=nb1/5 | ||
| 20 | if (de.lt.1.d-10)imp=0 | ||
| 21 | if(imp.eq.1)de=dmax1(de,-e/500.d0) | ||
| 22 | eg=0.d0 | ||
| 23 | z=zz | ||
| 24 | lam=lambda | ||
| 25 | nn=nofl | ||
| 26 | mesh=mess | ||
| 27 | c=scf | ||
| 28 | i0=0 | ||
| 29 | many = 150 | ||
| 30 | iflag=0 | ||
| 31 | 73 e=en | ||
| 32 | morev=0 | ||
| 33 | lessv=0 | ||
| 34 | emore=0.0d0 | ||
| 35 | eless=0.0d0 | ||
| 36 | more=0 | ||
| 37 | less=0 | ||
| 38 | mp=0 | ||
| 39 | nprint=0 | ||
| 40 | lamm=lam-1 | ||
| 41 | lamp=lam+1 | ||
| 42 | xlp=lamp | ||
| 43 | ndcr=nn-lamp | ||
| 44 | b=lam*lamp | ||
| 45 | oc=r(2) | ||
| 46 | h=oc | ||
| 47 | hsq=h*h | ||
| 48 | b3=(v(3)-v(2))/h-z/hsq | ||
| 49 | y=h+h | ||
| 50 | flps=4*lam+6 | ||
| 51 | slpt=6*lam+12 | ||
| 52 | elpt=8*lam+20 | ||
| 53 | a1=-z/xlp | ||
| 54 | ysq=y*y | ||
| 55 | b1=-z-z | ||
| 56 | ab1=a1*b1 | ||
| 57 | ab3=a1*b3 | ||
| 58 | c raise h and y to lam+1 | ||
| 59 | htl=h | ||
| 60 | ytl=y | ||
| 61 | if(lam)77,1102,1100 | ||
| 62 | 1100 do 1101 i=1,lam | ||
| 63 | htl=htl*h | ||
| 64 | 1101 ytl=ytl*y | ||
| 65 | 1102 h1=hsq | ||
| 66 | bohs=b/hsq | ||
| 67 | boh=b1/h | ||
| 68 | bth=b3*h | ||
| 69 | bq3=bohs+boh+bth | ||
| 70 | bq4=bohs/4.d0+boh/2.d0+bth+bth | ||
| 71 | epl=8+lam | ||
| 72 | fpl=5+lam | ||
| 73 | xifc=c*.21701389d-4 | ||
| 74 | c start outward integration | ||
| 75 | 10 nprint=nprint+1 | ||
| 76 | eps =e-eg | ||
| 77 | eg =e | ||
| 78 | if(many-nprint) 900,75,75 | ||
| 79 | 900 if(mp.eq.2)go to 300 | ||
| 80 | write (6,901)nn,lam ,z | ||
| 81 | call flush(6) | ||
| 82 | 901 format (21h no convergence on,i4,i1,f4.0) | ||
| 83 | iflag=1 | ||
| 84 | en=0.d0 | ||
| 85 | npr=nprint | ||
| 86 | return | ||
| 87 | 77 nstop=7 | ||
| 88 | 777 write(66,770) nstop | ||
| 89 | 770 format(' error in scheq',i6) | ||
| 90 | en=0.d0 | ||
| 91 | iflag=1 | ||
| 92 | npr=nprint | ||
| 93 | return | ||
| 94 | 75 do 11 i=1,mesh | ||
| 95 | 11 snlo(i)=0.0d0 | ||
| 96 | if(nprint-1) 77,500,529 | ||
| 97 | 500 continue | ||
| 98 | do 502 i= 4,mesh | ||
| 99 | qq(i) = v(i)+b/(r(i)*r(i))-e | ||
| 100 | 502 continue | ||
| 101 | 516 m= mesh | ||
| 102 | do 520 i=4,mesh | ||
| 103 | if(qq(m)) 519,520,520 | ||
| 104 | 519 ik=m+1 | ||
| 105 | go to 525 | ||
| 106 | 520 m=m-1 | ||
| 107 | write(66,562)lam,qq(m+1),e | ||
| 108 | 562 format(/' l: ',i5,' q: ',g15.6,' e: ',g15.6/) | ||
| 109 | 521 nstop =521 | ||
| 110 | c q is everywhere positive | ||
| 111 | go to 777 | ||
| 112 | 525 if(mesh-ik) 526,526,535 | ||
| 113 | 526 eps = qq(mesh-nbl) | ||
| 114 | e = e+eps | ||
| 115 | 529 continue | ||
| 116 | do 530 i=4,mesh | ||
| 117 | 530 qq(i) = qq(i)-eps | ||
| 118 | go to 516 | ||
| 119 | 535 continue | ||
| 120 | 14 ncross=0 | ||
| 121 | sig=1.0d0 | ||
| 122 | h=oc | ||
| 123 | y=h+h | ||
| 124 | c b= lam*(lam+1) | ||
| 125 | c b1= -2.d0*z | ||
| 126 | b2=3.0d0*z/h-e+2.0d0*v(2)-v(3) | ||
| 127 | c b3=(v(3)-v(2))/h -z/hsq | ||
| 128 | c a1= -z/(lam+1) | ||
| 129 | a2=(ab1+b2)/flps | ||
| 130 | c a2=(a1*b1+b2)/(4*lam+6) | ||
| 131 | a3=(a2*b1+a1*b2+b3)/slpt | ||
| 132 | c a3=(a2*b1+a1*b2+b3)/(6*lam+12) | ||
| 133 | a4=(a3*b1+a2*b2+ab3)/elpt | ||
| 134 | c a4=(a3*b1+a2*b2+a1*b3)/(8*lam+20) | ||
| 135 | p(3)=(1.0d0+h*(a1+h*(a2+h*(a3+h*a4))))*htl | ||
| 136 | c p(3)=(1.0d0+a1*h+a2*h**2+a3*h**3+a4*h**4)*h**(xl+1.0d0) | ||
| 137 | p(4)=(1.0d0+y*(a1+y*(a2+y*(a3+y*a4))))*ytl | ||
| 138 | c p(4)=(1.0d0+a1*y+a2*y**2+a3*y**3+a4*y**4)*y**(xl+1.0d0) | ||
| 139 | q(3)=bq3+b2 | ||
| 140 | c q(3)=(b+b1*h+b2*h**2+b3*h**3)/h**2 | ||
| 141 | q(4)=bq4+b2 | ||
| 142 | c q(4)=(b+b1*y+b2*y**2+b3*y**3)/y**2 | ||
| 143 | snlo(2)=p(3) | ||
| 144 | snlo(3)=p(4) | ||
| 145 | i=3 | ||
| 146 | dx=oc | ||
| 147 | h1=h**2 | ||
| 148 | h2=h1/12.0d0 | ||
| 149 | t(3)=p(3)*(1.0d0-h2*q(3)) | ||
| 150 | t(4)=p(4)*(1.0d0-h2*q(4)) | ||
| 151 | d(4)=t(4)-t(3) | ||
| 152 | ncount=3 | ||
| 153 | nint=2 | ||
| 154 | 15 i=i+1 | ||
| 155 | c if end of mesh is reached, modify trial eigenvalue | ||
| 156 | if(i-mesh) 16,3,3 | ||
| 157 | 3 if(ndcr-ncross) 32,33,33 | ||
| 158 | c return to begininning of outward integration if necessary | ||
| 159 | 16 q(5) =qq(i) | ||
| 160 | if(ik-i) 29,29,21 | ||
| 161 | 21 d(5)=d(4)+h1*q(4)*p(4) | ||
| 162 | t(5)=d(5)+t(4) | ||
| 163 | if(1.0d0-abs (h2*q(5))) 3,3,501 | ||
| 164 | 501 p(5)=t(5)/(1.0d0-h2*q(5)) | ||
| 165 | snlo(i) = p(5) | ||
| 166 | if(sig) 211,77,212 | ||
| 167 | 211 if(p(5)) 23,23,22 | ||
| 168 | 212 if(p(5)) 22,23,23 | ||
| 169 | 22 ncross=ncross+1 | ||
| 170 | c count changes in sign | ||
| 171 | sig=-sig | ||
| 172 | 23 ncount=ncount+1 | ||
| 173 | if(7-ncount)77,24,25 | ||
| 174 | 24 ncount=2 | ||
| 175 | 25 nint=nint+1 | ||
| 176 | if(nbl-nint)77,26,27 | ||
| 177 | 26 dx=dx+dx | ||
| 178 | h=dx | ||
| 179 | h1=h**2 | ||
| 180 | h2=h1/12.0d0 | ||
| 181 | nint=0 | ||
| 182 | t(5)=p(5)*(1.0d0-h2*q(5)) | ||
| 183 | t(3)=p(3)*(1.0d0-h2*q(3)) | ||
| 184 | d(5)=t(5)-t(3) | ||
| 185 | 27 do 28 k=1,4 | ||
| 186 | p(k)=p(k+1) | ||
| 187 | t(k)=t(k+1) | ||
| 188 | d(k)=d(k+1) | ||
| 189 | 28 q(k)=q(k+1) | ||
| 190 | go to 15 | ||
| 191 | 29 if(ncount-2)77,30,21 | ||
| 192 | 30 if(nint-4)21,21,31 | ||
| 193 | c matching radius has been reached going out | ||
| 194 | c if ndcr not equal to ncross,modify trial eigenvalue | ||
| 195 | 31 eigen=e | ||
| 196 | if(ndcr-ncross) 32,35,33 | ||
| 197 | 32 more=1 | ||
| 198 | mp=0 | ||
| 199 | c too many crossings, increase absf(e) | ||
| 200 | morev=morev+1 | ||
| 201 | if(morev-1) 50,53,52 | ||
| 202 | 50 nstop=50 | ||
| 203 | go to 777 | ||
| 204 | 52 if(e -emore) 53,54,54 | ||
| 205 | 53 emore=e | ||
| 206 | 54 if (less) 55,56,64 | ||
| 207 | 55 nstop=55 | ||
| 208 | go to 777 | ||
| 209 | 56 e=1.25d0*eg | ||
| 210 | go to 10 | ||
| 211 | 33 less=1 | ||
| 212 | mp=0 | ||
| 213 | c too few crossings, decrease abs (e) | ||
| 214 | lessv=lessv+1 | ||
| 215 | if(lessv-1) 57,60,59 | ||
| 216 | 57 nstop=57 | ||
| 217 | go to 777 | ||
| 218 | 59 if(eless- e) 60,61,61 | ||
| 219 | 60 eless=e | ||
| 220 | 61 if(more) 62,63,64 | ||
| 221 | 62 nstop=62 | ||
| 222 | go to 777 | ||
| 223 | 63 e=0.75d0*eg | ||
| 224 | go to 10 | ||
| 225 | 64 e=0.5d0*(emore+eless) | ||
| 226 | go to 10 | ||
| 227 | 35 if(abs (snlo(i-1))-abs (snlo(i-2))) 351,354,354 | ||
| 228 | c check to see that wave is in the damped region (absolute value | ||
| 229 | c decreasing and signs alike) | ||
| 230 | 351 if (p(5)) 352,21 ,353 | ||
| 231 | 352 if(snlo(i-2)) 401,21,21 | ||
| 232 | 353 if(snlo(i-2)) 21,21,401 | ||
| 233 | 354 if(1.0d+25 -abs (p(5)))33,33,21 | ||
| 234 | c large absolute value of p in what should be the damped region | ||
| 235 | c indicates too few peaks, decrease absf(e) | ||
| 236 | c now ndcr = ncross and matching radius lies in damped region | ||
| 237 | 401 imatch=i-2 | ||
| 238 | xmatch=r(i-2) | ||
| 239 | ppout=(t(4)-t(2)-0.5d0*(p(4)-p(2)))/h | ||
| 240 | s2=ppout/p(3) | ||
| 241 | c integration is by 8 applications of newton-cotes closed | ||
| 242 | c quadrature for five intervals on each block | ||
| 243 | c xifc =(5*h(block 1)/288)/2 ,h(1) =0.0025*scale factor | ||
| 244 | sum1=0.0d0 | ||
| 245 | xif=xifc | ||
| 246 | i=1 | ||
| 247 | value=0.0d0 | ||
| 248 | 36 mm=nmb | ||
| 249 | sum2=0.0d0 | ||
| 250 | xif=xif+xif | ||
| 251 | 37 y=value | ||
| 252 | value=snlo(i+5)**2 | ||
| 253 | sum2=sum2+19.d0*(value+y)+75.d0*(snlo(i+4)**2+snlo(i+1)**2) | ||
| 254 | 1 +50.0d0*(snlo(i+2)**2+snlo(i+3)**2) | ||
| 255 | i=i+5 | ||
| 256 | if (imatch-i) 77,39,371 | ||
| 257 | 371 mm=mm-1 | ||
| 258 | if(mm)77,38,37 | ||
| 259 | 38 sum1=sum2*xif+sum1 | ||
| 260 | go to 36 | ||
| 261 | 39 sum1= sum1+sum2*xif | ||
| 262 | 40 s1=sum1/p(3)**2 | ||
| 263 | pmatch=p(3) | ||
| 264 | if(nn-1)77,41,42 | ||
| 265 | 41 xinw=epl* xmatch | ||
| 266 | c for n =1, start inward integration at(8+lam)*xmatch or x max | ||
| 267 | go to 421 | ||
| 268 | 42 xinw=fpl*xmatch | ||
| 269 | c for n not=1, start at (5+lam)*xmatch or x max (end of mesh) | ||
| 270 | 421 do 44 i= nb1,mesh,nbl | ||
| 271 | if(xinw-r(i)) 43,43,44 | ||
| 272 | 43 kkk =i | ||
| 273 | go to 45 | ||
| 274 | 44 continue | ||
| 275 | kkk =mesh | ||
| 276 | 45 i =kkk | ||
| 277 | dx =r(i-1)-r(i) | ||
| 278 | h =dx | ||
| 279 | xif=0.17361111d-1*dx | ||
| 280 | hsq=h*h | ||
| 281 | hsq12=hsq/12.0d0 | ||
| 282 | q(3)= qq(i) | ||
| 283 | p(3)= exp (-r(i)*sqrt (q(3))) | ||
| 284 | 402 sum3=p(3)/q(3) | ||
| 285 | i=i-1 | ||
| 286 | q(4) =qq(i) | ||
| 287 | 404 p(4)=exp (-r(i)*sqrt (q(4))) | ||
| 288 | if (abs (p(4))-1.0d-35) 4041,4041,405 | ||
| 289 | 4041 kkk=kkk -nbl | ||
| 290 | if(kkk -imatch) 4042,4042,45 | ||
| 291 | 4042 write (5,4043)z ,nn,lam,kkk | ||
| 292 | 4043 format (6hoat z=,f6.0,6h nl =,i3,i1,7h kkk =,i5,22h is less tha | ||
| 293 | 1n imatch =,i5,44h inward integration will be tried at kkk+nbl) | ||
| 294 | kkk =kkk +nbl | ||
| 295 | p(4) = 1.5d-35 | ||
| 296 | p(3) = 1.0d-35 | ||
| 297 | 405 if(pmatch)102,77,103 | ||
| 298 | 102 p(3)=-p(3) | ||
| 299 | p(4)=-p(4) | ||
| 300 | 103 snlo(i+1)=p(3) | ||
| 301 | snlo(i)=p(4) | ||
| 302 | t(3)=p(3)*(1.0d0-hsq12 *q(3)) | ||
| 303 | t(4)=p(4)*(1.0d0-hsq12*q(4)) | ||
| 304 | d(4)=t(4)-t(3) | ||
| 305 | 104 do 106 m=2,nbl | ||
| 306 | i=i-1 | ||
| 307 | q(5) =qq(i) | ||
| 308 | d(5)=hsq*q(4)*p(4)+d(4) | ||
| 309 | t(5)=d(5)+t(4) | ||
| 310 | p(5)=t(5)/(1.0d0-hsq12*q(5)) | ||
| 311 | if(i-imatch+1)77,200,105 | ||
| 312 | 105 snlo(i)=p(5) | ||
| 313 | do 106 k=1,4 | ||
| 314 | p(k)=p(k+1) | ||
| 315 | t(k)=t(k+1) | ||
| 316 | d(k)=d(k+1) | ||
| 317 | 106 q(k)=q(k+1) | ||
| 318 | q(5) =qq(i-2) | ||
| 319 | d(5)=hsq*q(4)*p(4)+d(4) | ||
| 320 | t(5)=d(5)+t(4) | ||
| 321 | p(5)=t(5)/(1.0d0-hsq12*q(5)) | ||
| 322 | p(5)=1.09375d0*p(4)+0.2734375d0*p(5)-0.546875d0*p(3)+0.21875d0* | ||
| 323 | 1 p(2)-0.0390625d0*p(1) | ||
| 324 | i=i-1 | ||
| 325 | dx=dx/2.0d0 | ||
| 326 | q(5) =qq(i) | ||
| 327 | h=dx | ||
| 328 | hsq=h*h | ||
| 329 | hsq12=hsq/12.0d0 | ||
| 330 | t(5)=p(5)*(1.0d0-hsq12*q(5)) | ||
| 331 | t(4)=p(4)*(1.0d0-hsq12*q(4)) | ||
| 332 | d(5)=t(5)-t(4) | ||
| 333 | snlo(i)=p(5) | ||
| 334 | do 107 l=1,4 | ||
| 335 | p(l)=p(l+1) | ||
| 336 | t(l)=t(l+1) | ||
| 337 | d(l)=d(l+1) | ||
| 338 | 107 q(l)=q(l+1) | ||
| 339 | go to 104 | ||
| 340 | c matching radius has been reached coming in | ||
| 341 | 200 k=kkk | ||
| 342 | value=snlo(k)**2 | ||
| 343 | go to 202 | ||
| 344 | 2001 continue | ||
| 345 | 201 sum3=sum3+xif*sum4 | ||
| 346 | xif =xif*0.5d0 | ||
| 347 | 202 mm=nmb | ||
| 348 | sum4 =0.0d0 | ||
| 349 | 203 y=value | ||
| 350 | value=snlo(k-5)**2 | ||
| 351 | sum4=sum4+19.d0*(value+y)+75.d0*(snlo(k-1)**2+snlo(k-4)**2) | ||
| 352 | 1+50.0d0*(snlo(k-2)**2+snlo(k-3)**2) | ||
| 353 | k=k-5 | ||
| 354 | if(k-imatch) 77,2031,2030 | ||
| 355 | 2030 mm=mm-1 | ||
| 356 | if(mm) 77,2001,203 | ||
| 357 | 2031 sum3=sum3+xif*sum4 | ||
| 358 | 204 s3=sum3/p(4)**2 | ||
| 359 | ppin=(t(5)-t(3)-0.5d0*(p(5)-p(3)))/h | ||
| 360 | s4=ppin/p(4) | ||
| 361 | fe=s4-s2 | ||
| 362 | if(abs(fe).lt.1.d-08)go to 300 | ||
| 363 | c write(66,4711)mp,nprint,e,fe | ||
| 364 | ml=more*less | ||
| 365 | 4711 format(' mp',i2,' iter: ',i4,' e: ',e12.6,' fe: ',e12.6) | ||
| 366 | if(mp.eq.2)go to 9120 | ||
| 367 | if(mp.eq.1)go to 9100 | ||
| 368 | mp=1 | ||
| 369 | if(imp.eq.0)de=-e/10.d0 | ||
| 370 | de=dmin1(de,-e/10.d0) | ||
| 371 | if(i0.gt.0)de=de/5**i0 | ||
| 372 | i0=i0+1 | ||
| 373 | if(ml.gt.0)de=abs(emore-eless)/10.d0 | ||
| 374 | if(e.gt.-1.d-35)de=1.d-7 | ||
| 375 | eold=e | ||
| 376 | feold=fe | ||
| 377 | if(fe.gt.0)e=e-de | ||
| 378 | if(fe.lt.0)e=e+de | ||
| 379 | go to 10 | ||
| 380 | 9100 if(fe*feold.lt.0)go to 9110 | ||
| 381 | if(fe.gt.0.d0.and.imp.eq.0) de=-e/10.d0 | ||
| 382 | if(i0.gt.1.and.ml.gt.0)de=abs(emore-eless)/10.d0 | ||
| 383 | eold=e | ||
| 384 | feold=fe | ||
| 385 | 9101 if(fe.lt.0d0)e=e+de | ||
| 386 | if(fe.gt.0d0)e=e-de | ||
| 387 | go to 10 | ||
| 388 | 9110 continue | ||
| 389 | 9111 mp=2 | ||
| 390 | fe1=feold | ||
| 391 | fe2=fe | ||
| 392 | e1=eold | ||
| 393 | e2=e | ||
| 394 | eold=e | ||
| 395 | go to 9130 | ||
| 396 | 9120 if(fe1*fe.lt.0d0)e2=e | ||
| 397 | if(fe1*fe.lt.0d0)fe2=fe | ||
| 398 | if(fe2*fe.lt.0d0)e1=e | ||
| 399 | if(fe2*fe.lt.0d0)fe1=fe | ||
| 400 | eold=e | ||
| 401 | 6174 format(' e1: ',e12.6,' fe1: ',e12.6,' e2: ',e12.6, | ||
| 402 | j' fe2: ',e12.6) | ||
| 403 | 9130 e=(e1*fe2-e2*fe1)/(fe2-fe1) | ||
| 404 | if(abs((e2-e1)/e).lt.thresh)go to 300 | ||
| 405 | if(abs((e-eold)/e).lt.1d-06)go to 300 | ||
| 406 | go to 10 | ||
| 407 | 300 pop=pmatch/p(4) | ||
| 408 | do 302 j=imatch,kkk | ||
| 409 | 302 snlo(j)=snlo(j)*pop | ||
| 410 | sum1=0.0d0 | ||
| 411 | j=1 | ||
| 412 | xif=xifc | ||
| 413 | value=0.0d0 | ||
| 414 | 303 mm=nmb | ||
| 415 | xif=xif+xif | ||
| 416 | sum2=0.0d0 | ||
| 417 | 304 y=value | ||
| 418 | value=snlo(j+5)**2 | ||
| 419 | sum2=sum2+19.d0*(value+y)+75.d0*(snlo(j+4)**2+snlo(j+1)**2) | ||
| 420 | 1+50.d0*(snlo(j+2)**2+snlo(j+3)**2) | ||
| 421 | j=j+5 | ||
| 422 | mm=mm-1 | ||
| 423 | if(mm)77,305,304 | ||
| 424 | 305 sum1=sum1+xif*sum2 | ||
| 425 | if(kkk-j)77,307,303 | ||
| 426 | 307 c1=sqrt (sum1) | ||
| 427 | if(snlo(3))308,77,310 | ||
| 428 | 308 c1=-c1 | ||
| 429 | c | ||
| 430 | c include tail | ||
| 431 | c | ||
| 432 | 310 tail=snlo(mesh)**2/(2.d0*sqrt(abs(e))) | ||
| 433 | c1=c1+tail | ||
| 434 | do 311 i=1,kkk | ||
| 435 | 311 snlo(i)=snlo(i)/c1 | ||
| 436 | en=e | ||
| 437 | if(abs(en).lt.1.d-6) iflag=1 | ||
| 438 | npr=nprint | ||
| 439 | return | ||
| 440 | end | ||
| 441 | c ********************************************************************** | ||
| 442 | subroutine simpsh(ff,s) | ||
| 443 | implicit double precision (a-h,o-z) | ||
| 444 | c integrates the matrix ff on the herman-skillman mesh | ||
| 445 | common/mess/wj(301),dx,nblock,jblock | ||
| 446 | common/sc/gr(561),r(561),snlo(561),nbl | ||
| 447 | dimension ff(561) | ||
| 448 | nb1=nbl+1 | ||
| 449 | s=0.d0 | ||
| 450 | deltax=dx | ||
| 451 | do 10 j=1,jblock | ||
| 452 | do 11 jk=1,nb1 | ||
| 453 | i=(j-1)*nbl+jk | ||
| 454 | 11 s=s+ff(i)*wj(jk)*deltax | ||
| 455 | 10 deltax=2.d0*deltax | ||
| 456 | return | ||
| 457 | end | ||
| 458 | c ********************************************************************** | ||
| 459 | subroutine scrhs(roo,u,z,q,n) | ||
| 460 | implicit double precision (a-h,o-z) | ||
| 461 | c evaluates the screened poisson integral | ||
| 462 | c in the herman-skillman mesh | ||
| 463 | dimension roo(561),u(561),ss(561),apu(561) | ||
| 464 | common/sc/gr(561),r(561),snlo(561),nbl | ||
| 465 | pi=4.d0*atan(1.d0) | ||
| 466 | c=4.d0*pi | ||
| 467 | do 11 i=1,n | ||
| 468 | 11 ss(i)=-c*roo(i)*r(i)-q**2*u(i) | ||
| 469 | do 20 i=1,n | ||
| 470 | do 30 j=1,n | ||
| 471 | aa=gr(i)/gr(j) | ||
| 472 | if(j.gt.i) aa=1.d0/aa | ||
| 473 | ab=gr(i)*gr(j) | ||
| 474 | 30 apu(j)=(aa-ab)*ss(j) | ||
| 475 | call simpsh(apu,s) | ||
| 476 | 20 u(i)=-s/(2.d0*q)-z*gr(i) | ||
| 477 | return | ||
| 478 | end | ||
| 479 | c ********************************************************************** | ||
| 480 | function exc(r,s,ixc) | ||
| 481 | implicit double precision (a-h,o-z) | ||
| 482 | c ceperley alder perdew zunger | ||
| 483 | c or von barth hedin | ||
| 484 | data gp,bp1,bp2,gf,bf1,bf2/-.1423d0,1.0529d0,.3334d0,-.0843d0, | ||
| 485 | j1.3981d0,.2611d0/ | ||
| 486 | data ap,bp,cp,dp,af,bf,cf,df/.0311d0,-.048d0,.002d0,-.0116d0, | ||
| 487 | j.01555d0,-.0269d0,.0007d0,-.0048d0/ | ||
| 488 | if(r.lt.1.d-25)go to 100 | ||
| 489 | pi=4.d0*atan(1.d0) | ||
| 490 | if(s.gt.0.99999999d0)s=0.99999999d0 | ||
| 491 | if(s.lt.-0.99999999d0)s=-0.99999999d0 | ||
| 492 | sinv=(4.d0*pi*r/3.d0)**(1.d0/3.d0) | ||
| 493 | rs=1.d0/sinv | ||
| 494 | if(ixc.eq.1)go to 200 | ||
| 495 | if(rs.lt.1.d0)go to 10 | ||
| 496 | srs=sqrt(rs) | ||
| 497 | excp=gp/(1.d0+bp1*srs+bp2*rs) | ||
| 498 | excf=gf/(1.d0+bf1*srs+bf2*rs) | ||
| 499 | go to 20 | ||
| 500 | 10 aa=log(rs) | ||
| 501 | excp=ap*aa+bp+cp*rs*aa+dp*rs | ||
| 502 | excf=af*aa+bf+cf*rs*aa+df*rs | ||
| 503 | 20 f=((1.d0+s)**(4.d0/3.d0)+(1.d0-s)**(4.d0/3.d0)-2.d0)/ | ||
| 504 | 1 (2.d0**(4.d0/3.d0)-2.d0) | ||
| 505 | excf=excf-.5772521d0/rs | ||
| 506 | excp=excp-.4581653d0/rs | ||
| 507 | exc=excp+f*(excf-excp) | ||
| 508 | return | ||
| 509 | 100 exc=0.d0 | ||
| 510 | return | ||
| 511 | 200 x=s/2.d0+0.5d0 | ||
| 512 | d43=4.d0/3.d0 | ||
| 513 | rsf=rs/75.d0 | ||
| 514 | rsf2=rsf*rsf | ||
| 515 | rsf3=rsf2*rsf | ||
| 516 | rsp=rs/30.d0 | ||
| 517 | rsp2=rsp*rsp | ||
| 518 | rsp3=rsp2*rsp | ||
| 519 | fcf=(1.d0+rsf3)*log(1.d0+1.d0/rsf)+0.5d0*rsf-rsf2-1.d0/3.d0 | ||
| 520 | fcp=(1.d0+rsp3)*log(1.d0+1.d0/rsp)+0.5d0*rsp-rsp2-1.d0/3.d0 | ||
| 521 | epscp=-.0504d0*fcp | ||
| 522 | epscf=-.0254d0*fcf | ||
| 523 | epsxp=-.91633059d0/rs | ||
| 524 | cny=5.1297628d0*(epscf-epscp) | ||
| 525 | aa=.5d0**(1.d0/3.d0) | ||
| 526 | if(x.lt..000001d0) x=.000001d0 | ||
| 527 | if(x.gt..999999d0) x=.999999d0 | ||
| 528 | fx=(x**d43+(1.d0-x)**d43-aa)/(1.d0-aa) | ||
| 529 | exc=epsxp+epscp+fx*(cny+4.d0/3.d0*epsxp)/5.1297628d0 | ||
| 530 | exc=exc/2.d0 | ||
| 531 | return | ||
| 532 | end | ||
| 533 | c ********************************************************************** | ||
| 534 | function uxc(r,s,ispin,ixc) | ||
| 535 | implicit double precision (a-h,o-z) | ||
| 536 | c ceperley alder perdew zunger | ||
| 537 | data gp,bp1,bp2,gf,bf1,bf2/-.1423d0,1.0529d0,.3334d0,-.0843d0, | ||
| 538 | j1.3981d0,.2611d0/ | ||
| 539 | data ap,bp,cp,dp,af,bf,cf,df/.0311d0,-.048d0,.002d0,-.0116d0, | ||
| 540 | j.01555d0,-.0269d0,.0007d0,-.0048d0/ | ||
| 541 | if(r.lt.1.d-35)go to 100 | ||
| 542 | pi=4.d0*atan(1.d0) | ||
| 543 | sinv=(4.d0*pi*r/3.d0)**(1.d0/3.d0) | ||
| 544 | rs=1.d0/sinv | ||
| 545 | if(ixc.eq.1)go to 200 | ||
| 546 | if(rs.lt.1.d0)go to 10 | ||
| 547 | srs=sqrt(rs) | ||
| 548 | excp=gp/(1.d0+bp1*srs+bp2*rs) | ||
| 549 | excf=gf/(1.d0+bf1*srs+bf2*rs) | ||
| 550 | uxcp=excp*(1.d0+7.d0/6.d0*bp1*srs+4.d0/3.d0*bp2*rs) | ||
| 551 | j/(1.d0+bp1*srs+bp2*rs) | ||
| 552 | uxcf=excf*(1.d0+7.d0/6.d0*bf1*srs+4.d0/3.d0*bf2*rs) | ||
| 553 | j/(1.d0+bf1*srs+bf2*rs) | ||
| 554 | go to 20 | ||
| 555 | 10 aa=log(rs) | ||
| 556 | excp=ap*aa+bp+cp*rs*aa+dp*rs | ||
| 557 | excf=af*aa+bf+cf*rs*aa+df*rs | ||
| 558 | uxcp=ap*aa+(bp-ap/3.d0)+2.d0/3.d0*cp*rs*aa+(2.d0*dp-cp)*rs/3.d0 | ||
| 559 | uxcf=af*aa+(bf-af/3.d0)+2.d0/3.d0*cf*rs*aa+(2.d0*df-cf)*rs/3.d0 | ||
| 560 | 20 f=((1.d0+s)**(4.d0/3.d0)+(1.d0-s)**(4.d0/3.d0)-2.d0)/ | ||
| 561 | j (2.d0**(4.d0/3.d0)-2.d0) | ||
| 562 | ddf=4.d0/3.d0*((1.d0+s)**(1.d0/3.d0)-(1.d0-s)**(1.d0/3.d0)) | ||
| 563 | j /(2.d0**(4.d0/3.d0)-2.d0) | ||
| 564 | uxc=uxcp+f*(uxcf-uxcp)+(excf-excp)*(3.d0-2.d0*ispin-s)*ddf | ||
| 565 | j -.6108871d0/rs*(1.d0+(3.d0-2.d0*ispin)*s)**(1.d0/3.d0) | ||
| 566 | return | ||
| 567 | 100 uxc=0.d0 | ||
| 568 | return | ||
| 569 | 200 x=s/2.d0+0.5d0 | ||
| 570 | d43=4.d0/3.d0 | ||
| 571 | xx=0.5d0-s/2.d0 | ||
| 572 | rsf=rs/75.d0 | ||
| 573 | rsf2=rsf*rsf | ||
| 574 | rsf3=rsf2*rsf | ||
| 575 | rsp=rs/30.d0 | ||
| 576 | rsp2=rsp*rsp | ||
| 577 | rsp3=rsp2*rsp | ||
| 578 | fcf=(1.d0+rsf3)*log(1.d0+1.d0/rsf)+0.5d0*rsf-rsf2-1.d0/3.d0 | ||
| 579 | fcp=(1.d0+rsp3)*log(1.d0+1.d0/rsp)+0.5d0*rsp-rsp2-1.d0/3.d0 | ||
| 580 | epscp=-.0504d0*fcp | ||
| 581 | epscf=-.0254d0*fcf | ||
| 582 | epsxp=-.91633059d0/rs | ||
| 583 | cny=5.1297628d0*(epscf-epscp) | ||
| 584 | aa=.5d0**(1.d0/3.d0) | ||
| 585 | if(x.lt..000001d0) x=.000001d0 | ||
| 586 | if(xx.lt..000001d0) xx=.000001d0 | ||
| 587 | if(x.gt..999999d0) x=.999999d0 | ||
| 588 | if(xx.gt..999999d0) xx=.999999d0 | ||
| 589 | ars=-1.22177412d0/rs+cny | ||
| 590 | brs=-0.0504d0*log(1.d0+30.d0/rs)-cny | ||
| 591 | trx1=(2.d0*x)**(1.d0/3.d0) | ||
| 592 | trx2=(2.d0*xx)**(1.d0/3.d0) | ||
| 593 | if(ispin.eq.1)vxc=ars*trx1+brs | ||
| 594 | if(ispin.eq.2)vxc=ars*trx2+brs | ||
| 595 | uxc=vxc/2.d0 | ||
| 596 | return | ||
| 597 | end | ||
| 598 | c ************************************************************ | ||
| 599 | subroutine schrhs(v,k,l,ukl) | ||
| 600 | implicit double precision (a-h,o-z) | ||
| 601 | c integrates the radial schrodinger equation | ||
| 602 | c on the herman-skillman mesh | ||
| 603 | double precision k | ||
| 604 | dimension v(561),ukl(561),y(561) | ||
| 605 | common/mess/wj(301),dx,nblock,jblock | ||
| 606 | common/sc/gr(561),r(561),snlo(561),nbl | ||
| 607 | sd(i)=(2.d0*v(i)-k**2+l*(l+1)/r(i)**2)*ukl(i) | ||
| 608 | sdd(i)=(2.d0*v(i)-k**2+l*(l+1)/r(i)**2)*y(i) | ||
| 609 | c initial values have been stored at ukl(1)...ukl(4) | ||
| 610 | nb1=nbl+1 | ||
| 611 | hh=dx | ||
| 612 | do 10 i=5,nb1 | ||
| 613 | ukl(i)=ukl(i-1)+ukl(i-3)-ukl(i-4) | ||
| 614 | 1+hh**2/4.d0*(5.d0*sd(i-1)+2.d0*sd(i-2)+5.d0*sd(i-3)) | ||
| 615 | 10 ukl(i)=2.d0*ukl(i-1)-ukl(i-2)+ | ||
| 616 | 1hh**2/12.d0*(sd(i)+10.d0*sd(i-1)+sd(i-2)) | ||
| 617 | c set initial values for the next block | ||
| 618 | do 20 j=2,jblock | ||
| 619 | hh=2.d0*hh | ||
| 620 | jj=(j-1)*nbl | ||
| 621 | y(jj+1)=ukl(jj+1) | ||
| 622 | y(jj)=ukl(jj-1) | ||
| 623 | y(jj-1)=ukl(jj-3) | ||
| 624 | y(jj-2)=ukl(jj-5) | ||
| 625 | do 30 jk=2,nb1 | ||
| 626 | i=jj+jk | ||
| 627 | y(i)=y(i-1)+y(i-3)-y(i-4)+ | ||
| 628 | 1hh**2/4.d0*(5.d0*sdd(i-1)+2.d0*sdd(i-2)+5.d0*sdd(i-3)) | ||
| 629 | y(i)=2.d0*y(i-1)-y(i-2)+ | ||
| 630 | 1hh**2/12.d0*(sdd(i)+10.d0*sdd(i-1)+sdd(i-2)) | ||
| 631 | 30 ukl(i)=y(i) | ||
| 632 | 20 continue | ||
| 633 | return | ||
| 634 | end | ||
diff --git a/src/labat/spline.f b/src/labat/spline.f new file mode 100644 index 0000000..aa523be --- /dev/null +++ b/src/labat/spline.f | |||
| @@ -0,0 +1,34 @@ | |||
| 1 | subroutine spline(r,start,n,db,db2) | ||
| 2 | c spline calculates the cubic spline interpolation of the density | ||
| 3 | c together with subroutine splint. | ||
| 4 | c the main ideas are "stolen" from "numerical recipes", cambridge | ||
| 5 | c university press (1992). | ||
| 6 | c input r : position coordinate (array) | ||
| 7 | c input start : index, r(start) = starting point of the spline | ||
| 8 | c input n : index, r(n) = r_max | ||
| 9 | c input db : spin up and down density. (array) | ||
| 10 | c output db2 : second derivative of db (array) | ||
| 11 | implicit logical (a-z) | ||
| 12 | double precision r,db,db2,u,sig,p,qn,un | ||
| 13 | integer spin,start,n,i | ||
| 14 | dimension r(561),db(2,561),db2(2,561),u(561) | ||
| 15 | do 100 spin = 1,2 | ||
| 16 | db2(spin,start) = 0.d0 | ||
| 17 | u(start) = 0.d0 | ||
| 18 | do 10 i = start+1,n-1 | ||
| 19 | sig = (r(i)-r(i-1))/(r(i+1)-r(i-1)) | ||
| 20 | p = sig*db2(spin,i-1)+2.d0 | ||
| 21 | db2(spin,i) = (sig-1.d0)/p | ||
| 22 | u(i) = (6.d0*((db(spin,i+1)-db(spin,i))/(r(i+1)-r(i))- | ||
| 23 | j (db(spin,i)-db(spin,i-1))/(r(i)-r(i-1)))/ | ||
| 24 | j (r(i+1)-r(i-1))-sig*u(i-1))/p | ||
| 25 | 10 continue | ||
| 26 | qn = 0.d0 | ||
| 27 | un = 0.d0 | ||
| 28 | db2(spin,n) = (un-qn*u(n-1))/(qn*db2(spin,n-1)+1.d0) | ||
| 29 | do 20 i = n-1,start,-1 | ||
| 30 | db2(spin,i) = db2(spin,i)*db2(spin,i+1)+u(i) | ||
| 31 | 20 continue | ||
| 32 | 100 continue | ||
| 33 | return | ||
| 34 | end | ||
diff --git a/src/labat/splint.f b/src/labat/splint.f new file mode 100644 index 0000000..a25a942 --- /dev/null +++ b/src/labat/splint.f | |||
| @@ -0,0 +1,37 @@ | |||
| 1 | subroutine splint(r,db,db2,spin,start,n,ri,dbi) | ||
| 2 | c splint calculates the cubic spline interpolation of the density | ||
| 3 | c together with subroutine spline. | ||
| 4 | c the main ideas are "stolen" from "numerical recipes", cambridge | ||
| 5 | c university press (1992). | ||
| 6 | c input r : position coordinate (array) | ||
| 7 | c input db : spin up and down density. (array) | ||
| 8 | c input db2 : second derivative of db (array) | ||
| 9 | c input spin : 1 if spin up, -1 if spin down | ||
| 10 | c input start : starting point of spline = r(start) | ||
| 11 | c input n : index, r(n) = r_max | ||
| 12 | c input ri : position of interpolation | ||
| 13 | c output dbi : interpolated value of db | ||
| 14 | implicit logical (a-z) | ||
| 15 | integer spin,spinn,n,klo,khi,k,start | ||
| 16 | double precision r,db,db2,ri,dbi,h,a,b | ||
| 17 | dimension r(561),db(2,561),db2(2,561) | ||
| 18 | spinn = spin | ||
| 19 | if (spinn.eq.-1) spinn = 2 | ||
| 20 | klo = start | ||
| 21 | khi = n | ||
| 22 | 10 if (khi-klo.gt.1) then | ||
| 23 | k = (khi+klo)/2 | ||
| 24 | if (r(k).gt.ri) then | ||
| 25 | khi = k | ||
| 26 | else | ||
| 27 | klo = k | ||
| 28 | endif | ||
| 29 | goto 10 | ||
| 30 | endif | ||
| 31 | h = r(khi)-r(klo) | ||
| 32 | a = (r(khi)-ri)/h | ||
| 33 | b = (ri-r(klo))/h | ||
| 34 | dbi = a*db(spinn,klo)+b*db(spinn,khi)+((a**3-a)* | ||
| 35 | j db2(spinn,klo)+(b**3-b)*db2(spinn,khi))*(h**2)/6.d0 | ||
| 36 | return | ||
| 37 | end | ||
diff --git a/src/lang/basic.cc b/src/lang/basic.cc new file mode 100644 index 0000000..54d16a9 --- /dev/null +++ b/src/lang/basic.cc | |||
| @@ -0,0 +1,315 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <lang/env.h> | ||
| 21 | |||
| 22 | /////////////////////////////////////////////////// | ||
| 23 | |||
| 24 | TOK_IMPL(asis) { out<<env.arg(0)->expr; } | ||
| 25 | TOK_IMPL(mute) {} | ||
| 26 | TOK_IMPL(comment) {} | ||
| 27 | |||
| 28 | /////////////////////////////////////////////////// | ||
| 29 | |||
| 30 | TOK_IMPL(cond) { | ||
| 31 | Cond(*env.toks,env[0],env[1],tok_t::PUBLIC); | ||
| 32 | } | ||
| 33 | TOK_IMPL(global) { | ||
| 34 | Global(*env.toks,env[0],env[1],tok_t::PUBLIC); | ||
| 35 | } | ||
| 36 | TOK_IMPL(const) { | ||
| 37 | Const(*env.toks,env[0],env[1],tok_t::PUBLIC); | ||
| 38 | } | ||
| 39 | TOK_IMPL(reconst) { | ||
| 40 | Const(*env.toks,env[0],env[1],tok_t::PUBLIC,1); | ||
| 41 | } | ||
| 42 | |||
| 43 | /////////////////////////////////////////////////// | ||
| 44 | |||
| 45 | TOK_IMPL(type) { | ||
| 46 | tok_t* p=env.toks->get(env[0]); | ||
| 47 | if(env.is_clear(p)) out<<p->mod; | ||
| 48 | } | ||
| 49 | TOK_IMPL(desc) { | ||
| 50 | tok_t* p=env.toks->get(env[0]); | ||
| 51 | if(env.is_clear(p)) out<<Desc(*p); | ||
| 52 | } | ||
| 53 | TOK_IMPL(expr) { | ||
| 54 | tok_t* p=env.toks->get(env[0]); | ||
| 55 | if(env.is_clear(p)&&p->is_func()) ((func_t*)p)->x.trav(out,12); | ||
| 56 | } | ||
| 57 | TOK_IMPL(clear) { | ||
| 58 | ClearToken(*env.toks,env[0]); | ||
| 59 | } | ||
| 60 | |||
| 61 | ////////////////////////////////////////////////////// | ||
| 62 | |||
| 63 | TOK_IMPL(exist) { out<<env.glob_find(env[0]); } | ||
| 64 | TOK_IMPL(nexist) { out<<!env.glob_find(env[0]); } | ||
| 65 | TOK_IMPL(empty) { out<<env.glob(env[0]).empty(); } | ||
| 66 | TOK_IMPL(nempty) { out<<env.glob(env[0]).nempty(); } | ||
| 67 | |||
| 68 | /////////////////////////////////////////////////// | ||
| 69 | |||
| 70 | TOK_IMPL(export) { | ||
| 71 | rpile list; env.gloc_list(list,env[1]); | ||
| 72 | int n=*env[1]=='@'?env[1].size()-1:env[1].size(); | ||
| 73 | for(int i=0;i<list.size();i++) | ||
| 74 | Global(*env.toks,env[0]+list[i].right(n),env.gloc(list[i]),tok_t::PUBLIC); | ||
| 75 | } | ||
| 76 | |||
| 77 | TOK_IMPL(import) { | ||
| 78 | if(*env[0]=='@') env.glob_adb(env[0].popf(),env[1]); | ||
| 79 | else { | ||
| 80 | rpile list; env.glob_list(list,env[1]); | ||
| 81 | for(int i=0;i<list.size();i++) | ||
| 82 | env.aloc(env[0]+list[i].right(env[1].size()),env.glob(list[i])); | ||
| 83 | } | ||
| 84 | } | ||
| 85 | |||
| 86 | TOK_IMPL(list) { | ||
| 87 | mstring fx; env.parg(fx,-1); | ||
| 88 | rpile list; env.gloc_list(list,fx); | ||
| 89 | int n=*fx=='@'?fx.size()-1:fx.size(); | ||
| 90 | for(int i=0;i<list.size();i++) out<<list[i].right(n)<<"\n"; | ||
| 91 | } | ||
| 92 | |||
| 93 | TOK_IMPL(globlist) { | ||
| 94 | mstring fx; env.parg(fx,-1); | ||
| 95 | rpile list; env.glob_list(list,fx); | ||
| 96 | int n=*fx=='@'?fx.size()-1:fx.size(); | ||
| 97 | for(int i=0;i<list.size();i++) out<<list[i].right(n)<<"\n"; | ||
| 98 | } | ||
| 99 | |||
| 100 | TOK_IMPL(lrec) { | ||
| 101 | sref name=env[0],first,rest=env[1]; | ||
| 102 | mstring init; env.parg(init,-1); | ||
| 103 | while(Split(first,rest)) env.aloc(name+first,init); | ||
| 104 | } | ||
| 105 | |||
| 106 | /////////////////////////////////////////////////// | ||
| 107 | |||
| 108 | TOK_IMPL(arg) { if(env.up) env.up->parg(out,atoi(env[0])-1); } | ||
| 109 | TOK_IMPL(args) { if(env.up) out<<env.up->args; else out<<0; } | ||
| 110 | |||
| 111 | /////////////////////////////////////////////////// | ||
| 112 | |||
| 113 | TOK_IMPL(random) { | ||
| 114 | out<<Random(atoi(env[0])); | ||
| 115 | } | ||
| 116 | |||
| 117 | ////////////////////////////////////////////////////// | ||
| 118 | |||
| 119 | void envAddBasic(tokmap& T) | ||
| 120 | { | ||
| 121 | TOK_ADD(asis,"r",tok_t::PUBLIC, | ||
| 122 | "%Display body as is\n" | ||
| 123 | "%Syntax: \\asis{body}\n" | ||
| 124 | ); | ||
| 125 | TOK_ADD(mute,"x",tok_t::PUBLIC, | ||
| 126 | "%Evaluate but don't display\n" | ||
| 127 | "%Syntax: \\mute{body}\n" | ||
| 128 | ); | ||
| 129 | T.add(new binary_t(sref("*"), | ||
| 130 | sref("%Commentary - don't show or evaluate body\n" | ||
| 131 | "%Syntax: \\*{body}\n"), | ||
| 132 | tok_t::PUBLIC,sref("r"),impl_comment),0,1); | ||
| 133 | |||
| 134 | ////////////////////////////////////////////////////// | ||
| 135 | |||
| 136 | TOK_ADD(global,"xx",tok_t::PUBLIC, | ||
| 137 | "%Set global variable\n" | ||
| 138 | "%Syntax: \\global{varname}{expr}\n" | ||
| 139 | ); | ||
| 140 | TOK_ADD(cond,"xx",tok_t::PUBLIC, | ||
| 141 | "%Set global variable if not already defined\n" | ||
| 142 | "%Syntax: \\cond{varname}{expr}\n" | ||
| 143 | ); | ||
| 144 | TOK_ADD(const,"xx",tok_t::PUBLIC, | ||
| 145 | "%Set global constant\n" | ||
| 146 | "%Syntax: \\cond{varname}{expr}\n" | ||
| 147 | "%\n" | ||
| 148 | "%Generates an error if already defined\n" | ||
| 149 | ); | ||
| 150 | TOK_ADD(reconst,"xx",tok_t::PRIVATE, | ||
| 151 | "%Redefine global constant\n" | ||
| 152 | "%Syntax: \\cond{varname}{expr}\n" | ||
| 153 | "%\n" | ||
| 154 | "%Takes precedence over any existing constant\n" | ||
| 155 | ); | ||
| 156 | |||
| 157 | ////////////////////////////////////////////////////// | ||
| 158 | |||
| 159 | TOK_ADD(type,"x",tok_t::PRIVATE, | ||
| 160 | "%Show variable type\n" | ||
| 161 | "%Syntax: \\type{varname}\n" | ||
| 162 | "%\n" | ||
| 163 | "%The type is an integer bit-field consisting of:\n" | ||
| 164 | "%\n" | ||
| 165 | "%1 CONSTANT\n" | ||
| 166 | "%2 RESTRICT\n" | ||
| 167 | "%4 NORMAL\n" | ||
| 168 | "%8 SYSONLY\n" | ||
| 169 | "%16 INIT\n" | ||
| 170 | "%32 RUNNABLE\n" | ||
| 171 | "%64 FUNCTION\n" | ||
| 172 | "%128 BINARY\n" | ||
| 173 | "%\n" | ||
| 174 | "%The access modes consists of\n" | ||
| 175 | "%\n" | ||
| 176 | "%INIT\n" | ||
| 177 | "%SYSONLY\n" | ||
| 178 | "%PRIVATE = NORMAL|SYSONLY\n" | ||
| 179 | "%PUBLIC = PRIVATE|RESTRICT\n" | ||
| 180 | "%\n" | ||
| 181 | "%Those values are matched against the running modes\n" | ||
| 182 | "%to determine access. See run.\n" | ||
| 183 | ); | ||
| 184 | TOK_ADD(desc,"x",tok_t::PRIVATE, | ||
| 185 | "%Show variable description\n" | ||
| 186 | "%Syntax: \\desc{varname}\n" | ||
| 187 | "%\n" | ||
| 188 | "%Collects all lines starting with %.\n" | ||
| 189 | ); | ||
| 190 | TOK_ADD(expr,"x",tok_t::PRIVATE, | ||
| 191 | "%Show the expression tree of function\n" | ||
| 192 | "%Syntax: \\expr{varname}\n" | ||
| 193 | "%\n" | ||
| 194 | "%If desc is a function, the expression tree is shown.\n" | ||
| 195 | "%Mostly interesting for real expression, i.e., when the\n" | ||
| 196 | "%function body was defined within parenthesis.\n" | ||
| 197 | ); | ||
| 198 | TOK_ADD(clear,"x",tok_t::SYSONLY, | ||
| 199 | "%Clear variables\n" | ||
| 200 | "%Syntax: \\clear{partial varname}\n" | ||
| 201 | "%\n" | ||
| 202 | "%Clears all global variables on the current level\n" | ||
| 203 | "%beginning with the partial variable name.\n" | ||
| 204 | ); | ||
| 205 | |||
| 206 | ////////////////////////////////////////////////////// | ||
| 207 | |||
| 208 | TOK_ADD(exist,"x",tok_t::PUBLIC, | ||
| 209 | "%True if variable exist\n" | ||
| 210 | "%Syntax: \\exist{varname}\n" | ||
| 211 | ); | ||
| 212 | TOK_ADD(nexist,"x",tok_t::PUBLIC, | ||
| 213 | "%True if variable does not exist\n" | ||
| 214 | "%Syntax: \\nexist{varname}\n" | ||
| 215 | ); | ||
| 216 | TOK_ADD(empty,"x",tok_t::PUBLIC, | ||
| 217 | "%True if variable is empty\n" | ||
| 218 | "%Syntax: \\empty{varname}\n" | ||
| 219 | "%\n" | ||
| 220 | "%Generates an error if varname does not exist.\n" | ||
| 221 | ); | ||
| 222 | TOK_ADD(nempty,"x",tok_t::PUBLIC, | ||
| 223 | "%True if variable is non-empty\n" | ||
| 224 | "%Syntax: \\nempty{varname}\n" | ||
| 225 | "%\n" | ||
| 226 | "%Generates an error if varname does not exist.\n" | ||
| 227 | ); | ||
| 228 | |||
| 229 | ////////////////////////////////////////////////////// | ||
| 230 | |||
| 231 | TOK_ADD(export,"xx",tok_t::SYSONLY, | ||
| 232 | "%Export local variables\n" | ||
| 233 | "%Syntax: \\export{global partial name}{local partial name}\n" | ||
| 234 | "%\n" | ||
| 235 | "%Copies a sequence of local variables, beginning with the\n" | ||
| 236 | "%local partial name, from the same - not nescessarily the current -\n" | ||
| 237 | "%local stack into a set of global variables beginning with\n" | ||
| 238 | "%the global partial name.\n" | ||
| 239 | "%\n" | ||
| 240 | "%Copies all local variables in the current stack if no\n" | ||
| 241 | "%partial name is given.\n" | ||
| 242 | "%\n" | ||
| 243 | "%Copies all variables in the current database record\n" | ||
| 244 | "%if the partial name @ is given.\n" | ||
| 245 | ); | ||
| 246 | TOK_ADD(import,"xx",tok_t::SYSONLY, | ||
| 247 | "%Import global variables\n" | ||
| 248 | "%Syntax: \\import{local partial name}{global partial name}\n" | ||
| 249 | "%\n" | ||
| 250 | "%Copies a sequence of global variables, beginning with the\n" | ||
| 251 | "%global partial name, from the same - not nescessarily the\n" | ||
| 252 | "%current - global level into a set of local variables beginning\n" | ||
| 253 | "%with the local partial name.\n" | ||
| 254 | "%\n" | ||
| 255 | "%Copies all global variables on the current level if no\n" | ||
| 256 | "%partial name is given.\n" | ||
| 257 | "%\n" | ||
| 258 | "%Creates a new or updates an existing database record if\n" | ||
| 259 | "%the partial name @ is given.\n" | ||
| 260 | ); | ||
| 261 | TOK_ADD(list,"?",tok_t::PUBLIC, | ||
| 262 | "%List local variables\n" | ||
| 263 | "%Syntax: \\list<partial name>\n" | ||
| 264 | "%\n" | ||
| 265 | "%Generates a list of names, beginning with the partial name,\n" | ||
| 266 | "%from the same - not nescessarily the current - local stack.\n" | ||
| 267 | "%\n" | ||
| 268 | "%Generates all local variables in the current stack if no\n" | ||
| 269 | "%partial name is given.\n" | ||
| 270 | "%\n" | ||
| 271 | "%Generates a list of tables if @ is given.\n" | ||
| 272 | ); | ||
| 273 | TOK_ADD(globlist,"?",tok_t::PUBLIC, | ||
| 274 | "%List global variables\n" | ||
| 275 | "%Syntax: \\globlist<partial name>\n" | ||
| 276 | "%\n" | ||
| 277 | "%Generates a list of names, beginning with the partial name,\n" | ||
| 278 | "%from the same - not nescessarily the current - global level.\n" | ||
| 279 | "%\n" | ||
| 280 | "%Generates all global variables on the current level if no\n" | ||
| 281 | "%partial name is given.\n" | ||
| 282 | ); | ||
| 283 | TOK_ADD(lrec,"xx?",tok_t::PUBLIC, | ||
| 284 | "%Create a local record\n" | ||
| 285 | "%Syntax: \\lrec{partial name}{name list}<init>\n" | ||
| 286 | "%\n" | ||
| 287 | "%Creates a set of local variables, all beginning with the\n" | ||
| 288 | "%partial name, and initializes each variable to init.\n" | ||
| 289 | ); | ||
| 290 | |||
| 291 | ////////////////////////////////////////////////////// | ||
| 292 | |||
| 293 | TOK_ADD(arg,"x",tok_t::PUBLIC, | ||
| 294 | "%Show/Evaluate argument #n.\n" | ||
| 295 | "%Syntax: \\arg{n}\n" | ||
| 296 | "%\n" | ||
| 297 | "%Same as the command \\1, \\2 etc, except this\n" | ||
| 298 | "%may be used to index the arguments e.g. using local variables.\n" | ||
| 299 | ); | ||
| 300 | TOK_ADD(args,"",tok_t::PUBLIC, | ||
| 301 | "%Number of arguments in the current function\n" | ||
| 302 | "%Syntax: \\args\n" | ||
| 303 | "%\n" | ||
| 304 | "%Note that the optional argument will count as one variable,\n" | ||
| 305 | "%and may be accesed using either \\0 or \\arg{\\args}.\n" | ||
| 306 | ); | ||
| 307 | |||
| 308 | ////////////////////////////////////////////////////// | ||
| 309 | |||
| 310 | TOK_ADD(random,"x",tok_t::PRIVATE, | ||
| 311 | "%Get n random digits between 0 and 9 inclusive\n" | ||
| 312 | "%Syntax: \\random{n}\n" | ||
| 313 | ); | ||
| 314 | |||
| 315 | } | ||
diff --git a/src/lang/db.cc b/src/lang/db.cc new file mode 100644 index 0000000..9192d09 --- /dev/null +++ b/src/lang/db.cc | |||
| @@ -0,0 +1,237 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <lang/env.h> | ||
| 21 | |||
| 22 | static dbmap* GetDB(Env& env) throw(merror_t) { | ||
| 23 | if(!env.db) THROW("htc: no open database"); | ||
| 24 | return env.db; | ||
| 25 | } | ||
| 26 | |||
| 27 | static int eval(Env& env,expr_t* x,int mod=OP_ALL) { | ||
| 28 | mswrite out; | ||
| 29 | if(x->status&OP_PARSE) env.parse(out,x->expr); else x->eval(out,env,mod); | ||
| 30 | return atob(out.str()); | ||
| 31 | } | ||
| 32 | |||
| 33 | //////////////////////////////////////////////////////////////////////////// | ||
| 34 | |||
| 35 | TOK_IMPL(create) { | ||
| 36 | dbref_t* ref=DBRef(*env.toks,env[0],ms_empty,tok_t::PUBLIC,1); | ||
| 37 | ref->db.Open("/dev/zero",1); | ||
| 38 | sref first,rest=env[1]; int n=0; | ||
| 39 | while(Split(first,rest)) ref->db.InsertTable(n++,first); | ||
| 40 | ref->db.Order(env[2],env[3]); | ||
| 41 | } | ||
| 42 | |||
| 43 | TOK_IMPL(sort) { | ||
| 44 | dbref_t* ref=(dbref_t*)env.toks->get_this(env[0]); | ||
| 45 | if(env.is_clear(ref)&&ref->is_dbref()) { | ||
| 46 | ref->db.remap(); | ||
| 47 | ref->db.Sort(env[1],env[2]); | ||
| 48 | } | ||
| 49 | else THROW("htc: "<<env[0]<<" is not a sortable on the current level"); | ||
| 50 | } | ||
| 51 | |||
| 52 | TOK_IMPL(db) { | ||
| 53 | dbref_t* ref=(dbref_t*)env.toks->get(env[0]); | ||
| 54 | if(env.is_clear(ref)&&ref->is_dbref()) { | ||
| 55 | ref->db.remap(); | ||
| 56 | Env(env,ref->db).parse(out,env.arg(1)); | ||
| 57 | } | ||
| 58 | else THROW("htc: "<<env[0]<<" is not a db reference"); | ||
| 59 | } | ||
| 60 | |||
| 61 | //////////////////////////////////////////////////////////////////////////// | ||
| 62 | |||
| 63 | TOK_IMPL(query) { | ||
| 64 | dbmap* db=GetDB(env); | ||
| 65 | expr_t* x[2]={env.arg(0),env.arg(1)}; | ||
| 66 | Env nenv(env,*db); | ||
| 67 | nenv.dbat=0; | ||
| 68 | while(nenv.dbat>=0&&env.req->is_running()&&nenv.dbat<db->size()) { | ||
| 69 | int size=db->size(); | ||
| 70 | if(eval(nenv,x[0],OP_LOCAL)) nenv.parse(out,x[1]); | ||
| 71 | if(db->size()==size) nenv.dbat++; | ||
| 72 | } | ||
| 73 | } | ||
| 74 | |||
| 75 | TOK_IMPL(find_rec) { | ||
| 76 | dbmap* db=GetDB(env); | ||
| 77 | Env nenv(env,*db); | ||
| 78 | nenv.dbat=db->Find(env[0]); | ||
| 79 | if(nenv.dbat>=0&&nenv.dbat<db->size()) nenv.parse(out,env.arg(1)); | ||
| 80 | else env.parg(out,2); | ||
| 81 | } | ||
| 82 | |||
| 83 | //////////////////////////////////////////////////////////////////// | ||
| 84 | |||
| 85 | TOK_IMPL(first_rec) { env.dbat=0; } | ||
| 86 | TOK_IMPL(prev_rec) { if(env.dbat>0) env.dbat--; } | ||
| 87 | TOK_IMPL(next_rec) { if(env.dbat<GetDB(env)->size()) env.dbat++; } | ||
| 88 | TOK_IMPL(exist_rec) { out<<bool(env.dbat>=0&&env.dbat<GetDB(env)->size()); } | ||
| 89 | |||
| 90 | TOK_IMPL(rem_rec) { | ||
| 91 | dbmap* db=GetDB(env); | ||
| 92 | if(env.dbat>=0&&env.dbat<env.db->size()) db->Rem(env.dbat); | ||
| 93 | } | ||
| 94 | |||
| 95 | //////////////////////////////////////////////////////////////////// | ||
| 96 | |||
| 97 | TOK_IMPL(lastkey) { | ||
| 98 | dbmap* db=GetDB(env); | ||
| 99 | if(!db->empty()) out<<db->at(db->size()-1,db->Index()); | ||
| 100 | } | ||
| 101 | |||
| 102 | TOK_IMPL(prevkey) { | ||
| 103 | dbmap* db=GetDB(env); | ||
| 104 | if(env.dbat>0&&env.dbat<=db->size()) out<<db->at(env.dbat-1,db->Index()); | ||
| 105 | } | ||
| 106 | |||
| 107 | TOK_IMPL(nextkey) { | ||
| 108 | dbmap* db=GetDB(env); | ||
| 109 | if(env.dbat>=0&&env.dbat+1<db->size()) out<<db->at(env.dbat+1,db->Index()); | ||
| 110 | } | ||
| 111 | |||
| 112 | TOK_IMPL(qprevkey) { | ||
| 113 | dbmap* db=GetDB(env); | ||
| 114 | expr_t* x=env.arg(0); | ||
| 115 | Env nenv(env,*db); | ||
| 116 | nenv.dbat=env.dbat-1; | ||
| 117 | while(nenv.dbat>=0&&env.req->is_running()&&nenv.dbat<db->size()) { | ||
| 118 | if(eval(nenv,x,OP_LOCAL)) { out<<db->at(nenv.dbat,db->Index()); break; } | ||
| 119 | else nenv.dbat--; | ||
| 120 | } | ||
| 121 | } | ||
| 122 | |||
| 123 | TOK_IMPL(qnextkey) { | ||
| 124 | dbmap* db=GetDB(env); | ||
| 125 | expr_t* x=env.arg(0); | ||
| 126 | Env nenv(env,*db); | ||
| 127 | nenv.dbat=env.dbat+1; | ||
| 128 | while(nenv.dbat>=0&&env.req->is_running()&&nenv.dbat<db->size()) { | ||
| 129 | if(eval(nenv,x,OP_LOCAL)) { out<<db->at(nenv.dbat,db->Index()); break; } | ||
| 130 | else nenv.dbat++; | ||
| 131 | } | ||
| 132 | } | ||
| 133 | |||
| 134 | //////////////////////////////////////////////////////////////////// | ||
| 135 | |||
| 136 | void envAddDB(tokmap& T) | ||
| 137 | { | ||
| 138 | TOK_ADD(create,"xxxx",tok_t::SYSONLY, | ||
| 139 | "%Create a new database\n" | ||
| 140 | "%Syntax: \\create{varname}{tables}{index}{comp}\n" | ||
| 141 | "%\n" | ||
| 142 | "%Index is the unique, ordered table.\n" | ||
| 143 | "%Comp is the compare function.\n" | ||
| 144 | "%A maxmimum of 32 tables are allowed in HDB/1.2\n" | ||
| 145 | ); | ||
| 146 | TOK_ADD(sort,"xxx",tok_t::PRIVATE, | ||
| 147 | "%Sort a database\n" | ||
| 148 | "%Syntax: \\sort{varname}{index}{comp}\n" | ||
| 149 | "%\n" | ||
| 150 | "%Note that only globals on the current level are sortable.\n" | ||
| 151 | ); | ||
| 152 | |||
| 153 | //////////////////////////////////////////////////////// | ||
| 154 | |||
| 155 | TOK_ADD(db,"xr",tok_t::PRIVATE, | ||
| 156 | "%Set current database\n" | ||
| 157 | "%Syntax: \\db{varname}{body}\n" | ||
| 158 | "%\n" | ||
| 159 | "%Within body, all database functions apply.\n" | ||
| 160 | ); | ||
| 161 | TOK_ADD(query,"xr",tok_t::PRIVATE, | ||
| 162 | "%Query current database\n" | ||
| 163 | "%Syntax: \\query{test}{body}\n" | ||
| 164 | "%\n" | ||
| 165 | "%Evaluates body for all record where test is true.\n" | ||
| 166 | "%\n" | ||
| 167 | "%optimizes globals; it is ok to use full function\n" | ||
| 168 | "%expressions in the query. Turned out to be better after all.\n" | ||
| 169 | ); | ||
| 170 | TOK_ADD(find_rec,"xr?",tok_t::PRIVATE, | ||
| 171 | "%Find record by key, in current database\n" | ||
| 172 | "%Syntax: \\find.rec{key}{body}<else>\n" | ||
| 173 | "%\n" | ||
| 174 | "%Evaluates body if key is found in the current ordering.\n" | ||
| 175 | "%Otherwise, evaluates <else>, if exist.\n" | ||
| 176 | ); | ||
| 177 | |||
| 178 | //////////////////////////////////////////////////////// | ||
| 179 | |||
| 180 | TOK_ADD(first_rec,"",tok_t::PRIVATE, | ||
| 181 | "%Go to first record\n" | ||
| 182 | "%Syntax: \\first.rec\n" | ||
| 183 | ); | ||
| 184 | TOK_ADD(exist_rec,"",tok_t::PRIVATE, | ||
| 185 | "%True if current record exist\n" | ||
| 186 | "%Syntax: \\exist.rec\n" | ||
| 187 | ); | ||
| 188 | TOK_ADD(next_rec,"",tok_t::PRIVATE, | ||
| 189 | "%Go to next record\n" | ||
| 190 | "%Syntax: \\next.rec\n" | ||
| 191 | ); | ||
| 192 | TOK_ADD(prev_rec,"",tok_t::PRIVATE, | ||
| 193 | "%Go to previous record\n" | ||
| 194 | "%Syntax: \\prev.rec\n" | ||
| 195 | ); | ||
| 196 | TOK_ADD(rem_rec,"",tok_t::SYSONLY, | ||
| 197 | "%Remove current record\n" | ||
| 198 | "%Syntax: \\rem.rec\n" | ||
| 199 | ); | ||
| 200 | |||
| 201 | //////////////////////////////////////////////////////// | ||
| 202 | |||
| 203 | TOK_ADD(lastkey,"",tok_t::PRIVATE, | ||
| 204 | "%Last key of current order\n" | ||
| 205 | "%Syntax: \\lastkey\n" | ||
| 206 | "%\n" | ||
| 207 | "%Silently ignored if not found.\n" | ||
| 208 | ); | ||
| 209 | TOK_ADD(prevkey,"",tok_t::PRIVATE, | ||
| 210 | "%Previous key of current order\n" | ||
| 211 | "%Syntax: \\prevkey\n" | ||
| 212 | "%\n" | ||
| 213 | "%Silently ignored if not found.\n" | ||
| 214 | ); | ||
| 215 | TOK_ADD(nextkey,"",tok_t::PRIVATE, | ||
| 216 | "%Next key of current order\n" | ||
| 217 | "%Syntax: \\nextkey\n" | ||
| 218 | "%\n" | ||
| 219 | "%Silently ignored if not found.\n" | ||
| 220 | ); | ||
| 221 | |||
| 222 | //////////////////////////////////////////////////////// | ||
| 223 | |||
| 224 | TOK_ADD(qprevkey,"r",tok_t::PRIVATE, | ||
| 225 | "%Previous key of current order, satisfying query\n" | ||
| 226 | "%Syntax: \\qprevkey\n" | ||
| 227 | "%\n" | ||
| 228 | "%Silently ignored if not found.\n" | ||
| 229 | ); | ||
| 230 | TOK_ADD(qnextkey,"r",tok_t::PRIVATE, | ||
| 231 | "%Next key of current order, satisfying query\n" | ||
| 232 | "%Syntax: \\qnextkey\n" | ||
| 233 | "%\n" | ||
| 234 | "%Silently ignored if not found.\n" | ||
| 235 | ); | ||
| 236 | |||
| 237 | } | ||
diff --git a/src/lang/env.cc b/src/lang/env.cc new file mode 100644 index 0000000..83f1a7e --- /dev/null +++ b/src/lang/env.cc | |||
| @@ -0,0 +1,308 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <lang/env.h> | ||
| 21 | #include <mt/random.h> | ||
| 22 | |||
| 23 | static unsigned long seed=RandomInit(time(0)); | ||
| 24 | |||
| 25 | mstring Random(int n) | ||
| 26 | { | ||
| 27 | mstring s; | ||
| 28 | for(int i=0;i<n;i++) { | ||
| 29 | int digit=int(10*Uniform()); | ||
| 30 | if(digit>9) THROW("env: assertion on lib failed"); | ||
| 31 | s+=char(48+digit); | ||
| 32 | } | ||
| 33 | return s; | ||
| 34 | } | ||
| 35 | |||
| 36 | /////////////////////////////////////////////////// | ||
| 37 | |||
| 38 | void Env::clear_args() | ||
| 39 | { | ||
| 40 | for(int i=0;i<xarg.size();i++) delete xarg[i]; xarg.clear(); | ||
| 41 | for(int i=0;i<rarg.size();i++) delete rarg[i]; rarg.clear(); | ||
| 42 | args=0; | ||
| 43 | } | ||
| 44 | |||
| 45 | void Env::parg(mstream& out,int n) throw(merror_t) | ||
| 46 | { | ||
| 47 | if(args) { | ||
| 48 | if(n<0) n+=args; | ||
| 49 | if(n>=0&&n<args) { | ||
| 50 | if(n<xsize()) out<<xarg[n]->result; | ||
| 51 | else eval(out,rarg[n-xsize()],0); | ||
| 52 | } | ||
| 53 | } | ||
| 54 | else if(up) up->parg(out,n); | ||
| 55 | } | ||
| 56 | |||
| 57 | void Env::parg(mstring& tmp,int n) throw(merror_t) | ||
| 58 | { | ||
| 59 | swrite sw(tmp); | ||
| 60 | parg(sw,n); | ||
| 61 | } | ||
| 62 | |||
| 63 | mstring Env::parg(int n) throw(merror_t) | ||
| 64 | { | ||
| 65 | mswrite tmp; parg(tmp,n); return tmp.str(); | ||
| 66 | } | ||
| 67 | |||
| 68 | ////////////////////////////////////////////////////// | ||
| 69 | |||
| 70 | int Env::onarg(int n) const | ||
| 71 | { | ||
| 72 | if(args) { | ||
| 73 | if(n<0) n+=args; | ||
| 74 | if(n>=0&&n<args) { | ||
| 75 | if(n<xsize()) return xarg[n]->result.nempty(); | ||
| 76 | else return rarg[n-xsize()]->expr.nempty(); | ||
| 77 | } | ||
| 78 | } | ||
| 79 | else if(up) return up->onarg(n); | ||
| 80 | return 0; | ||
| 81 | } | ||
| 82 | |||
| 83 | expr_t* Env::arg(int n) throw(merror_t) { | ||
| 84 | if(args) { | ||
| 85 | if(n<0) n+=args; | ||
| 86 | if(n>=0&&n<args) { | ||
| 87 | if(n<xsize()) return xarg[n]; | ||
| 88 | else return rarg[n-xsize()]; | ||
| 89 | } | ||
| 90 | } | ||
| 91 | else if(up) return up->arg(n); | ||
| 92 | THROW("env: bad arg number "<<n); | ||
| 93 | return 0; | ||
| 94 | } | ||
| 95 | |||
| 96 | const sref& Env::operator[](int n) const throw(merror_t) { | ||
| 97 | if(args) { | ||
| 98 | if(n<0) n+=args; | ||
| 99 | if(n>=0&&n<args) { | ||
| 100 | if(n<xsize()) return xarg[n]->result; | ||
| 101 | else THROW("env: post-eval expression not readable here"); | ||
| 102 | } | ||
| 103 | } | ||
| 104 | else if(up) return up->operator[](n); | ||
| 105 | THROW("env: bad arg number "<<n); | ||
| 106 | return ms_empty; | ||
| 107 | } | ||
| 108 | |||
| 109 | ////////////////////////////////////////////////////// | ||
| 110 | |||
| 111 | const sref Env::glob(const sref& t) const throw(merror_t) | ||
| 112 | { | ||
| 113 | const tok_t* p=toks->get(t); | ||
| 114 | if(is_clear(p)&&!p->is_runnable()) return p->body; | ||
| 115 | THROW("env: could not find global variable "<<t); | ||
| 116 | return ms_empty; | ||
| 117 | } | ||
| 118 | |||
| 119 | int Env::glob_find(const sref& t) const | ||
| 120 | { | ||
| 121 | const tok_t* p=toks->get(t); | ||
| 122 | return is_clear(p)&&!p->is_runnable(); | ||
| 123 | } | ||
| 124 | |||
| 125 | int Env::onglob(const sref& t) const | ||
| 126 | { | ||
| 127 | const tok_t* p=toks->get(t); | ||
| 128 | return is_clear(p)&&!p->is_runnable()&&p->body.nempty(); | ||
| 129 | } | ||
| 130 | |||
| 131 | void Env::glob_list(rpile& list,const sref& t) const | ||
| 132 | { | ||
| 133 | list.clear(); | ||
| 134 | if(t.empty()) { | ||
| 135 | for(const_iterator p=toks->begin();p!=toks->end();++p) { | ||
| 136 | if(is_clear(*p)&&!(*p)->is_runnable()) list.push_back((*p)->name); | ||
| 137 | } | ||
| 138 | } | ||
| 139 | else { | ||
| 140 | int cont=1; | ||
| 141 | for(const tokmap* tok=toks;tok&&cont;tok=tok->up) { | ||
| 142 | for(const_iterator p=tok->begin();p!=tok->end();++p) { | ||
| 143 | if((*p)->name.left(t.size())==t&&is_clear(*p)&&!(*p)->is_runnable()) { | ||
| 144 | list.push_back((*p)->name); | ||
| 145 | cont=0; | ||
| 146 | } | ||
| 147 | } | ||
| 148 | } | ||
| 149 | } | ||
| 150 | } | ||
| 151 | |||
| 152 | void Env::glob_adb(const sref& fx,const sref& t) throw(merror_t) | ||
| 153 | { | ||
| 154 | if(!db) THROW("htc: no active database"); | ||
| 155 | rpile list; glob_list(list,t); | ||
| 156 | mrvec<int> col(list.size()); | ||
| 157 | int index=-1; | ||
| 158 | for(int i=0;i<col.size();i++) { | ||
| 159 | col[i]=db->Index(fx+list[i].right(t.size())); | ||
| 160 | if(col[i]==db->Index()) index=i; | ||
| 161 | } | ||
| 162 | if(index<0) THROW("env: index required when adding a db record"); | ||
| 163 | int row=db->Find(glob(list[index])); | ||
| 164 | if(row>=0) { | ||
| 165 | for(int i=0;i<list.size();i++) if(i!=index) db->Set(row,col[i],glob(list[i])); | ||
| 166 | } | ||
| 167 | else { | ||
| 168 | spile nlist(db->Tables()); | ||
| 169 | for(int i=0;i<list.size();i++) nlist[col[i]]=glob(list[i]); | ||
| 170 | row=db->Insert(nlist,1); | ||
| 171 | } | ||
| 172 | if(row<0) THROW("htc: could not add record - denied"); | ||
| 173 | dbat=row; | ||
| 174 | } | ||
| 175 | |||
| 176 | ////////////////////////////////////////////////////// | ||
| 177 | |||
| 178 | const sref Env::aloc(const sref& t,const sref& v) throw(merror_t) | ||
| 179 | { | ||
| 180 | if(!is_tokname(t)) THROW("env: bad token name "<<t); | ||
| 181 | return loc.add(new tok_t(t,v,tight()),1,1)->body; | ||
| 182 | } | ||
| 183 | |||
| 184 | const sref Env::sloc(const sref& t,const sref& v) throw(merror_t) | ||
| 185 | { | ||
| 186 | if(db) { | ||
| 187 | int p=db->FindIndex(*t=='@'?t.popf():t); | ||
| 188 | if(p>=0) { | ||
| 189 | if(p==db->Index()) THROW("env: cannot assign to db index"); | ||
| 190 | if(dbat<0||dbat>=db->size()) THROW("env: not a valid db record"); | ||
| 191 | db->Set(dbat,p,v); | ||
| 192 | return db->at(dbat,p); | ||
| 193 | } | ||
| 194 | } | ||
| 195 | return loc.set(new tok_t(t,v,tight()),1,1)->body; | ||
| 196 | } | ||
| 197 | |||
| 198 | const sref Env::gloc(const sref& t) const throw(merror_t) | ||
| 199 | { | ||
| 200 | if(db) { | ||
| 201 | int p=db->FindIndex(*t=='@'?t.popf():t); | ||
| 202 | if(p>=0) { | ||
| 203 | if(dbat>=0&&dbat<db->size()) return db->at(dbat,p); | ||
| 204 | else THROW("env: not a valid database record"); | ||
| 205 | } | ||
| 206 | } | ||
| 207 | const tok_t* p=loc.get(t); | ||
| 208 | if(is_clear(p)&&!p->is_runnable()) return p->body; | ||
| 209 | THROW("env: could not find local variable "<<t); | ||
| 210 | return ms_empty; | ||
| 211 | } | ||
| 212 | |||
| 213 | int Env::gloc_find(const sref& t) const | ||
| 214 | { | ||
| 215 | if(db) { | ||
| 216 | int p=db->FindIndex(*t=='@'?t.popf():t); | ||
| 217 | if(p>=0) return dbat>=0&&dbat<db->size(); | ||
| 218 | } | ||
| 219 | const tok_t* p=loc.get(t); | ||
| 220 | return is_clear(p)&&!p->is_runnable(); | ||
| 221 | } | ||
| 222 | |||
| 223 | int Env::onloc(const sref& t) const | ||
| 224 | { | ||
| 225 | if(db) { | ||
| 226 | int p=db->FindIndex(*t=='@'?t.popf():t); | ||
| 227 | if(p>=0) return dbat>=0&&dbat<db->size()&&db->at(dbat,p).nempty(); | ||
| 228 | } | ||
| 229 | const tok_t* p=loc.get(t); | ||
| 230 | return is_clear(p)&&!p->is_runnable()&&p->body.nempty(); | ||
| 231 | } | ||
| 232 | |||
| 233 | void Env::gloc_list(rpile& list,const sref& t) const | ||
| 234 | { | ||
| 235 | list.clear(); | ||
| 236 | if(t.empty()) { | ||
| 237 | for(const_iterator p=loc.begin();p!=loc.end();++p) { | ||
| 238 | if(is_clear(*p)&&!(*p)->is_runnable()) list.push_back((*p)->name); | ||
| 239 | } | ||
| 240 | } | ||
| 241 | else if(*t=='@') { | ||
| 242 | if(db) { | ||
| 243 | sref tt=t.popf(); | ||
| 244 | for(int i=0;i<db->Tables();i++) { | ||
| 245 | if(tt.empty()||db->Table(i).left(tt.size())==tt) list.push_back(db->Table(i)); | ||
| 246 | } | ||
| 247 | } | ||
| 248 | else THROW("env: cannot use '@' - no active database"); | ||
| 249 | } | ||
| 250 | else { | ||
| 251 | int cont=1; | ||
| 252 | for(const tokmap* tok=&loc;tok&&cont;tok=tok->up) { | ||
| 253 | for(const_iterator p=tok->begin();p!=tok->end();++p) { | ||
| 254 | if((*p)->name.left(t.size())==t&&is_clear(*p)&&!(*p)->is_runnable()) { | ||
| 255 | list.push_back((*p)->name); | ||
| 256 | cont=0; | ||
| 257 | } | ||
| 258 | } | ||
| 259 | } | ||
| 260 | } | ||
| 261 | } | ||
| 262 | |||
| 263 | void Env::gloc_adb(const sref& fx,const sref& t) throw(merror_t) | ||
| 264 | { | ||
| 265 | if(!db) THROW("htc: no active database"); | ||
| 266 | rpile list; gloc_list(list,t); | ||
| 267 | mrvec<int> col(list.size()); | ||
| 268 | int index=-1; | ||
| 269 | for(int i=0;i<col.size();i++) { | ||
| 270 | col[i]=db->Index(fx+list[i].right(t.size())); | ||
| 271 | if(col[i]==db->Index()) index=i; | ||
| 272 | } | ||
| 273 | if(index<0) THROW("env: index required when adding a db record"); | ||
| 274 | int row=db->Find(gloc(list[index])); | ||
| 275 | if(row>=0) { | ||
| 276 | for(int i=0;i<list.size();i++) if(i!=index) db->Set(row,col[i],gloc(list[i])); | ||
| 277 | } | ||
| 278 | else { | ||
| 279 | spile nlist(db->Tables()); | ||
| 280 | for(int i=0;i<list.size();i++) nlist[col[i]]=gloc(list[i]); | ||
| 281 | row=db->Insert(nlist,1); | ||
| 282 | } | ||
| 283 | if(row<0) THROW("htc: could not add record - denied"); | ||
| 284 | dbat=row; | ||
| 285 | } | ||
| 286 | |||
| 287 | ////////////////////////////////////////////////////// | ||
| 288 | |||
| 289 | const mstring sback="../",sident="./",sdots="..",sslash="//"; | ||
| 290 | |||
| 291 | mstring Env::URI(const sref& raw) | ||
| 292 | { | ||
| 293 | int s; mstring cwd=pwd.left_last('/'),uri=raw; | ||
| 294 | while(uri.left(sback.size())==sback) { | ||
| 295 | uri.erase(0,sback.size()); | ||
| 296 | cwd=cwd.left_last('/'); | ||
| 297 | } | ||
| 298 | while((s=uri.find(sback))>=0) { | ||
| 299 | mstring tmp=uri.left(s).left_last('/').leftand_last('/'); | ||
| 300 | tmp+=uri.right(s+sback.size()); | ||
| 301 | uri=tmp; | ||
| 302 | } | ||
| 303 | while((s=uri.find(sdots))>=0) uri.erase(s,sdots.size()); | ||
| 304 | while((s=uri.find(sident))>=0) uri.erase(s,sident.size()); | ||
| 305 | while((s=uri.find(sslash))>=0) uri.erase(s,sslash.size()); | ||
| 306 | if(*uri=='/') return uri; | ||
| 307 | else { cwd+='/'; cwd+=uri; return cwd; } | ||
| 308 | } | ||
diff --git a/src/lang/env.h b/src/lang/env.h new file mode 100644 index 0000000..1313d18 --- /dev/null +++ b/src/lang/env.h | |||
| @@ -0,0 +1,156 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef ENVH | ||
| 21 | #define ENVH | ||
| 22 | |||
| 23 | #include <lang/token.h> | ||
| 24 | |||
| 25 | mstring Random(int n); | ||
| 26 | |||
| 27 | const int OP_PARSE=8; | ||
| 28 | const mstring para_def="\n"; | ||
| 29 | |||
| 30 | //////////////////////////////////////////////////////////////////// | ||
| 31 | |||
| 32 | struct Lang { | ||
| 33 | volatile int running; | ||
| 34 | opmap ops; | ||
| 35 | tokmap toks; | ||
| 36 | Lang(); | ||
| 37 | virtual ~Lang() {} | ||
| 38 | }; | ||
| 39 | |||
| 40 | struct req_env { | ||
| 41 | Lang* glob; | ||
| 42 | tokmap toks; | ||
| 43 | mstring uri; | ||
| 44 | int lang; | ||
| 45 | volatile int* running; | ||
| 46 | |||
| 47 | int is_running() const { return glob->running&&(!running||*running); } | ||
| 48 | |||
| 49 | req_env(Lang& g,tokmap& p) : glob(&g),toks(p),uri(),lang(0),running(0) {} | ||
| 50 | virtual ~req_env() {} | ||
| 51 | }; | ||
| 52 | |||
| 53 | //////////////////////////////////////////////////////////////////// | ||
| 54 | |||
| 55 | struct Env : public op_env { | ||
| 56 | typedef mrvec<expr_t*> xpile; | ||
| 57 | typedef tokmap::iterator iterator; | ||
| 58 | typedef tokmap::const_iterator const_iterator; | ||
| 59 | |||
| 60 | Env(opmap& op,req_env& r,unsigned m): | ||
| 61 | op_env(op),req(&r),toks(&r.toks),up(0),mod(m), | ||
| 62 | loc(),db(0),dbat(0),pwd(r.uri),para(para_def),args(0) {} | ||
| 63 | |||
| 64 | Env(Env& p,tokmap& tok,const sref& cwd): | ||
| 65 | op_env(p),req(p.req),toks(&tok),up(p.up),mod(p.mod), | ||
| 66 | loc(p.loc),db(0),dbat(0),pwd(cwd),para(p.para),args(0) {} | ||
| 67 | Env(Env& p,unsigned m,const sref& cwd): | ||
| 68 | op_env(p),req(p.req),toks(p.toks),up(p.up),mod(m), | ||
| 69 | loc(p.loc),db(0),dbat(0),pwd(cwd),para(p.para),args(0) {} | ||
| 70 | |||
| 71 | Env(Env& p): | ||
| 72 | op_env(p),req(p.req),toks(p.toks),up(p.up),mod(p.mod), | ||
| 73 | loc(p.loc),db(p.db),dbat(p.dbat),pwd(p.pwd),para(p.para),args(0) {} | ||
| 74 | Env(Env& p,dbmap& dbm): | ||
| 75 | op_env(p),req(p.req),toks(p.toks),up(p.up),mod(p.mod), | ||
| 76 | loc(p.loc),db(&dbm),dbat(0),pwd(p.pwd),para(p.para),args(0) {} | ||
| 77 | Env(Env& p,opmap& op): | ||
| 78 | op_env(op),req(p.req),toks(p.toks),up(p.up),mod(p.mod), | ||
| 79 | loc(p.loc),db(p.db),dbat(p.dbat),pwd(p.pwd),para(p.para),args(0) {} | ||
| 80 | |||
| 81 | ~Env() { clear_args(); } | ||
| 82 | |||
| 83 | int is_clear(const tok_t* tok) const { return tok&&tok->is_clear(mod); } | ||
| 84 | unsigned tight() const { return tok_t::tight(mod); } | ||
| 85 | |||
| 86 | int check_arg(const runnable_t& ftok) const; | ||
| 87 | int is_arg(const sref& t) const { return cset_digit.test(t.front()); } | ||
| 88 | |||
| 89 | int xsize() const { return xarg.size(); } | ||
| 90 | int rsize() const { return rarg.size(); } | ||
| 91 | |||
| 92 | void xpush(const sref& in) throw(merror_t); | ||
| 93 | void rpush(const sref& in) throw(merror_t); | ||
| 94 | void clear_args(); | ||
| 95 | |||
| 96 | void parg(mstream& out,int n) throw(merror_t); | ||
| 97 | void parg(mstring& buf,int n) throw(merror_t); | ||
| 98 | mstring parg(int n) throw(merror_t); | ||
| 99 | |||
| 100 | const sref& operator[](int m) const throw(merror_t); | ||
| 101 | expr_t* arg(int m) throw(merror_t); | ||
| 102 | |||
| 103 | const sref glob(const sref& t) const throw(merror_t); | ||
| 104 | |||
| 105 | int glob_find(const sref& t) const; | ||
| 106 | void glob_list(rpile& list,const sref& t) const; | ||
| 107 | void glob_adb(const sref& fx,const sref& t) throw(merror_t); | ||
| 108 | |||
| 109 | const sref aloc(const sref& t,const sref& v) throw(merror_t); | ||
| 110 | const sref sloc(const sref& t,const sref& v) throw(merror_t); | ||
| 111 | const sref gloc(const sref& t) const throw(merror_t); | ||
| 112 | |||
| 113 | int gloc_find(const sref& t) const; | ||
| 114 | void gloc_list(rpile& list,const sref& t) const; | ||
| 115 | void gloc_adb(const sref& fx,const sref& t) throw(merror_t); | ||
| 116 | |||
| 117 | int onarg(int m) const; | ||
| 118 | int onglob(const sref& s) const; | ||
| 119 | int onloc(const sref& s) const; | ||
| 120 | |||
| 121 | void parse(mstream& out,const sref& in) throw(merror_t); | ||
| 122 | void expr(mstream& out,const sref& in) throw(merror_t); | ||
| 123 | void parse(mstream& out,expr_t* x) throw(merror_t); | ||
| 124 | |||
| 125 | void eval(mstream& out,const sref& in,int child) throw(merror_t); | ||
| 126 | void eval(mstream& out,expr_t* x,int child) throw(merror_t); | ||
| 127 | void eval(mstream& out,runnable_t* ftok,int child) throw(merror_t); | ||
| 128 | |||
| 129 | int split(sref& first,sref& rest) throw(merror_t); | ||
| 130 | void term(mstream& out,expr_t* x) throw(merror_t); | ||
| 131 | |||
| 132 | mstring URI(const sref& raw); | ||
| 133 | |||
| 134 | Env *up; | ||
| 135 | req_env* req; | ||
| 136 | tokmap* toks; | ||
| 137 | int mod,dbat; | ||
| 138 | tokmap loc; | ||
| 139 | dbmap* db; | ||
| 140 | mstring pwd,para,epilog; | ||
| 141 | int args; | ||
| 142 | xpile xarg,rarg; | ||
| 143 | }; | ||
| 144 | |||
| 145 | ///////////////////////////////////////////////////////////////////// | ||
| 146 | |||
| 147 | struct latex_env : public Env { | ||
| 148 | latex_env(Env& p); | ||
| 149 | |||
| 150 | int split(sref& first,sref& rest) throw(merror_t); | ||
| 151 | void term(mstream& out,expr_t* x) throw(merror_t); | ||
| 152 | }; | ||
| 153 | |||
| 154 | ///////////////////////////////////////////////////////////////////// | ||
| 155 | |||
| 156 | #endif | ||
diff --git a/src/lang/flow.cc b/src/lang/flow.cc new file mode 100644 index 0000000..c7c70a0 --- /dev/null +++ b/src/lang/flow.cc | |||
| @@ -0,0 +1,198 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <lang/env.h> | ||
| 21 | #include <mt/dates.h> | ||
| 22 | using namespace std; | ||
| 23 | |||
| 24 | TOK_IMPL(branch) { | ||
| 25 | int index=atoi(env[0]); | ||
| 26 | if(index<0) index+=env.args; | ||
| 27 | if(index>0&&index<env.args) env.parg(out,index); | ||
| 28 | else if(index<0||index>=env.args) THROW("htc: bad branching index "<<index); | ||
| 29 | } | ||
| 30 | |||
| 31 | TOK_IMPL(if) { | ||
| 32 | if(atob(env[0])) env.parg(out,1); else env.parg(out,2); | ||
| 33 | } | ||
| 34 | |||
| 35 | TOK_IMPL(nif) { | ||
| 36 | if(!atob(env[0])) env.parg(out,1); else env.parg(out,2); | ||
| 37 | } | ||
| 38 | |||
| 39 | TOK_IMPL(switch) { | ||
| 40 | sref s=env[0]; | ||
| 41 | int i; | ||
| 42 | for(i=1;i+1<env.args;i+=2) if(env.parg(i)==s) { env.parg(out,i+1); return; } | ||
| 43 | if(i<env.args) env.parg(out,i); | ||
| 44 | } | ||
| 45 | |||
| 46 | ///////////////////////////////////////////////////////////////////// | ||
| 47 | |||
| 48 | static int eval(Env& env,expr_t* x,int mod) { | ||
| 49 | mswrite out; | ||
| 50 | if(x->status&OP_PARSE) env.parse(out,x->expr); else x->eval(out,env,mod); | ||
| 51 | return atob(out.str()); | ||
| 52 | } | ||
| 53 | |||
| 54 | TOK_IMPL(for) { | ||
| 55 | expr_t* x[4]={env.arg(0),env.arg(1),env.arg(2),env.arg(3)}; | ||
| 56 | Env nenv(env); | ||
| 57 | for(eval(nenv,x[0],OP_ALL); | ||
| 58 | env.req->is_running()&&eval(nenv,x[1],OP_LOCAL); | ||
| 59 | eval(nenv,x[2],OP_LOCAL)) | ||
| 60 | nenv.parse(out,x[3]); | ||
| 61 | } | ||
| 62 | |||
| 63 | TOK_IMPL(while) { | ||
| 64 | expr_t* x[2]={env.arg(0),env.arg(1)}; | ||
| 65 | Env nenv(env); | ||
| 66 | while(env.req->is_running()&&eval(nenv,x[0],OP_ALL)) nenv.parse(out,x[1]); | ||
| 67 | } | ||
| 68 | |||
| 69 | ///////////////////////////////////////////////////////////////////// | ||
| 70 | |||
| 71 | TOK_IMPL(forall) { | ||
| 72 | mstring sep; env.parg(sep,-1); | ||
| 73 | sref s=env[0]; | ||
| 74 | sref p,e=env[1]; | ||
| 75 | expr_t* x=env.arg(2); | ||
| 76 | Env nenv(env); | ||
| 77 | if(sep.nempty()) { | ||
| 78 | charset seps(sep.c_str()); | ||
| 79 | while(Split(p,e,seps)) { | ||
| 80 | nenv.aloc(s,p); | ||
| 81 | nenv.parse(out,x); | ||
| 82 | } | ||
| 83 | } | ||
| 84 | else { | ||
| 85 | while(Split(p,e)) { | ||
| 86 | nenv.aloc(s,p); | ||
| 87 | nenv.parse(out,x); | ||
| 88 | } | ||
| 89 | } | ||
| 90 | } | ||
| 91 | |||
| 92 | ///////////////////////////////////////////////////////////////////// | ||
| 93 | |||
| 94 | TOK_IMPL(on_arg) { | ||
| 95 | if(env.up&&env.up->onarg(atoi(env[0])-1)) env.parg(out,1); else env.parg(out,2); | ||
| 96 | } | ||
| 97 | TOK_IMPL(on_glob) { if(env.onglob(env[0])) env.parg(out,1); else env.parg(out,2); } | ||
| 98 | TOK_IMPL(on_loc) { if(env.onloc(env[0])) env.parg(out,1); else env.parg(out,2); } | ||
| 99 | |||
| 100 | ///////////////////////////////////////////////////////////////////// | ||
| 101 | |||
| 102 | TOK_IMPL(setlang) { | ||
| 103 | env.req->lang=Language(env[0]); if(env.req->lang<0) env.req->lang=0; | ||
| 104 | } | ||
| 105 | |||
| 106 | TOK_IMPL(lang) { | ||
| 107 | env.parg(out,env.req->lang); | ||
| 108 | } | ||
| 109 | |||
| 110 | ///////////////////////////////////////////////////////////////////// | ||
| 111 | |||
| 112 | void envAddFlow(tokmap& T) | ||
| 113 | { | ||
| 114 | TOK_ADD(branch,"x*",tok_t::PUBLIC, | ||
| 115 | "%Multiple branch\n" | ||
| 116 | "%Syntax: \\branch{x}<body>..<body>\n" | ||
| 117 | "%\n" | ||
| 118 | "%x==0 means nothing is executed, the first body for x==1, etc\n" | ||
| 119 | "%Negative values wrap to end\n" | ||
| 120 | ); | ||
| 121 | TOK_ADD(if,"xr?",tok_t::PUBLIC, | ||
| 122 | "%if - logical branch\n" | ||
| 123 | "%Syntax: \\if{x}{body}<else>\n" | ||
| 124 | "%\n" | ||
| 125 | "%if x is non-zero, evaluates body, otherwise else if exist\n" | ||
| 126 | ); | ||
| 127 | TOK_ADD(nif,"xr?",tok_t::PUBLIC, | ||
| 128 | "%nif - logical branch\n" | ||
| 129 | "%Syntax: \\nif{x}{body}<else>\n" | ||
| 130 | "%\n" | ||
| 131 | "%if x is zero, evaluates body, otherwise else if exist\n" | ||
| 132 | ); | ||
| 133 | TOK_ADD(switch,"x*",tok_t::PUBLIC, | ||
| 134 | "%Multiple switch\n" | ||
| 135 | "%Syntax: \\switch{x}<val><body>..<val><body>..<default>\n" | ||
| 136 | "%\n" | ||
| 137 | "%A sequence of pairs <val><body> follows x\n" | ||
| 138 | "%x==val means body is executed\n" | ||
| 139 | "%\n" | ||
| 140 | "%An unpaired body at the end is treated as default\n" | ||
| 141 | ); | ||
| 142 | |||
| 143 | ///////////////////////////////////////////////////////////////////// | ||
| 144 | |||
| 145 | TOK_ADD(for,"rrrr",tok_t::PRIVATE, | ||
| 146 | "%C style\n" | ||
| 147 | "%Syntax: \\for{start}{test}{next}{body}\n" | ||
| 148 | "%\n" | ||
| 149 | "%Note that test and next are evaluated with optimization: only\n" | ||
| 150 | "%local variables are updated. Hence, you cannot use a function\n" | ||
| 151 | "%as the whole test, only as a part of the test, as in i<\\function.\n" | ||
| 152 | ); | ||
| 153 | TOK_ADD(while,"rr",tok_t::PRIVATE, | ||
| 154 | "%C style\n" | ||
| 155 | "%Syntax: \\while{test}{body}\n" | ||
| 156 | "%\n" | ||
| 157 | "%There is no optimization on test - globals are re-evaluated in each step\n" | ||
| 158 | ); | ||
| 159 | TOK_ADD(forall,"xx?r",tok_t::PUBLIC, | ||
| 160 | "%Loop through elements\n" | ||
| 161 | "%Syntax: \\forall{varname}{list}<additional whitespace>{body}\n" | ||
| 162 | "%\n" | ||
| 163 | "%Default whitespace are ( \\t\\r\\n). Optional whitespace characters\n" | ||
| 164 | "%may be given. This enables the design of special lists.\n" | ||
| 165 | ); | ||
| 166 | |||
| 167 | ///////////////////////////////////////////////////////////////////// | ||
| 168 | |||
| 169 | TOK_ADD(on_arg,"xr?",tok_t::PUBLIC, | ||
| 170 | "%Do if arg exist and is non-empty\n" | ||
| 171 | "%Syntax: \\on.arg{number}{body}<else>\n" | ||
| 172 | ); | ||
| 173 | TOK_ADD(on_glob,"xr?",tok_t::PUBLIC, | ||
| 174 | "%Do if global variable exist and is non-empty\n" | ||
| 175 | "%Syntax: \\on.glob{varname}{body}<else>\n" | ||
| 176 | ); | ||
| 177 | TOK_ADD(on_loc,"xr?",tok_t::PUBLIC, | ||
| 178 | "%Do if local variable exist and is non-empty\n" | ||
| 179 | "%Syntax: \\on.loc{varname}{body}<else>\n" | ||
| 180 | ); | ||
| 181 | |||
| 182 | ///////////////////////////////////////////////////////////////////// | ||
| 183 | |||
| 184 | TOK_ADD(lang,"r*",tok_t::PUBLIC, | ||
| 185 | "%Branch on global language\n" | ||
| 186 | "%Syntax: \\lang{en}{sv}..\n" | ||
| 187 | "%\n" | ||
| 188 | "%Currently English (en) and Swedish (sv) are supported\n" | ||
| 189 | ); | ||
| 190 | TOK_ADD(setlang,"x",tok_t::PUBLIC, | ||
| 191 | "%Set global language\n" | ||
| 192 | "%Syntax: \\setlang{language code list}\n" | ||
| 193 | "%\n" | ||
| 194 | "%The language actually set is a negotitation -\n" | ||
| 195 | "%the first code in the list recognized is set.\n" | ||
| 196 | "%If not found, the default language English (en) is set.\n" | ||
| 197 | ); | ||
| 198 | } | ||
diff --git a/src/lang/func.cc b/src/lang/func.cc new file mode 100644 index 0000000..98cc04c --- /dev/null +++ b/src/lang/func.cc | |||
| @@ -0,0 +1,249 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <lang/env.h> | ||
| 21 | #include <unistd.h> | ||
| 22 | |||
| 23 | const mstring cron_tag="cron."; | ||
| 24 | const int SSECS=4; | ||
| 25 | |||
| 26 | TOK_IMPL(def) { | ||
| 27 | expr_t* x=env.arg(2); | ||
| 28 | func_t* tok=Func(*env.toks,env[0],x->expr,tok_t::PUBLIC,env[1]); | ||
| 29 | if(x->status&OP_PARSE) tok->x.status=OP_PARSE; else tok->x.expand(env); | ||
| 30 | } | ||
| 31 | |||
| 32 | TOK_IMPL(redef) { | ||
| 33 | expr_t* x=env.arg(2); | ||
| 34 | func_t* tok=Func(*env.toks,env[0],x->expr,tok_t::PUBLIC,env[1],1); | ||
| 35 | if(x->status&OP_PARSE) tok->x.status=OP_PARSE; else tok->x.expand(env); | ||
| 36 | } | ||
| 37 | |||
| 38 | TOK_IMPL(ldef) { | ||
| 39 | if(env.toks->get(env[0])) THROW("htc: local function would override global token"); | ||
| 40 | expr_t* x=env.arg(2); | ||
| 41 | func_t* tok=Func(env.loc,env[0],x->expr,tok_t::PUBLIC,env[1]); | ||
| 42 | if(x->status&OP_PARSE) tok->x.status=OP_PARSE; else tok->x.expand(env); | ||
| 43 | } | ||
| 44 | |||
| 45 | TOK_IMPL(cron) { | ||
| 46 | mstring name=cron_tag+env[0]; | ||
| 47 | expr_t* x=env.arg(1); | ||
| 48 | cron_t* tok=Cron(*env.toks,name,x->expr,tok_t::PUBLIC,atoi(env[0])); | ||
| 49 | if(x->status&OP_PARSE) tok->x.status=OP_PARSE; else tok->x.expand(env); | ||
| 50 | } | ||
| 51 | |||
| 52 | /////////////////////////////////////////////////// | ||
| 53 | |||
| 54 | static void Run(tokmap& m,mstream& out,Env& env,const sref& s) throw(merror_t) { | ||
| 55 | tok_t* p=m.get(s); | ||
| 56 | if(!p) THROW("htc: cannot run "<<s<<"; does not exist"); | ||
| 57 | try { | ||
| 58 | if(p->is_reference()) env.parse(out,((reference_t*)p)->data); | ||
| 59 | else if(!p->is_runnable()) env.parse(out,p->body); | ||
| 60 | } | ||
| 61 | catch(const merror_t& e) { | ||
| 62 | out<<e.desc; | ||
| 63 | } | ||
| 64 | } | ||
| 65 | |||
| 66 | TOK_IMPL(run) { | ||
| 67 | Env e(env,env.mod,env.pwd); | ||
| 68 | Run(*env.toks,out,e,env[0]); | ||
| 69 | } | ||
| 70 | TOK_IMPL(run_private) { | ||
| 71 | Env e(env,XPRIVATE,env.pwd); | ||
| 72 | Run(*env.toks,out,e,env[0]); | ||
| 73 | } | ||
| 74 | TOK_IMPL(run_public) { | ||
| 75 | Env e(env,XPUBLIC,env.pwd); | ||
| 76 | Run(*env.toks,out,e,env[0]); | ||
| 77 | } | ||
| 78 | TOK_IMPL(run_local) { | ||
| 79 | try { | ||
| 80 | Env e(env,XPUBLIC,env.pwd); | ||
| 81 | e.parse(out,env.gloc(env[0])); | ||
| 82 | } | ||
| 83 | catch(const merror_t& e) { | ||
| 84 | out<<e.desc; | ||
| 85 | } | ||
| 86 | } | ||
| 87 | TOK_IMPL(run_cron) { | ||
| 88 | mrvec<cron_t*> cron; | ||
| 89 | int cont=1; for(tokmap* tok=env.toks;tok&&cont;tok=tok->up) { | ||
| 90 | for(Env::iterator p=tok->begin();p!=tok->end();++p) { | ||
| 91 | if((*p)->name.left(cron_tag.size())==cron_tag&&(*p)->is_cron()) { | ||
| 92 | cron.push_back((cron_t*)(*p)); | ||
| 93 | cont=0; | ||
| 94 | } | ||
| 95 | } | ||
| 96 | } | ||
| 97 | while(env.req->is_running()&&cron.size()) { | ||
| 98 | int cont=1; | ||
| 99 | for(int i=0;i<cron.size()&&cont;i++) { | ||
| 100 | if(time(0)>cron[i]->last+cron[i]->interval) { | ||
| 101 | mstream ms; | ||
| 102 | env.eval(ms,&cron[i]->x,0); | ||
| 103 | cron[i]->last=time(0); | ||
| 104 | cont=0; | ||
| 105 | } | ||
| 106 | } | ||
| 107 | if(cont) sleep(SSECS); | ||
| 108 | } | ||
| 109 | } | ||
| 110 | |||
| 111 | ////////////////////////////////////////////////////// | ||
| 112 | |||
| 113 | void envAddFunc(tokmap& T) | ||
| 114 | { | ||
| 115 | TOK_ADD(def,"xxr",tok_t::PUBLIC, | ||
| 116 | "%Define new global function\n" | ||
| 117 | "%Syntax: \\def{varname}{argument string [xr?*]}{body}\n" | ||
| 118 | "%\n" | ||
| 119 | "%The argument string is a sequence of characters describing\n" | ||
| 120 | "%the argument type, which is one of x (pre-evaluate), r (post-evaluate),\n" | ||
| 121 | "%? (optional post-evaluate) or * (optional at end, post-evaluate).\n" | ||
| 122 | "%The can be only one optional (?) argument.\n" | ||
| 123 | "%The body contains the function body. The arguments are retrieved\n" | ||
| 124 | "%as \\1, \\2 etc, except the optional argument which is retrieved as \\0,\n" | ||
| 125 | "%regardless of where it stands in the sequence.\n" | ||
| 126 | "%\n" | ||
| 127 | "%Generates an error if already defined.\n" | ||
| 128 | ); | ||
| 129 | TOK_ADD(redef,"xxr",tok_t::PRIVATE, | ||
| 130 | "%Redefine global function\n" | ||
| 131 | "%Syntax: \\def{varname}{argument string [xr?*]}{body}\n" | ||
| 132 | "%\n" | ||
| 133 | "%The argument string is a sequence of characters describing\n" | ||
| 134 | "%the argument type, which is one of x (pre-evaluate), r (post-evaluate),\n" | ||
| 135 | "%? (optional post-evaluate) or * (optional at end, post-evaluate).\n" | ||
| 136 | "%The can be only one optional (?) argument.\n" | ||
| 137 | "%The body contains the function body. The arguments are retrieved\n" | ||
| 138 | "%as \\1, \\2 etc, except the optional argument which is retrieved as \\0,\n" | ||
| 139 | "%regardless of where it stands in the sequence.\n" | ||
| 140 | "%\n" | ||
| 141 | "%Takes precedence over any existing function.\n" | ||
| 142 | ); | ||
| 143 | TOK_ADD(ldef,"xxr",tok_t::PUBLIC, | ||
| 144 | "%Define a local function\n" | ||
| 145 | "%Syntax: \\ldef{varname}{argument string [xr?*]}{body}\n" | ||
| 146 | "%\n" | ||
| 147 | "%The argument string is a sequence of characters describing\n" | ||
| 148 | "%the argument type, which is one of x (pre-evaluate), r (post-evaluate),\n" | ||
| 149 | "%? (optional post-evaluate) or * (optional at end, post-evaluate).\n" | ||
| 150 | "%The can be only one optional (?) argument.\n" | ||
| 151 | "%The body contains the function body. The arguments are retrieved\n" | ||
| 152 | "%as \\1, \\2 etc, except the optional argument which is retrieved as \\0,\n" | ||
| 153 | "%regardless of where it stands in the sequence.\n" | ||
| 154 | "%\n" | ||
| 155 | "%Local functions work just like global functions, but are only\n" | ||
| 156 | "%accessible from within the current stack frame.\n" | ||
| 157 | ); | ||
| 158 | TOK_ADD(cron,"xr",tok_t::SYSONLY, | ||
| 159 | "%Define a cron function\n" | ||
| 160 | "%Syntax: \\cron{interval}{body}\n" | ||
| 161 | "%\n" | ||
| 162 | "%A cron function is executed every interval seconds,\n" | ||
| 163 | "%when running in cron mode.\n" | ||
| 164 | "%\n" | ||
| 165 | "%See \\run.cron.\n" | ||
| 166 | ); | ||
| 167 | |||
| 168 | ////////////////////////////////////////////////////// | ||
| 169 | |||
| 170 | TOK_ADD(run,"x",tok_t::SYSONLY, | ||
| 171 | "%Evaluate the body of variable in current running mode\n" | ||
| 172 | "%Syntax: \\run{varname}\n" | ||
| 173 | "%\n" | ||
| 174 | "%The running modes are:\n" | ||
| 175 | "%\n" | ||
| 176 | "%XINIT Init mode is only used to collect meta information\n" | ||
| 177 | "%XSYSTEM The system mode - everything is accessible\n" | ||
| 178 | "%XPRIVATE Private mode - suitable for in-door custom programs\n" | ||
| 179 | "%XPUBLIC Public mode - quite restrictive, may be run by anyone\n" | ||
| 180 | "% via the web. This is the default mode for all derivative\n" | ||
| 181 | "% functions, as well as for globals and constants.\n" | ||
| 182 | "%\n" | ||
| 183 | "%IT IS A MAJOR SECURITY HAZARD TO EVALUATE UNKNOWN\n" | ||
| 184 | "%VARIABLES IN XSYSTEM MODE!!\n" | ||
| 185 | "%\n" | ||
| 186 | "%If at all, user-supplied information should only be run\n" | ||
| 187 | "%in public mode, for instance to allow the expansion of latex\n" | ||
| 188 | "%commands. NEVER use this mode outside the core.\n" | ||
| 189 | ); | ||
| 190 | TOK_ADD(run_private,"x",tok_t::SYSONLY, | ||
| 191 | "%Evaluate the body of variable in private mode\n" | ||
| 192 | "%Syntax: \\run.private{varname}\n" | ||
| 193 | "%\n" | ||
| 194 | "%The running modes are:\n" | ||
| 195 | "%\n" | ||
| 196 | "%XINIT Init mode is only used to collect meta information\n" | ||
| 197 | "%XSYSONLY The system mode - everything is accessible\n" | ||
| 198 | "%XPRIVATE Private mode - suitable for in-door custom htc code\n" | ||
| 199 | "%XPUBLIC Public mode - quite restrictive, may be run by anyone\n" | ||
| 200 | "% via the web. This is the default mode for all derivative\n" | ||
| 201 | "% functions, as well as for globals and constants.\n" | ||
| 202 | "%\n" | ||
| 203 | "%The execution of sysonly functions is silent, just as it wasn't there.\n" | ||
| 204 | ); | ||
| 205 | TOK_ADD(run_public,"x",tok_t::PRIVATE, | ||
| 206 | "%Evaluate the body of variable in public mode\n" | ||
| 207 | "%Syntax: \\run.public{varname}\n" | ||
| 208 | "%\n" | ||
| 209 | "%The running modes are:\n" | ||
| 210 | "%\n" | ||
| 211 | "%XINIT Init mode is only used to collect meta information\n" | ||
| 212 | "%XSYSONLY The system mode - everything is accessible\n" | ||
| 213 | "%XPRIVATE Private mode - suitable for in-door custom programs\n" | ||
| 214 | "%XPUBLIC Public mode - quite restrictive, may be run by anyone\n" | ||
| 215 | "% via the web. This is the default mode for all derivative\n" | ||
| 216 | "% functions, as well as for globals and constants.\n" | ||
| 217 | "%\n" | ||
| 218 | "%The execution of sysonly or private functions is silent,\n" | ||
| 219 | "%just as they weren't there.\n" | ||
| 220 | ); | ||
| 221 | TOK_ADD(run_local,"x",tok_t::PRIVATE, | ||
| 222 | "%Evaluate the body of the local variable in public mode\n" | ||
| 223 | "%Syntax: \\run.local{varname}\n" | ||
| 224 | "%\n" | ||
| 225 | "%The running modes are:\n" | ||
| 226 | "%\n" | ||
| 227 | "%XINIT Init mode is only used to collect meta information\n" | ||
| 228 | "%XSYSTEM The system mode - everything is accessible\n" | ||
| 229 | "%XPRIVATE Private mode - suitable for in-door custom programs\n" | ||
| 230 | "%XPUBLIC Public mode - quite restrictive, may be run by anyone\n" | ||
| 231 | "% via the web. This is the default mode for all derivative\n" | ||
| 232 | "% functions, as well as for globals and constants.\n" | ||
| 233 | "%\n" | ||
| 234 | "%The execution of sysonly or private functions is silent,\n" | ||
| 235 | "%just as they weren't there.\n" | ||
| 236 | ); | ||
| 237 | TOK_ADD(run_cron,"",tok_t::SYSONLY, | ||
| 238 | "%Go into an infinite loop and run the crontab command.\n" | ||
| 239 | "%Syntax: \\run.cron{}\n" | ||
| 240 | "%\n" | ||
| 241 | "%Note that only cron functions from the highest global level\n" | ||
| 242 | "%where a cron function is defined is run. Hence you may redefine\n" | ||
| 243 | "%earlier crontabs, but cannot mix between levels.\n" | ||
| 244 | "%\n" | ||
| 245 | "%You can only have one crontab of a certain interval.\n" | ||
| 246 | "%\n" | ||
| 247 | "%Produces no output.\n" | ||
| 248 | ); | ||
| 249 | } | ||
diff --git a/src/lang/help.cc b/src/lang/help.cc new file mode 100644 index 0000000..750a13a --- /dev/null +++ b/src/lang/help.cc | |||
| @@ -0,0 +1,140 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <lang/env.h> | ||
| 21 | |||
| 22 | TOK_IMPL(help) { | ||
| 23 | out<<"HTC/1.2 - HyperText Compiler (H. Rydberg (C) 1998,1999,2000,2001)\n"; | ||
| 24 | out<<"\n"; | ||
| 25 | out<<"Try these commands:\n"; | ||
| 26 | out<<"\\help - This message\n"; | ||
| 27 | out<<"\\ops - List all operators\n"; | ||
| 28 | out<<"\\ops{op} - Get info on operator\n"; | ||
| 29 | out<<"\\tok - List all tokens\n"; | ||
| 30 | out<<"\\tok{tok} - Get info on token\n"; | ||
| 31 | out<<"\\src{tok} - View token source\n"; | ||
| 32 | } | ||
| 33 | |||
| 34 | TOK_IMPL(ops) { | ||
| 35 | mstring cmd; env.parg(cmd,-1); | ||
| 36 | if(cmd.nempty()) { | ||
| 37 | out<<cmd<<"\n"; | ||
| 38 | const op_t* p=env.ops->get(cmd); | ||
| 39 | if(p) { | ||
| 40 | if(p->pre1) out<<"Unary operator, precedence "<<p->pre1<<"\n"; | ||
| 41 | if(p->pre2) out<<"Binary operator, precedence "<<p->pre2<<"\n"; | ||
| 42 | out<<"\n"; | ||
| 43 | out<<p->desc; | ||
| 44 | } | ||
| 45 | else { | ||
| 46 | out<<"(not found)\n"; | ||
| 47 | } | ||
| 48 | } | ||
| 49 | else { | ||
| 50 | mstring line; | ||
| 51 | line.convert("%-3s %-3s %s\n","P1","P2","NAME"); | ||
| 52 | out<<line; | ||
| 53 | for(opmap::iterator p=env.ops->begin();p!=env.ops->end();p++) { | ||
| 54 | line.convert("%-3d %-3d %s\n",(*p)->pre1,(*p)->pre2,(*p)->name.c_str()); | ||
| 55 | out<<line; | ||
| 56 | } | ||
| 57 | } | ||
| 58 | } | ||
| 59 | |||
| 60 | TOK_IMPL(tok) { | ||
| 61 | mstring cmd; env.parg(cmd,-1); | ||
| 62 | if(cmd.nempty()) { | ||
| 63 | out<<cmd<<"\n"; | ||
| 64 | const tok_t* p=env.toks->get(cmd); | ||
| 65 | if(p) { | ||
| 66 | out<<"Mode: "<<Mode(*p)<<"\n"; | ||
| 67 | if(p->mod&tok_t::RESTRICT) out<<"public "; | ||
| 68 | else if(p->mod&tok_t::NORMAL) out<<"normal "; | ||
| 69 | else if(p->mod&tok_t::SYSONLY) out<<"system "; | ||
| 70 | else if(p->mod&tok_t::INIT) out<<"init "; | ||
| 71 | if(p->is_runnable()) { | ||
| 72 | if(p->is_binary()) out<<"built-in "; | ||
| 73 | out<<"function\n"; | ||
| 74 | } | ||
| 75 | else { | ||
| 76 | if(p->is_const()) out<<"constant"; else out<<"variable"; | ||
| 77 | if(p->is_reference()) out<<" reference"; | ||
| 78 | if(p->is_dbref()) out<<" database reference"; | ||
| 79 | out<<"\n"; | ||
| 80 | } | ||
| 81 | out<<"Usage: "; | ||
| 82 | if(p->is_runnable()) out<<*(func_t*)p; else out<<"\\"<<p->name; | ||
| 83 | out<<"\n"; | ||
| 84 | if(p->is_runnable()) { | ||
| 85 | mstring desc=Desc(*p); | ||
| 86 | if(desc.nempty()) { out<<"\n"; out<<desc; } | ||
| 87 | } | ||
| 88 | } | ||
| 89 | else { | ||
| 90 | out<<"(not found)\n"; | ||
| 91 | } | ||
| 92 | } | ||
| 93 | else { | ||
| 94 | mstring line; | ||
| 95 | int n=0; | ||
| 96 | for(tokmap* tok=env.toks;tok;tok=tok->up) { | ||
| 97 | line.convert("%-12s %s %d\n","MODE","NAME LEVEL",n); | ||
| 98 | out<<line; | ||
| 99 | for(tokmap::iterator p=tok->begin();p!=tok->end();p++) { | ||
| 100 | line.convert("%s %s\n",Mode(*(*p)).c_str(),(*p)->name.c_str()); | ||
| 101 | out<<line; | ||
| 102 | } | ||
| 103 | n--; | ||
| 104 | } | ||
| 105 | } | ||
| 106 | } | ||
| 107 | |||
| 108 | TOK_IMPL(src) { | ||
| 109 | const tok_t* p=env.toks->get(env[0]); | ||
| 110 | if(!p) out<<env[0]<<" (not found)\n"; | ||
| 111 | else { | ||
| 112 | if(p->is_runnable()) { | ||
| 113 | const func_t* ftok=(func_t*)p; | ||
| 114 | out<<"{"<<ftok->name<<"}{"<<ftok->arg<<"}"; | ||
| 115 | if(p->is_binary()) out<<" (built-in function)\n"; | ||
| 116 | else out<<"{"<<ftok->x.expr<<"}\n"; | ||
| 117 | } | ||
| 118 | else out<<env[0]<<" (not a function)\n"; | ||
| 119 | } | ||
| 120 | } | ||
| 121 | |||
| 122 | void envAddHelp(tokmap& T) | ||
| 123 | { | ||
| 124 | TOK_ADD(help,"",tok_t::PRIVATE, | ||
| 125 | "%Help message\n" | ||
| 126 | "%Syntax: \\help\n" | ||
| 127 | ); | ||
| 128 | TOK_ADD(ops,"?",tok_t::PRIVATE, | ||
| 129 | "%Help on operators\n" | ||
| 130 | "%Syntax: \\ops<opname>\n" | ||
| 131 | ); | ||
| 132 | TOK_ADD(tok,"?",tok_t::PRIVATE, | ||
| 133 | "%Help on tokens\n" | ||
| 134 | "%Syntax: \\tok<tokname>\n" | ||
| 135 | ); | ||
| 136 | TOK_ADD(src,"x",tok_t::SYSONLY, | ||
| 137 | "%Source of token\n" | ||
| 138 | "%Syntax: \\src{tokname}\n" | ||
| 139 | ); | ||
| 140 | } | ||
diff --git a/src/lang/lang.cc b/src/lang/lang.cc new file mode 100644 index 0000000..28e56f3 --- /dev/null +++ b/src/lang/lang.cc | |||
| @@ -0,0 +1,39 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <lang/env.h> | ||
| 21 | |||
| 22 | void envAddOps(opmap& M,tokmap& T); | ||
| 23 | void envAddBasic(tokmap& T); | ||
| 24 | void envAddFunc(tokmap& T); | ||
| 25 | void envAddFlow(tokmap& T); | ||
| 26 | void envAddDB(tokmap& T); | ||
| 27 | void envAddLatex(tokmap& T); | ||
| 28 | void envAddHelp(tokmap& T); | ||
| 29 | |||
| 30 | Lang::Lang() : running(1) | ||
| 31 | { | ||
| 32 | envAddOps(ops,toks); | ||
| 33 | envAddBasic(toks); | ||
| 34 | envAddFunc(toks); | ||
| 35 | envAddFlow(toks); | ||
| 36 | envAddDB(toks); | ||
| 37 | envAddLatex(toks); | ||
| 38 | envAddHelp(toks); | ||
| 39 | } | ||
diff --git a/src/lang/latex.cc b/src/lang/latex.cc new file mode 100644 index 0000000..d423230 --- /dev/null +++ b/src/lang/latex.cc | |||
| @@ -0,0 +1,152 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <lang/env.h> | ||
| 21 | using namespace std; | ||
| 22 | |||
| 23 | static opmap op_latex; | ||
| 24 | |||
| 25 | latex_env::latex_env(Env& p) : Env(p) { ops=&op_latex; } | ||
| 26 | |||
| 27 | ////////////////////////////////////////////////////// | ||
| 28 | |||
| 29 | TOK_IMPL(it) { | ||
| 30 | mstring s; env.parg(s,-1); | ||
| 31 | if(s.nempty()) { out<<"<i>"; out<<s.right_first_not_of(cset_ws); out<<"</i>"; } | ||
| 32 | else { out<<"<i>"; env.epilog=sref("</i>")+env.epilog; } | ||
| 33 | } | ||
| 34 | |||
| 35 | TOK_IMPL(em) { | ||
| 36 | mstring s; env.parg(s,-1); | ||
| 37 | if(s.nempty()) { out<<"<em>"; out<<s.right_first_not_of(cset_ws); out<<"</em>"; } | ||
| 38 | else { out<<"<em>"; env.epilog=sref("</em>")+env.epilog; } | ||
| 39 | } | ||
| 40 | |||
| 41 | TOK_IMPL(bf) { | ||
| 42 | mstring s; env.parg(s,-1); | ||
| 43 | if(s.nempty()) { out<<"<b>"; out<<s.right_first_not_of(cset_ws); out<<"</b>"; } | ||
| 44 | else { out<<"<b>"; env.epilog=sref("</b>")+env.epilog; } | ||
| 45 | } | ||
| 46 | |||
| 47 | TOK_IMPL(mathbf) { | ||
| 48 | mstring s; env.parg(s,-1); | ||
| 49 | if(s.nempty()) { out<<"<b>"; out<<s.right_first_not_of(cset_ws); out<<"</b>"; } | ||
| 50 | else { out<<"<b>"; env.epilog=sref("</b>")+env.epilog; } | ||
| 51 | } | ||
| 52 | |||
| 53 | TOK_IMPL(rm) { | ||
| 54 | mstring s; env.parg(s,-1); | ||
| 55 | if(s.nempty()) { out<<s.right_first_not_of(cset_ws); } | ||
| 56 | } | ||
| 57 | |||
| 58 | ////////////////////////////////////////////////////////// | ||
| 59 | |||
| 60 | TOK_IMPL(setpara) { | ||
| 61 | env.para=env[0]; | ||
| 62 | } | ||
| 63 | |||
| 64 | TOK_IMPL(epilog) { | ||
| 65 | env.epilog=env[0]+env.epilog; | ||
| 66 | } | ||
| 67 | |||
| 68 | ////////////////////////////////////////////////////////// | ||
| 69 | |||
| 70 | TOK_IMPL(equation) { | ||
| 71 | out<<env.para; | ||
| 72 | latex_env(env).expr(out,env.arg(0)->expr); | ||
| 73 | out<<env.para; | ||
| 74 | } | ||
| 75 | |||
| 76 | ////////////////////////////////////////////////////////// | ||
| 77 | |||
| 78 | void envAddLatex(tokmap& T) | ||
| 79 | { | ||
| 80 | static int init; if(!init) { init=1; opAddLatex(op_latex); } | ||
| 81 | |||
| 82 | ////////////////////////////////////////////////////////// | ||
| 83 | |||
| 84 | TOK_ADD(it,"?",tok_t::PUBLIC, | ||
| 85 | "%Set Italics mode\n" | ||
| 86 | "%Syntax: \\it<body>\n" | ||
| 87 | "%\n" | ||
| 88 | "%Note that the body is optional, just like in latex.\n" | ||
| 89 | ); | ||
| 90 | TOK_ADD(em,"?",tok_t::PUBLIC, | ||
| 91 | "%Set emph mode\n" | ||
| 92 | "%Syntax: \\em<body>\n" | ||
| 93 | "%\n" | ||
| 94 | "%Note that the body is optional, just like in latex.\n" | ||
| 95 | ); | ||
| 96 | TOK_ADD(bf,"?",tok_t::PUBLIC, | ||
| 97 | "%Set Boldface mode\n" | ||
| 98 | "%Syntax: \\bf<body>\n" | ||
| 99 | "%\n" | ||
| 100 | "%Note that the body is optional, just like in latex.\n" | ||
| 101 | ); | ||
| 102 | TOK_ADD(mathbf,"?",tok_t::PUBLIC, | ||
| 103 | "%Set Math boldface mode\n" | ||
| 104 | "%Syntax: \\mathbf<body>\n" | ||
| 105 | "%\n" | ||
| 106 | "%Note that the body is optional, just like in latex.\n" | ||
| 107 | ); | ||
| 108 | TOK_ADD(rm,"?",tok_t::PUBLIC, | ||
| 109 | "%Set rm face mode\n" | ||
| 110 | "%Syntax: \\rm<body>\n" | ||
| 111 | "%\n" | ||
| 112 | "%Note that the body is optional, just like in latex.\n" | ||
| 113 | ); | ||
| 114 | |||
| 115 | ////////////////////////////////////////////////////////// | ||
| 116 | |||
| 117 | TOK_ADD(setpara,"x",tok_t::PUBLIC, | ||
| 118 | "%Set paragraph string\n" | ||
| 119 | "%Syntax: \\setpara{string}\n" | ||
| 120 | "%\n" | ||
| 121 | "%Whenever a series of newlines is encountered, it is\n" | ||
| 122 | "%replaced by this string. The default is a newline.\n" | ||
| 123 | "%\n" | ||
| 124 | "%Operates on stack level (may be nested)\n" | ||
| 125 | ); | ||
| 126 | TOK_ADD(epilog,"x",tok_t::PUBLIC, | ||
| 127 | "%Add string to the epilog\n" | ||
| 128 | "%Syntax: \\epilog{string}\n" | ||
| 129 | "%\n" | ||
| 130 | "%The epilog string is output when the current stack frame\n" | ||
| 131 | "%goes out of scope. For functions like \\bf, which needs\n" | ||
| 132 | "%an end tag to be inserted at the right place.\n" | ||
| 133 | "%\n" | ||
| 134 | "%Operates on stack level (may be nested)\n" | ||
| 135 | ); | ||
| 136 | |||
| 137 | ////////////////////////////////////////////////////////// | ||
| 138 | |||
| 139 | TOK_ADD(equation,"r",tok_t::PUBLIC, | ||
| 140 | "%Evaluate equation (LaTeX)\n" | ||
| 141 | "%Syntax: \\equation{body}\n" | ||
| 142 | ); | ||
| 143 | |||
| 144 | ////////////////////////////////////////////////////////// | ||
| 145 | |||
| 146 | Const(T,sref("t"),sref("\t"),tok_t::PUBLIC); | ||
| 147 | Const(T,sref("n"),sref("\n"),tok_t::PUBLIC); | ||
| 148 | Const(T,sref("f"),sref("\f"),tok_t::PUBLIC); | ||
| 149 | |||
| 150 | ////////////////////////////////////////////////////////// | ||
| 151 | } | ||
| 152 | |||
diff --git a/src/lang/ops.cc b/src/lang/ops.cc new file mode 100644 index 0000000..7916d96 --- /dev/null +++ b/src/lang/ops.cc | |||
| @@ -0,0 +1,150 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <lang/env.h> | ||
| 21 | |||
| 22 | ////////////////////////////////////////////////////// | ||
| 23 | |||
| 24 | struct xop_t : public op_t { | ||
| 25 | typedef void (*xop1_t)(mstream&,Env&,const sref&); | ||
| 26 | typedef void (*xop2_t)(mstream&,Env&,const sref&,const sref&); | ||
| 27 | xop_t(const mstring& s,int p1,int p2,int l,int r, | ||
| 28 | xop1_t op1,xop2_t op2,const mstring& d): | ||
| 29 | op_t(s,p1,p2,l,r,(op1_t)op1,(op2_t)op2,d) {} | ||
| 30 | }; | ||
| 31 | |||
| 32 | ////////////////////////////////////////////////////// | ||
| 33 | |||
| 34 | #define X1_IMPL(name) \ | ||
| 35 | static void impl_##name(mstream& out,Env& env,const sref& a) throw(merror_t) | ||
| 36 | #define X2_IMPL(name) \ | ||
| 37 | static void impl_##name(mstream& out,Env& env,const sref& L,const sref& R) throw(merror_t) | ||
| 38 | |||
| 39 | #define X1_ADDN(p,l,r,f,n,d) M.add(new xop_t(#n,p,0,l,r,impl_##f,0,d)) | ||
| 40 | #define X2_ADDN(p,l,r,f,n,d) M.add(new xop_t(#n,0,p,l,r,0,impl_##f,d)) | ||
| 41 | |||
| 42 | ////////////////////////////////////////////////////// | ||
| 43 | |||
| 44 | X1_IMPL(exist) { | ||
| 45 | mstring name; | ||
| 46 | swrite sw(name); | ||
| 47 | env.eval(sw,a,0); | ||
| 48 | out<<env.gloc_find(name); | ||
| 49 | } | ||
| 50 | |||
| 51 | X2_IMPL(new) { | ||
| 52 | mstring name; | ||
| 53 | swrite sw(name); | ||
| 54 | env.eval(sw,L,0); | ||
| 55 | env.aloc(name,R); | ||
| 56 | } | ||
| 57 | |||
| 58 | X2_IMPL(assign) { | ||
| 59 | mstring name; | ||
| 60 | swrite sw(name); | ||
| 61 | env.eval(sw,L,0); | ||
| 62 | env.sloc(name,R); | ||
| 63 | } | ||
| 64 | |||
| 65 | X2_IMPL(incr) { | ||
| 66 | mstring name; | ||
| 67 | swrite sw(name); | ||
| 68 | env.eval(sw,L,0); | ||
| 69 | env.sloc(name,ftoa(atof(env.gloc(name))+atof(R))); | ||
| 70 | } | ||
| 71 | |||
| 72 | X2_IMPL(decr) { | ||
| 73 | mstring name; | ||
| 74 | swrite sw(name); | ||
| 75 | env.eval(sw,L,0); | ||
| 76 | env.sloc(name,ftoa(atof(env.gloc(name))-atof(R))); | ||
| 77 | } | ||
| 78 | |||
| 79 | ////////////////////////////////////////////////////// | ||
| 80 | |||
| 81 | X2_IMPL(new_rec) { | ||
| 82 | if(*L=='@') env.gloc_adb(L.popf(),R); | ||
| 83 | else { | ||
| 84 | rpile list; env.gloc_list(list,R); | ||
| 85 | int n=*R=='@'?R.size()-1:R.size(); | ||
| 86 | for(int i=0;i<list.size();i++) env.aloc(L+list[i].right(n),env.gloc(list[i])); | ||
| 87 | } | ||
| 88 | } | ||
| 89 | |||
| 90 | X2_IMPL(copy_rec) { | ||
| 91 | rpile list; env.gloc_list(list,L); | ||
| 92 | int n=*L=='@'?L.size()-1:L.size(); | ||
| 93 | for(int i=0;i<list.size();i++) env.sloc(R+list[i].right(n),env.gloc(list[i])); | ||
| 94 | } | ||
| 95 | |||
| 96 | ////////////////////////////////////////////////////// | ||
| 97 | |||
| 98 | void envAddOps(opmap& M,tokmap& T) | ||
| 99 | { | ||
| 100 | opAddHEXP(M); | ||
| 101 | X1_ADDN(40,0,1,exist,?, | ||
| 102 | "True if a exist\n" | ||
| 103 | "Syntax: ? (varname)\n" | ||
| 104 | "Returns: (int)\n" | ||
| 105 | ); | ||
| 106 | X2_ADDN(4,1,2,new,:=, | ||
| 107 | "New assignment\n" | ||
| 108 | "Syntax: (varname) := (expr)\n" | ||
| 109 | "Returns: nothing\n" | ||
| 110 | ); | ||
| 111 | X2_ADDN(4,1,2,assign,=, | ||
| 112 | "Assignment to existing variable\n" | ||
| 113 | "Syntax: (varname) = (expr)\n" | ||
| 114 | "Returns: nothing\n" | ||
| 115 | ); | ||
| 116 | X2_ADDN(4,1,2,incr,+=, | ||
| 117 | "Increment operator\n" | ||
| 118 | "Syntax: (varname) += (real)\n" | ||
| 119 | "Returns: nothing\n" | ||
| 120 | ); | ||
| 121 | X2_ADDN(4,1,2,decr,-=, | ||
| 122 | "Decrement operator\n" | ||
| 123 | "Syntax: (varname) -= (real)\n" | ||
| 124 | "Returns: nothing\n" | ||
| 125 | ); | ||
| 126 | |||
| 127 | X2_ADDN(4,1,1,new_rec,<-, | ||
| 128 | "New local record\n" | ||
| 129 | "Syntax: (partial name) <- (partial name)\n" | ||
| 130 | "Returns: nothing\n" | ||
| 131 | "\n" | ||
| 132 | "If the partial name @ is given as the left argument,\n" | ||
| 133 | "a new record is created or silently updated, depending\n" | ||
| 134 | "on whether it is unique or not according to the default order.\n" | ||
| 135 | "The index table must however exist in the right argument.\n" | ||
| 136 | "\n" | ||
| 137 | "The default order may only be set at creation or when saving\n" | ||
| 138 | "a database to disk.\n" | ||
| 139 | ); | ||
| 140 | X2_ADDN(4,1,1,copy_rec,->, | ||
| 141 | "Copy local record\n" | ||
| 142 | "Syntax: (partial name) -> (partial name)\n" | ||
| 143 | "Returns: nothing\n" | ||
| 144 | "\n" | ||
| 145 | "The partial name @ for data base records works in both arguments.\n" | ||
| 146 | "\n" | ||
| 147 | "Generates an error if any of the expanded names of the right\n" | ||
| 148 | "partial argument does not exist.\n" | ||
| 149 | ); | ||
| 150 | } | ||
diff --git a/src/lang/parse.cc b/src/lang/parse.cc new file mode 100644 index 0000000..7e24a11 --- /dev/null +++ b/src/lang/parse.cc | |||
| @@ -0,0 +1,453 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <lang/env.h> | ||
| 21 | |||
| 22 | static const charset escaped("%$[]{};"); | ||
| 23 | static const charset prename("\"'`^~*,_=!\\"); | ||
| 24 | static const charset spec("+-*/%<=>^_!~&|,?:;"); | ||
| 25 | static const charset spec_latex("+-*/<=>^_;"); | ||
| 26 | static const charset delim("\"{}()\\"); | ||
| 27 | static const charset delim_latex("{}()[]\\"); | ||
| 28 | static const charset specws=spec|delim|cset_ws; | ||
| 29 | static const charset specws_latex=spec_latex|delim_latex|cset_ws; | ||
| 30 | static const charset tokname=cset_alphareal; | ||
| 31 | static const charset pretok=tokname|prename; | ||
| 32 | |||
| 33 | const mstring begin_tag="begin",end_left="\\end{",end_right="}"; | ||
| 34 | |||
| 35 | int is_tokname(const sref& s) { | ||
| 36 | return s.back()!='.'&&pretok.test(s.front())&&s.right(1).find_not_of(tokname)<0; | ||
| 37 | } | ||
| 38 | |||
| 39 | int is_arglist(const sref& s) | ||
| 40 | { | ||
| 41 | const char* p=s.begin(); int opt=0; | ||
| 42 | if(*p=='?') { ++p; opt=1; } | ||
| 43 | while(*p=='x') ++p; | ||
| 44 | while(*p=='r') ++p; | ||
| 45 | if(!opt&&*p=='?') ++p; | ||
| 46 | if(*p=='*') ++p; | ||
| 47 | return !*p; | ||
| 48 | } | ||
| 49 | |||
| 50 | /////////////////////////////////////////////////////////// | ||
| 51 | |||
| 52 | static sref getlocal(const sref& in) { | ||
| 53 | int w=0,i=0; for(;i<in.size();i++) { | ||
| 54 | if(in[i]=='[') w++; | ||
| 55 | else if(in[i]==']') w--; | ||
| 56 | else if(!w&&specws.test(in[i])) break; | ||
| 57 | } | ||
| 58 | return in.left(i); | ||
| 59 | } | ||
| 60 | |||
| 61 | static sref getname(const sref& in) { | ||
| 62 | int i=0; | ||
| 63 | if(pretok.test(*in)) { | ||
| 64 | int w=0; | ||
| 65 | for(i=1;i<in.size();i++) { | ||
| 66 | if(in[i]=='[') w++; | ||
| 67 | else if(in[i]==']') w--; | ||
| 68 | else if(!w&&!tokname.test(in[i])) break; | ||
| 69 | } | ||
| 70 | } | ||
| 71 | if(i>0&&in[i-1]=='.') return in.left(i-1); | ||
| 72 | else return in.left(i); | ||
| 73 | } | ||
| 74 | |||
| 75 | static int skip_quotes(const sref& in) throw(merror_t) { | ||
| 76 | int s=in.skip(cset_quotes); | ||
| 77 | if(s<0) THROW("parse: unmatched '\"'"); | ||
| 78 | return s; | ||
| 79 | } | ||
| 80 | |||
| 81 | static int skip_braces(const sref& in) throw(merror_t) { | ||
| 82 | int s=in.skip(cset_braces); | ||
| 83 | if(s<0) THROW("parse: unmatched '{'"); | ||
| 84 | return s; | ||
| 85 | } | ||
| 86 | |||
| 87 | static int skip_para(const sref& in) throw(merror_t) { | ||
| 88 | int s=in.skip(cset_para); | ||
| 89 | if(s<0) THROW("parse: unmatched '('"); | ||
| 90 | return s; | ||
| 91 | } | ||
| 92 | |||
| 93 | static int skip_indices(const sref& in) throw(merror_t) { | ||
| 94 | int s=in.skip(cset_indices); | ||
| 95 | if(s<0) THROW("parse: unmatched '['"); | ||
| 96 | return s; | ||
| 97 | } | ||
| 98 | |||
| 99 | static int skip_dollars(const sref& in) throw(merror_t) { | ||
| 100 | int s=in.skip(cset_dollars); | ||
| 101 | //if(s<0) THROW("parse: unmatched '$'"); | ||
| 102 | return s; | ||
| 103 | } | ||
| 104 | |||
| 105 | /////////////////////////////////////////////////////////// | ||
| 106 | |||
| 107 | static int count_args(const sref& in) throw(merror_t) | ||
| 108 | { | ||
| 109 | sref e=in.right_first_not_of(cset_ws); | ||
| 110 | int s,n=0; while((s=skip_braces(e))>0||(s=skip_para(e))>0) { | ||
| 111 | e=e.adv(s).right_first_not_of(cset_ws); n++; | ||
| 112 | } | ||
| 113 | return n; | ||
| 114 | } | ||
| 115 | |||
| 116 | static int past_args(const sref& in) throw(merror_t) | ||
| 117 | { | ||
| 118 | sref p=in,e=in.right_first_not_of(cset_ws); | ||
| 119 | int s; while((s=skip_braces(e))>0||(s=skip_para(e))>0) { | ||
| 120 | e=(p=e.adv(s)).right_first_not_of(cset_ws); | ||
| 121 | } | ||
| 122 | return p-in; | ||
| 123 | } | ||
| 124 | |||
| 125 | static int parse_args(Env& env,runnable_t* ftok,const sref& in,int inbegend) throw(merror_t) | ||
| 126 | { | ||
| 127 | env.clear_args(); | ||
| 128 | sref option,p=in,e=in.right_first_not_of(cset_ws); | ||
| 129 | int s,narg=0,carg=count_args(e); | ||
| 130 | while((s=e.skip(cset_braces))>0||(s==0&&(s=e.skip(cset_para))>0)) { | ||
| 131 | if(ftok->arg[narg]=='?'&&carg<ftok->arg.size()) narg++; | ||
| 132 | switch(ftok->arg[narg]){ | ||
| 133 | case 'x': env.xpush(e.left(s)); break; | ||
| 134 | case 'r': case '*': env.rpush(e.left(s)); break; | ||
| 135 | case '?': option=e.left(s); break; | ||
| 136 | case 0: THROW("htc: too many args in "<<ftok->name); | ||
| 137 | default: THROW("htc: bad argument descriptor in "<<ftok->name); | ||
| 138 | } | ||
| 139 | e=(p=e.adv(s)).right_first_not_of(cset_ws); | ||
| 140 | if(ftok->arg[narg]!='*') narg++; | ||
| 141 | } | ||
| 142 | if(s<0) THROW("htc: unmatched parenthesis in function "<<ftok->name); | ||
| 143 | if(inbegend) { | ||
| 144 | mstring tag=end_left+ftok->name+end_right; | ||
| 145 | s=p.find(tag); if(s<0) THROW("htc: unmatched begin/end in function "<<ftok->name); | ||
| 146 | if(ftok->arg[narg]=='?'&&carg<ftok->arg.size()) narg++; | ||
| 147 | switch(ftok->arg[narg]){ | ||
| 148 | case 'x': env.xpush(p.left(s)); break; | ||
| 149 | case 'r': case '*': env.rpush(p.left(s)); break; | ||
| 150 | case '?': option=p.left(s); break; | ||
| 151 | case 0: THROW("htc: too many args in begin/end "<<ftok->name); | ||
| 152 | default: THROW("htc: bad argument descriptor in "<<ftok->name); | ||
| 153 | } | ||
| 154 | p=p.adv(s+tag.size()); | ||
| 155 | } | ||
| 156 | if(ftok->arg.find('?')>=0&&env.args<ftok->arg.size()) env.rpush(option); | ||
| 157 | return p-in; | ||
| 158 | } | ||
| 159 | |||
| 160 | int Env::check_arg(const runnable_t& ftok) const | ||
| 161 | { | ||
| 162 | static const charset tag("xr?"); | ||
| 163 | const char* p=ftok.arg.begin(); int x=0,r=0,o=0; | ||
| 164 | while(tag.test(*p)) { | ||
| 165 | switch(*p++) { | ||
| 166 | case 'x': x++; break; | ||
| 167 | case 'r': r++; break; | ||
| 168 | case '?': r++; o++; break; | ||
| 169 | } | ||
| 170 | } | ||
| 171 | if(*p=='*') { o++; ++p; } | ||
| 172 | if(*p||x!=xsize()||o>1||o==1&&rsize()<r||o==0&&r!=rsize()) return 0; | ||
| 173 | return 1; | ||
| 174 | } | ||
| 175 | |||
| 176 | /////////////////////////////////////////////////////////// | ||
| 177 | |||
| 178 | void Env::expr(mstream& out,const sref& in) throw(merror_t) | ||
| 179 | { | ||
| 180 | expr_t x(in); | ||
| 181 | x.expand(*this); | ||
| 182 | x.eval(out,*this,OP_ALL); | ||
| 183 | } | ||
| 184 | |||
| 185 | void Env::xpush(const sref& in) throw(merror_t) | ||
| 186 | { | ||
| 187 | expr_t* x=new expr_t(in(1,-3)); | ||
| 188 | xarg.push_back(x); args++; | ||
| 189 | if(*in=='(') x->expand(*this); else x->status=OP_PARSE; | ||
| 190 | swrite sw(x->result); | ||
| 191 | eval(sw,x,0); | ||
| 192 | } | ||
| 193 | |||
| 194 | void Env::rpush(const sref& in) throw(merror_t) | ||
| 195 | { | ||
| 196 | expr_t* x=new expr_t(in(1,-3)); | ||
| 197 | rarg.push_back(x); args++; | ||
| 198 | if(*in=='(') x->expand(*this); else x->status=OP_PARSE; | ||
| 199 | } | ||
| 200 | |||
| 201 | /////////////////////////////////////////////////////////// | ||
| 202 | |||
| 203 | static int indent(sref& p) { | ||
| 204 | if(cset_newl.test(p.front())) { p=p.right_first_not_of(cset_ws); return 1; } | ||
| 205 | else return 0; | ||
| 206 | } | ||
| 207 | |||
| 208 | static int backindent(sref& p) { | ||
| 209 | if(cset_newl.test(p.leftand_last_not_of(cset_spaces).back())) { | ||
| 210 | p=p.leftand_last_not_of(cset_ws); return 1; | ||
| 211 | } | ||
| 212 | else return 0; | ||
| 213 | } | ||
| 214 | |||
| 215 | static int pastsemi(sref& p) { | ||
| 216 | int s=p.find_not_of(cset_spaces); | ||
| 217 | if(s>=0&&p[s]==';') return indent(p=p.adv(s+1)); else return 0; | ||
| 218 | } | ||
| 219 | |||
| 220 | static int past_func(const sref& in) throw(merror_t) | ||
| 221 | { | ||
| 222 | sref e=getname(in.popf()),p=in.adv(e); | ||
| 223 | return p.adv(past_args(p))-in; | ||
| 224 | } | ||
| 225 | |||
| 226 | static int parse_func(mstream& out,Env& env,const sref& in,int& run) throw(merror_t) | ||
| 227 | { | ||
| 228 | run=0; sref e=getname(in),p=in.adv(e); | ||
| 229 | mstring name; | ||
| 230 | swrite sw(name); | ||
| 231 | env.eval(sw,e,0); | ||
| 232 | if(env.is_arg(name)) { | ||
| 233 | //if(count_args(p)) THROW("htc: expected no argument after "<<name); | ||
| 234 | if(env.up) env.up->parg(out,atoi(name)-1); | ||
| 235 | return p-in; | ||
| 236 | } | ||
| 237 | int inbegend=0; | ||
| 238 | if(name==begin_tag) { | ||
| 239 | sref next=p.right_first_not_of(cset_ws); | ||
| 240 | int s=skip_braces(next); | ||
| 241 | if(s>0) { name=next(1,s-2); p=next.adv(s); inbegend=1; } | ||
| 242 | } | ||
| 243 | tok_t* tok=env.toks->get(name); | ||
| 244 | if(!tok) { if(!(tok=env.loc.get(name))||!tok->is_func()) tok=0; } | ||
| 245 | if(!tok) return 0; | ||
| 246 | if(!tok->is_runnable()) { | ||
| 247 | //if(count_args(p)) THROW("htc: expected no argument after "<<name); | ||
| 248 | if(env.is_clear(tok)) out<<tok->body; | ||
| 249 | return p-in; | ||
| 250 | } | ||
| 251 | runnable_t* ftok=(runnable_t*)tok; | ||
| 252 | if(env.is_clear(ftok)) { | ||
| 253 | p=p.adv(parse_args(env,ftok,p,inbegend)); | ||
| 254 | run=1; env.eval(out,ftok,1); | ||
| 255 | } | ||
| 256 | else p=p.adv(past_args(p)); | ||
| 257 | return p-in; | ||
| 258 | } | ||
| 259 | |||
| 260 | void Env::parse(mstream& out,const sref& in) throw(merror_t) | ||
| 261 | { | ||
| 262 | static const charset sensors=escaped|cset_newl|'\\'; | ||
| 263 | epilog.clear(); | ||
| 264 | int s,run; | ||
| 265 | sref p=in; | ||
| 266 | indent(p); | ||
| 267 | backindent(p); | ||
| 268 | sref e=p; | ||
| 269 | while(*p) { | ||
| 270 | switch(*p) { | ||
| 271 | case ';': | ||
| 272 | case '}': | ||
| 273 | case ']': | ||
| 274 | out.put(*p); | ||
| 275 | p=p.popf(); | ||
| 276 | break; | ||
| 277 | case '%': | ||
| 278 | if(p-e>0) { out.put(*p); p=p.popf(); } | ||
| 279 | else e=p=p.past_nl().right_first_not_of(cset_ws); | ||
| 280 | break; | ||
| 281 | case '\r': | ||
| 282 | p=p.popf(); | ||
| 283 | break; | ||
| 284 | case '\n': | ||
| 285 | out.put(*p); p=p.popf(); | ||
| 286 | if(cset_newl.test(*p.right_first_not_of(cset_spaces))) out<<para; | ||
| 287 | e=p=p.right_first_not_of(cset_ws); | ||
| 288 | break; | ||
| 289 | case '{': | ||
| 290 | if(mod&tok_t::PUBLIC){ | ||
| 291 | if((s=skip_braces(p))>0) { | ||
| 292 | eval(out,p(1,s-2),0); | ||
| 293 | if(pastsemi(p=p.adv(s))) e=p; | ||
| 294 | } | ||
| 295 | } | ||
| 296 | else { out.put(*p); p=p.popf(); } | ||
| 297 | break; | ||
| 298 | case '[': | ||
| 299 | if(mod&tok_t::PUBLIC){ | ||
| 300 | if((s=skip_indices(p))>0) { | ||
| 301 | expr(out,p(1,s-2)); | ||
| 302 | if(pastsemi(p=p.adv(s))) e=p; | ||
| 303 | } | ||
| 304 | } | ||
| 305 | else { out.put(*p); p=p.popf(); } | ||
| 306 | break; | ||
| 307 | case '$': | ||
| 308 | if(mod&tok_t::PUBLIC){ | ||
| 309 | if((s=skip_dollars(p))>0) { | ||
| 310 | latex_env(*this).expr(out,p(1,s-2)); | ||
| 311 | if(pastsemi(p=p.adv(s))) e=p; | ||
| 312 | } | ||
| 313 | } | ||
| 314 | else { out.put(*p); p=p.popf(); } | ||
| 315 | break; | ||
| 316 | case '\\': | ||
| 317 | p=p.popf(); | ||
| 318 | if(p.empty()) out.put('\\'); | ||
| 319 | else if(escaped.test(*p)) { out.put(*p); p=p.popf(); } | ||
| 320 | else { | ||
| 321 | if((s=parse_func(out,*this,p,run))>0) { if(pastsemi(p=p.adv(s))) e=p; } | ||
| 322 | else out.put('\\'); | ||
| 323 | } | ||
| 324 | break; | ||
| 325 | default: | ||
| 326 | if((s=p.find_of(sensors))>=0) { out<<p.left(s); p=p.adv(s); } | ||
| 327 | else { out<<p; p.clear(); } | ||
| 328 | break; | ||
| 329 | } | ||
| 330 | } | ||
| 331 | out<<epilog; | ||
| 332 | } | ||
| 333 | |||
| 334 | void Env::parse(mstream& out,expr_t* x) throw(merror_t) | ||
| 335 | { | ||
| 336 | if(x->status&OP_PARSE) parse(out,x->expr); | ||
| 337 | else x->eval(out,*this,OP_ALL); | ||
| 338 | } | ||
| 339 | |||
| 340 | /////////////////////////////////////////////////////////// | ||
| 341 | |||
| 342 | void Env::eval(mstream& out,const sref& in,int child) throw(merror_t) | ||
| 343 | { | ||
| 344 | Env nenv(*this); if(child) nenv.up=this; | ||
| 345 | nenv.parse(out,in); | ||
| 346 | } | ||
| 347 | |||
| 348 | void Env::eval(mstream& out,expr_t* x,int child) throw(merror_t) | ||
| 349 | { | ||
| 350 | Env nenv(*this); if(child) nenv.up=this; | ||
| 351 | nenv.parse(out,x); | ||
| 352 | } | ||
| 353 | |||
| 354 | void Env::eval(mstream& out,runnable_t* ftok,int child) throw(merror_t) | ||
| 355 | { | ||
| 356 | if(child&&!check_arg(*ftok)) THROW("htc: bad number of args; expected "<<*ftok); | ||
| 357 | if(ftok->is_binary()) ((binary_t*)ftok)->func(out,*this); | ||
| 358 | else if(ftok->is_func()) eval(out,&((func_t*)ftok)->x,child); | ||
| 359 | else THROW("htc: unknown runnable"); | ||
| 360 | } | ||
| 361 | |||
| 362 | ////////////////////////////////////////////////////// | ||
| 363 | |||
| 364 | int Env::split(sref& first,sref& rest) throw(merror_t) | ||
| 365 | { | ||
| 366 | int s; | ||
| 367 | rest=rest.right_first_not_of(cset_ws); | ||
| 368 | if(*rest=='\\') { | ||
| 369 | first=rest.left(past_func(rest)); | ||
| 370 | rest=rest.adv(first); | ||
| 371 | } | ||
| 372 | else if(spec.test(*rest)) { | ||
| 373 | first=rest.left_first_not_of(spec); | ||
| 374 | rest=rest.adv(first); | ||
| 375 | } | ||
| 376 | else if((s=skip_quotes(rest))>0||(s=skip_braces(rest))>0) { | ||
| 377 | first=rest.left(s); | ||
| 378 | rest=rest.adv(first); | ||
| 379 | } | ||
| 380 | else if((s=skip_para(rest))>0) { | ||
| 381 | first=rest(1,s-2); | ||
| 382 | rest=rest.right(s); | ||
| 383 | } | ||
| 384 | else { | ||
| 385 | first=getlocal(rest); | ||
| 386 | rest=rest.adv(first); | ||
| 387 | } | ||
| 388 | return first.nempty(); | ||
| 389 | } | ||
| 390 | |||
| 391 | void Env::term(mstream& out,expr_t* x) throw(merror_t) | ||
| 392 | { | ||
| 393 | if(x->expr.empty()) x->status=0; | ||
| 394 | else if(*x->expr=='\"') { out<<x->expr(1,-3); x->status=0; } | ||
| 395 | else if(*x->expr=='{') { eval(out,x->expr(1,-3),0); x->status=0; } | ||
| 396 | else if(x->expr.find_not_of(cset_real)<0) { out<<x->expr; x->status=0; } | ||
| 397 | else if(*x->expr=='\\') { | ||
| 398 | sref p=x->expr.popf(); | ||
| 399 | if(p.empty()) { out.put('\\'); x->status=0; } | ||
| 400 | else if(escaped.test(*p)) { out.put(*p); x->status=0; } | ||
| 401 | else { | ||
| 402 | int run; | ||
| 403 | if(parse_func(out,*this,p,run)>0) x->status=run?OP_LOCAL:OP_GLOBAL; | ||
| 404 | else { out.put('\\')<<x->expr; x->status=OP_NINIT; } | ||
| 405 | } | ||
| 406 | } | ||
| 407 | else { | ||
| 408 | mstring name; | ||
| 409 | swrite sw(name); | ||
| 410 | eval(sw,x->expr,0); | ||
| 411 | out<<gloc(name); | ||
| 412 | x->status=OP_LOCAL; | ||
| 413 | } | ||
| 414 | } | ||
| 415 | |||
| 416 | /////////////////////////////////////////////////////////////////// | ||
| 417 | |||
| 418 | int latex_env::split(sref& first,sref& rest) throw(merror_t) | ||
| 419 | { | ||
| 420 | int s; | ||
| 421 | rest=rest.right_first_not_of(cset_ws); | ||
| 422 | if(*rest=='\\') { | ||
| 423 | first=rest.left(past_func(rest)); | ||
| 424 | rest=rest.adv(first); | ||
| 425 | } | ||
| 426 | else if(spec.test(*rest)) { | ||
| 427 | first=rest.left_first_not_of(spec); | ||
| 428 | rest=rest.adv(first); | ||
| 429 | } | ||
| 430 | else if((s=skip_braces(rest))>0||(s=skip_para(rest))>0||(s=skip_indices(rest))>0) { | ||
| 431 | first=rest.left(s); | ||
| 432 | rest=rest.adv(first); | ||
| 433 | } | ||
| 434 | else { | ||
| 435 | first=rest.left_first_of(specws); | ||
| 436 | rest=rest.adv(first); | ||
| 437 | } | ||
| 438 | return first.nempty(); | ||
| 439 | } | ||
| 440 | |||
| 441 | void latex_env::term(mstream& out,expr_t* x) throw(merror_t) | ||
| 442 | { | ||
| 443 | if(x->expr.empty()) x->status=0; | ||
| 444 | else if(*x->expr=='\\') { eval(out,x->expr,0); x->status=0; } | ||
| 445 | else if(*x->expr=='{') { eval(out,x->expr(1,-3),0); x->status=0; } | ||
| 446 | else if(*x->expr=='('||*x->expr=='[') { | ||
| 447 | out.put(x->expr.front()); | ||
| 448 | expr(out,x->expr(1,-3)); | ||
| 449 | out.put(x->expr.back()); | ||
| 450 | x->status=0; | ||
| 451 | } | ||
| 452 | else { out<<x->expr; x->status=0; } | ||
| 453 | } | ||
diff --git a/src/lang/test.cc b/src/lang/test.cc new file mode 100644 index 0000000..e59a719 --- /dev/null +++ b/src/lang/test.cc | |||
| @@ -0,0 +1,45 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <lang/env.h> | ||
| 21 | |||
| 22 | static fp_stream mout(stdout),merr(stderr); | ||
| 23 | |||
| 24 | main(int argc,char* argv[]) try | ||
| 25 | { | ||
| 26 | Lang lang; | ||
| 27 | req_env req(lang,lang.toks); | ||
| 28 | Env env(lang.ops,req,XSYSTEM); | ||
| 29 | mstring line; | ||
| 30 | while(!feof(stdin)) { | ||
| 31 | merr<<"lang>"; | ||
| 32 | getline(line,stdin); | ||
| 33 | try { | ||
| 34 | env.parse(mout,line); | ||
| 35 | mout<<"\n"; | ||
| 36 | } | ||
| 37 | catch(const merror_t& e) { | ||
| 38 | merr<<e.desc<<"\n"; | ||
| 39 | } | ||
| 40 | } | ||
| 41 | return 0; | ||
| 42 | } | ||
| 43 | catch(const merror_t& e) { | ||
| 44 | merr<<"ERROR: ["<<e.desc<<"]\n"; | ||
| 45 | } | ||
diff --git a/src/lang/token.cc b/src/lang/token.cc new file mode 100644 index 0000000..5bee9ca --- /dev/null +++ b/src/lang/token.cc | |||
| @@ -0,0 +1,268 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <lang/token.h> | ||
| 21 | #include <algorithm> | ||
| 22 | using namespace std; | ||
| 23 | |||
| 24 | /////////////////////////////////////////////////////////////////// | ||
| 25 | |||
| 26 | const unsigned tok_t::CONSTANT=1; | ||
| 27 | const unsigned tok_t::RESTRICT=2; | ||
| 28 | const unsigned tok_t::NORMAL=4; | ||
| 29 | const unsigned tok_t::SYSONLY=8; | ||
| 30 | const unsigned tok_t::INIT=16; | ||
| 31 | const unsigned tok_t::RUNNABLE=32; | ||
| 32 | const unsigned tok_t::FUNCTION=64; | ||
| 33 | const unsigned tok_t::BINARY=128; | ||
| 34 | const unsigned tok_t::REFERENCE=256; | ||
| 35 | const unsigned tok_t::DBREF=512; | ||
| 36 | const unsigned tok_t::CRON=1024; | ||
| 37 | const unsigned tok_t::PRIVATE=NORMAL|SYSONLY; | ||
| 38 | const unsigned tok_t::PUBLIC=RESTRICT|PRIVATE; | ||
| 39 | const unsigned tok_t::XMODES=PUBLIC|INIT; | ||
| 40 | |||
| 41 | /////////////////////////////////////////////////////////////////// | ||
| 42 | |||
| 43 | uniheap<sizeof(tok_t)> tok_t::tree; | ||
| 44 | void* tok_t::operator new(size_t n) { return tree.push(); } | ||
| 45 | void tok_t::operator delete(void* p) { tree.pop(p); } | ||
| 46 | |||
| 47 | uniheap<sizeof(reference_t)> reference_t::tree; | ||
| 48 | void* reference_t::operator new(size_t n) { return tree.push(); } | ||
| 49 | void reference_t::operator delete(void* p) { tree.pop(p); } | ||
| 50 | |||
| 51 | uniheap<sizeof(dbref_t)> dbref_t::tree; | ||
| 52 | void* dbref_t::operator new(size_t n) { return tree.push(); } | ||
| 53 | void dbref_t::operator delete(void* p) { tree.pop(p); } | ||
| 54 | |||
| 55 | uniheap<sizeof(runnable_t)> runnable_t::tree; | ||
| 56 | void* runnable_t::operator new(size_t n) { return tree.push(); } | ||
| 57 | void runnable_t::operator delete(void* p) { tree.pop(p); } | ||
| 58 | |||
| 59 | uniheap<sizeof(func_t)> func_t::tree; | ||
| 60 | void* func_t::operator new(size_t n) { return tree.push(); } | ||
| 61 | void func_t::operator delete(void* p) { tree.pop(p); } | ||
| 62 | |||
| 63 | uniheap<sizeof(cron_t)> cron_t::tree; | ||
| 64 | void* cron_t::operator new(size_t n) { return tree.push(); } | ||
| 65 | void cron_t::operator delete(void* p) { tree.pop(p); } | ||
| 66 | |||
| 67 | uniheap<sizeof(binary_t)> binary_t::tree; | ||
| 68 | void* binary_t::operator new(size_t n) { return tree.push(); } | ||
| 69 | void binary_t::operator delete(void* p) { tree.pop(p); } | ||
| 70 | |||
| 71 | /////////////////////////////////////////////////////////////////// | ||
| 72 | |||
| 73 | mstring uscore2dot(const char* s) { | ||
| 74 | mstring t=s; int p; while((p=t.find('_'))>=0) t[p]='.'; return t; | ||
| 75 | } | ||
| 76 | |||
| 77 | /////////////////////////////////////////////////////////////////// | ||
| 78 | |||
| 79 | tok_t::~tok_t() {} | ||
| 80 | |||
| 81 | /////////////////////////////////////////////////////////////////// | ||
| 82 | |||
| 83 | void tokmap::clear() | ||
| 84 | { | ||
| 85 | for(iterator p=list.begin();p!=list.end();p++) delete *p; | ||
| 86 | list.clear(); | ||
| 87 | } | ||
| 88 | |||
| 89 | tok_t* tokmap::get_this(const sref& t) | ||
| 90 | { | ||
| 91 | pair<iterator,iterator> p=equal_range(list.begin(),list.end(),(val_t)0,comp_t(t)); | ||
| 92 | return p.first!=p.second?*p.first:0; | ||
| 93 | } | ||
| 94 | |||
| 95 | const tok_t* tokmap::get_this(const sref& t) const | ||
| 96 | { | ||
| 97 | pair<const_iterator,const_iterator> p= | ||
| 98 | equal_range(list.begin(),list.end(),(val_t)0,comp_t(t)); | ||
| 99 | return p.first!=p.second?*p.first:0; | ||
| 100 | } | ||
| 101 | |||
| 102 | const tok_t* tokmap::get(const sref& t) const | ||
| 103 | { | ||
| 104 | const tok_t* p=get_this(t); return p?p:up?up->get(t):0; | ||
| 105 | } | ||
| 106 | |||
| 107 | tok_t* tokmap::get(const sref& t) | ||
| 108 | { | ||
| 109 | tok_t* p=get_this(t); return p?p:up?up->get(t):0; | ||
| 110 | } | ||
| 111 | |||
| 112 | tok_t* tokmap::set(tok_t* tok,int replace,int force) throw(merror_t) | ||
| 113 | { | ||
| 114 | pair<iterator,iterator> p= | ||
| 115 | equal_range(list.begin(),list.end(),(val_t)0,comp_t(tok->name)); | ||
| 116 | if(p.first!=p.second) { | ||
| 117 | if(!(*p.first)->is_replaceable(*tok)) { | ||
| 118 | delete tok; | ||
| 119 | THROW("token: Could not set "<<(*p.first)->name<<" - protected"); | ||
| 120 | return 0; | ||
| 121 | } | ||
| 122 | else if((*p.first)->is_const()&&!replace) { | ||
| 123 | delete tok; | ||
| 124 | if(force) THROW("token: Could not set "<<(*p.first)->name<<" - constant"); | ||
| 125 | return 0; | ||
| 126 | } | ||
| 127 | else { delete *p.first; return *p.first=tok; } | ||
| 128 | } | ||
| 129 | else if(up) return up->set(tok,replace,force); | ||
| 130 | else { | ||
| 131 | mstring name=tok->name; | ||
| 132 | delete tok; | ||
| 133 | if(force) THROW("token: Could not set "<<name<<" - not found"); | ||
| 134 | return 0; | ||
| 135 | } | ||
| 136 | } | ||
| 137 | |||
| 138 | tok_t* tokmap::add(tok_t* tok,int replace,int force) throw(merror_t) | ||
| 139 | { | ||
| 140 | tok_t* old=get(tok->name); | ||
| 141 | if(old) { | ||
| 142 | if(!old->is_replaceable(*tok)) { | ||
| 143 | delete tok; | ||
| 144 | THROW("token: Could not add "<<old->name<<" - protected"); | ||
| 145 | return 0; | ||
| 146 | } | ||
| 147 | else if(old->is_const()&&!replace) { | ||
| 148 | delete tok; | ||
| 149 | if(force) THROW("token: Could not add "<<old->name<<" - constant"); | ||
| 150 | return 0; | ||
| 151 | } | ||
| 152 | } | ||
| 153 | pair<iterator,iterator> p= | ||
| 154 | equal_range(list.begin(),list.end(),(val_t)0,comp_t(tok->name)); | ||
| 155 | if(p.first!=p.second) { delete *p.first; return *p.first=tok; } | ||
| 156 | else return *list.insert(p.second,tok); | ||
| 157 | } | ||
| 158 | |||
| 159 | /////////////////////////////////////////////////////////////////// | ||
| 160 | |||
| 161 | static void Check(const sref& s) throw(merror_t) | ||
| 162 | { | ||
| 163 | if(!is_tokname(s)) THROW("token: bad name ("<<s<<")"); | ||
| 164 | } | ||
| 165 | |||
| 166 | static void CheckArg(const sref& s) throw(merror_t) | ||
| 167 | { | ||
| 168 | if(!is_arglist(s)) THROW("ftok: bad argspec ("<<s<<")"); | ||
| 169 | } | ||
| 170 | |||
| 171 | /////////////////////////////////////////////////////////////////// | ||
| 172 | |||
| 173 | tok_t* Cond(tokmap& map,const sref& s,const sref& b,unsigned m) throw(merror_t) | ||
| 174 | { | ||
| 175 | Check(s); | ||
| 176 | return map.add(new tok_t(s,b,m),0,0); | ||
| 177 | } | ||
| 178 | |||
| 179 | tok_t* Global(tokmap& map,const sref& s,const sref& b,unsigned m,int rpl) throw(merror_t) | ||
| 180 | { | ||
| 181 | Check(s); | ||
| 182 | return map.add(new tok_t(s,b,m),rpl,1); | ||
| 183 | } | ||
| 184 | |||
| 185 | tok_t* Const(tokmap& map,const sref& s,const sref& b,unsigned m,int rpl) throw(merror_t) | ||
| 186 | { | ||
| 187 | Check(s); | ||
| 188 | return map.add(new tok_t(s,b,m|tok_t::CONSTANT),rpl,1); | ||
| 189 | } | ||
| 190 | |||
| 191 | func_t* Func(tokmap& map,const sref& s,const sref& b, | ||
| 192 | unsigned m,const sref& a,int rpl) throw(merror_t) | ||
| 193 | { | ||
| 194 | Check(s); | ||
| 195 | CheckArg(a); | ||
| 196 | return (func_t*)map.add(new func_t(s,b,m,a),rpl,1); | ||
| 197 | } | ||
| 198 | |||
| 199 | cron_t* Cron(tokmap& map,const sref& s,const sref& b, | ||
| 200 | unsigned m,int i,int rpl) throw(merror_t) | ||
| 201 | { | ||
| 202 | Check(s); | ||
| 203 | return (cron_t*)map.add(new cron_t(s,b,m,i),rpl,1); | ||
| 204 | } | ||
| 205 | |||
| 206 | binary_t* Binary(tokmap& map,const sref& s,const sref& b, | ||
| 207 | unsigned m,const sref& a,s_func_t f,int rpl) throw(merror_t) | ||
| 208 | { | ||
| 209 | Check(s); | ||
| 210 | CheckArg(a); | ||
| 211 | return (binary_t*)map.add(new binary_t(s,b,m,a,f),rpl,1); | ||
| 212 | } | ||
| 213 | |||
| 214 | reference_t* Reference(tokmap& map,const sref& s, | ||
| 215 | const sref& b,unsigned m,int rpl) throw(merror_t) | ||
| 216 | { | ||
| 217 | Check(s); | ||
| 218 | return (reference_t*)map.add(new reference_t(s,b,m),rpl,1); | ||
| 219 | } | ||
| 220 | |||
| 221 | dbref_t* DBRef(tokmap& map,const sref& s, | ||
| 222 | const sref& b,unsigned m,int rpl) throw(merror_t) | ||
| 223 | { | ||
| 224 | Check(s); | ||
| 225 | return (dbref_t*)map.add(new dbref_t(s,b,m),rpl,1); | ||
| 226 | } | ||
| 227 | |||
| 228 | void ClearToken(tokmap& map,const sref& s) throw(merror_t) | ||
| 229 | { | ||
| 230 | if(s.nempty()) { | ||
| 231 | tokmap::iterator p=map.begin(); | ||
| 232 | while(p<map.end()) { | ||
| 233 | if((*p)->name.left(s.size())==s) p=map.erase(p); else p++; | ||
| 234 | } | ||
| 235 | } | ||
| 236 | } | ||
| 237 | |||
| 238 | /////////////////////////////////////////////////////////////// | ||
| 239 | |||
| 240 | mstream& operator<<(mstream& out,const runnable_t& ftok) | ||
| 241 | { | ||
| 242 | out<<"\\"<<ftok.name; | ||
| 243 | for(const char* p=ftok.arg.begin();p!=ftok.arg.end();p++) out.put('{').put(*p).put('}'); | ||
| 244 | return out; | ||
| 245 | } | ||
| 246 | |||
| 247 | mstring Mode(const tok_t& tok) | ||
| 248 | { | ||
| 249 | mstring m; | ||
| 250 | for(int i=11;i>=0;i--) { if(tok.mod&(1<<i)) m+='1'; else m+='0'; } | ||
| 251 | return m; | ||
| 252 | } | ||
| 253 | |||
| 254 | mstring Desc(const tok_t& tok) | ||
| 255 | { | ||
| 256 | mstring m; | ||
| 257 | sref first,rest=tok.body; | ||
| 258 | while(Splitln(first,rest)) { | ||
| 259 | first=first.right_first_not_of(cset_ws); | ||
| 260 | if(*first=='%') { | ||
| 261 | first=first.popf().right_first_not_of(cset_ws); | ||
| 262 | m+=first; | ||
| 263 | m+='\n'; | ||
| 264 | } | ||
| 265 | } | ||
| 266 | return m; | ||
| 267 | } | ||
| 268 | |||
diff --git a/src/lang/token.h b/src/lang/token.h new file mode 100644 index 0000000..bf32820 --- /dev/null +++ b/src/lang/token.h | |||
| @@ -0,0 +1,230 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef TOKENH | ||
| 21 | #define TOKENH | ||
| 22 | |||
| 23 | #include <ops/express.h> | ||
| 24 | #include <hdb/db.h> | ||
| 25 | |||
| 26 | #define TOK_ARGS (mstream& out,Env& env) | ||
| 27 | #define TOK_IMPL(func) static void impl_##func TOK_ARGS throw(merror_t) | ||
| 28 | #define TOK_ADD(func,a,mod,help) \ | ||
| 29 | T.add(new binary_t(uscore2dot(#func),sref(help),mod,sref(a),impl_##func),0,1) | ||
| 30 | |||
| 31 | mstring uscore2dot(const char* s); | ||
| 32 | |||
| 33 | class Env; | ||
| 34 | typedef void (*s_func_t)TOK_ARGS; | ||
| 35 | |||
| 36 | class tok_t { | ||
| 37 | public: | ||
| 38 | static const unsigned CONSTANT,RESTRICT,NORMAL,SYSONLY,INIT; | ||
| 39 | static const unsigned RUNNABLE,FUNCTION,BINARY; | ||
| 40 | static const unsigned REFERENCE,DBREF,CRON; | ||
| 41 | static const unsigned PRIVATE,PUBLIC,XMODES; | ||
| 42 | |||
| 43 | static inline unsigned tight(unsigned xmod) { | ||
| 44 | // INIT is ignored here simply because no mode can | ||
| 45 | // read variables in INIT mode... defaults to public. | ||
| 46 | return (xmod&SYSONLY)?SYSONLY:(xmod&NORMAL)?PRIVATE:PUBLIC; | ||
| 47 | } | ||
| 48 | |||
| 49 | mstring name,body; | ||
| 50 | unsigned mod; | ||
| 51 | |||
| 52 | int is_clear(int xmod) const { return (mod&xmod)!=0; } | ||
| 53 | int is_replaceable(const tok_t& t) const { return (mod&t.mod)==t.mod; } | ||
| 54 | |||
| 55 | int is_const() const { return (mod&CONSTANT)!=0; } | ||
| 56 | int is_runnable() const { return (mod&RUNNABLE)!=0; } | ||
| 57 | int is_func() const { return (mod&FUNCTION)!=0; } | ||
| 58 | int is_cron() const { return (mod&CRON)!=0; } | ||
| 59 | int is_binary() const { return (mod&BINARY)!=0; } | ||
| 60 | int is_reference() const { return (mod&REFERENCE)!=0; } | ||
| 61 | int is_dbref() const { return (mod&DBREF)!=0; } | ||
| 62 | |||
| 63 | tok_t(const sref& s,const sref& b,unsigned m) : name(s),body(b),mod(m) {} | ||
| 64 | virtual ~tok_t(); | ||
| 65 | |||
| 66 | static void* operator new(size_t n); | ||
| 67 | static void operator delete(void* p); | ||
| 68 | private: | ||
| 69 | static uniheap<32> tree; | ||
| 70 | }; | ||
| 71 | |||
| 72 | /////////////////////////////////////////////////////////////////// | ||
| 73 | |||
| 74 | class reference_t : public tok_t { | ||
| 75 | public: | ||
| 76 | mstring data; | ||
| 77 | reference_t(const sref& s,const sref& b,unsigned m): | ||
| 78 | tok_t(s,b,m|REFERENCE|CONSTANT) {} | ||
| 79 | |||
| 80 | static void* operator new(size_t n); | ||
| 81 | static void operator delete(void* p); | ||
| 82 | private: | ||
| 83 | static uniheap<44> tree; | ||
| 84 | }; | ||
| 85 | |||
| 86 | /////////////////////////////////////////////////////////////////// | ||
| 87 | |||
| 88 | class dbref_t : public tok_t { | ||
| 89 | public: | ||
| 90 | dbmap db; | ||
| 91 | dbref_t(const sref& s,const sref& b,unsigned m): | ||
| 92 | tok_t(s,b,m|DBREF|CONSTANT) {} | ||
| 93 | |||
| 94 | static void* operator new(size_t n); | ||
| 95 | static void operator delete(void* p); | ||
| 96 | private: | ||
| 97 | static uniheap<96> tree; | ||
| 98 | }; | ||
| 99 | |||
| 100 | /////////////////////////////////////////////////////////////////// | ||
| 101 | |||
| 102 | class runnable_t : public tok_t { | ||
| 103 | public: | ||
| 104 | mstring arg; | ||
| 105 | runnable_t(const sref& s,const sref& b,unsigned m,const sref& a): | ||
| 106 | tok_t(s,b,m|RUNNABLE|CONSTANT),arg(a) {} | ||
| 107 | |||
| 108 | static void* operator new(size_t n); | ||
| 109 | static void operator delete(void* p); | ||
| 110 | private: | ||
| 111 | static uniheap<44> tree; | ||
| 112 | }; | ||
| 113 | |||
| 114 | /////////////////////////////////////////////////////////////////// | ||
| 115 | |||
| 116 | class func_t : public runnable_t { | ||
| 117 | public: | ||
| 118 | expr_t x; | ||
| 119 | func_t(const sref& s,const sref& b,unsigned m,const sref& a): | ||
| 120 | runnable_t(s,b,m|FUNCTION,a) { x=body; } | ||
| 121 | |||
| 122 | static void* operator new(size_t n); | ||
| 123 | static void operator delete(void* p); | ||
| 124 | private: | ||
| 125 | static uniheap<80> tree; | ||
| 126 | }; | ||
| 127 | |||
| 128 | /////////////////////////////////////////////////////////////////// | ||
| 129 | |||
| 130 | class cron_t : public func_t { | ||
| 131 | public: | ||
| 132 | int last,interval; | ||
| 133 | cron_t(const sref& s,const sref& b,unsigned m,int i): | ||
| 134 | func_t(s,b,m|CRON,ms_empty),last(0),interval(i) {} | ||
| 135 | |||
| 136 | static void* operator new(size_t n); | ||
| 137 | static void operator delete(void* p); | ||
| 138 | private: | ||
| 139 | static uniheap<88> tree; | ||
| 140 | }; | ||
| 141 | |||
| 142 | /////////////////////////////////////////////////////////////////// | ||
| 143 | |||
| 144 | class binary_t : public runnable_t { | ||
| 145 | public: | ||
| 146 | s_func_t func; | ||
| 147 | binary_t(const sref& s,const sref& b,unsigned m,const sref& a,s_func_t f): | ||
| 148 | runnable_t(s,b,m|BINARY,a),func(f) {} | ||
| 149 | |||
| 150 | static void* operator new(size_t n); | ||
| 151 | static void operator delete(void* p); | ||
| 152 | private: | ||
| 153 | static uniheap<48> tree; | ||
| 154 | }; | ||
| 155 | |||
| 156 | /////////////////////////////////////////////////////////////////// | ||
| 157 | |||
| 158 | mstream& operator<<(mstream&,const runnable_t& ftok); | ||
| 159 | mstring Mode(const tok_t& tok); | ||
| 160 | mstring Desc(const tok_t& tok); | ||
| 161 | |||
| 162 | /////////////////////////////////////////////////////////////////// | ||
| 163 | |||
| 164 | struct tokmap { | ||
| 165 | typedef tok_t* val_t; | ||
| 166 | typedef mrvec<val_t> map_t; | ||
| 167 | typedef map_t::iterator iterator; | ||
| 168 | typedef map_t::const_iterator const_iterator; | ||
| 169 | |||
| 170 | struct comp_t { | ||
| 171 | sref key; | ||
| 172 | comp_t(const sref& skey) : key(skey) {} | ||
| 173 | bool operator()(val_t a,val_t b) const { | ||
| 174 | return (a?((const sref&)a->name):key)<(b?((const sref&)b->name):key); | ||
| 175 | } | ||
| 176 | }; | ||
| 177 | |||
| 178 | tokmap* up; | ||
| 179 | map_t list; | ||
| 180 | |||
| 181 | tokmap() : up(0),list() {} | ||
| 182 | tokmap(tokmap& p) : up(&p),list() {} | ||
| 183 | ~tokmap() { clear(); } | ||
| 184 | |||
| 185 | iterator begin() { return list.begin(); } | ||
| 186 | const_iterator begin() const { return list.begin(); } | ||
| 187 | |||
| 188 | iterator end() { return list.end(); } | ||
| 189 | const_iterator end() const { return list.end(); } | ||
| 190 | |||
| 191 | void clear(); | ||
| 192 | iterator erase(iterator p) { delete *p; return list.erase(p); } | ||
| 193 | |||
| 194 | tok_t* get_this(const sref& t); | ||
| 195 | const tok_t* get_this(const sref& t) const; | ||
| 196 | const tok_t* get(const sref& t) const; | ||
| 197 | tok_t* get(const sref& t); | ||
| 198 | |||
| 199 | tok_t* set(tok_t* tok,int replace,int force) throw(merror_t); | ||
| 200 | tok_t* add(tok_t* tok,int replace,int force) throw(merror_t); | ||
| 201 | }; | ||
| 202 | |||
| 203 | /////////////////////////////////////////////////////////////////// | ||
| 204 | |||
| 205 | int is_tokname(const sref& s); | ||
| 206 | int is_arglist(const sref& s); | ||
| 207 | |||
| 208 | tok_t* Cond(tokmap& map,const sref& s,const sref& b,unsigned m) throw(merror_t); | ||
| 209 | tok_t* Global(tokmap& map,const sref& s,const sref& b,unsigned m,int rpl=0) throw(merror_t); | ||
| 210 | tok_t* Const(tokmap& map,const sref& s,const sref& b,unsigned m,int rpl=0) throw(merror_t); | ||
| 211 | func_t* Func(tokmap& map,const sref& s,const sref& b, | ||
| 212 | unsigned m,const sref& a,int rpl=0) throw(merror_t); | ||
| 213 | cron_t* Cron(tokmap& map,const sref& s,const sref& b, | ||
| 214 | unsigned m,int i,int rpl=0) throw(merror_t); | ||
| 215 | binary_t* Binary(tokmap& map,const sref& s,const sref& b, | ||
| 216 | unsigned m,const sref& a,s_func_t f,int rpl=0) throw(merror_t); | ||
| 217 | reference_t* Reference(tokmap& map,const sref& s,const sref& b, | ||
| 218 | unsigned m,int rpl=0) throw(merror_t); | ||
| 219 | dbref_t* DBRef(tokmap& map,const sref& s, | ||
| 220 | const sref& b,unsigned m,int rpl=0) throw(merror_t); | ||
| 221 | void ClearToken(tokmap& map,const sref& s) throw(merror_t); | ||
| 222 | |||
| 223 | /////////////////////////////////////////////////////////////////// | ||
| 224 | |||
| 225 | const int XPUBLIC=tok_t::RESTRICT; | ||
| 226 | const int XPRIVATE=XPUBLIC|tok_t::NORMAL; | ||
| 227 | const int XSYSTEM=XPRIVATE|tok_t::SYSONLY; | ||
| 228 | const int XINIT=tok_t::INIT; | ||
| 229 | |||
| 230 | #endif | ||
diff --git a/src/mail/inbox.cc b/src/mail/inbox.cc new file mode 100644 index 0000000..b605cd3 --- /dev/null +++ b/src/mail/inbox.cc | |||
| @@ -0,0 +1,36 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <mail/res.h> | ||
| 21 | #include <mt/lock.h> | ||
| 22 | #include <unistd.h> | ||
| 23 | |||
| 24 | main(int argc,char* argv[]) | ||
| 25 | { | ||
| 26 | if(argc<3) return -1; | ||
| 27 | const char* infile=INBOX.c_str(); // argv[1] not used | ||
| 28 | const char* outfile=argv[2]; | ||
| 29 | LockFile(infile); | ||
| 30 | Mailbox box; | ||
| 31 | GetMessages(box,infile); | ||
| 32 | int ok=AppendMessages(box,outfile); | ||
| 33 | if(ok) truncate(infile,0); | ||
| 34 | UnlockFile(infile); | ||
| 35 | return !ok; | ||
| 36 | } | ||
diff --git a/src/mail/list.cc b/src/mail/list.cc new file mode 100644 index 0000000..f50c41b --- /dev/null +++ b/src/mail/list.cc | |||
| @@ -0,0 +1,52 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <mail/res.h> | ||
| 21 | #include <mime/enc.h> | ||
| 22 | |||
| 23 | static fp_stream mout(stdout),merr(stderr); | ||
| 24 | const mstring multipart="multipart/"; | ||
| 25 | |||
| 26 | main(int argc,char* argv[]) try | ||
| 27 | { | ||
| 28 | if(argc<2) { | ||
| 29 | merr<<"Usage: "<<argv[0]<<" <inbox> [index]\n"; | ||
| 30 | return -1; | ||
| 31 | } | ||
| 32 | const char* infile=argv[1]; | ||
| 33 | Mailbox box; | ||
| 34 | GetMessages(box,infile); | ||
| 35 | if(argc>2) { | ||
| 36 | int m=atoi(argv[2])-1; | ||
| 37 | if(m>=0&&m<box.size()) mout<<box[m]<<"\n"; | ||
| 38 | } | ||
| 39 | else { | ||
| 40 | merr<<"Read "<<box.size()<<" messages.\n"; | ||
| 41 | for(int i=0;i<box.size();i++) { | ||
| 42 | Message msg(box[i]); | ||
| 43 | int multi=msg.cont_type.find(multipart)>=0; | ||
| 44 | mout<<"["<<(i+1)<<"]["<<multi<<"]["<<msg.subject<<"]["<<msg.from<<"]\n"; | ||
| 45 | } | ||
| 46 | } | ||
| 47 | return 0; | ||
| 48 | } | ||
| 49 | catch(const merror_t& e) | ||
| 50 | { | ||
| 51 | fprintf(stderr,"main: %d: %s\n",e.num,e.desc.c_str()); | ||
| 52 | } | ||
diff --git a/src/mail/move.cc b/src/mail/move.cc new file mode 100644 index 0000000..bbcce0d --- /dev/null +++ b/src/mail/move.cc | |||
| @@ -0,0 +1,60 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <mail/res.h> | ||
| 21 | #include <mt/lock.h> | ||
| 22 | |||
| 23 | static fp_stream mout(stdout),merr(stderr); | ||
| 24 | |||
| 25 | main(int argc,char* argv[]) | ||
| 26 | { | ||
| 27 | if(argc<3) { | ||
| 28 | merr<<"Usage: "<<argv[0]<<" <frombox> <tobox> [indices]\n"; | ||
| 29 | return -1; | ||
| 30 | } | ||
| 31 | const char* infile=argv[1]; | ||
| 32 | const char* outfile=argv[2]; | ||
| 33 | Mailbox box,keep; | ||
| 34 | LockFile(infile); | ||
| 35 | LockFile(outfile); | ||
| 36 | FILE* outbox=fopen(outfile,"a+"); | ||
| 37 | if(outbox) { | ||
| 38 | GetMessages(box,infile); | ||
| 39 | for(int i=0;i<box.size();i++) { | ||
| 40 | int move=0; | ||
| 41 | if(argc>3) { | ||
| 42 | for(int j=3;j<argc;j++) if(atoi(argv[j])-1==i) { move=1; break; } | ||
| 43 | } | ||
| 44 | else { | ||
| 45 | move=1; | ||
| 46 | } | ||
| 47 | if(move) AppendMessage(outbox,box[i]); | ||
| 48 | else keep.push_back(box[i]); | ||
| 49 | } | ||
| 50 | if(fclose(outbox)) { | ||
| 51 | merr<<"Write error: messages kept (but possibly duplicates).\n"; | ||
| 52 | } | ||
| 53 | else { | ||
| 54 | PutMessages(keep,infile); | ||
| 55 | } | ||
| 56 | } | ||
| 57 | UnlockFile(outfile); | ||
| 58 | UnlockFile(infile); | ||
| 59 | return 0; | ||
| 60 | } | ||
diff --git a/src/mail/res.h b/src/mail/res.h new file mode 100644 index 0000000..5c54c31 --- /dev/null +++ b/src/mail/res.h | |||
| @@ -0,0 +1,30 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef MAILRESH | ||
| 21 | #define MAILRESH | ||
| 22 | |||
| 23 | #include <mime/mailbox.h> | ||
| 24 | #include <mt/config.h> | ||
| 25 | |||
| 26 | const mstring INBOX=htchome()+sref("/mail/INBOX"); | ||
| 27 | const mstring TODO=htchome()+sref("/mail/TODO"); | ||
| 28 | const mstring DONE=htchome()+sref("/mail/DONE"); | ||
| 29 | |||
| 30 | #endif | ||
diff --git a/src/makefile b/src/makefile new file mode 100644 index 0000000..09670b2 --- /dev/null +++ b/src/makefile | |||
| @@ -0,0 +1,177 @@ | |||
| 1 | ######################################################################### | ||
| 2 | # | ||
| 3 | # HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | # | ||
| 5 | # This program is free software; you can redistribute it and/or modify | ||
| 6 | # it under the terms of the GNU General Public License as published by | ||
| 7 | # the Free Software Foundation; either version 2 of the License, or | ||
| 8 | # (at your option) any later version. | ||
| 9 | # | ||
| 10 | # This program is distributed in the hope that it will be useful, | ||
| 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | # GNU General Public License for more details. | ||
| 14 | # | ||
| 15 | # You should have received a copy of the GNU General Public License | ||
| 16 | # along with this program; if not, write to the Free Software | ||
| 17 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | # | ||
| 19 | |||
| 20 | LIBRARY = libhtc.a | ||
| 21 | INSTALL = ../bin | ||
| 22 | |||
| 23 | ############################################################################ | ||
| 24 | |||
| 25 | MODULE += mt | ||
| 26 | mt_c = test | ||
| 27 | mt_o = cfind crfind strip \ | ||
| 28 | sfind srfind sfindtab srfindtab scomptab sconvert \ | ||
| 29 | find_of rfind_of find_not_of rfind_not_of skip_parentesis \ | ||
| 30 | stringref mstream mread mstring mset msmap \ | ||
| 31 | random dates lock lookup issue config | ||
| 32 | |||
| 33 | |||
| 34 | MODULE += mime | ||
| 35 | mime_c = test | ||
| 36 | mime_o = mime def mailbox base64 qp pack | ||
| 37 | |||
| 38 | |||
| 39 | MODULE += mail | ||
| 40 | mail_c = inbox move list | ||
| 41 | |||
| 42 | |||
| 43 | MODULE += http | ||
| 44 | http_c = test | ||
| 45 | http_o = mime req resp | ||
| 46 | |||
| 47 | |||
| 48 | MODULE += ops | ||
| 49 | ops_c = test | ||
| 50 | ops_o = operator express basic comp string latex | ||
| 51 | |||
| 52 | |||
| 53 | MODULE += hdb | ||
| 54 | hdb_c = test hdbtest hdbcvt hdbfix | ||
| 55 | hdb_o = filemap sortable db comp cvt | ||
| 56 | |||
| 57 | |||
| 58 | MODULE += hed | ||
| 59 | hed_c = test hed | ||
| 60 | hed_o = input edit tables | ||
| 61 | hed_x = hed | ||
| 62 | |||
| 63 | |||
| 64 | MODULE += lang | ||
| 65 | lang_c = test | ||
| 66 | lang_o = token env parse ops basic func latex help flow db lang | ||
| 67 | |||
| 68 | |||
| 69 | MODULE += sh | ||
| 70 | sh_c = htc | ||
| 71 | sh_o = file convert dates user tree sys net main | ||
| 72 | sh_x = htc | ||
| 73 | |||
| 74 | MODULE += serv | ||
| 75 | serv_c = htcs | ||
| 76 | serv_o = direct request const auth form tempmap main | ||
| 77 | serv_x = htcs | ||
| 78 | |||
| 79 | MODULE += net | ||
| 80 | net_c = test htcd redirect route80 | ||
| 81 | net_o = isocket server thrserv | ||
| 82 | net_x = htcd redirect | ||
| 83 | |||
| 84 | MODULE += labat | ||
| 85 | labat_c = atomlab | ||
| 86 | labat_f = labat | ||
| 87 | labat_o = resten deriv grad grabgr laplac laplac2 ggaexc \ | ||
| 88 | exchen ldaec gcor ggaec ggauxc exchpt ldauc \ | ||
| 89 | ggauc spline splint | ||
| 90 | labat_x = atomlab labat | ||
| 91 | |||
| 92 | ############################################################################ | ||
| 93 | |||
| 94 | CTARGET = $(foreach mod,$(MODULE),\ | ||
| 95 | $(addprefix $(mod)/,$($(mod)_c))) | ||
| 96 | |||
| 97 | FTARGET = $(foreach mod,$(MODULE),\ | ||
| 98 | $(addprefix $(mod)/,$($(mod)_f))) | ||
| 99 | |||
| 100 | LTARGET = $(foreach mod,$(MODULE),\ | ||
| 101 | $(addprefix $(mod)/,$($(mod)_o))) | ||
| 102 | |||
| 103 | XTARGET = $(foreach mod,$(MODULE),\ | ||
| 104 | $(addprefix $(mod)/,$($(mod)_x))) | ||
| 105 | |||
| 106 | XLIST = $(foreach mod,$(MODULE),$($(mod)_x)) | ||
| 107 | |||
| 108 | CTARG = $(addprefix tmp/bin/,$(CTARGET)) | ||
| 109 | FTARG = $(addprefix tmp/bin/,$(FTARGET)) | ||
| 110 | XTARG = $(addprefix tmp/bin/,$(XTARGET)) | ||
| 111 | COBJ = $(addprefix tmp/obj/c/,$(addsuffix .o,$(CTARGET))) | ||
| 112 | FOBJ = $(addprefix tmp/obj/f/,$(addsuffix .o,$(FTARGET))) | ||
| 113 | LOBJ = $(addprefix tmp/obj/l/,$(addsuffix .o,$(LTARGET))) | ||
| 114 | TLIB = $(addprefix tmp/obj/,$(LIBRARY)) | ||
| 115 | |||
| 116 | ############################################################################ | ||
| 117 | |||
| 118 | INCLUDE = -I. | ||
| 119 | COPT = -O3 -pthread | ||
| 120 | FOPT = -O5 | ||
| 121 | CLIBS = -lncurses | ||
| 122 | FLIBS = | ||
| 123 | |||
| 124 | .PHONY: all man html clean mkobj install | ||
| 125 | .PRECIOUS: tmp/obj/c/%.o tmp/obj/f/%.o tmp/obj/l/%.o | ||
| 126 | |||
| 127 | ############################################################################ | ||
| 128 | |||
| 129 | all: $(LOBJ) $(TLIB) $(FOBJ) $(COBJ) $(FTARG) $(CTARG) | ||
| 130 | |||
| 131 | tmp/bin/%: tmp/obj/c/%.o $(TLIB) | ||
| 132 | @mkdir -p $(@D) | ||
| 133 | g++ $(COPT) $< $(TLIB) $(CLIBS) -o $@ | ||
| 134 | |||
| 135 | tmp/bin/%: tmp/obj/f/%.o $(TLIB) | ||
| 136 | @mkdir -p $(@D) | ||
| 137 | f77 $(FOPT) $< $(TLIB) $(FLIBS) -o $@ | ||
| 138 | |||
| 139 | tmp/obj/c/%.o: %.cc | ||
| 140 | @mkdir -p $(@D) | ||
| 141 | gcc $(INCLUDE) $(COPT) -c $< -o $@ | ||
| 142 | |||
| 143 | tmp/obj/f/%.o: %.f | ||
| 144 | @mkdir -p $(@D) | ||
| 145 | f77 $(FOPT) -c $< -o $@ | ||
| 146 | |||
| 147 | $(TLIB): $(LOBJ) | ||
| 148 | @rm -f $(TLIB) | ||
| 149 | ar qc $(TLIB) $(LOBJ) | ||
| 150 | |||
| 151 | tmp/obj/l/%.o: %.cc | ||
| 152 | @mkdir -p $(@D) | ||
| 153 | gcc $(INCLUDE) $(COPT) -c $< -o $@ | ||
| 154 | |||
| 155 | tmp/obj/l/%.o: %.f | ||
| 156 | @mkdir -p $(@D) | ||
| 157 | f77 $(FOPT) -c $< -o $@ | ||
| 158 | |||
| 159 | man: | ||
| 160 | @rm -rf tmp/man | ||
| 161 | doxygen etc/doxman | ||
| 162 | |||
| 163 | html: | ||
| 164 | @rm -rf tmp/html | ||
| 165 | doxygen etc/doxhtml | ||
| 166 | |||
| 167 | install: $(XTARG) | ||
| 168 | @mkdir -p $(INSTALL) | ||
| 169 | cp -rfp $(XTARG) $(INSTALL) | ||
| 170 | |||
| 171 | clean: | ||
| 172 | rm -rf tmp | ||
| 173 | |||
| 174 | distclean: | ||
| 175 | rm -rf tmp; cd $(INSTALL); rm -rf $(XLIST) | ||
| 176 | |||
| 177 | ############################################################################ | ||
diff --git a/src/mime/base64.cc b/src/mime/base64.cc new file mode 100644 index 0000000..842bbd3 --- /dev/null +++ b/src/mime/base64.cc | |||
| @@ -0,0 +1,132 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <mime/enc.h> | ||
| 21 | |||
| 22 | static unsigned char char2six[256]={ | ||
| 23 | 65,65,65,65,65,65,65,65, | ||
| 24 | 65,65,65,65,65,65,65,65, | ||
| 25 | 65,65,65,65,65,65,65,65, | ||
| 26 | 65,65,65,65,65,65,65,65, | ||
| 27 | 65,65,65,65,65,65,65,65, | ||
| 28 | 65,65,65,62,65,65,65,63, | ||
| 29 | 52,53,54,55,56,57,58,59, | ||
| 30 | 60,61,65,65,65,64,65,65, | ||
| 31 | 65, 0, 1, 2, 3, 4, 5, 6, | ||
| 32 | 7, 8, 9,10,11,12,13,14, | ||
| 33 | 15,16,17,18,19,20,21,22, | ||
| 34 | 23,24,25,65,65,65,65,65, | ||
| 35 | 65,26,27,28,29,30,31,32, | ||
| 36 | 33,34,35,36,37,38,39,40, | ||
| 37 | 41,42,43,44,45,46,47,48, | ||
| 38 | 49,50,51,65,65,65,65,65, | ||
| 39 | 65,65,65,65,65,65,65,65, | ||
| 40 | 65,65,65,65,65,65,65,65, | ||
| 41 | 65,65,65,65,65,65,65,65, | ||
| 42 | 65,65,65,65,65,65,65,65, | ||
| 43 | 65,65,65,65,65,65,65,65, | ||
| 44 | 65,65,65,65,65,65,65,65, | ||
| 45 | 65,65,65,65,65,65,65,65, | ||
| 46 | 65,65,65,65,65,65,65,65, | ||
| 47 | 65,65,65,65,65,65,65,65, | ||
| 48 | 65,65,65,65,65,65,65,65, | ||
| 49 | 65,65,65,65,65,65,65,65, | ||
| 50 | 65,65,65,65,65,65,65,65, | ||
| 51 | 65,65,65,65,65,65,65,65, | ||
| 52 | 65,65,65,65,65,65,65,65, | ||
| 53 | 65,65,65,65,65,65,65,65, | ||
| 54 | 65,65,65,65,65,65,65,65 | ||
| 55 | }; | ||
| 56 | static unsigned char six2char[64]={ | ||
| 57 | 'A','B','C','D','E','F','G','H', | ||
| 58 | 'I','J','K','L','M','N','O','P', | ||
| 59 | 'Q','R','S','T','U','V','W','X', | ||
| 60 | 'Y','Z','a','b','c','d','e','f', | ||
| 61 | 'g','h','i','j','k','l','m','n', | ||
| 62 | 'o','p','q','r','s','t','u','v', | ||
| 63 | 'w','x','y','z','0','1','2','3', | ||
| 64 | '4','5','6','7','8','9','+','/' | ||
| 65 | }; | ||
| 66 | inline void tri2quad(mstream& out,unsigned code,int m=4) | ||
| 67 | { | ||
| 68 | char buf[4]; | ||
| 69 | buf[3]=six2char[code&63U]; code>>=6; | ||
| 70 | buf[2]=six2char[code&63U]; code>>=6; | ||
| 71 | buf[1]=six2char[code&63U]; code>>=6; | ||
| 72 | buf[0]=six2char[code&63U]; | ||
| 73 | out.write(buf,m); | ||
| 74 | } | ||
| 75 | inline void quad2tri(mstream& out,unsigned code,int m=3) | ||
| 76 | { | ||
| 77 | char buf[3]; | ||
| 78 | buf[2]=code&255U; code>>=8; | ||
| 79 | buf[1]=code&255U; code>>=8; | ||
| 80 | buf[0]=code&255U; | ||
| 81 | out.write(buf,m); | ||
| 82 | } | ||
| 83 | |||
| 84 | void encode64(mstream& out,const sref& in) | ||
| 85 | { | ||
| 86 | unsigned m=0,code=0,wrap=0; | ||
| 87 | for(const char* p=in.begin();p!=in.end();p++) { | ||
| 88 | code<<=8; | ||
| 89 | code|=(unsigned char)*p; | ||
| 90 | if(++m==3) { | ||
| 91 | tri2quad(out,code); | ||
| 92 | m=0; | ||
| 93 | if(++wrap==15) { out<<CRLF; wrap=0; } | ||
| 94 | } | ||
| 95 | } | ||
| 96 | if(m==1) { | ||
| 97 | code<<=16; | ||
| 98 | tri2quad(out,code,2); | ||
| 99 | out<<"=="; | ||
| 100 | if(++wrap==15) { out<<CRLF; wrap=0; } | ||
| 101 | } | ||
| 102 | else if(m==2) { | ||
| 103 | code<<=8; | ||
| 104 | tri2quad(out,code,3); | ||
| 105 | out.put('='); | ||
| 106 | if(++wrap==15) { out<<CRLF; wrap=0; } | ||
| 107 | } | ||
| 108 | if(wrap>0) out<<CRLF; | ||
| 109 | } | ||
| 110 | |||
| 111 | void decode64(mstream& out,const sref& in) | ||
| 112 | { | ||
| 113 | unsigned m=0,code=0,six=0; | ||
| 114 | for(const char* p=in.begin();p!=in.end();p++) { | ||
| 115 | six=char2six[(unsigned char)*p]; | ||
| 116 | if(six>=64) continue; | ||
| 117 | code<<=6; | ||
| 118 | code|=six; | ||
| 119 | if(++m==4) { | ||
| 120 | quad2tri(out,code); | ||
| 121 | m=0; | ||
| 122 | } | ||
| 123 | } | ||
| 124 | if(m==2) { | ||
| 125 | code<<=12; | ||
| 126 | quad2tri(out,code,1); | ||
| 127 | } | ||
| 128 | else if(m==3) { | ||
| 129 | code<<=6; | ||
| 130 | quad2tri(out,code,2); | ||
| 131 | } | ||
| 132 | } | ||
diff --git a/src/mime/def.cc b/src/mime/def.cc new file mode 100644 index 0000000..0a692cd --- /dev/null +++ b/src/mime/def.cc | |||
| @@ -0,0 +1,149 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <mime/mime.h> | ||
| 21 | #include <mt/msmap.h> | ||
| 22 | |||
| 23 | struct table_t { char ext[16],name[64]; }; | ||
| 24 | |||
| 25 | static table_t table[]={ | ||
| 26 | {"ai","application/postscript"}, | ||
| 27 | {"aif","audio/x-aiff"}, | ||
| 28 | {"aifc","audio/x-aiff"}, | ||
| 29 | {"aiff","audio/x-aiff"}, | ||
| 30 | {"au","audio/basic"}, | ||
| 31 | {"avi","video/x-msvideo"}, | ||
| 32 | {"bcpio","application/x-bcpio"}, | ||
| 33 | {"bin","application/octet-stream"}, | ||
| 34 | {"cdf","application/x-netcdf"}, | ||
| 35 | {"class","application/octet-stream"}, | ||
| 36 | {"cpio","application/x-cpio"}, | ||
| 37 | {"cpt","application/mac-compactpro"}, | ||
| 38 | {"csh","application/x-csh"}, | ||
| 39 | {"css","text/css"}, | ||
| 40 | {"dcr","application/x-director"}, | ||
| 41 | {"dir","application/x-director"}, | ||
| 42 | {"dms","application/octet-stream"}, | ||
| 43 | {"doc","application/msword"}, | ||
| 44 | {"dvi","application/x-dvi"}, | ||
| 45 | {"dxr","application/x-director"}, | ||
| 46 | {"eps","application/postscript"}, | ||
| 47 | {"etx","text/x-setext"}, | ||
| 48 | {"exe","application/octet-stream"}, | ||
| 49 | {"gif","image/gif"}, | ||
| 50 | {"gtar","application/x-gtar"}, | ||
| 51 | {"gz","application/x-gzip"}, | ||
| 52 | {"hdf","application/x-hdf"}, | ||
| 53 | {"hqx","application/mac-binhex40"}, | ||
| 54 | {"htc","text/x-htc"}, | ||
| 55 | {"hts","text/plain"}, | ||
| 56 | {"htx","text/x-htx"}, | ||
| 57 | {"htm","text/html"}, | ||
| 58 | {"html","text/html"}, | ||
| 59 | {"ice","x-conference/x-cooltalk"}, | ||
| 60 | {"ief","image/ief"}, | ||
| 61 | {"jpe","image/jpeg"}, | ||
| 62 | {"jpeg","image/jpeg"}, | ||
| 63 | {"jpg","image/jpeg"}, | ||
| 64 | {"kar","audio/midi"}, | ||
| 65 | {"latex","application/x-latex"}, | ||
| 66 | {"lha","application/octet-stream"}, | ||
| 67 | {"lzh","application/octet-stream"}, | ||
| 68 | {"man","application/x-troff-man"}, | ||
| 69 | {"me","application/x-troff-me"}, | ||
| 70 | {"mid","audio/midi"}, | ||
| 71 | {"midi","audio/midi"}, | ||
| 72 | {"mif","application/x-mif"}, | ||
| 73 | {"mov","video/quicktime"}, | ||
| 74 | {"movie","video/x-sgi-movie"}, | ||
| 75 | {"mp2","audio/mpeg"}, | ||
| 76 | {"mp3","audio/mpeg"}, | ||
| 77 | {"mpe","video/mpeg"}, | ||
| 78 | {"mpeg","video/mpeg"}, | ||
| 79 | {"mpg","video/mpeg"}, | ||
| 80 | {"mpga","audio/mpeg"}, | ||
| 81 | {"ms","application/x-troff-ms"}, | ||
| 82 | {"nc","application/x-netcdf"}, | ||
| 83 | {"oda","application/oda"}, | ||
| 84 | {"pbm","image/x-portable-bitmap"}, | ||
| 85 | {"pdb","chemical/x-pdb"}, | ||
| 86 | {"pdf","application/pdf"}, | ||
| 87 | {"pgm","image/x-portable-graymap"}, | ||
| 88 | {"png","image/png"}, | ||
| 89 | {"pnm","image/x-portable-anymap"}, | ||
| 90 | {"ppm","image/x-portable-pixmap"}, | ||
| 91 | {"ppt","application/powerpoint"}, | ||
| 92 | {"ps","application/postscript"}, | ||
| 93 | {"qt","video/quicktime"}, | ||
| 94 | {"ra","audio/x-realaudio"}, | ||
| 95 | {"ram","audio/x-pn-realaudio"}, | ||
| 96 | {"ras","image/x-cmu-raster"}, | ||
| 97 | {"rgb","image/x-rgb"}, | ||
| 98 | {"roff","application/x-troff"}, | ||
| 99 | {"rpm","audio/x-pn-realaudio-plugin"}, | ||
| 100 | {"rtf","application/rtf"}, | ||
| 101 | {"rtx","text/richtext"}, | ||
| 102 | {"sgm","text/x-sgml"}, | ||
| 103 | {"sgml","text/x-sgml"}, | ||
| 104 | {"sh","application/x-sh"}, | ||
| 105 | {"shar","application/x-shar"}, | ||
| 106 | {"sit","application/x-stuffit"}, | ||
| 107 | {"skd","application/x-koan"}, | ||
| 108 | {"skm","application/x-koan"}, | ||
| 109 | {"skp","application/x-koan"}, | ||
| 110 | {"skt","application/x-koan"}, | ||
| 111 | {"snd","audio/basic"}, | ||
| 112 | {"src","application/x-wais-source"}, | ||
| 113 | {"sv4cpio","application/x-sv4cpio"}, | ||
| 114 | {"sv4crc","application/x-sv4crc"}, | ||
| 115 | {"t","application/x-troff"}, | ||
| 116 | {"tar","application/x-tar"}, | ||
| 117 | {"tcl","application/x-tcl"}, | ||
| 118 | {"tex","application/x-tex"}, | ||
| 119 | {"texi","application/x-texinfo"}, | ||
| 120 | {"texinfo","application/x-texinfo"}, | ||
| 121 | {"tif","image/tiff"}, | ||
| 122 | {"tiff","image/tiff"}, | ||
| 123 | {"tr","application/x-troff"}, | ||
| 124 | {"tsv","text/tab-separated-values"}, | ||
| 125 | {"txt","text/plain"}, | ||
| 126 | {"ustar","application/x-ustar"}, | ||
| 127 | {"vcd","application/x-cdlink"}, | ||
| 128 | {"vrml","x-world/x-vrml"}, | ||
| 129 | {"wav","audio/x-wav"}, | ||
| 130 | {"wrl","x-world/x-vrml"}, | ||
| 131 | {"xbm","image/x-xbitmap"}, | ||
| 132 | {"xpm","image/x-xpixmap"}, | ||
| 133 | {"xwd","image/x-xwindowdump"}, | ||
| 134 | {"xyz","chemical/x-pdb"}, | ||
| 135 | {"zip","application/zip"}, | ||
| 136 | {"",""} | ||
| 137 | }; | ||
| 138 | |||
| 139 | const sref* file2mime(const sref& file) | ||
| 140 | { | ||
| 141 | static rrmap mime; | ||
| 142 | if(mime.empty()) { | ||
| 143 | for(table_t* p=table;*p->ext;p++) mime.add(sref(p->ext),sref(p->name)); | ||
| 144 | } | ||
| 145 | mstring path=file.past_last('.'); | ||
| 146 | path.tolower(); | ||
| 147 | if(path.nempty()) return mime.get(path); | ||
| 148 | return 0; | ||
| 149 | } | ||
diff --git a/src/mime/enc.h b/src/mime/enc.h new file mode 100644 index 0000000..a6ec57a --- /dev/null +++ b/src/mime/enc.h | |||
| @@ -0,0 +1,36 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef ENCMIMEH | ||
| 21 | #define ENCMIMEH | ||
| 22 | |||
| 23 | #include <mime/pack.h> | ||
| 24 | |||
| 25 | const mstring trans_base64="base64"; | ||
| 26 | const mstring trans_quote="quoted-printable"; | ||
| 27 | const mstring mime_default="iso-8859-1"; | ||
| 28 | |||
| 29 | void decode64(mstream& out,const sref& in); | ||
| 30 | void encode64(mstream& out,const sref& in); | ||
| 31 | void decodeQP(mstream& out,const sref& in); | ||
| 32 | void encodeQP(mstream& out,const sref& in); | ||
| 33 | void decodeHeader(mstream& out,mstring& mime,const sref& in); | ||
| 34 | void encodeHeader(mstream& out,const sref& mime,const sref& in); | ||
| 35 | |||
| 36 | #endif | ||
diff --git a/src/mime/mailbox.cc b/src/mime/mailbox.cc new file mode 100644 index 0000000..69f8140 --- /dev/null +++ b/src/mime/mailbox.cc | |||
| @@ -0,0 +1,137 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <mime/mailbox.h> | ||
| 21 | |||
| 22 | static int FromHead(const sref& body) | ||
| 23 | { | ||
| 24 | sref tag,from,rest=body; | ||
| 25 | Split(tag,rest); | ||
| 26 | Split(from,rest); | ||
| 27 | return tag==from_tag&&htcTime(0,rest)>=0; | ||
| 28 | } | ||
| 29 | |||
| 30 | ///////////////////////////////////////////////////////////////////// | ||
| 31 | |||
| 32 | const mstring nextmsg_tag="\nFrom "; | ||
| 33 | const mstring sep_tag="--"; | ||
| 34 | |||
| 35 | Message::Message() | ||
| 36 | { | ||
| 37 | } | ||
| 38 | |||
| 39 | int Message::Special(sref line) | ||
| 40 | { | ||
| 41 | line=Rest(line); | ||
| 42 | from=from0=First(line); | ||
| 43 | date=Rest(line); | ||
| 44 | idate=htcTime(0,date); | ||
| 45 | return idate>=0; | ||
| 46 | } | ||
| 47 | |||
| 48 | int Message::Handle(const sref& name, | ||
| 49 | const sref& rawval, | ||
| 50 | const sref& val, | ||
| 51 | const rrpile& opts) | ||
| 52 | { | ||
| 53 | mstring mime; | ||
| 54 | if(Mime::Handle(name,rawval,val,opts)) return 1; | ||
| 55 | else if(eqn(name,from_tag)) { | ||
| 56 | swrite sw(from); | ||
| 57 | decodeHeader(sw,mime,rawval); | ||
| 58 | } | ||
| 59 | else if(eqn(name,subject_tag)) { | ||
| 60 | swrite sw(subject); | ||
| 61 | decodeHeader(sw,mime,rawval); | ||
| 62 | } | ||
| 63 | else if(eqn(name,to_tag)) { | ||
| 64 | swrite sw(to); | ||
| 65 | decodeHeader(sw,mime,rawval); | ||
| 66 | } | ||
| 67 | else if(eqn(name,msgid_tag)) msgid=rawval; | ||
| 68 | else if(eqn(name,received_tag)) received.push_back(rawval); | ||
| 69 | else return 0; | ||
| 70 | return 1; | ||
| 71 | } | ||
| 72 | |||
| 73 | void Message::putHead(mstream& out) const | ||
| 74 | { | ||
| 75 | if(from0.nempty()) { out<<"From "<<from0<<" "<<date<<"\r\n"; } | ||
| 76 | if(putval(out,from_tag,from)) putend(out); | ||
| 77 | if(putval(out,subject_tag,subject)) putend(out); | ||
| 78 | if(putval(out,to_tag,to)) putend(out); | ||
| 79 | if(putval(out,msgid_tag,msgid)) putend(out); | ||
| 80 | for(spile::const_iterator p=received.begin();p!=received.end();p++) | ||
| 81 | if(putval(out,received_tag,*p)) putend(out); | ||
| 82 | Mime::putHead(out); | ||
| 83 | } | ||
| 84 | |||
| 85 | /////////////////////////////////////////////////////////////// | ||
| 86 | |||
| 87 | void AppendMessage(FILE* fp,const sref& msg) | ||
| 88 | { | ||
| 89 | fwrite(msg.data(),1,msg.size(),fp); | ||
| 90 | } | ||
| 91 | |||
| 92 | void AppendMessages(FILE* fp,const Mailbox& box) | ||
| 93 | { | ||
| 94 | for(int i=0;i<box.size();i++) AppendMessage(fp,box[i]); | ||
| 95 | } | ||
| 96 | |||
| 97 | int PutMessages(const Mailbox& box,const mstring& path) | ||
| 98 | { | ||
| 99 | FILE* fp=fopen(path.c_str(),"w+"); | ||
| 100 | if(!fp) return 0; | ||
| 101 | AppendMessages(fp,box); | ||
| 102 | return fclose(fp)==0; | ||
| 103 | } | ||
| 104 | |||
| 105 | int AppendMessages(const Mailbox& box,const mstring& path) | ||
| 106 | { | ||
| 107 | FILE* fp=fopen(path.c_str(),"a+"); | ||
| 108 | if(!fp) return 0; | ||
| 109 | AppendMessages(fp,box); | ||
| 110 | return fclose(fp)==0; | ||
| 111 | } | ||
| 112 | |||
| 113 | /////////////////////////////////////////////////////////////// | ||
| 114 | |||
| 115 | int GetMessages(Mailbox& box,const mstring& path) | ||
| 116 | { | ||
| 117 | mstring buffer; if(buffer.load(path)<0) return -1; | ||
| 118 | sref next,rest=buffer; | ||
| 119 | int old=box.size(); | ||
| 120 | while(rest.nempty()) { | ||
| 121 | Message msg(rest); | ||
| 122 | if(msg.from0.empty()) break; // should not happen, I guess | ||
| 123 | |||
| 124 | if(msg.cont_length.nempty()) | ||
| 125 | next=msg.body.right(atoi(msg.cont_length)); | ||
| 126 | else if(msg.cont_type_boundary.nempty()) | ||
| 127 | next=msg.body.past_first(sep_tag+msg.cont_type_boundary+sep_tag).right_first(nextmsg_tag).popf(); | ||
| 128 | else | ||
| 129 | next=rest.right_first(nextmsg_tag).popf(); | ||
| 130 | |||
| 131 | box.push_back(rest.left(next-rest)); | ||
| 132 | |||
| 133 | rest=next.right_first_not_of(cset_ws); | ||
| 134 | while(rest.nempty()&&!FromHead(rest)) rest=rest.right_first(nextmsg_tag).popf(); | ||
| 135 | } | ||
| 136 | return box.size()-old; | ||
| 137 | } | ||
diff --git a/src/mime/mailbox.h b/src/mime/mailbox.h new file mode 100644 index 0000000..3e5838c --- /dev/null +++ b/src/mime/mailbox.h | |||
| @@ -0,0 +1,60 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef MAILBOXH | ||
| 21 | #define MAILBOXH | ||
| 22 | |||
| 23 | #include <mime/mime.h> | ||
| 24 | #include <mt/dates.h> | ||
| 25 | |||
| 26 | const mstring from_tag="From"; | ||
| 27 | const mstring to_tag="To"; | ||
| 28 | const mstring subject_tag="Subject"; | ||
| 29 | const mstring msgid_tag="Message-ID"; | ||
| 30 | const mstring received_tag="Received"; | ||
| 31 | |||
| 32 | class Message : public Mime { | ||
| 33 | public: | ||
| 34 | Message(); | ||
| 35 | Message(const sref& msg) { Init(msg); } | ||
| 36 | |||
| 37 | mstring from0,from,date,subject,to,msgid; | ||
| 38 | spile received; | ||
| 39 | time_t idate; | ||
| 40 | |||
| 41 | void putHead(mstream& out) const; | ||
| 42 | protected: | ||
| 43 | int Special(sref line); | ||
| 44 | int Handle(const sref& name, | ||
| 45 | const sref& rawval, | ||
| 46 | const sref& val, | ||
| 47 | const rrpile& opts); | ||
| 48 | }; | ||
| 49 | |||
| 50 | typedef msvec<mstring> Mailbox; | ||
| 51 | |||
| 52 | void AppendMessage(FILE* fp,const sref& msg); | ||
| 53 | void AppendMessages(FILE* fp,const Mailbox& box); | ||
| 54 | |||
| 55 | int PutMessages(const Mailbox& box,const mstring& path); | ||
| 56 | int AppendMessages(const Mailbox& box,const mstring& path); | ||
| 57 | |||
| 58 | int GetMessages(Mailbox& box,const mstring& path); | ||
| 59 | |||
| 60 | #endif | ||
diff --git a/src/mime/mime.cc b/src/mime/mime.cc new file mode 100644 index 0000000..a7a1884 --- /dev/null +++ b/src/mime/mime.cc | |||
| @@ -0,0 +1,188 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <mime/mime.h> | ||
| 21 | |||
| 22 | const charset par_left("([{"),par_right("}])"); | ||
| 23 | |||
| 24 | inline int is_field(const sref& s) { | ||
| 25 | sref p=s.left_first(':'); | ||
| 26 | while(cset_spaces.test(p.back())) p=p.popb(); | ||
| 27 | return p.nempty()&&p.find_of(cset_spaces)<0; | ||
| 28 | } | ||
| 29 | |||
| 30 | inline int getquoted(const sref& s,char c) { | ||
| 31 | int i,quote=0,par=0; | ||
| 32 | for(i=0;i<s.size();i++) { | ||
| 33 | if(s[i]=='\"') quote=!quote; | ||
| 34 | else if(par_left.test(s[i])) par++; | ||
| 35 | else if(par_right.test(s[i])) par--; | ||
| 36 | else if(s[i]==c&&!quote&&!par) break; | ||
| 37 | } | ||
| 38 | return i; | ||
| 39 | } | ||
| 40 | |||
| 41 | void Mime::Init(const sref& message) | ||
| 42 | { | ||
| 43 | mstring line; | ||
| 44 | rrpile pile; | ||
| 45 | sref first; | ||
| 46 | head=body=message; | ||
| 47 | while(Splitln(first,body)) { | ||
| 48 | if(first.empty()) break; | ||
| 49 | if(!is_field(first)) Special(first); | ||
| 50 | else { | ||
| 51 | line=first; | ||
| 52 | while(cset_spaces.test(*body)) { | ||
| 53 | Splitln(first,body); | ||
| 54 | line.append(1,' '); | ||
| 55 | line+=first.right_first_not_of(cset_spaces); | ||
| 56 | } | ||
| 57 | sref opt=line; | ||
| 58 | int col=opt.find(':'); | ||
| 59 | sref name=Trim(opt.left(col),cset_quotes); | ||
| 60 | opt=opt.adv(col).popf(); | ||
| 61 | sref rawval=Trim(opt); | ||
| 62 | int semi=getquoted(opt,';'); | ||
| 63 | sref val=Trim(opt.left(semi),cset_quotes); | ||
| 64 | if(getquoted(val,'=')<val.size()) val.clear(); | ||
| 65 | else opt=opt.adv(semi).popf(); | ||
| 66 | pile.clear(); | ||
| 67 | while(opt.nempty()) { | ||
| 68 | sref optname=opt.left(getquoted(opt,'=')); | ||
| 69 | opt=opt.adv(optname).popf(); | ||
| 70 | semi=getquoted(opt,';'); | ||
| 71 | sref optval=opt.left(semi); | ||
| 72 | opt=opt.adv(semi).popf(); | ||
| 73 | optname=Trim(optname,cset_quotes); | ||
| 74 | optval=Trim(optval,cset_quotes); | ||
| 75 | if(optname.nempty()) pile.push_back(rrstring(optname,optval)); | ||
| 76 | } | ||
| 77 | Handle(name,rawval,val,pile); | ||
| 78 | } | ||
| 79 | } | ||
| 80 | head=head.left(body-head); | ||
| 81 | } | ||
| 82 | |||
| 83 | |||
| 84 | /////////////////////////////////////////////////////////////////////////// | ||
| 85 | |||
| 86 | Mime::Mime() | ||
| 87 | { | ||
| 88 | mime_version="1.0"; | ||
| 89 | } | ||
| 90 | |||
| 91 | int Mime::Special(sref line) | ||
| 92 | { | ||
| 93 | return 0; | ||
| 94 | } | ||
| 95 | |||
| 96 | int Mime::Handle(const sref& name, | ||
| 97 | const sref& rawval, | ||
| 98 | const sref& val, | ||
| 99 | const rrpile& opts) { | ||
| 100 | if(eqn(name,mime_version_tag)) mime_version=val; | ||
| 101 | else if(eqn(name,cont_type_tag)) { | ||
| 102 | (cont_type=val).tolower(); | ||
| 103 | for(rrpile::const_iterator p=opts.begin();p!=opts.end();p++) { | ||
| 104 | if(eqn(p->first,charset_tag)) cont_type_charset=p->second; | ||
| 105 | else if(eqn(p->first,name_tag)) cont_type_name=p->second; | ||
| 106 | else if(eqn(p->first,boundary_tag)) cont_type_boundary=p->second; | ||
| 107 | } | ||
| 108 | } | ||
| 109 | else if(eqn(name,cont_id_tag)) cont_id=val; | ||
| 110 | else if(eqn(name,cont_desc_tag)) cont_desc=val; | ||
| 111 | else if(eqn(name,cont_disp_tag)) { | ||
| 112 | cont_disp=val; | ||
| 113 | for(rrpile::const_iterator p=opts.begin();p!=opts.end();p++) { | ||
| 114 | if(eqn(p->first,name_tag)) cont_disp_name=p->second; | ||
| 115 | else if(eqn(p->first,file_tag)) cont_disp_file=p->second; | ||
| 116 | } | ||
| 117 | } | ||
| 118 | else if(eqn(name,cont_trans_enc_tag)) cont_trans_enc=val; | ||
| 119 | else if(eqn(name,cont_length_tag)) cont_length=val; | ||
| 120 | else return 0; | ||
| 121 | return 1; | ||
| 122 | } | ||
| 123 | |||
| 124 | /////////////////////////////////////////////////////////////////////////// | ||
| 125 | |||
| 126 | void Mime::putHead(mstream& out) const | ||
| 127 | { | ||
| 128 | if(putval(out,mime_version_tag,mime_version)) putend(out); | ||
| 129 | if(putval(out,cont_type_tag,cont_type)) { | ||
| 130 | putopt(out,charset_tag,cont_type_charset); | ||
| 131 | putopt(out,name_tag,cont_type_name); | ||
| 132 | putopt(out,boundary_tag,cont_type_boundary); | ||
| 133 | putend(out); | ||
| 134 | } | ||
| 135 | if(putval(out,cont_id_tag,cont_id)) putend(out); | ||
| 136 | if(putval(out,cont_desc_tag,cont_desc)) putend(out); | ||
| 137 | if(putval(out,cont_disp_tag,cont_disp)) { | ||
| 138 | putopt(out,name_tag,cont_disp_name); | ||
| 139 | putopt(out,file_tag,cont_disp_file); | ||
| 140 | putend(out); | ||
| 141 | } | ||
| 142 | if(putval(out,cont_trans_enc_tag,cont_trans_enc)) putend(out); | ||
| 143 | if(putval(out,cont_length_tag,cont_length)) putend(out); | ||
| 144 | } | ||
| 145 | |||
| 146 | |||
| 147 | /////////////////////////////////////////////////////////////////////////// | ||
| 148 | |||
| 149 | int Mime::Multipart(rpile& list) const | ||
| 150 | { | ||
| 151 | if(cont_type_boundary.empty()) return 0; | ||
| 152 | mstring bound=sref("--")+cont_type_boundary; | ||
| 153 | sref rest=body.past_first(bound).past_nl(); | ||
| 154 | while(rest.nempty()) { | ||
| 155 | int pos=rest.find(bound); | ||
| 156 | if(pos>=0) { | ||
| 157 | sref first=rest.left(pos); | ||
| 158 | if(first.back()=='\n') { | ||
| 159 | first=first.popb(); | ||
| 160 | if(first.back()=='\r') first=first.popb(); | ||
| 161 | } | ||
| 162 | list.push_back(first); | ||
| 163 | rest=rest.right(pos).adv(bound.size()); | ||
| 164 | if(*rest=='-') rest.clear(); else rest=rest.past_nl(); | ||
| 165 | } | ||
| 166 | else { | ||
| 167 | list.push_back(rest); | ||
| 168 | rest.clear(); | ||
| 169 | } | ||
| 170 | } | ||
| 171 | return !list.empty(); | ||
| 172 | } | ||
| 173 | |||
| 174 | void Mime::Pick(const sref& mime) | ||
| 175 | { | ||
| 176 | rpile list; | ||
| 177 | if(Multipart(list)) { | ||
| 178 | if(eqn(cont_type,mime_multialt)) { | ||
| 179 | int pos=0; | ||
| 180 | for(int i=0;i<list.size();i++) { | ||
| 181 | Mime msg(list[i]); | ||
| 182 | if(eqn(msg.cont_type,mime)) { pos=i; break; } | ||
| 183 | } | ||
| 184 | Init(list[pos]); | ||
| 185 | } | ||
| 186 | } | ||
| 187 | } | ||
| 188 | |||
diff --git a/src/mime/mime.h b/src/mime/mime.h new file mode 100644 index 0000000..fb2ae0f --- /dev/null +++ b/src/mime/mime.h | |||
| @@ -0,0 +1,99 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef MIMEH | ||
| 21 | #define MIMEH | ||
| 22 | |||
| 23 | #include <mime/enc.h> | ||
| 24 | |||
| 25 | // MIME Headers | ||
| 26 | const mstring mime_version_tag="MIME-Version"; | ||
| 27 | const mstring cont_type_tag="Content-Type"; | ||
| 28 | const mstring cont_trans_enc_tag="Content-Transfer-Encoding"; | ||
| 29 | const mstring cont_id_tag="Content-ID"; | ||
| 30 | const mstring cont_desc_tag="Content-Description"; | ||
| 31 | const mstring cont_disp_tag="Content-Disposition"; | ||
| 32 | const mstring cont_length_tag="Content-Length"; | ||
| 33 | // Option headers | ||
| 34 | const mstring name_tag="name"; | ||
| 35 | const mstring file_tag="filename"; | ||
| 36 | const mstring charset_tag="charset"; | ||
| 37 | const mstring boundary_tag="boundary"; | ||
| 38 | const mstring path_tag="path"; | ||
| 39 | // Some Content types | ||
| 40 | const mstring mime_textplain="text/plain"; | ||
| 41 | const mstring mime_texthtml="text/html"; | ||
| 42 | const mstring mime_texthtc="text/x-htc"; | ||
| 43 | const mstring mime_multialt="multipart/alternative"; | ||
| 44 | |||
| 45 | ///////////////////////////////////////////////////////////////// | ||
| 46 | |||
| 47 | const sref* file2mime(const sref& file); | ||
| 48 | |||
| 49 | ///////////////////////////////////////////////////////////////// | ||
| 50 | |||
| 51 | class Mime { | ||
| 52 | public: | ||
| 53 | sref head,body; | ||
| 54 | |||
| 55 | mstring mime_version; | ||
| 56 | mstring cont_type,cont_type_charset,cont_type_name,cont_type_boundary; | ||
| 57 | mstring cont_id; | ||
| 58 | mstring cont_desc; | ||
| 59 | mstring cont_disp,cont_disp_name,cont_disp_file; | ||
| 60 | mstring cont_trans_enc; | ||
| 61 | mstring cont_length; | ||
| 62 | |||
| 63 | virtual void putHead(mstream& out) const; | ||
| 64 | |||
| 65 | void Init(const sref& in); | ||
| 66 | |||
| 67 | int Multipart(rpile& list) const; | ||
| 68 | void Pick(const sref& mime); | ||
| 69 | |||
| 70 | Mime(); | ||
| 71 | Mime(const sref& msg) { Init(msg); } | ||
| 72 | |||
| 73 | protected: | ||
| 74 | virtual int Special(sref line); | ||
| 75 | virtual int Handle(const sref& name, | ||
| 76 | const sref& rawval, | ||
| 77 | const sref& val, | ||
| 78 | const rrpile& opts); | ||
| 79 | }; | ||
| 80 | |||
| 81 | ////////////////////////////////////////////////////////////////// | ||
| 82 | |||
| 83 | inline int putval(mstream& out,const sref& tag,const sref& val) { | ||
| 84 | if(val.nempty()) { out<<tag<<": "<<val; return 1; } else return 0; | ||
| 85 | } | ||
| 86 | inline void putopt(mstream& out,const sref& tag,const sref& val) { | ||
| 87 | if(val.nempty()) out<<"; "<<tag<<"=\""<<val<<"\""; | ||
| 88 | } | ||
| 89 | inline int putopt1(mstream& out,const sref& tag,const sref& val) { | ||
| 90 | if(val.nempty()) { out<<tag<<"=\""<<val<<"\""; return 1; } else return 0; | ||
| 91 | } | ||
| 92 | inline int putopt2(mstream& out,const sref& tag,const sref& val) { | ||
| 93 | if(val.nempty()) { out<<tag<<"="<<val; return 1; } else return 0; | ||
| 94 | } | ||
| 95 | inline void putend(mstream& out) { out<<CRLF; } | ||
| 96 | |||
| 97 | ////////////////////////////////////////////////////////////////// | ||
| 98 | |||
| 99 | #endif | ||
diff --git a/src/mime/pack.cc b/src/mime/pack.cc new file mode 100644 index 0000000..78fde26 --- /dev/null +++ b/src/mime/pack.cc | |||
| @@ -0,0 +1,143 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <mime/pack.h> | ||
| 21 | |||
| 22 | const char hex2char[16]={ | ||
| 23 | '0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F' | ||
| 24 | }; | ||
| 25 | const unsigned char2hex[256]={ | ||
| 26 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
| 27 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,6,7,8,9,0,0,0,0,0,0, | ||
| 28 | 0,10,11,12,13,14,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
| 29 | 0,10,11,12,13,14,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
| 30 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
| 31 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
| 32 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
| 33 | 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | ||
| 34 | }; | ||
| 35 | |||
| 36 | mstream& cashex(mstream& out,unsigned char c) { | ||
| 37 | return out.put(hex2char[c>>4]).put(hex2char[c&15]); | ||
| 38 | } | ||
| 39 | char hexasc(unsigned char c1,unsigned char c2) { | ||
| 40 | return ((char2hex[c1]<<4)|char2hex[c2]); | ||
| 41 | } | ||
| 42 | |||
| 43 | void Pack(mstream& out,const sref& s) | ||
| 44 | { | ||
| 45 | static const charset escaped("&=%+\"'? "); | ||
| 46 | static const charset conv=~cset_printable|escaped; | ||
| 47 | sref q,p=s; | ||
| 48 | while(p.nempty()) { | ||
| 49 | p=p.adv(q=p.left_first_of(conv)); | ||
| 50 | out<<q; | ||
| 51 | while(conv.test(p.front())) { | ||
| 52 | char c=*p; p=p.popf(); | ||
| 53 | if(c==' ') out.put('+'); | ||
| 54 | else { | ||
| 55 | out.put('%'); | ||
| 56 | cashex(out,c); | ||
| 57 | } | ||
| 58 | } | ||
| 59 | } | ||
| 60 | } | ||
| 61 | |||
| 62 | void Pack(mstream& out,const rpile& list) | ||
| 63 | { | ||
| 64 | for(rpile::const_iterator p=list.begin();p!=list.end();++p) { | ||
| 65 | Pack(out,*p); | ||
| 66 | out.put('&'); | ||
| 67 | } | ||
| 68 | } | ||
| 69 | |||
| 70 | void Pack(mstream& out,const rrpile& list) | ||
| 71 | { | ||
| 72 | for(rrpile::const_iterator p=list.begin();p!=list.end();++p) { | ||
| 73 | Pack(out,p->first); | ||
| 74 | out.put('='); | ||
| 75 | Pack(out,p->second); | ||
| 76 | out.put('&'); | ||
| 77 | } | ||
| 78 | } | ||
| 79 | |||
| 80 | /////////////////////////////////////////////////////////////// | ||
| 81 | |||
| 82 | void Unpack(mstream& out,const sref& in) | ||
| 83 | { | ||
| 84 | static const charset tags("%+"); | ||
| 85 | sref e,p=in; | ||
| 86 | while(p.nempty()) { | ||
| 87 | p=p.adv(e=p.left_first_of(tags)); | ||
| 88 | out<<e; | ||
| 89 | while(tags.test(p.front())) { | ||
| 90 | char c=*p; p=p.popf(); | ||
| 91 | if(c=='+') out.put(' '); | ||
| 92 | else if(c=='%') { | ||
| 93 | unsigned char c1=p[0],c2=p[1]; p=p.adv(2); | ||
| 94 | out.put(hexasc(c1,c2)); | ||
| 95 | } | ||
| 96 | else out.put(c); | ||
| 97 | } | ||
| 98 | } | ||
| 99 | } | ||
| 100 | |||
| 101 | void Unpack(spile& list,const sref& in) | ||
| 102 | { | ||
| 103 | sref e,p=in; | ||
| 104 | while(p.nempty()) { | ||
| 105 | p=p.adv(e=p.left_first('&')).popf(); | ||
| 106 | if(e.nempty()) { | ||
| 107 | list.push_back(mstring()); | ||
| 108 | swrite sw(list.back()); | ||
| 109 | Unpack(sw,e); | ||
| 110 | } | ||
| 111 | } | ||
| 112 | } | ||
| 113 | |||
| 114 | void Unpack(sspile& list,const sref& in) | ||
| 115 | { | ||
| 116 | sref e1,e2,p=in; | ||
| 117 | while(p.nempty()) { | ||
| 118 | p=p.adv(e1=p.left_first('=')).popf(); | ||
| 119 | if(e1.nempty()) { | ||
| 120 | p=p.adv(e2=p.left_first('&')).popf(); | ||
| 121 | list.push_back(sstring()); | ||
| 122 | swrite sw1(list.back().first); | ||
| 123 | Unpack(sw1,e1); | ||
| 124 | swrite sw2(list.back().second); | ||
| 125 | Unpack(sw2,e2); | ||
| 126 | } | ||
| 127 | } | ||
| 128 | } | ||
| 129 | |||
| 130 | /////////////////////////////////////////////////////////////// | ||
| 131 | |||
| 132 | void CRLF2LF(mstream& out,const sref& in) | ||
| 133 | { | ||
| 134 | sref first,rest=in; | ||
| 135 | while(Splitln(first,rest)) out<<first<<"\n"; | ||
| 136 | } | ||
| 137 | |||
| 138 | void LF2CRLF(mstream& out,const sref& in) | ||
| 139 | { | ||
| 140 | sref first,rest=in; | ||
| 141 | while(Splitln(first,rest)) out<<first<<CRLF; | ||
| 142 | } | ||
| 143 | |||
diff --git a/src/mime/pack.h b/src/mime/pack.h new file mode 100644 index 0000000..e750aac --- /dev/null +++ b/src/mime/pack.h | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef PACKH | ||
| 21 | #define PACKH | ||
| 22 | |||
| 23 | #include <mt/mset.h> | ||
| 24 | #include <mt/msmap.h> | ||
| 25 | |||
| 26 | // Really mimefunctions, but needed here | ||
| 27 | |||
| 28 | mstream& cashex(mstream& out,unsigned char c); | ||
| 29 | char hexasc(unsigned char c1,unsigned char c2); | ||
| 30 | |||
| 31 | // Packing means application/x-www-form-urlencoded | ||
| 32 | |||
| 33 | void Unpack(mstream& out,const sref& in); | ||
| 34 | void Unpack(spile& list,const sref& in); | ||
| 35 | void Unpack(sspile& list,const sref& in); | ||
| 36 | |||
| 37 | void Pack(mstream& out,const sref& in); | ||
| 38 | void Pack(mstream& out,const rpile& list); | ||
| 39 | void Pack(mstream& out,const rrpile& list); | ||
| 40 | |||
| 41 | // CR LF and CRLF business | ||
| 42 | |||
| 43 | const mstring CRLF="\r\n"; | ||
| 44 | |||
| 45 | void CRLF2LF(mstream& out,const sref& in); | ||
| 46 | void LF2CRLF(mstream& out,const sref& in); | ||
| 47 | |||
| 48 | #endif | ||
diff --git a/src/mime/qp.cc b/src/mime/qp.cc new file mode 100644 index 0000000..78dc36f --- /dev/null +++ b/src/mime/qp.cc | |||
| @@ -0,0 +1,150 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <mime/enc.h> | ||
| 21 | #include <mime/pack.h> | ||
| 22 | #include <algorithm> | ||
| 23 | |||
| 24 | const charset special("=\"#$\\^`{|}~"); | ||
| 25 | //const charset special("=!\"#$@[\\]^`{|}~"); | ||
| 26 | const charset headspecial("_?"); | ||
| 27 | const charset printable=cset_printable&~special; | ||
| 28 | const charset printhead=printable&~headspecial; | ||
| 29 | const mstring beg_tag("=?"),end_tag("?="); | ||
| 30 | const mstring enc_qp_tag("Q"),enc_64_tag("B"); | ||
| 31 | const int WRAPAT=76; | ||
| 32 | const int HEADWRAP=WRAPAT-7; | ||
| 33 | |||
| 34 | void decodeQP(mstream& out,const sref& in) | ||
| 35 | { | ||
| 36 | const char* p=in.begin(); | ||
| 37 | while(p<in.end()) { | ||
| 38 | unsigned char c=*p++; | ||
| 39 | if(c=='=') { | ||
| 40 | if(cset_ws.test(*p)) p=in(p).past_nl().data(); | ||
| 41 | else { | ||
| 42 | unsigned char c1=*p++,c2=*p++; | ||
| 43 | out.put(hexasc(c1,c2)); | ||
| 44 | } | ||
| 45 | } | ||
| 46 | else out.put(c); | ||
| 47 | } | ||
| 48 | } | ||
| 49 | |||
| 50 | void encodeQP(mstream& out,const sref& in) | ||
| 51 | { | ||
| 52 | sref first,rest=in; | ||
| 53 | while(Splitln(first,rest)) { | ||
| 54 | int n=0; | ||
| 55 | const char* p=first.begin(); | ||
| 56 | while(p<first.end()) { | ||
| 57 | unsigned char c=*p++; | ||
| 58 | if(printable.test(c)) { | ||
| 59 | if(first(p).empty()&&cset_spaces.test(c)) { cashex(out.put('='),c); n+=3; } | ||
| 60 | else { out.put(c); n++; } | ||
| 61 | } | ||
| 62 | else { cashex(out.put('='),c); n+=3; } | ||
| 63 | if(first(p).nempty()&&n>=WRAPAT) { out.put('=')<<CRLF; n=0; } | ||
| 64 | } | ||
| 65 | out<<CRLF; | ||
| 66 | } | ||
| 67 | } | ||
| 68 | |||
| 69 | static void decodeHQ(mstream& out,const sref& in) | ||
| 70 | { | ||
| 71 | const char* p=in.begin(); | ||
| 72 | while(p<in.end()) { | ||
| 73 | unsigned char c=*p++; | ||
| 74 | if(c=='=') { | ||
| 75 | unsigned char c1=*p++,c2=*p++; | ||
| 76 | out.put(hexasc(c1,c2)); | ||
| 77 | } | ||
| 78 | else if(c=='_') out.put(' '); | ||
| 79 | else out.put(c); | ||
| 80 | } | ||
| 81 | } | ||
| 82 | |||
| 83 | static int encodeHQ(mstream& out,const sref& in) | ||
| 84 | { | ||
| 85 | int enc=0; | ||
| 86 | const char* p=in.begin(); | ||
| 87 | while(p<in.end()) { | ||
| 88 | unsigned char c=*p++; | ||
| 89 | if(!printable.test(c)) enc=1; | ||
| 90 | if(printhead.test(c)) { if(c==32) out.put('_'); else out.put(c); } | ||
| 91 | else cashex(out.put('='),c); | ||
| 92 | } | ||
| 93 | return enc; | ||
| 94 | } | ||
| 95 | |||
| 96 | void decodeHeader(mstream& out,mstring& mime,const sref& in) | ||
| 97 | { | ||
| 98 | sref e,p=in; | ||
| 99 | while(p.nempty()) { | ||
| 100 | p=p.adv(e=p.left_first(beg_tag)); | ||
| 101 | out<<e; | ||
| 102 | if(p.nempty()) { | ||
| 103 | p=p.adv(beg_tag.size()); | ||
| 104 | mime=p.left_first('?'); | ||
| 105 | p=p.adv(mime.size()); | ||
| 106 | if(p.empty()) { out<<beg_tag<<mime; p.clear(); } | ||
| 107 | else { | ||
| 108 | p=p.popf(); | ||
| 109 | sref enc=p.left_first('?'); | ||
| 110 | p=p.adv(enc); | ||
| 111 | if(p.empty()) { out<<beg_tag<<mime<<"?"<<enc; p.clear(); } | ||
| 112 | else { | ||
| 113 | p=p.adv(e=p.popf().left_first(end_tag)); | ||
| 114 | if(p.empty()) { out<<beg_tag<<mime<<"?"<<enc<<"?"<<e; p.clear(); } | ||
| 115 | else { | ||
| 116 | p=p.adv(end_tag.size()); | ||
| 117 | if(eqn(enc,enc_qp_tag)) decodeHQ(out,e); | ||
| 118 | else if(eqn(enc,enc_64_tag)) decode64(out,e); | ||
| 119 | else out<<"BAD: ["<<mime<<"]["<<enc<<"]["<<e<<"]"; | ||
| 120 | } | ||
| 121 | } | ||
| 122 | } | ||
| 123 | } | ||
| 124 | } | ||
| 125 | } | ||
| 126 | |||
| 127 | void encodeHeader(mstream& out,const sref& mime,const sref& in) | ||
| 128 | { | ||
| 129 | mstring tmp; | ||
| 130 | swrite sw(tmp); | ||
| 131 | if(encodeHQ(sw,in)) { | ||
| 132 | int wrapat=HEADWRAP-mime.size(); | ||
| 133 | sref e,p=tmp; | ||
| 134 | p=p.adv(e=p.left(std::min(wrapat,p.size()))); | ||
| 135 | out<<beg_tag<<mime<<"?Q?"<<e<<end_tag; | ||
| 136 | while(p.nempty()) { | ||
| 137 | p=p.adv(e=p.left(std::min(wrapat,p.size()))); | ||
| 138 | out<<"\r\n\t"<<beg_tag<<mime<<"?Q?"<<e<<end_tag; | ||
| 139 | } | ||
| 140 | } | ||
| 141 | else { | ||
| 142 | sref e,p=in; | ||
| 143 | p=p.adv(e=p.left(std::min(WRAPAT,p.size()))); | ||
| 144 | out<<e; | ||
| 145 | while(p.nempty()) { | ||
| 146 | p=p.adv(e=p.left(std::min(WRAPAT,p.size()))); | ||
| 147 | out<<"\r\n\t"<<e; | ||
| 148 | } | ||
| 149 | } | ||
| 150 | } | ||
diff --git a/src/mime/test.cc b/src/mime/test.cc new file mode 100644 index 0000000..6392904 --- /dev/null +++ b/src/mime/test.cc | |||
| @@ -0,0 +1,108 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <mime/mailbox.h> | ||
| 21 | #include <mime/mime.h> | ||
| 22 | #include <mime/enc.h> | ||
| 23 | #include <sys/stat.h> | ||
| 24 | |||
| 25 | static fp_stream mout(stdout),merr(stderr); | ||
| 26 | |||
| 27 | static void Show(mstream& out,const Message& msg) | ||
| 28 | { | ||
| 29 | if(msg.cont_type.empty()|| | ||
| 30 | eqn(msg.cont_type,mime_textplain)|| | ||
| 31 | eqn(msg.cont_type,mime_texthtml)) { | ||
| 32 | if(eqn(msg.cont_trans_enc,trans_quote)) { | ||
| 33 | //decodeQP(out,msg.body); | ||
| 34 | mswrite tmp; | ||
| 35 | decodeQP(tmp,msg.body); | ||
| 36 | encodeQP(out,tmp.str()); | ||
| 37 | } | ||
| 38 | else { | ||
| 39 | //out<<msg.body<<"\n"; | ||
| 40 | encodeQP(out,msg.body); | ||
| 41 | } | ||
| 42 | } | ||
| 43 | else out<<"(not shown)\n"; | ||
| 44 | } | ||
| 45 | |||
| 46 | main(int argc,char* argv[]) | ||
| 47 | { | ||
| 48 | if(argc<2) { | ||
| 49 | merr<<"Usage: "<<argv[0]<<" <source> [index]\n"; | ||
| 50 | return 1; | ||
| 51 | } | ||
| 52 | Mailbox box; | ||
| 53 | GetMessages(box,argv[1]); | ||
| 54 | merr<<"Found "<<box.size()<<" messages\n"; | ||
| 55 | if(argc>2) { | ||
| 56 | Message msg(box[atoi(argv[2])]); | ||
| 57 | //msg.Pick(mime_textplain); | ||
| 58 | |||
| 59 | mswrite tmp; | ||
| 60 | encodeHeader(tmp,mime_default,msg.subject); | ||
| 61 | msg.subject=tmp.str(); | ||
| 62 | |||
| 63 | msg.putHead(mout); | ||
| 64 | mout<<"-----------------------------------------\n"; | ||
| 65 | rpile part; | ||
| 66 | if(msg.Multipart(part)) { | ||
| 67 | for(int i=0;i<part.size();i++) { | ||
| 68 | Message pm(part[i]); | ||
| 69 | pm.putHead(mout); | ||
| 70 | mout<<"-------------------------------\n"; | ||
| 71 | Show(mout,pm); | ||
| 72 | mout<<"-------------------------------\n"; | ||
| 73 | } | ||
| 74 | } | ||
| 75 | else { | ||
| 76 | Show(mout,msg); | ||
| 77 | } | ||
| 78 | |||
| 79 | mout<<"**********\n"; | ||
| 80 | mout<<msg.head; | ||
| 81 | mout<<"**********\n"; | ||
| 82 | mout<<msg.body; | ||
| 83 | mout<<"**********\n"; | ||
| 84 | |||
| 85 | } | ||
| 86 | |||
| 87 | return 0; | ||
| 88 | } | ||
| 89 | |||
| 90 | /* | ||
| 91 | main(int argc,char* argv[]) | ||
| 92 | { | ||
| 93 | if(argc<2) { | ||
| 94 | merr<<"Usage: "<<argv[0]<<" <source>\n"; | ||
| 95 | return 1; | ||
| 96 | } | ||
| 97 | mstring buffer; buffer.load(argv[1]); | ||
| 98 | merr<<buffer.size()<<"\n"; | ||
| 99 | mswrite enc; | ||
| 100 | encode64(enc,buffer); | ||
| 101 | merr<<enc.str().size()<<"\n"; | ||
| 102 | mswrite nbuf; | ||
| 103 | decode64(nbuf,enc.str()); | ||
| 104 | merr<<nbuf.str().size()<<"\n"; | ||
| 105 | if(nbuf.str()==buffer) merr<<"Match.\n"; | ||
| 106 | mout<<enc.str(); | ||
| 107 | } | ||
| 108 | */ | ||
diff --git a/src/mt/cfind.f b/src/mt/cfind.f new file mode 100644 index 0000000..3d101ec --- /dev/null +++ b/src/mt/cfind.f | |||
| @@ -0,0 +1,80 @@ | |||
| 1 | ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc | ||
| 2 | c | ||
| 3 | c HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | c | ||
| 5 | c This program is free software; you can redistribute it and/or modify | ||
| 6 | c it under the terms of the GNU General Public License as published by | ||
| 7 | c the Free Software Foundation; either version 2 of the License, or | ||
| 8 | c (at your option) any later version. | ||
| 9 | c | ||
| 10 | c This program is distributed in the hope that it will be useful, | ||
| 11 | c but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | c GNU General Public License for more details. | ||
| 14 | c | ||
| 15 | c You should have received a copy of the GNU General Public License | ||
| 16 | c along with this program; if not, write to the Free Software | ||
| 17 | c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | c | ||
| 19 | |||
| 20 | integer function cfind(s,n,c) | ||
| 21 | character s(0:1),c | ||
| 22 | integer i,m,n | ||
| 23 | m=mod(n,16) | ||
| 24 | do 10 i=0,m-1 | ||
| 25 | if(s(i).eq.c)go to 100 | ||
| 26 | 10 continue | ||
| 27 | do 20 i=m,n-1,16 | ||
| 28 | if(s(i).eq.c)go to 100 | ||
| 29 | if(s(i+1).eq.c)go to 101 | ||
| 30 | if(s(i+2).eq.c)go to 102 | ||
| 31 | if(s(i+3).eq.c)go to 103 | ||
| 32 | if(s(i+4).eq.c)go to 104 | ||
| 33 | if(s(i+5).eq.c)go to 105 | ||
| 34 | if(s(i+6).eq.c)go to 106 | ||
| 35 | if(s(i+7).eq.c)go to 107 | ||
| 36 | if(s(i+8).eq.c)go to 108 | ||
| 37 | if(s(i+9).eq.c)go to 109 | ||
| 38 | if(s(i+10).eq.c)go to 110 | ||
| 39 | if(s(i+11).eq.c)go to 111 | ||
| 40 | if(s(i+12).eq.c)go to 112 | ||
| 41 | if(s(i+13).eq.c)go to 113 | ||
| 42 | if(s(i+14).eq.c)go to 114 | ||
| 43 | if(s(i+15).eq.c)go to 115 | ||
| 44 | 20 continue | ||
| 45 | cfind=-1 | ||
| 46 | return | ||
| 47 | 100 cfind=i | ||
| 48 | return | ||
| 49 | 101 cfind=i+1 | ||
| 50 | return | ||
| 51 | 102 cfind=i+2 | ||
| 52 | return | ||
| 53 | 103 cfind=i+3 | ||
| 54 | return | ||
| 55 | 104 cfind=i+4 | ||
| 56 | return | ||
| 57 | 105 cfind=i+5 | ||
| 58 | return | ||
| 59 | 106 cfind=i+6 | ||
| 60 | return | ||
| 61 | 107 cfind=i+7 | ||
| 62 | return | ||
| 63 | 108 cfind=i+8 | ||
| 64 | return | ||
| 65 | 109 cfind=i+9 | ||
| 66 | return | ||
| 67 | 110 cfind=i+10 | ||
| 68 | return | ||
| 69 | 111 cfind=i+11 | ||
| 70 | return | ||
| 71 | 112 cfind=i+12 | ||
| 72 | return | ||
| 73 | 113 cfind=i+13 | ||
| 74 | return | ||
| 75 | 114 cfind=i+14 | ||
| 76 | return | ||
| 77 | 115 cfind=i+15 | ||
| 78 | return | ||
| 79 | end | ||
| 80 | |||
diff --git a/src/mt/charset.h b/src/mt/charset.h new file mode 100644 index 0000000..84742b9 --- /dev/null +++ b/src/mt/charset.h | |||
| @@ -0,0 +1,131 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef CHARSETH | ||
| 21 | #define CHARSETH | ||
| 22 | |||
| 23 | #include <string.h> | ||
| 24 | |||
| 25 | struct charset { | ||
| 26 | explicit charset(const char s[]) { | ||
| 27 | memset(negmap,0,256); while(*s) map[*s++]=1; | ||
| 28 | } | ||
| 29 | charset(char beg,char end) { | ||
| 30 | memset(negmap,0,256); while(beg<=end) map[beg++]=1; | ||
| 31 | } | ||
| 32 | int test(char c) const { return map[c]; } | ||
| 33 | int operator[](char c) const { return map[c]; } | ||
| 34 | char negmap[128],map[128]; | ||
| 35 | }; | ||
| 36 | |||
| 37 | inline charset operator|(const charset& a,const charset& b) { | ||
| 38 | charset c(a); for(int i=-127;i<128;i++) c.map[i]|=b.map[i]; return c; | ||
| 39 | } | ||
| 40 | inline charset operator|(const charset& a,char b) { | ||
| 41 | charset c(a); c.map[b]=(b!=0); return c; | ||
| 42 | } | ||
| 43 | inline charset operator|(char a,const charset& b) { | ||
| 44 | charset c(b); c.map[a]=(a!=0); return c; | ||
| 45 | } | ||
| 46 | inline charset operator&(const charset& a,const charset& b) { | ||
| 47 | charset c(a); for(int i=-127;i<128;i++) c.map[i]&=b.map[i]; return c; | ||
| 48 | } | ||
| 49 | inline charset operator^(const charset& a,const charset& b) { | ||
| 50 | charset c(a); for(int i=-127;i<128;i++) c.map[i]^=b.map[i]; return c; | ||
| 51 | } | ||
| 52 | inline charset operator-(const charset& a,const charset& b) { | ||
| 53 | charset c(a); for(int i=-127;i<128;i++) c.map[i]&=~b.map[i]; return c; | ||
| 54 | } | ||
| 55 | inline charset operator-(const charset& a,char b) { | ||
| 56 | charset c(a); c.map[b]=0; return c; | ||
| 57 | } | ||
| 58 | inline charset operator~(const charset& a) { | ||
| 59 | charset c(a); for(int i=-127;i<128;i++) c.map[i]=!c.map[i]; c.map[0]=0; | ||
| 60 | return c; | ||
| 61 | } | ||
| 62 | |||
| 63 | ////////////////////////////////////////////////////////////////////////// | ||
| 64 | |||
| 65 | struct charmap { | ||
| 66 | charmap() { for(int i=-127;i<128;i++) map[i]=i; } | ||
| 67 | charmap(const charset& a,const charset& b) { | ||
| 68 | for(int i=-127,j=-127;i<128;i++) { | ||
| 69 | if(a[i]) { while(j<128&&!b[j]) j++; map[i]=j++; } | ||
| 70 | else map[i]=i; | ||
| 71 | } | ||
| 72 | } | ||
| 73 | charmap(const charset& a,const char* b) { | ||
| 74 | for(int i=-127;i<128;i++) if(a[i]&&*b) map[i]=*b++; else map[i]=i; | ||
| 75 | } | ||
| 76 | char operator[](char c) const { return map[c]; } | ||
| 77 | char negmap[128],map[128]; | ||
| 78 | }; | ||
| 79 | |||
| 80 | inline charmap operator<<(const charmap& a,const charmap& b) { | ||
| 81 | charmap c(a); | ||
| 82 | for(int i=-127;i<128;i++) if(b.map[i]!=i) c.map[i]=b.map[i]; | ||
| 83 | for(int i=-127;i<128;i++) c.map[i]=c.map[c.map[i]]; | ||
| 84 | return c; | ||
| 85 | } | ||
| 86 | |||
| 87 | ////////////////////////////////////////////////////////////////////////// | ||
| 88 | |||
| 89 | struct bracket { | ||
| 90 | explicit bracket(const char s[]) { strncpy(&left,s,sizeof(bracket)); } | ||
| 91 | int test(char c) const { return c==left||c==right; } | ||
| 92 | char left,right,esc,end; | ||
| 93 | }; | ||
| 94 | |||
| 95 | ////////////////////////////////////////////////////////////////////////// | ||
| 96 | |||
| 97 | const charset cset_spaces(" \t"); | ||
| 98 | const charset cset_newl("\r\n"); | ||
| 99 | const charset cset_ws=cset_spaces|cset_newl; | ||
| 100 | const charset cset_printable(' ','~'); | ||
| 101 | const charset cset_digit('0','9'); | ||
| 102 | const charset cset_real=cset_digit|'.'; | ||
| 103 | const charset cset_sign("+-"); | ||
| 104 | const charset cset_lalpha('a','z'); | ||
| 105 | const charset cset_ualpha('A','Z'); | ||
| 106 | const charset cset_alpha=cset_lalpha|cset_ualpha; | ||
| 107 | const charset cset_alphanum=cset_alpha|cset_digit; | ||
| 108 | const charset cset_alphareal=cset_alpha|cset_real; | ||
| 109 | const charset cset_lext1(-32,-10),cset_lext2(-8,-2); | ||
| 110 | const charset cset_uext1(-64,-42),cset_uext2(-40,-34); | ||
| 111 | const charset cset_liso=cset_lalpha|cset_lext1|cset_lext2; | ||
| 112 | const charset cset_uiso=cset_ualpha|cset_uext1|cset_uext2; | ||
| 113 | |||
| 114 | const charmap cset_ident; | ||
| 115 | const charmap cset_leqv1(cset_lext1,"aaaaaaaceeeeiiiidnooooo"); | ||
| 116 | const charmap cset_leqv2(cset_lext2,"ouuuuyp"); | ||
| 117 | const charmap cset_ueqv1(cset_uext1,"AAAAAAACEEEEIIIIDNOOOOO"); | ||
| 118 | const charmap cset_ueqv2(cset_uext2,"OUUUUYP"); | ||
| 119 | |||
| 120 | const charmap cset_lcase(cset_uiso,cset_liso); | ||
| 121 | const charmap cset_ucase(cset_liso,cset_uiso); | ||
| 122 | const charmap cset_sim=cset_lcase<<cset_leqv1<<cset_leqv2; | ||
| 123 | |||
| 124 | const bracket cset_quotes("\"\"\\"); | ||
| 125 | const bracket cset_indices("[]\\"); | ||
| 126 | const bracket cset_braces("{}\\"); | ||
| 127 | const bracket cset_para("()\\"); | ||
| 128 | const bracket cset_dollars("$$\\"); | ||
| 129 | const bracket cset_hooks("<>\\"); | ||
| 130 | |||
| 131 | #endif | ||
diff --git a/src/mt/config.cc b/src/mt/config.cc new file mode 100644 index 0000000..1797780 --- /dev/null +++ b/src/mt/config.cc | |||
| @@ -0,0 +1,33 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <mt/config.h> | ||
| 21 | |||
| 22 | mstring htchome() | ||
| 23 | { | ||
| 24 | const char* p=getenv("HTCHOME"); | ||
| 25 | if(!p) { | ||
| 26 | fprintf(stderr,"env: HTCHOME not set, exiting\n"); | ||
| 27 | exit(-1); | ||
| 28 | } | ||
| 29 | mstring home=p; | ||
| 30 | if(home.back()=='/') home=home.popb(); | ||
| 31 | return home; | ||
| 32 | } | ||
| 33 | |||
diff --git a/src/mt/config.h b/src/mt/config.h new file mode 100644 index 0000000..5389755 --- /dev/null +++ b/src/mt/config.h | |||
| @@ -0,0 +1,27 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef CONFIGH | ||
| 21 | #define CONFIGH | ||
| 22 | |||
| 23 | #include <mt/mstring.h> | ||
| 24 | |||
| 25 | mstring htchome(); | ||
| 26 | |||
| 27 | #endif | ||
diff --git a/src/mt/crfind.f b/src/mt/crfind.f new file mode 100644 index 0000000..f996ac4 --- /dev/null +++ b/src/mt/crfind.f | |||
| @@ -0,0 +1,80 @@ | |||
| 1 | ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc | ||
| 2 | c | ||
| 3 | c HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | c | ||
| 5 | c This program is free software; you can redistribute it and/or modify | ||
| 6 | c it under the terms of the GNU General Public License as published by | ||
| 7 | c the Free Software Foundation; either version 2 of the License, or | ||
| 8 | c (at your option) any later version. | ||
| 9 | c | ||
| 10 | c This program is distributed in the hope that it will be useful, | ||
| 11 | c but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | c GNU General Public License for more details. | ||
| 14 | c | ||
| 15 | c You should have received a copy of the GNU General Public License | ||
| 16 | c along with this program; if not, write to the Free Software | ||
| 17 | c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | c | ||
| 19 | |||
| 20 | integer function crfind(s,n,c) | ||
| 21 | character s(0:1),c | ||
| 22 | integer i,m,n | ||
| 23 | m=mod(n,16) | ||
| 24 | do 10 i=n-16,m,-16 | ||
| 25 | if(s(i+15).eq.c)go to 115 | ||
| 26 | if(s(i+14).eq.c)go to 114 | ||
| 27 | if(s(i+13).eq.c)go to 113 | ||
| 28 | if(s(i+12).eq.c)go to 112 | ||
| 29 | if(s(i+11).eq.c)go to 111 | ||
| 30 | if(s(i+10).eq.c)go to 110 | ||
| 31 | if(s(i+9).eq.c)go to 109 | ||
| 32 | if(s(i+8).eq.c)go to 108 | ||
| 33 | if(s(i+7).eq.c)go to 107 | ||
| 34 | if(s(i+6).eq.c)go to 106 | ||
| 35 | if(s(i+5).eq.c)go to 105 | ||
| 36 | if(s(i+4).eq.c)go to 104 | ||
| 37 | if(s(i+3).eq.c)go to 103 | ||
| 38 | if(s(i+2).eq.c)go to 102 | ||
| 39 | if(s(i+1).eq.c)go to 101 | ||
| 40 | if(s(i).eq.c)go to 100 | ||
| 41 | 10 continue | ||
| 42 | do 20 i=m-1,0,-1 | ||
| 43 | if(s(i).eq.c)go to 100 | ||
| 44 | 20 continue | ||
| 45 | crfind=-1 | ||
| 46 | return | ||
| 47 | 100 crfind=i | ||
| 48 | return | ||
| 49 | 101 crfind=i+1 | ||
| 50 | return | ||
| 51 | 102 crfind=i+2 | ||
| 52 | return | ||
| 53 | 103 crfind=i+3 | ||
| 54 | return | ||
| 55 | 104 crfind=i+4 | ||
| 56 | return | ||
| 57 | 105 crfind=i+5 | ||
| 58 | return | ||
| 59 | 106 crfind=i+6 | ||
| 60 | return | ||
| 61 | 107 crfind=i+7 | ||
| 62 | return | ||
| 63 | 108 crfind=i+8 | ||
| 64 | return | ||
| 65 | 109 crfind=i+9 | ||
| 66 | return | ||
| 67 | 110 crfind=i+10 | ||
| 68 | return | ||
| 69 | 111 crfind=i+11 | ||
| 70 | return | ||
| 71 | 112 crfind=i+12 | ||
| 72 | return | ||
| 73 | 113 crfind=i+13 | ||
| 74 | return | ||
| 75 | 114 crfind=i+14 | ||
| 76 | return | ||
| 77 | 115 crfind=i+15 | ||
| 78 | return | ||
| 79 | end | ||
| 80 | |||
diff --git a/src/mt/dates.cc b/src/mt/dates.cc new file mode 100644 index 0000000..8c244e5 --- /dev/null +++ b/src/mt/dates.cc | |||
| @@ -0,0 +1,207 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <mt/dates.h> | ||
| 21 | #include <mt/split.h> | ||
| 22 | #include <ctype.h> | ||
| 23 | |||
| 24 | const mstring SWEEK[MAXLANG][7]={ | ||
| 25 | "Sun","Mon","Tue","Wed","Thu","Fri","Sat", | ||
| 26 | "Sön","Mån","Tis","Ons","Tor","Fre","Lör" | ||
| 27 | }; | ||
| 28 | const mstring SMONTH[MAXLANG][12]={ | ||
| 29 | "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec", | ||
| 30 | "Jan","Feb","Mar","Apr","Maj","Jun","Jul","Aug","Sep","Okt","Nov","Dec" | ||
| 31 | }; | ||
| 32 | const mstring WEEK[MAXLANG][7]={ | ||
| 33 | "Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday", | ||
| 34 | "Söndag","Måndag","Tisdag","Onsdag","Torsdag","Fredag","Lördag" | ||
| 35 | }; | ||
| 36 | const mstring MONTH[MAXLANG][12]={ | ||
| 37 | "January","February","March","April","May","June", | ||
| 38 | "July","August","September","October","November","December", | ||
| 39 | "Januari","Februari","Mars","April","Maj","Juni", | ||
| 40 | "Juli","Augusti","September","Oktober","November","December" | ||
| 41 | }; | ||
| 42 | |||
| 43 | time_t Today(time_t now) | ||
| 44 | { | ||
| 45 | tm s; localtime_r(&now,&s); | ||
| 46 | s.tm_hour=0; | ||
| 47 | s.tm_min=0; | ||
| 48 | s.tm_sec=0; | ||
| 49 | return mktime(&s); | ||
| 50 | } | ||
| 51 | |||
| 52 | time_t Sunday(time_t now) | ||
| 53 | { | ||
| 54 | tm s; localtime_r(&now,&s); | ||
| 55 | s.tm_mday-=s.tm_wday; | ||
| 56 | return mktime(&s); | ||
| 57 | } | ||
| 58 | |||
| 59 | const mstring& Week(int lang,time_t t) | ||
| 60 | { | ||
| 61 | tm s; return WEEK[lang][localtime_r(&t,&s)->tm_wday]; | ||
| 62 | } | ||
| 63 | |||
| 64 | const mstring& Month(int lang,time_t t) | ||
| 65 | { | ||
| 66 | tm s; return MONTH[lang][localtime_r(&t,&s)->tm_mon]; | ||
| 67 | } | ||
| 68 | |||
| 69 | const mstring& SWeek(int lang,time_t t) | ||
| 70 | { | ||
| 71 | tm s; return SWEEK[lang][localtime_r(&t,&s)->tm_wday]; | ||
| 72 | } | ||
| 73 | |||
| 74 | const mstring& SMonth(int lang,time_t t) | ||
| 75 | { | ||
| 76 | tm s; return SMONTH[lang][localtime_r(&t,&s)->tm_mon]; | ||
| 77 | } | ||
| 78 | |||
| 79 | mstring httpTime(time_t t) | ||
| 80 | { | ||
| 81 | tm tt; gmtime_r(&t,&tt); | ||
| 82 | return mstring().convert("%s, %02d %s %4d %02d:%02d:%02d GMT", | ||
| 83 | SWEEK[0][tt.tm_wday].c_str(), | ||
| 84 | tt.tm_mday, | ||
| 85 | SMONTH[0][tt.tm_mon].c_str(), | ||
| 86 | tt.tm_year+1900, | ||
| 87 | tt.tm_hour, | ||
| 88 | tt.tm_min, | ||
| 89 | tt.tm_sec); | ||
| 90 | } | ||
| 91 | |||
| 92 | mstring htcTime(int lang,time_t t) | ||
| 93 | { | ||
| 94 | tm tt; localtime_r(&t,&tt); | ||
| 95 | mstring s(32); asctime_r(&tt,s.data()); s.resize(24); | ||
| 96 | if(lang) { | ||
| 97 | for(int i=0;i<7;i++) if(s(0,3)==SWEEK[0][i]) { | ||
| 98 | s.replace(0,3,SWEEK[lang][i]); | ||
| 99 | break; | ||
| 100 | } | ||
| 101 | for(int i=0;i<12;i++) if(s(4,3)==SMONTH[0][i]) { | ||
| 102 | s.replace(4,3,SMONTH[lang][i]); | ||
| 103 | break; | ||
| 104 | } | ||
| 105 | } | ||
| 106 | return s; | ||
| 107 | } | ||
| 108 | |||
| 109 | static int Month(int& mon,const sref& st) | ||
| 110 | { | ||
| 111 | mstring s=st; s.tolower(); s[0]=toupper(s[0]); | ||
| 112 | for(int lang=0;lang<MAXLANG;lang++) { | ||
| 113 | for(int m=0;m<12;m++) if(s==SMONTH[lang][m]) { mon=m; return 1; } | ||
| 114 | } | ||
| 115 | return 0; | ||
| 116 | } | ||
| 117 | |||
| 118 | static int Week(int& week,const sref& st) | ||
| 119 | { | ||
| 120 | mstring s=st; s.tolower(); s[0]=toupper(s[0]); | ||
| 121 | for(int lang=0;lang<MAXLANG;lang++) { | ||
| 122 | for(int w=0;w<7;w++) if(s==SWEEK[lang][w]) { week=w; return 1; } | ||
| 123 | } | ||
| 124 | return 0; | ||
| 125 | } | ||
| 126 | |||
| 127 | static int Time(int& th,int& tmi,int& ts,const sref& st) | ||
| 128 | { | ||
| 129 | static const charset sep_tag(":"); | ||
| 130 | sref hour,min,sec,when=st; | ||
| 131 | int h,m,s; | ||
| 132 | if(when.find(':')<0) return 0; | ||
| 133 | Split(hour,when,sep_tag); | ||
| 134 | Split(min,when,sep_tag); | ||
| 135 | Split(sec,when,sep_tag); | ||
| 136 | h=atoi(hour); | ||
| 137 | m=atoi(min); | ||
| 138 | s=atoi(sec); | ||
| 139 | if(h>=0&&h<=24&&m>=0&&m<60&&s>=0&&s<60) { th=h; tmi=m; ts=s; return 1; } | ||
| 140 | return 0; | ||
| 141 | } | ||
| 142 | |||
| 143 | static int Day(int& day,const sref& s) | ||
| 144 | { | ||
| 145 | if(s.find_not_of(cset_digit)>=0) return 0; | ||
| 146 | int d=atoi(s); | ||
| 147 | if(d>0&&d<32) { day=d; return 1; } | ||
| 148 | return 0; | ||
| 149 | } | ||
| 150 | |||
| 151 | static int Year(int& year,const sref& s) | ||
| 152 | { | ||
| 153 | if(s.find_not_of(cset_digit)>=0) return 0; | ||
| 154 | int y=atoi(s); | ||
| 155 | if(y>=32&&y<9999) { year=y; return 1; } | ||
| 156 | return 0; | ||
| 157 | } | ||
| 158 | |||
| 159 | time_t htcTime(int lang,const sref& date) | ||
| 160 | { | ||
| 161 | sref week,month,day,when,year,rest=date; | ||
| 162 | Split(week,rest); | ||
| 163 | Split(month,rest); | ||
| 164 | Split(day,rest); | ||
| 165 | Split(when,rest); | ||
| 166 | Split(year,rest); | ||
| 167 | struct tm t; | ||
| 168 | Time(t.tm_hour,t.tm_min,t.tm_sec,when); | ||
| 169 | t.tm_mday=atoi(day); | ||
| 170 | Month(t.tm_mon,month); | ||
| 171 | t.tm_year=atoi(year)-1900; | ||
| 172 | Week(t.tm_wday,week); | ||
| 173 | t.tm_isdst=-1; | ||
| 174 | return mktime(&t); | ||
| 175 | } | ||
| 176 | |||
| 177 | time_t cvtTime(const sref& code) | ||
| 178 | { | ||
| 179 | time_t now=time(0); | ||
| 180 | tm t; localtime_r(&now,&t); | ||
| 181 | t.tm_hour=0;t.tm_min=0;t.tm_sec=0; | ||
| 182 | //Start with 00:00:00 today | ||
| 183 | sref first,rest=code; | ||
| 184 | int w=0,m=0,d=0,h=0,y=0; | ||
| 185 | while(Split(first,rest)) { | ||
| 186 | if(!w) w=Week(t.tm_wday,first); | ||
| 187 | if(!m) m=Month(t.tm_mon,first); | ||
| 188 | if(!h) h=Time(t.tm_hour,t.tm_min,t.tm_sec,first); | ||
| 189 | if(!d) d=Day(t.tm_mday,first); | ||
| 190 | if(!y) if(y=Year(t.tm_year,first)) t.tm_year-=1900; | ||
| 191 | } | ||
| 192 | t.tm_isdst=-1; | ||
| 193 | return mktime(&t); | ||
| 194 | } | ||
| 195 | |||
| 196 | ////////////////////////////// | ||
| 197 | |||
| 198 | int Language(const sref& st) | ||
| 199 | { | ||
| 200 | static const charset seps=cset_ws|charset(",;"); | ||
| 201 | mstring s=st; s.tolower(); | ||
| 202 | sref first,rest=s; | ||
| 203 | while(Split(first,rest,seps)) { | ||
| 204 | for(int i=0;i<MAXLANG;i++) if(first==LANG[i]) return i; | ||
| 205 | } | ||
| 206 | return -1; | ||
| 207 | } | ||
diff --git a/src/mt/dates.h b/src/mt/dates.h new file mode 100644 index 0000000..fe05245 --- /dev/null +++ b/src/mt/dates.h | |||
| @@ -0,0 +1,49 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef DATESH | ||
| 21 | #define DATESH | ||
| 22 | |||
| 23 | #include <mt/mstring.h> | ||
| 24 | #include <time.h> | ||
| 25 | |||
| 26 | const time_t SEC_PER_DAY=86400; | ||
| 27 | const int MAXLANG=2; | ||
| 28 | const mstring LANG[MAXLANG]={"en","sv"}; | ||
| 29 | |||
| 30 | inline time_t Now() { return time(0); } | ||
| 31 | inline time_t Days(int days) { return days*SEC_PER_DAY; } | ||
| 32 | |||
| 33 | time_t Today(time_t); | ||
| 34 | time_t Sunday(time_t); | ||
| 35 | |||
| 36 | const mstring& Week(int lang,time_t t); | ||
| 37 | const mstring& Month(int lang,time_t t); | ||
| 38 | |||
| 39 | const mstring& SWeek(int lang,time_t t); | ||
| 40 | const mstring& SMonth(int lang,time_t t); | ||
| 41 | |||
| 42 | mstring httpTime(time_t t); | ||
| 43 | mstring htcTime(int lang,time_t t); | ||
| 44 | time_t htcTime(int lang,const sref& date); | ||
| 45 | time_t cvtTime(const sref& code); | ||
| 46 | |||
| 47 | int Language(const sref& s); | ||
| 48 | |||
| 49 | #endif | ||
diff --git a/src/mt/find_not_of.f b/src/mt/find_not_of.f new file mode 100644 index 0000000..11d9287 --- /dev/null +++ b/src/mt/find_not_of.f | |||
| @@ -0,0 +1,80 @@ | |||
| 1 | ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc | ||
| 2 | c | ||
| 3 | c HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | c | ||
| 5 | c This program is free software; you can redistribute it and/or modify | ||
| 6 | c it under the terms of the GNU General Public License as published by | ||
| 7 | c the Free Software Foundation; either version 2 of the License, or | ||
| 8 | c (at your option) any later version. | ||
| 9 | c | ||
| 10 | c This program is distributed in the hope that it will be useful, | ||
| 11 | c but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | c GNU General Public License for more details. | ||
| 14 | c | ||
| 15 | c You should have received a copy of the GNU General Public License | ||
| 16 | c along with this program; if not, write to the Free Software | ||
| 17 | c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | c | ||
| 19 | |||
| 20 | integer function find_not_of(s,n,c) | ||
| 21 | byte s(0:1),c(0:1) | ||
| 22 | integer i,m,n | ||
| 23 | m=mod(n,16) | ||
| 24 | do 10 i=0,m-1 | ||
| 25 | if(c(s(i)).eq.0)go to 100 | ||
| 26 | 10 continue | ||
| 27 | do 20 i=m,n-1,16 | ||
| 28 | if(c(s(i)).eq.0)go to 100 | ||
| 29 | if(c(s(i+1)).eq.0)go to 101 | ||
| 30 | if(c(s(i+2)).eq.0)go to 102 | ||
| 31 | if(c(s(i+3)).eq.0)go to 103 | ||
| 32 | if(c(s(i+4)).eq.0)go to 104 | ||
| 33 | if(c(s(i+5)).eq.0)go to 105 | ||
| 34 | if(c(s(i+6)).eq.0)go to 106 | ||
| 35 | if(c(s(i+7)).eq.0)go to 107 | ||
| 36 | if(c(s(i+8)).eq.0)go to 108 | ||
| 37 | if(c(s(i+9)).eq.0)go to 109 | ||
| 38 | if(c(s(i+10)).eq.0)go to 110 | ||
| 39 | if(c(s(i+11)).eq.0)go to 111 | ||
| 40 | if(c(s(i+12)).eq.0)go to 112 | ||
| 41 | if(c(s(i+13)).eq.0)go to 113 | ||
| 42 | if(c(s(i+14)).eq.0)go to 114 | ||
| 43 | if(c(s(i+15)).eq.0)go to 115 | ||
| 44 | 20 continue | ||
| 45 | find_not_of=-1 | ||
| 46 | return | ||
| 47 | 100 find_not_of=i | ||
| 48 | return | ||
| 49 | 101 find_not_of=i+1 | ||
| 50 | return | ||
| 51 | 102 find_not_of=i+2 | ||
| 52 | return | ||
| 53 | 103 find_not_of=i+3 | ||
| 54 | return | ||
| 55 | 104 find_not_of=i+4 | ||
| 56 | return | ||
| 57 | 105 find_not_of=i+5 | ||
| 58 | return | ||
| 59 | 106 find_not_of=i+6 | ||
| 60 | return | ||
| 61 | 107 find_not_of=i+7 | ||
| 62 | return | ||
| 63 | 108 find_not_of=i+8 | ||
| 64 | return | ||
| 65 | 109 find_not_of=i+9 | ||
| 66 | return | ||
| 67 | 110 find_not_of=i+10 | ||
| 68 | return | ||
| 69 | 111 find_not_of=i+11 | ||
| 70 | return | ||
| 71 | 112 find_not_of=i+12 | ||
| 72 | return | ||
| 73 | 113 find_not_of=i+13 | ||
| 74 | return | ||
| 75 | 114 find_not_of=i+14 | ||
| 76 | return | ||
| 77 | 115 find_not_of=i+15 | ||
| 78 | return | ||
| 79 | end | ||
| 80 | |||
diff --git a/src/mt/find_of.f b/src/mt/find_of.f new file mode 100644 index 0000000..81cd99d --- /dev/null +++ b/src/mt/find_of.f | |||
| @@ -0,0 +1,80 @@ | |||
| 1 | ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc | ||
| 2 | c | ||
| 3 | c HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | c | ||
| 5 | c This program is free software; you can redistribute it and/or modify | ||
| 6 | c it under the terms of the GNU General Public License as published by | ||
| 7 | c the Free Software Foundation; either version 2 of the License, or | ||
| 8 | c (at your option) any later version. | ||
| 9 | c | ||
| 10 | c This program is distributed in the hope that it will be useful, | ||
| 11 | c but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | c GNU General Public License for more details. | ||
| 14 | c | ||
| 15 | c You should have received a copy of the GNU General Public License | ||
| 16 | c along with this program; if not, write to the Free Software | ||
| 17 | c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | c | ||
| 19 | |||
| 20 | integer function find_of(s,n,c) | ||
| 21 | byte s(0:1),c(0:1) | ||
| 22 | integer i,m,n | ||
| 23 | m=mod(n,16) | ||
| 24 | do 10 i=0,m-1 | ||
| 25 | if(c(s(i)).ne.0)go to 100 | ||
| 26 | 10 continue | ||
| 27 | do 20 i=m,n-1,16 | ||
| 28 | if(c(s(i)).ne.0)go to 100 | ||
| 29 | if(c(s(i+1)).ne.0)go to 101 | ||
| 30 | if(c(s(i+2)).ne.0)go to 102 | ||
| 31 | if(c(s(i+3)).ne.0)go to 103 | ||
| 32 | if(c(s(i+4)).ne.0)go to 104 | ||
| 33 | if(c(s(i+5)).ne.0)go to 105 | ||
| 34 | if(c(s(i+6)).ne.0)go to 106 | ||
| 35 | if(c(s(i+7)).ne.0)go to 107 | ||
| 36 | if(c(s(i+8)).ne.0)go to 108 | ||
| 37 | if(c(s(i+9)).ne.0)go to 109 | ||
| 38 | if(c(s(i+10)).ne.0)go to 110 | ||
| 39 | if(c(s(i+11)).ne.0)go to 111 | ||
| 40 | if(c(s(i+12)).ne.0)go to 112 | ||
| 41 | if(c(s(i+13)).ne.0)go to 113 | ||
| 42 | if(c(s(i+14)).ne.0)go to 114 | ||
| 43 | if(c(s(i+15)).ne.0)go to 115 | ||
| 44 | 20 continue | ||
| 45 | find_of=-1 | ||
| 46 | return | ||
| 47 | 100 find_of=i | ||
| 48 | return | ||
| 49 | 101 find_of=i+1 | ||
| 50 | return | ||
| 51 | 102 find_of=i+2 | ||
| 52 | return | ||
| 53 | 103 find_of=i+3 | ||
| 54 | return | ||
| 55 | 104 find_of=i+4 | ||
| 56 | return | ||
| 57 | 105 find_of=i+5 | ||
| 58 | return | ||
| 59 | 106 find_of=i+6 | ||
| 60 | return | ||
| 61 | 107 find_of=i+7 | ||
| 62 | return | ||
| 63 | 108 find_of=i+8 | ||
| 64 | return | ||
| 65 | 109 find_of=i+9 | ||
| 66 | return | ||
| 67 | 110 find_of=i+10 | ||
| 68 | return | ||
| 69 | 111 find_of=i+11 | ||
| 70 | return | ||
| 71 | 112 find_of=i+12 | ||
| 72 | return | ||
| 73 | 113 find_of=i+13 | ||
| 74 | return | ||
| 75 | 114 find_of=i+14 | ||
| 76 | return | ||
| 77 | 115 find_of=i+15 | ||
| 78 | return | ||
| 79 | end | ||
| 80 | |||
diff --git a/src/mt/issue.cc b/src/mt/issue.cc new file mode 100644 index 0000000..fa31f36 --- /dev/null +++ b/src/mt/issue.cc | |||
| @@ -0,0 +1,51 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <mt/issue.h> | ||
| 21 | #include <signal.h> | ||
| 22 | #include <sys/wait.h> | ||
| 23 | |||
| 24 | void issue_t::run(mstream& out,const sref& in) throw(merror_t) | ||
| 25 | { | ||
| 26 | int ip[2],op[2]; | ||
| 27 | pipe(ip); pipe(op); | ||
| 28 | sigignore(SIGPIPE); | ||
| 29 | int pid=fork(); | ||
| 30 | if(pid) { | ||
| 31 | close(ip[0]); | ||
| 32 | close(op[1]); | ||
| 33 | write(ip[1],in.data(),in.size()); | ||
| 34 | close(ip[1]); | ||
| 35 | sref_t buf; int n; | ||
| 36 | while((n=read(op[0],buf,sizeof(sref_t)))>0) out.write(buf,n); | ||
| 37 | close(op[0]); | ||
| 38 | if(wait(0)<0) kill(pid,SIGKILL); | ||
| 39 | } | ||
| 40 | else { | ||
| 41 | close(ip[1]); | ||
| 42 | close(op[0]); | ||
| 43 | dup2(ip[0],0); | ||
| 44 | close(ip[0]); | ||
| 45 | dup2(op[1],1); | ||
| 46 | close(op[1]); | ||
| 47 | execv(*argv(),argv()); | ||
| 48 | _exit(0); | ||
| 49 | } | ||
| 50 | } | ||
| 51 | |||
diff --git a/src/mt/issue.h b/src/mt/issue.h new file mode 100644 index 0000000..27f6aa0 --- /dev/null +++ b/src/mt/issue.h | |||
| @@ -0,0 +1,55 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef ISSUEH | ||
| 21 | #define ISSUEH | ||
| 22 | |||
| 23 | #include <mt/mstring.h> | ||
| 24 | #include <mt/mvec.h> | ||
| 25 | #include <mt/split.h> | ||
| 26 | |||
| 27 | // ISSUE A PIPED COMMAND | ||
| 28 | // | ||
| 29 | // This class is tuned to work in a mt environment. | ||
| 30 | // The aim is to make this work locally as if it was | ||
| 31 | // a single thread returning something to the stream out | ||
| 32 | // depending on the input in. | ||
| 33 | |||
| 34 | struct issue_t { | ||
| 35 | mrvec<char*> arg; | ||
| 36 | |||
| 37 | issue_t() {} | ||
| 38 | ~issue_t() { clear(); } | ||
| 39 | |||
| 40 | issue_t(const sref& s,const charset& ws=cset_ws) { | ||
| 41 | sref first,rest=s; | ||
| 42 | while(Split(first,rest,ws)) arg.push_back(first.news()); | ||
| 43 | arg.push_back(0); | ||
| 44 | } | ||
| 45 | |||
| 46 | void clear() { for(int i=0;i<arg.size();i++) delete arg[i]; arg.clear(); } | ||
| 47 | void add(const sref& s) { arg.push_back(s.news()); } | ||
| 48 | void end() { arg.push_back(0); } | ||
| 49 | char* const* argv() const { return arg.begin(); } | ||
| 50 | |||
| 51 | void run(mstream& out,const sref& in) throw(merror_t); | ||
| 52 | }; | ||
| 53 | |||
| 54 | #endif | ||
| 55 | |||
diff --git a/src/mt/lock.cc b/src/mt/lock.cc new file mode 100644 index 0000000..5b72967 --- /dev/null +++ b/src/mt/lock.cc | |||
| @@ -0,0 +1,114 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <mt/lock.h> | ||
| 21 | #include <unistd.h> | ||
| 22 | #include <fcntl.h> | ||
| 23 | #include <errno.h> | ||
| 24 | #include <sys/utsname.h> | ||
| 25 | #include <signal.h> | ||
| 26 | using namespace std; | ||
| 27 | |||
| 28 | const mstring LOCK=".lock"; | ||
| 29 | |||
| 30 | void LockFile(const mstring& path,int prot) throw(merror_t) | ||
| 31 | { | ||
| 32 | mstring name=path+LOCK; int fd; | ||
| 33 | while((fd=open(name.c_str(),O_CREAT|O_WRONLY|O_TRUNC|O_EXCL,prot))==-1&& | ||
| 34 | errno==EEXIST) sleep(1); | ||
| 35 | if(fd<0) THROW("lock: could not create lock file "<<name); | ||
| 36 | close(fd); | ||
| 37 | } | ||
| 38 | |||
| 39 | int remove(const char* path); | ||
| 40 | void UnlockFile(const mstring& path) | ||
| 41 | { | ||
| 42 | remove((path+LOCK).c_str()); | ||
| 43 | } | ||
| 44 | |||
| 45 | /////////////////////////////////////////////////////////////////// | ||
| 46 | |||
| 47 | proclock_t::proclock_t(const mstring& p,int prot) : pid(0),path(p+LOCK) | ||
| 48 | { | ||
| 49 | mstring buf,name=path; | ||
| 50 | int fd=open(path.c_str(),O_CREAT|O_WRONLY|O_TRUNC|O_EXCL,prot); | ||
| 51 | if(fd<0) { | ||
| 52 | if(errno==EEXIST) { | ||
| 53 | buf.load(path); | ||
| 54 | int oldpid=atoi(buf); | ||
| 55 | if(kill(oldpid,0)==0) THROW("proclock: already running as "<<buf) | ||
| 56 | else fd=open(path.c_str(),O_CREAT|O_WRONLY|O_TRUNC,prot); | ||
| 57 | } | ||
| 58 | else THROW("proclock: could not create lock file "<<path); | ||
| 59 | } | ||
| 60 | pid=getpid(); | ||
| 61 | buf.convert("%d",pid); | ||
| 62 | write(fd,buf.data(),buf.size()); | ||
| 63 | close(fd); | ||
| 64 | } | ||
| 65 | |||
| 66 | proclock_t::~proclock_t() | ||
| 67 | { | ||
| 68 | if(getpid()==pid) remove(path.c_str()); | ||
| 69 | } | ||
| 70 | |||
| 71 | /////////////////////////////////////////////////////////////////// | ||
| 72 | |||
| 73 | nodelock_t::nodelock_t(const mstring& p,int prot) : pid(0),path(p+LOCK) | ||
| 74 | { | ||
| 75 | struct utsname uts; uname(&uts); | ||
| 76 | mstring buf; | ||
| 77 | int fd=open(path.c_str(),O_CREAT|O_WRONLY|O_TRUNC|O_EXCL,prot); | ||
| 78 | if(fd<0) { | ||
| 79 | if(errno==EEXIST) { | ||
| 80 | if(buf.load(path)>=0) { | ||
| 81 | if(buf.nempty()&&buf!=sref(uts.nodename)) | ||
| 82 | THROW("nodelock: already locked on "<<buf); | ||
| 83 | } | ||
| 84 | else { | ||
| 85 | fd=open(path.c_str(),O_CREAT|O_WRONLY|O_TRUNC,prot); | ||
| 86 | pid=getpid(); | ||
| 87 | buf=uts.nodename; | ||
| 88 | write(fd,buf.data(),buf.size()); | ||
| 89 | close(fd); | ||
| 90 | } | ||
| 91 | } | ||
| 92 | else THROW("nodelock: could not create lock file "<<path); | ||
| 93 | } | ||
| 94 | else { | ||
| 95 | pid=getpid(); | ||
| 96 | buf=uts.nodename; | ||
| 97 | write(fd,buf.data(),buf.size()); | ||
| 98 | close(fd); | ||
| 99 | } | ||
| 100 | } | ||
| 101 | |||
| 102 | nodelock_t::~nodelock_t() | ||
| 103 | { | ||
| 104 | if(getpid()==pid) remove(path.c_str()); | ||
| 105 | } | ||
| 106 | |||
| 107 | /////////////////////////////////////////////////////////////////// | ||
| 108 | |||
| 109 | void ProcTerminate(const mstring& p,int stime) | ||
| 110 | { | ||
| 111 | mstring buf,path=p+LOCK; | ||
| 112 | if(buf.load(path)>=0) while(!kill(atoi(buf),SIGTERM)) sleep(stime); | ||
| 113 | } | ||
| 114 | |||
diff --git a/src/mt/lock.h b/src/mt/lock.h new file mode 100644 index 0000000..e019158 --- /dev/null +++ b/src/mt/lock.h | |||
| @@ -0,0 +1,72 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef LOCKH | ||
| 21 | #define LOCKH | ||
| 22 | |||
| 23 | #include <mt/mstring.h> | ||
| 24 | |||
| 25 | // OFFERS TWO LOCKING MECHANISMS | ||
| 26 | |||
| 27 | void LockFile(const mstring& path,int prot=0660) throw(merror_t); | ||
| 28 | void UnlockFile(const mstring& path); | ||
| 29 | |||
| 30 | // These functions create an exclusive lock on path by | ||
| 31 | // creating a file path.lock. | ||
| 32 | // Works well and is the same mechnism used by | ||
| 33 | // mailing systems. | ||
| 34 | |||
| 35 | //////////////////////////////////////////// | ||
| 36 | |||
| 37 | struct proclock_t { | ||
| 38 | pid_t pid; | ||
| 39 | mstring path; | ||
| 40 | proclock_t(const mstring& p,int prot=0660); | ||
| 41 | ~proclock_t(); | ||
| 42 | }; | ||
| 43 | |||
| 44 | #define PROCLOCK(p) proclock_t proclock(p) | ||
| 45 | |||
| 46 | // The proclock class creates a file named path.lock | ||
| 47 | // and stores the curent process id in it. | ||
| 48 | // once the destructor is called in the same | ||
| 49 | // process, the file is removed. | ||
| 50 | |||
| 51 | //////////////////////////////////////////// | ||
| 52 | |||
| 53 | struct nodelock_t { | ||
| 54 | pid_t pid; | ||
| 55 | mstring path; | ||
| 56 | nodelock_t(const mstring& p,int prot=0660); | ||
| 57 | ~nodelock_t(); | ||
| 58 | }; | ||
| 59 | |||
| 60 | #define NODELOCK(p) nodelock_t nodelock(p) | ||
| 61 | |||
| 62 | // The nodelock class creates a file named path.lock | ||
| 63 | // and stores the curent network node name in it. | ||
| 64 | // once the destructor is called in the same | ||
| 65 | // process, the file is removed. | ||
| 66 | |||
| 67 | //////////////////////////////////////////// | ||
| 68 | |||
| 69 | void ProcTerminate(const mstring& path,int stime=2); | ||
| 70 | |||
| 71 | #endif | ||
| 72 | |||
diff --git a/src/mt/lookup.cc b/src/mt/lookup.cc new file mode 100644 index 0000000..c0e72c8 --- /dev/null +++ b/src/mt/lookup.cc | |||
| @@ -0,0 +1,88 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <mt/lookup.h> | ||
| 21 | #include <mt/mvec.h> | ||
| 22 | #include <mt/lock.h> | ||
| 23 | #include <arpa/inet.h> | ||
| 24 | #include <netinet/in.h> | ||
| 25 | #include <sys/socket.h> | ||
| 26 | |||
| 27 | const time_t VALIDSEC=120; | ||
| 28 | static msvec<IPnode> cache; | ||
| 29 | static mutex_t mutex; | ||
| 30 | |||
| 31 | int Lookup(IPnode& node,const in_addr& ia) | ||
| 32 | { | ||
| 33 | MLOCK(mutex); | ||
| 34 | IPnode* p=cache.begin(); | ||
| 35 | time_t now=time(0); | ||
| 36 | while(p<cache.end()) { | ||
| 37 | if(now>p->valid) cache.erase(p); | ||
| 38 | else if(memcmp(&p->addr,&ia,sizeof(ia))==0) {p->valid=now+VALIDSEC;node=*p;return 1;} | ||
| 39 | else p++; | ||
| 40 | } | ||
| 41 | hostent hent; | ||
| 42 | sref_t buf; | ||
| 43 | int herr; | ||
| 44 | hostent* hp=0; | ||
| 45 | gethostbyaddr_r((const char*)&ia,sizeof(ia),AF_INET, | ||
| 46 | &hent, | ||
| 47 | buf,sizeof(sref_t), | ||
| 48 | &hp, | ||
| 49 | &herr); | ||
| 50 | if(!hp) return 0; | ||
| 51 | memcpy(&node.addr,hp->h_addr,sizeof(hp->h_length)); | ||
| 52 | node.ip=inet_ntoa(node.addr); | ||
| 53 | node.name=hp->h_name; | ||
| 54 | node.valid=now+VALIDSEC; | ||
| 55 | cache.push_back(node); | ||
| 56 | return 1; | ||
| 57 | } | ||
| 58 | |||
| 59 | int Lookup(IPnode& node,const sref& s) | ||
| 60 | { | ||
| 61 | MLOCK(mutex); | ||
| 62 | IPnode* p=cache.begin(); | ||
| 63 | time_t now=time(0); | ||
| 64 | while(p<cache.end()) { | ||
| 65 | if(now>p->valid) cache.erase(p); | ||
| 66 | else if(p->ip==s||p->name==s) { p->valid=now+VALIDSEC; node=*p; return 1; } | ||
| 67 | else p++; | ||
| 68 | } | ||
| 69 | hostent hent; | ||
| 70 | sref_t sbuf,buf; | ||
| 71 | int herr; | ||
| 72 | hostent* hp=0; | ||
| 73 | for(int i=0;s[i];i++) if(s[i]!='.'&&(s[i]<'0'||s[i]>'9')) { | ||
| 74 | gethostbyname_r(s.copyto(sbuf),&hent,buf,sizeof(sref_t),&hp,&herr); | ||
| 75 | break; | ||
| 76 | } | ||
| 77 | if(!hp) { | ||
| 78 | unsigned long a=inet_addr(s.copyto(buf)); | ||
| 79 | gethostbyaddr_r((char*)&a,sizeof(a),AF_INET,&hent,buf,sizeof(sref_t),&hp,&herr); | ||
| 80 | } | ||
| 81 | if(!hp) return 0; | ||
| 82 | memcpy(&node.addr,hp->h_addr,sizeof(hp->h_length)); | ||
| 83 | node.ip=inet_ntoa(node.addr); | ||
| 84 | node.name=hp->h_name; | ||
| 85 | node.valid=now+VALIDSEC; | ||
| 86 | cache.push_back(node); | ||
| 87 | return 1; | ||
| 88 | } | ||
diff --git a/src/mt/lookup.h b/src/mt/lookup.h new file mode 100644 index 0000000..d073766 --- /dev/null +++ b/src/mt/lookup.h | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef LOOKUPH | ||
| 21 | #define LOOKUPH | ||
| 22 | |||
| 23 | #include <mt/mstring.h> | ||
| 24 | #include <netdb.h> | ||
| 25 | #include <netinet/in.h> | ||
| 26 | |||
| 27 | struct IPnode { time_t valid; in_addr addr; mstring ip,name; }; | ||
| 28 | |||
| 29 | int Lookup(IPnode& node,const sref& s); | ||
| 30 | int Lookup(IPnode& node,const in_addr& ia); | ||
| 31 | |||
| 32 | #endif | ||
diff --git a/src/mt/mlock.h b/src/mt/mlock.h new file mode 100644 index 0000000..4639cf4 --- /dev/null +++ b/src/mt/mlock.h | |||
| @@ -0,0 +1,48 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef MLOCKH | ||
| 21 | #define MLOCKH | ||
| 22 | |||
| 23 | #if 1 | ||
| 24 | #include <pthread.h> | ||
| 25 | typedef pthread_mutex_t mutex_t; | ||
| 26 | typedef pthread_cond_t mtcond_t; | ||
| 27 | const mutex_t MUTEX_INIT=PTHREAD_MUTEX_INITIALIZER; | ||
| 28 | const mtcond_t MTCOND_INIT=PTHREAD_COND_INITIALIZER; | ||
| 29 | struct mlock_t { | ||
| 30 | mutex_t* lock; | ||
| 31 | |||
| 32 | mlock_t(mutex_t& m) { pthread_mutex_lock(lock=&m); } | ||
| 33 | ~mlock_t() { if(lock) pthread_mutex_unlock(lock); } | ||
| 34 | }; | ||
| 35 | #define MLOCK(m) mlock_t mlock(m) | ||
| 36 | #define MSUSPEND(m,c) { MLOCK(m); pthread_cond_wait(&c,&m); } | ||
| 37 | #define MCONTINUE(c) pthread_cond_signal(&c) | ||
| 38 | #else | ||
| 39 | typedef int mutex_t; | ||
| 40 | typedef int mtcond_t; | ||
| 41 | const mutex_t MUTEX_INIT=0; | ||
| 42 | const mtcond_t MTCOND_INIT=0; | ||
| 43 | #define MLOCK(m) | ||
| 44 | #define MSUSPEND(m,c) | ||
| 45 | #define MCONTINUE(c) | ||
| 46 | #endif | ||
| 47 | |||
| 48 | #endif | ||
diff --git a/src/mt/mread.cc b/src/mt/mread.cc new file mode 100644 index 0000000..da5a966 --- /dev/null +++ b/src/mt/mread.cc | |||
| @@ -0,0 +1,135 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <mt/mread.h> | ||
| 21 | #include <mt/split.h> | ||
| 22 | #include <poll.h> | ||
| 23 | #include <signal.h> | ||
| 24 | #include <errno.h> | ||
| 25 | |||
| 26 | const int MSEC=4000; | ||
| 27 | const int RETRY=3; | ||
| 28 | const int TIMEOUT=2; | ||
| 29 | |||
| 30 | ////////////////////////////////////////////////////////////////////////// | ||
| 31 | |||
| 32 | mread::mread() : fd(-1),buf() | ||
| 33 | { | ||
| 34 | } | ||
| 35 | |||
| 36 | mread::mread(int f) : fd(f),buf() | ||
| 37 | { | ||
| 38 | } | ||
| 39 | |||
| 40 | ////////////////////////////////////////////////////////////////////////// | ||
| 41 | |||
| 42 | void mread::clear() | ||
| 43 | { | ||
| 44 | buf.clear(); | ||
| 45 | } | ||
| 46 | |||
| 47 | int mread::poll() | ||
| 48 | { | ||
| 49 | pollfd pfd={fd,POLLIN,0}; | ||
| 50 | return ::poll(&pfd,1,MSEC); | ||
| 51 | } | ||
| 52 | |||
| 53 | int mread::read(char* s,int n) | ||
| 54 | { | ||
| 55 | if(buf.empty()) { | ||
| 56 | int m=::read(fd,s,n); | ||
| 57 | for(int i=0;i<RETRY&&m<0&&errno==EAGAIN&&poll()>=0;i++) m=::read(fd,s,n); | ||
| 58 | if(m<0&&n) *s=0; | ||
| 59 | return m; | ||
| 60 | } | ||
| 61 | else { | ||
| 62 | if(n>buf.size()) n=buf.size(); | ||
| 63 | memcpy(s,buf.data(),n); | ||
| 64 | buf.erase(0,n); | ||
| 65 | return n; | ||
| 66 | } | ||
| 67 | } | ||
| 68 | |||
| 69 | void mread::putback(const sref& s) | ||
| 70 | { | ||
| 71 | if(s.nempty()) buf.insert(0,s); | ||
| 72 | } | ||
| 73 | |||
| 74 | ////////////////////////////////////////////////////////////////////////// | ||
| 75 | |||
| 76 | int mread::readx(char* s,int n) | ||
| 77 | { | ||
| 78 | int tries=0,acc=0; | ||
| 79 | while(acc<n) { | ||
| 80 | int m=read(s+acc,n-acc); | ||
| 81 | if(m<0) return -1; | ||
| 82 | else if(m==0) { | ||
| 83 | if(poll()<0) return -1; | ||
| 84 | if(tries++>=TIMEOUT) return acc; | ||
| 85 | } | ||
| 86 | else { | ||
| 87 | acc+=m; | ||
| 88 | tries=0; | ||
| 89 | } | ||
| 90 | } | ||
| 91 | return acc; | ||
| 92 | } | ||
| 93 | |||
| 94 | ////////////////////////////////////////////////////////////////////////// | ||
| 95 | |||
| 96 | int mread::readln(char* s,int n) | ||
| 97 | { | ||
| 98 | int tries=0,acc=0; | ||
| 99 | while(acc<n) { | ||
| 100 | int m=read(s+acc,n-acc); | ||
| 101 | if(m<0) return -1; | ||
| 102 | else if(m==0) { | ||
| 103 | if(poll()<0) return -1; | ||
| 104 | if(tries++>=TIMEOUT) return acc?-1:0; | ||
| 105 | } | ||
| 106 | else { | ||
| 107 | int p=sref(s+acc,m).find('\n')+1; | ||
| 108 | if(p>0) { acc+=p; putback(sref(s+acc,m-p)); return acc; } | ||
| 109 | else { acc+=m; tries=0; } | ||
| 110 | } | ||
| 111 | } | ||
| 112 | return acc; | ||
| 113 | } | ||
| 114 | |||
| 115 | int mread::readpara(char* s,int n) | ||
| 116 | { | ||
| 117 | int tries=0,acc=0; | ||
| 118 | while(acc<n) { | ||
| 119 | int m=read(s+acc,n-acc); | ||
| 120 | if(m<0) return -1; | ||
| 121 | else if(m==0) { | ||
| 122 | if(poll()<0) return -1; | ||
| 123 | if(tries++>=TIMEOUT) return acc?-1:0; | ||
| 124 | } | ||
| 125 | else { | ||
| 126 | int found=0; | ||
| 127 | sref first,rest(s+acc,m); | ||
| 128 | while(Splitln(first,rest)) if(first.empty()) { found=1; break; } | ||
| 129 | if(found) { acc=rest.begin()-s; putback(rest); return acc; } | ||
| 130 | else { acc+=m; tries=0; } | ||
| 131 | } | ||
| 132 | } | ||
| 133 | return acc; | ||
| 134 | } | ||
| 135 | |||
diff --git a/src/mt/mread.h b/src/mt/mread.h new file mode 100644 index 0000000..11516a2 --- /dev/null +++ b/src/mt/mread.h | |||
| @@ -0,0 +1,63 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef MREADH | ||
| 21 | #define MREADH | ||
| 22 | |||
| 23 | // These functions work with nonblocking pipes | ||
| 24 | // as well as normal devices, and does not produce | ||
| 25 | // any signals on pipe errors | ||
| 26 | |||
| 27 | #include <mt/mstring.h> | ||
| 28 | #include <unistd.h> | ||
| 29 | #include <fcntl.h> | ||
| 30 | |||
| 31 | class mread { | ||
| 32 | public: | ||
| 33 | mread(); | ||
| 34 | mread(int f); | ||
| 35 | |||
| 36 | void setfd(int f) { clear(); fd=f; } | ||
| 37 | int getfd() const { return fd; } | ||
| 38 | |||
| 39 | void setflag(int f) { fcntl(fd,F_SETFL,f); } | ||
| 40 | int getflag() const { return fcntl(fd,F_GETFL,0); } | ||
| 41 | |||
| 42 | // Basic, pipe-safe, normally non-blocking, reads | ||
| 43 | void clear(); | ||
| 44 | int poll(); | ||
| 45 | int read(char* s,int n); | ||
| 46 | void putback(const sref& s); | ||
| 47 | |||
| 48 | // Buffered reads | ||
| 49 | int readx(char* s,int n); // may timeout and return less than wanted | ||
| 50 | int readln(char* s,int n); | ||
| 51 | int readpara(char* s,int n); | ||
| 52 | |||
| 53 | private: | ||
| 54 | int fd; | ||
| 55 | mstring buf; | ||
| 56 | }; | ||
| 57 | |||
| 58 | // All functions return number of bytes written, or -1 on error. | ||
| 59 | // Note that although ln and para continues to read until | ||
| 60 | // it finds a newline or a paragraph, it may read more than that. | ||
| 61 | // Use clear() to restore reading state | ||
| 62 | |||
| 63 | #endif | ||
diff --git a/src/mt/mset.cc b/src/mt/mset.cc new file mode 100644 index 0000000..ec5b69e --- /dev/null +++ b/src/mt/mset.cc | |||
| @@ -0,0 +1,81 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <mt/mset.h> | ||
| 21 | #include <algorithm> | ||
| 22 | using namespace std; | ||
| 23 | |||
| 24 | mset::mset() : rpile() {} | ||
| 25 | mset::mset(const sref& in) : rpile() { | ||
| 26 | sref first,rest=in; | ||
| 27 | while(Split(first,rest)) insert(first); | ||
| 28 | } | ||
| 29 | |||
| 30 | ///////////////////////////////////////////////////////////////////////////// | ||
| 31 | |||
| 32 | int mset::exist(const sref& t) const { | ||
| 33 | pair<const_iterator,const_iterator> p=equal_range(begin(),end(),t); | ||
| 34 | return p.first!=p.second; | ||
| 35 | } | ||
| 36 | int mset::insert(const sref& t) { | ||
| 37 | pair<iterator,iterator> p=equal_range(begin(),end(),t); | ||
| 38 | if(p.first==p.second) { rpile::insert(p.second,t); return 1; } | ||
| 39 | else return 0; | ||
| 40 | } | ||
| 41 | |||
| 42 | ///////////////////////////////////////////////////////////////////////////// | ||
| 43 | |||
| 44 | void mset::Union(const mset& a,const mset& b) { | ||
| 45 | clear(); | ||
| 46 | for(int i=0;i<a.size();i++) insert(a[i]); | ||
| 47 | for(int i=0;i<b.size();i++) insert(b[i]); | ||
| 48 | } | ||
| 49 | void mset::Intersection(const mset& a,const mset& b) { | ||
| 50 | clear(); | ||
| 51 | for(int i=0;i<a.size();i++) if(b.exist(a[i])) insert(a[i]); | ||
| 52 | } | ||
| 53 | void mset::Difference(const mset& a,const mset& b) { | ||
| 54 | clear(); | ||
| 55 | for(int i=0;i<a.size();i++) if(!b.exist(a[i])) insert(a[i]); | ||
| 56 | } | ||
| 57 | |||
| 58 | ///////////////////////////////////////////////////////////////////////////// | ||
| 59 | |||
| 60 | mstream& operator<<(mstream& out,const mset& m) { | ||
| 61 | for(int i=0;i<m.size();i++) { if(i) out.put(' '); out<<m[i]; } return out; | ||
| 62 | } | ||
| 63 | |||
| 64 | ///////////////////////////////////////////////////////////////////////////// | ||
| 65 | |||
| 66 | int msset::exist(const mstring& t) const { | ||
| 67 | pair<const_iterator,const_iterator> p=equal_range(begin(),end(),t); | ||
| 68 | return p.first!=p.second; | ||
| 69 | } | ||
| 70 | int msset::insert(const mstring& t) { | ||
| 71 | pair<iterator,iterator> p=equal_range(begin(),end(),t); | ||
| 72 | if(p.first==p.second) { spile::insert(p.second,t); return 1; } | ||
| 73 | else return 0; | ||
| 74 | } | ||
| 75 | |||
| 76 | ///////////////////////////////////////////////////////////////////////////// | ||
| 77 | |||
| 78 | mstream& operator<<(mstream& out,const msset& m) { | ||
| 79 | for(int i=0;i<m.size();i++) { if(i) out.put(' '); out<<m[i]; } return out; | ||
| 80 | } | ||
| 81 | |||
diff --git a/src/mt/mset.h b/src/mt/mset.h new file mode 100644 index 0000000..469166f --- /dev/null +++ b/src/mt/mset.h | |||
| @@ -0,0 +1,62 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef MSETH | ||
| 21 | #define MSETH | ||
| 22 | |||
| 23 | #include <mt/split.h> | ||
| 24 | #include <mt/mstring.h> | ||
| 25 | #include <mt/mvec.h> | ||
| 26 | |||
| 27 | typedef mrvec<sref> rpile; | ||
| 28 | |||
| 29 | struct mset : public rpile | ||
| 30 | { | ||
| 31 | typedef rpile::iterator iterator; | ||
| 32 | typedef rpile::const_iterator const_iterator; | ||
| 33 | |||
| 34 | mset(); | ||
| 35 | mset(const sref& in); | ||
| 36 | |||
| 37 | int exist(const sref& t) const; | ||
| 38 | int insert(const sref& t); | ||
| 39 | |||
| 40 | void Union(const mset& a,const mset& b); | ||
| 41 | void Intersection(const mset& a,const mset& b); | ||
| 42 | void Difference(const mset& a,const mset& b); | ||
| 43 | }; | ||
| 44 | |||
| 45 | mstream& operator<<(mstream& out,const mset& m); | ||
| 46 | |||
| 47 | ////////////////////////////////////////////////////////// | ||
| 48 | |||
| 49 | typedef msvec<mstring> spile; | ||
| 50 | |||
| 51 | struct msset : public spile | ||
| 52 | { | ||
| 53 | typedef spile::iterator iterator; | ||
| 54 | typedef spile::const_iterator const_iterator; | ||
| 55 | |||
| 56 | int exist(const mstring& t) const; | ||
| 57 | int insert(const mstring& t); | ||
| 58 | }; | ||
| 59 | |||
| 60 | mstream& operator<<(mstream& out,const mset& m); | ||
| 61 | |||
| 62 | #endif | ||
diff --git a/src/mt/msmap.cc b/src/mt/msmap.cc new file mode 100644 index 0000000..c1284fb --- /dev/null +++ b/src/mt/msmap.cc | |||
| @@ -0,0 +1,84 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <mt/msmap.h> | ||
| 21 | #include <algorithm> | ||
| 22 | using namespace std; | ||
| 23 | |||
| 24 | const sref* rrmap::get(const sref& t) const | ||
| 25 | { | ||
| 26 | pair<const_iterator,const_iterator> p=equal_range(begin(),end(),rrstring(t)); | ||
| 27 | return p.first!=p.second?&p.first->second:0; | ||
| 28 | } | ||
| 29 | |||
| 30 | const sref* rrmap::add(const sref& t,const sref& s) | ||
| 31 | { | ||
| 32 | rrstring tmp(t,s); | ||
| 33 | pair<iterator,iterator> p=equal_range(begin(),end(),tmp); | ||
| 34 | if(p.first!=p.second) return &(*p.first=tmp).second; | ||
| 35 | else return &insert(p.second,tmp)->second; | ||
| 36 | } | ||
| 37 | |||
| 38 | void rrmap::sort() | ||
| 39 | { | ||
| 40 | ::sort(begin(),end()); | ||
| 41 | } | ||
| 42 | |||
| 43 | //////////////////////////////////////////////////////////////// | ||
| 44 | |||
| 45 | int rimap::get(const sref& t) const | ||
| 46 | { | ||
| 47 | pair<const_iterator,const_iterator> p=equal_range(begin(),end(),rimap_t(t)); | ||
| 48 | return p.first!=p.second?p.first->at:-1; | ||
| 49 | } | ||
| 50 | |||
| 51 | int rimap::add(const sref& t,int at) | ||
| 52 | { | ||
| 53 | rimap_t tmp(t,at); | ||
| 54 | pair<iterator,iterator> p=equal_range(begin(),end(),tmp); | ||
| 55 | if(p.first!=p.second) return (*p.first=tmp).at; | ||
| 56 | else return insert(p.second,tmp)->at; | ||
| 57 | } | ||
| 58 | |||
| 59 | void rimap::sort() | ||
| 60 | { | ||
| 61 | ::sort(begin(),end()); | ||
| 62 | } | ||
| 63 | |||
| 64 | //////////////////////////////////////////////////////////////// | ||
| 65 | |||
| 66 | const mstring* ssmap::get(const mstring& t) const | ||
| 67 | { | ||
| 68 | pair<const_iterator,const_iterator> p=equal_range(begin(),end(),sstring(t)); | ||
| 69 | return p.first!=p.second?&p.first->second:0; | ||
| 70 | } | ||
| 71 | |||
| 72 | const mstring* ssmap::add(const mstring& t,const mstring& s) | ||
| 73 | { | ||
| 74 | sstring tmp(t,s); | ||
| 75 | pair<iterator,iterator> p=equal_range(begin(),end(),tmp); | ||
| 76 | if(p.first!=p.second) return &(*p.first=tmp).second; | ||
| 77 | else return &insert(p.second,tmp)->second; | ||
| 78 | } | ||
| 79 | |||
| 80 | void ssmap::sort() | ||
| 81 | { | ||
| 82 | ::sort(begin(),end()); | ||
| 83 | } | ||
| 84 | |||
diff --git a/src/mt/msmap.h b/src/mt/msmap.h new file mode 100644 index 0000000..a719a7b --- /dev/null +++ b/src/mt/msmap.h | |||
| @@ -0,0 +1,89 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef MSMAPH | ||
| 21 | #define MSMAPH | ||
| 22 | |||
| 23 | #include <mt/mstring.h> | ||
| 24 | #include <mt/mvec.h> | ||
| 25 | |||
| 26 | struct rrstring { | ||
| 27 | sref first,second; | ||
| 28 | rrstring() : first(),second() {} | ||
| 29 | explicit rrstring(const sref& a) : first(a),second() {} | ||
| 30 | rrstring(const sref& a,const sref& b) : first(a),second(b) {} | ||
| 31 | }; | ||
| 32 | inline bool operator<(const rrstring& a,const rrstring& b) { return a.first<b.first; } | ||
| 33 | |||
| 34 | typedef mrvec<rrstring> rrpile; | ||
| 35 | |||
| 36 | struct rrmap : public rrpile | ||
| 37 | { | ||
| 38 | typedef rrpile::iterator iterator; | ||
| 39 | typedef rrpile::const_iterator const_iterator; | ||
| 40 | |||
| 41 | const sref* get(const sref& t) const; | ||
| 42 | const sref* add(const sref& t,const sref& s); | ||
| 43 | void sort(); | ||
| 44 | }; | ||
| 45 | |||
| 46 | ////////////////////////////////////////////////////////////////// | ||
| 47 | |||
| 48 | struct rimap_t { | ||
| 49 | sref name; | ||
| 50 | int at; | ||
| 51 | rimap_t() : name(),at(0) {} | ||
| 52 | explicit rimap_t(const sref& a) : name(a),at(0) {} | ||
| 53 | rimap_t(const sref& a,int p) : name(a),at(p) {} | ||
| 54 | }; | ||
| 55 | inline bool operator<(const rimap_t& a,const rimap_t& b) { return a.name<b.name; } | ||
| 56 | |||
| 57 | struct rimap : public mrvec<rimap_t> | ||
| 58 | { | ||
| 59 | typedef mrvec<rimap_t>::iterator iterator; | ||
| 60 | typedef mrvec<rimap_t>::const_iterator const_iterator; | ||
| 61 | |||
| 62 | int get(const sref& t) const; | ||
| 63 | int add(const sref& t,int at); | ||
| 64 | void sort(); | ||
| 65 | }; | ||
| 66 | |||
| 67 | ////////////////////////////////////////////////////////////////// | ||
| 68 | |||
| 69 | struct sstring { | ||
| 70 | mstring first,second; | ||
| 71 | sstring() : first(),second() {} | ||
| 72 | explicit sstring(const mstring& a) : first(a),second() {} | ||
| 73 | sstring(const mstring& a,const mstring& b) : first(a),second(b) {} | ||
| 74 | }; | ||
| 75 | inline bool operator<(const sstring& a,const sstring& b) { return a.first<b.first; } | ||
| 76 | |||
| 77 | typedef msvec<sstring> sspile; | ||
| 78 | |||
| 79 | struct ssmap : public sspile | ||
| 80 | { | ||
| 81 | typedef sspile::iterator iterator; | ||
| 82 | typedef sspile::const_iterator const_iterator; | ||
| 83 | |||
| 84 | const mstring* get(const mstring& t) const; | ||
| 85 | const mstring* add(const mstring& t,const mstring& s); | ||
| 86 | void sort(); | ||
| 87 | }; | ||
| 88 | |||
| 89 | #endif | ||
diff --git a/src/mt/mstream.cc b/src/mt/mstream.cc new file mode 100644 index 0000000..3d94936 --- /dev/null +++ b/src/mt/mstream.cc | |||
| @@ -0,0 +1,72 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <mt/mstream.h> | ||
| 21 | #include <poll.h> | ||
| 22 | #include <signal.h> | ||
| 23 | |||
| 24 | const char cvt_form_f[]="%#.12f"; | ||
| 25 | const int MSEC=4000; | ||
| 26 | |||
| 27 | sref ftoa(sref_t& buf,double f) | ||
| 28 | { | ||
| 29 | char* e=buf+sprintf(buf,cvt_form_f,f)-1; | ||
| 30 | while(*e=='0') e--; if(*e=='.') e--; | ||
| 31 | return sref(buf,e-buf+1); | ||
| 32 | } | ||
| 33 | |||
| 34 | /////////////////////////////////////////////////////////// | ||
| 35 | |||
| 36 | int mstream::appc(char c) { return -1; } | ||
| 37 | int mstream::appi(int i) { return -1; } | ||
| 38 | int mstream::appf(double f) { return -1; } | ||
| 39 | int mstream::apps(const sref& s) { return -1; } | ||
| 40 | |||
| 41 | /////////////////////////////////////////////////////////// | ||
| 42 | |||
| 43 | int cvt_stream::appi(int i) { sref_t buf; return apps(itoa(buf,i)); } | ||
| 44 | int cvt_stream::appf(double f) { sref_t buf; return apps(ftoa(buf,f)); } | ||
| 45 | |||
| 46 | /////////////////////////////////////////////////////////// | ||
| 47 | |||
| 48 | int fp_stream::appc(char c) { return putc(c,fp)<0?-1:1; } | ||
| 49 | int fp_stream::apps(const sref& s) { return fwrite(s.data(),s.size(),1,fp); } | ||
| 50 | |||
| 51 | /////////////////////////////////////////////////////////// | ||
| 52 | |||
| 53 | int fd_stream::appc(char c) { return ::write(fd,&c,1); } | ||
| 54 | int fd_stream::apps(const sref& s) { return ::write(fd,s.data(),s.size()); } | ||
| 55 | |||
| 56 | /////////////////////////////////////////////////////////// | ||
| 57 | |||
| 58 | int pipe_stream::appc(char c) { return mwrite(&c,1); } | ||
| 59 | int pipe_stream::apps(const sref& s) { return mwrite(s.data(),s.size()); } | ||
| 60 | |||
| 61 | int pipe_stream::mwrite(const char* s,int n) | ||
| 62 | { | ||
| 63 | int old=n; | ||
| 64 | while(n>0&&!hup) { | ||
| 65 | pollfd pfd={fd,POLLOUT,0}; | ||
| 66 | if(::poll(&pfd,1,MSEC)<0) return hup=-1; | ||
| 67 | int m=::write(fd,s,n); | ||
| 68 | if(m<0) return hup=-1; | ||
| 69 | s+=m; n-=m; | ||
| 70 | } | ||
| 71 | return hup?-1:old; | ||
| 72 | } | ||
diff --git a/src/mt/mstream.h b/src/mt/mstream.h new file mode 100644 index 0000000..4f5aeaf --- /dev/null +++ b/src/mt/mstream.h | |||
| @@ -0,0 +1,103 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef MSTREAMH | ||
| 21 | #define MSTREAMH | ||
| 22 | |||
| 23 | #include <mt/stringref.h> | ||
| 24 | #include <unistd.h> | ||
| 25 | #include <stdio.h> | ||
| 26 | |||
| 27 | /////////////////////////////////////////////////////////// | ||
| 28 | |||
| 29 | const char cvt_form_i[]="%d"; | ||
| 30 | |||
| 31 | /////////////////////////////////////////////////////////// | ||
| 32 | |||
| 33 | inline sref itoa(sref_t& buf,int i) { return sref(buf,sprintf(buf,cvt_form_i,i)); } | ||
| 34 | sref ftoa(sref_t& buf,double f); | ||
| 35 | |||
| 36 | /////////////////////////////////////////////////////////// | ||
| 37 | |||
| 38 | struct mstream { | ||
| 39 | virtual int appc(char c); | ||
| 40 | virtual int appi(int i); | ||
| 41 | virtual int appf(double f); | ||
| 42 | virtual int apps(const sref& s); | ||
| 43 | |||
| 44 | mstream& put(char c) { return appc(c),*this; } | ||
| 45 | int write(const char* s,int n) { return apps(sref(s,n)); } | ||
| 46 | }; | ||
| 47 | |||
| 48 | inline mstream& operator<<(mstream& out,int i) { return out.appi(i),out; } | ||
| 49 | inline mstream& operator<<(mstream& out,long l) { return out.appi(l),out; } | ||
| 50 | inline mstream& operator<<(mstream& out,unsigned u) { return out.appi(u),out; } | ||
| 51 | inline mstream& operator<<(mstream& out,unsigned long ul) { return out.appi(ul),out; } | ||
| 52 | inline mstream& operator<<(mstream& out,double f) { return out.appf(f),out; } | ||
| 53 | |||
| 54 | inline mstream& operator<<(mstream& out,const sref& s) { return out.apps(s),out; } | ||
| 55 | inline mstream& operator<<(mstream& out,const char* s) { return out.apps(sref(s)),out; } | ||
| 56 | |||
| 57 | /////////////////////////////////////////////////////////// | ||
| 58 | |||
| 59 | struct cvt_stream : public mstream { | ||
| 60 | int appi(int i); | ||
| 61 | int appf(double f); | ||
| 62 | }; | ||
| 63 | |||
| 64 | /////////////////////////////////////////////////////////// | ||
| 65 | |||
| 66 | struct fp_stream : public cvt_stream { | ||
| 67 | FILE* fp; | ||
| 68 | |||
| 69 | int appc(char c); | ||
| 70 | int apps(const sref& s); | ||
| 71 | |||
| 72 | fp_stream(FILE* f) : fp(f) {} | ||
| 73 | |||
| 74 | int flush() { return fflush(fp); } | ||
| 75 | }; | ||
| 76 | |||
| 77 | /////////////////////////////////////////////////////////// | ||
| 78 | |||
| 79 | struct fd_stream : public cvt_stream { | ||
| 80 | int fd; | ||
| 81 | |||
| 82 | int appc(char c); | ||
| 83 | int apps(const sref& s); | ||
| 84 | |||
| 85 | fd_stream(int f) : fd(f) {} | ||
| 86 | }; | ||
| 87 | |||
| 88 | /////////////////////////////////////////////////////////// | ||
| 89 | |||
| 90 | struct pipe_stream : public cvt_stream { | ||
| 91 | int fd,hup; | ||
| 92 | |||
| 93 | int appc(char c); | ||
| 94 | int apps(const sref& s); | ||
| 95 | |||
| 96 | pipe_stream(int f) : fd(f),hup(0) {} | ||
| 97 | |||
| 98 | int mwrite(const char* s,int n); | ||
| 99 | }; | ||
| 100 | |||
| 101 | /////////////////////////////////////////////////////////// | ||
| 102 | |||
| 103 | #endif | ||
diff --git a/src/mt/mstring.cc b/src/mt/mstring.cc new file mode 100644 index 0000000..7be82e3 --- /dev/null +++ b/src/mt/mstring.cc | |||
| @@ -0,0 +1,139 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <mt/mstring.h> | ||
| 21 | #include <unistd.h> | ||
| 22 | #include <fcntl.h> | ||
| 23 | #include <sys/stat.h> | ||
| 24 | #include <stdarg.h> | ||
| 25 | |||
| 26 | uniheap<ms_mincaps> mstring::heap; | ||
| 27 | |||
| 28 | /////////////////////////////////////////////////////////////////// | ||
| 29 | |||
| 30 | mstring::mstring() : sref(heap.push(),0),caps(ms_mincaps) { | ||
| 31 | map[dim]=0; | ||
| 32 | } | ||
| 33 | mstring::mstring(int n) : sref(heap.push(),0),caps(ms_mincaps) { | ||
| 34 | if(caps<n) { while(caps<n) caps<<=1; heap.pop(map); map=(char*)malloc(caps); } | ||
| 35 | map[dim=0]=0; | ||
| 36 | } | ||
| 37 | mstring::mstring(int n,char c) : sref(heap.push(),0),caps(ms_mincaps) { | ||
| 38 | resize(n); | ||
| 39 | memset(map,c,dim); | ||
| 40 | } | ||
| 41 | mstring::mstring(const char* s) : sref(heap.push(),0),caps(ms_mincaps) { | ||
| 42 | resize(strlen(s)); | ||
| 43 | memcpy(map,s,dim); | ||
| 44 | } | ||
| 45 | mstring::mstring(const char* s,int n) : sref(heap.push(),0),caps(ms_mincaps) { | ||
| 46 | resize(n); | ||
| 47 | memcpy(map,s,dim); | ||
| 48 | } | ||
| 49 | mstring::mstring(const sref& s) : sref(heap.push(),0),caps(ms_mincaps) { | ||
| 50 | resize(s.size()); | ||
| 51 | memcpy(map,s.data(),dim); | ||
| 52 | } | ||
| 53 | mstring::mstring(const mstring& s) : sref(heap.push(),0),caps(ms_mincaps) { | ||
| 54 | resize(s.dim); | ||
| 55 | memcpy(map,s.map,dim); | ||
| 56 | } | ||
| 57 | mstring::~mstring() { | ||
| 58 | if(caps==ms_mincaps) heap.pop(map); | ||
| 59 | else free(map); | ||
| 60 | } | ||
| 61 | |||
| 62 | /////////////////////////////////////////////////////////////////// | ||
| 63 | |||
| 64 | void mstring::erase(int pos,int n) | ||
| 65 | { | ||
| 66 | if(pos<0) { pos+=dim; if(pos<0) pos=0; } | ||
| 67 | if(pos<dim) { | ||
| 68 | if(n<0) { n+=dim+1; if(n<0) n=0; } | ||
| 69 | if(n>=dim-pos) map[dim=pos]=0; | ||
| 70 | else { memmove(map+pos,map+pos+n,dim-pos-n); map[dim-=n]=0; } | ||
| 71 | } | ||
| 72 | } | ||
| 73 | |||
| 74 | void mstring::reserve(int n) { | ||
| 75 | if(caps<=n) { | ||
| 76 | if(caps==ms_mincaps) { | ||
| 77 | while(caps<=n) caps<<=1; | ||
| 78 | char* p=(char*)memcpy(malloc(caps),map,dim); | ||
| 79 | heap.pop(map); | ||
| 80 | map=p; | ||
| 81 | } | ||
| 82 | else { | ||
| 83 | while(caps<=n) caps<<=1; | ||
| 84 | map=(char*)realloc(map,caps); | ||
| 85 | } | ||
| 86 | } | ||
| 87 | } | ||
| 88 | |||
| 89 | /////////////////////////////////////////////////////////////////// | ||
| 90 | |||
| 91 | int mstring::load(const mstring& path) | ||
| 92 | { | ||
| 93 | int fd=open(path.c_str(),O_RDONLY); | ||
| 94 | if(fd<0) return -1; | ||
| 95 | struct stat fs; fstat(fd,&fs); | ||
| 96 | resize(fs.st_size); | ||
| 97 | read(fd,map,dim); | ||
| 98 | close(fd); | ||
| 99 | return dim; | ||
| 100 | } | ||
| 101 | |||
| 102 | /////////////////////////////////////////////////////////////////// | ||
| 103 | |||
| 104 | mstring& mstring::convert(const char* format,...) | ||
| 105 | { | ||
| 106 | sref_t buf; | ||
| 107 | va_list ap; | ||
| 108 | va_start(ap,format); | ||
| 109 | resize(vsprintf(buf,format,ap)); | ||
| 110 | memcpy(map,buf,dim); | ||
| 111 | va_end(ap); | ||
| 112 | return *this; | ||
| 113 | } | ||
| 114 | |||
| 115 | /////////////////////////////////////////////////////////////////// | ||
| 116 | |||
| 117 | int swrite::appc(char c) { return mp->put(c),1; } | ||
| 118 | int swrite::apps(const sref& s) { return mp->put(s),s.size(); } | ||
| 119 | |||
| 120 | /////////////////////////////////////////////////////////////////// | ||
| 121 | |||
| 122 | int mswrite::appc(char c) { return m.put(c),1; } | ||
| 123 | int mswrite::apps(const sref& s) { return m.put(s),s.size(); } | ||
| 124 | |||
| 125 | /////////////////////////////////////////////////////////////////// | ||
| 126 | |||
| 127 | int merror_t::appc(char c) { return desc.put(c),1; } | ||
| 128 | int merror_t::apps(const sref& s) { return desc.put(s),s.size(); } | ||
| 129 | |||
| 130 | /////////////////////////////////////////////////////////////////// | ||
| 131 | |||
| 132 | void getline(mstring& m,FILE* fp,char end) | ||
| 133 | { | ||
| 134 | m.clear(); | ||
| 135 | int c=getc(fp); | ||
| 136 | while(c!=end&&c!=EOF) { m.append(1,c); c=getc(fp); } | ||
| 137 | } | ||
| 138 | |||
| 139 | |||
diff --git a/src/mt/mstring.h b/src/mt/mstring.h new file mode 100644 index 0000000..be07c1a --- /dev/null +++ b/src/mt/mstring.h | |||
| @@ -0,0 +1,222 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef MSTRINGH | ||
| 21 | #define MSTRINGH | ||
| 22 | |||
| 23 | #include <mt/mstream.h> | ||
| 24 | #include <mt/uniheap.h> | ||
| 25 | |||
| 26 | const int ms_mincaps=32; | ||
| 27 | |||
| 28 | class mstring : public sref { | ||
| 29 | public: | ||
| 30 | mstring(); | ||
| 31 | explicit mstring(int n); | ||
| 32 | mstring(int n,char c); | ||
| 33 | mstring(const char* s); | ||
| 34 | mstring(const char* s,int n); | ||
| 35 | mstring(const sref& s); | ||
| 36 | mstring(const mstring& s); | ||
| 37 | ~mstring(); | ||
| 38 | |||
| 39 | //////////////////////////////////////////////////////////////// | ||
| 40 | |||
| 41 | const char* c_str() const { return map; } | ||
| 42 | int capacity() const { return caps; } | ||
| 43 | |||
| 44 | void clear() { map[dim=0]=0; } | ||
| 45 | |||
| 46 | int own(const sref& s) const { int p=s.data()-map; return p>=0&&p<caps; } | ||
| 47 | |||
| 48 | //////////////////////////////////////////////////////////////// | ||
| 49 | |||
| 50 | void assign(int sdim,char c) { | ||
| 51 | resize(sdim); | ||
| 52 | memset(map,c,sdim); | ||
| 53 | } | ||
| 54 | void assign(const sref& s) { | ||
| 55 | reserve(s.size()); | ||
| 56 | memmove(map,s.data(),s.size()); | ||
| 57 | map[dim=s.size()]=0; | ||
| 58 | } | ||
| 59 | |||
| 60 | void put(char c) { if(dim+1>=caps) reserve(dim+1); map[dim++]=c; map[dim]=0; } | ||
| 61 | void put(const sref& s) { | ||
| 62 | reserve(dim+s.size()); | ||
| 63 | memcpy(map+dim,s.data(),s.size()); | ||
| 64 | map[dim+=s.size()]=0; | ||
| 65 | } | ||
| 66 | |||
| 67 | mstring& append(int sdim,char c) { | ||
| 68 | reserve(dim+sdim); | ||
| 69 | memset(map+dim,c,sdim); | ||
| 70 | map[dim+=sdim]=0; | ||
| 71 | return *this; | ||
| 72 | } | ||
| 73 | |||
| 74 | mstring& append(const sref& s) { | ||
| 75 | reserve(dim+s.size()); | ||
| 76 | memmove(map+dim,s.data(),s.size()); | ||
| 77 | map[dim+=s.size()]=0; | ||
| 78 | return *this; | ||
| 79 | } | ||
| 80 | |||
| 81 | int insert(int pos,int n) { | ||
| 82 | if(pos<0||pos>dim) return 0; | ||
| 83 | if(n) { reserve(dim+n); memmove(map+pos+n,map+pos,dim-pos); map[dim+=n]=0; } | ||
| 84 | return 1; | ||
| 85 | } | ||
| 86 | |||
| 87 | mstring& insert(int pos,int sdim,char c) { | ||
| 88 | if(insert(pos,sdim)) memset(map+pos,c,sdim); | ||
| 89 | return *this; | ||
| 90 | } | ||
| 91 | mstring& insert(int pos,const sref& s) { | ||
| 92 | if(insert(pos,s.size())) memcpy(map+pos,s.data(),s.size()); | ||
| 93 | return *this; | ||
| 94 | } | ||
| 95 | |||
| 96 | mstring& replace(int pos,int n,int sdim,char c) { | ||
| 97 | if(insert(pos+n,sdim-n)) memset(map+pos,c,sdim); | ||
| 98 | return *this; | ||
| 99 | } | ||
| 100 | mstring& replace(int pos,int n,const sref& s) { | ||
| 101 | if(insert(pos+n,s.size()-n)) memcpy(map+pos,s.data(),s.size()); | ||
| 102 | return *this; | ||
| 103 | } | ||
| 104 | |||
| 105 | //////////////////////////////////////////////////////////////// | ||
| 106 | |||
| 107 | void erase(int pos,int n=-1); | ||
| 108 | void reserve(int n); | ||
| 109 | void resize(int n) { reserve(n); map[dim=n]=0; } | ||
| 110 | |||
| 111 | //////////////////////////////////////////////////////////////// | ||
| 112 | |||
| 113 | mstring& operator=(const mstring& s) { assign(s); return *this; } | ||
| 114 | mstring& operator=(const sref& s) { assign(s); return *this; } | ||
| 115 | mstring& operator=(char c) { assign(1,c); return *this; } | ||
| 116 | |||
| 117 | mstring& operator+=(const sref& s) { return append(s); } | ||
| 118 | mstring& operator+=(char c) { return append(1,c); } | ||
| 119 | |||
| 120 | //////////////////////////////////////////////////////////////// | ||
| 121 | |||
| 122 | int load(const mstring& path); | ||
| 123 | |||
| 124 | //////////////////////////////////////////////////////////////// | ||
| 125 | |||
| 126 | // NOTE: if you apply convert to %s or any unbound data, | ||
| 127 | // you're in trouble. Internal buffer is sref_t. | ||
| 128 | |||
| 129 | mstring& convert(const char* format,...); | ||
| 130 | |||
| 131 | protected: | ||
| 132 | static uniheap<ms_mincaps> heap; | ||
| 133 | private: | ||
| 134 | int caps; | ||
| 135 | }; | ||
| 136 | |||
| 137 | /////////////////////////////////////////////////////////////////// | ||
| 138 | |||
| 139 | inline void swap(mstring& a,mstring& b) | ||
| 140 | { | ||
| 141 | char buf[sizeof(mstring)]; | ||
| 142 | memcpy(buf,&a,sizeof(mstring)); | ||
| 143 | memcpy(&a,&b,sizeof(mstring)); | ||
| 144 | memcpy(&b,buf,sizeof(mstring)); | ||
| 145 | } | ||
| 146 | |||
| 147 | /////////////////////////////////////////////////////////////////// | ||
| 148 | |||
| 149 | inline mstring operator+(const sref& a,const sref& b) | ||
| 150 | { | ||
| 151 | return mstring(a).append(b); | ||
| 152 | } | ||
| 153 | inline mstring operator+(const sref& a,char b) { | ||
| 154 | return mstring(a).append(1,b); | ||
| 155 | } | ||
| 156 | inline mstring operator+(char a,const sref& b) { | ||
| 157 | return mstring(1,a).append(b); | ||
| 158 | } | ||
| 159 | |||
| 160 | /////////////////////////////////////////////////////////////////// | ||
| 161 | |||
| 162 | inline mstring btoa(int b) { return mstring(1,b?'1':'0'); } | ||
| 163 | inline mstring itoa(int i) { sref_t buf; return mstring(itoa(buf,i)); } | ||
| 164 | inline mstring ftoa(double f) { sref_t buf; return mstring(ftoa(buf,f)); } | ||
| 165 | |||
| 166 | /////////////////////////////////////////////////////////////////// | ||
| 167 | |||
| 168 | const mstring ms_empty; | ||
| 169 | |||
| 170 | /////////////////////////////////////////////////////////////////// | ||
| 171 | |||
| 172 | struct swrite : public cvt_stream { | ||
| 173 | mstring* mp; | ||
| 174 | |||
| 175 | int appc(char c); | ||
| 176 | int apps(const sref& s); | ||
| 177 | |||
| 178 | swrite() : mp(0) {} | ||
| 179 | swrite(mstring& m) : mp(&m) { mp->clear(); } | ||
| 180 | |||
| 181 | swrite& operator()(mstring& m) { (mp=&m)->clear(); return *this; } | ||
| 182 | swrite& hold(mstring& m) { mp=&m; return *this; } | ||
| 183 | }; | ||
| 184 | |||
| 185 | /////////////////////////////////////////////////////////////////// | ||
| 186 | |||
| 187 | class mswrite : public cvt_stream { | ||
| 188 | public: | ||
| 189 | mstring m; | ||
| 190 | |||
| 191 | int appc(char c); | ||
| 192 | int apps(const sref& s); | ||
| 193 | |||
| 194 | const mstring& str() const { return m; } // compatibility | ||
| 195 | void clear() { m.clear(); } | ||
| 196 | |||
| 197 | mswrite() : m() {} | ||
| 198 | private: | ||
| 199 | mswrite(mstring&) {} // make no mistakes due to similarity with swrite | ||
| 200 | }; | ||
| 201 | |||
| 202 | /////////////////////////////////////////////////////////////////// | ||
| 203 | |||
| 204 | struct merror_t : public cvt_stream { | ||
| 205 | int num; | ||
| 206 | mstring desc; | ||
| 207 | |||
| 208 | int appc(char c); | ||
| 209 | int apps(const sref& s); | ||
| 210 | |||
| 211 | merror_t(int n) : num(n),desc() {} | ||
| 212 | }; | ||
| 213 | |||
| 214 | #define THROW(x) { merror_t merr(0); merr<<x; throw merr; } | ||
| 215 | |||
| 216 | /////////////////////////////////////////////////////////////////// | ||
| 217 | |||
| 218 | void getline(mstring& m,FILE* fp,char end='\n'); | ||
| 219 | |||
| 220 | /////////////////////////////////////////////////////////////////// | ||
| 221 | |||
| 222 | #endif | ||
diff --git a/src/mt/mvec.h b/src/mt/mvec.h new file mode 100644 index 0000000..9f31c1e --- /dev/null +++ b/src/mt/mvec.h | |||
| @@ -0,0 +1,149 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef MVECH | ||
| 21 | #define MVECH | ||
| 22 | |||
| 23 | #include <malloc.h> | ||
| 24 | #include <string.h> | ||
| 25 | #include <new> | ||
| 26 | |||
| 27 | const int mv_mincaps=16; | ||
| 28 | |||
| 29 | template <class T> class mrvec { | ||
| 30 | public: | ||
| 31 | typedef T* iterator; | ||
| 32 | typedef const T* const_iterator; | ||
| 33 | |||
| 34 | mrvec(): | ||
| 35 | map((T*)malloc(mv_mincaps*sizeof(T))),dim(0),caps(mv_mincaps) {} | ||
| 36 | mrvec(int n): | ||
| 37 | map((T*)malloc(mv_mincaps*sizeof(T))),dim(0),caps(mv_mincaps) { resize(n); } | ||
| 38 | ~mrvec() { free(map); } | ||
| 39 | |||
| 40 | int size() const { return dim; } | ||
| 41 | int capacity() const { return caps; } | ||
| 42 | |||
| 43 | bool empty() const { return dim==0; } | ||
| 44 | bool nempty() const { return dim!=0; } | ||
| 45 | |||
| 46 | T& at(int pos) { return map[pos]; } | ||
| 47 | const T& at(int pos) const { return map[pos]; } | ||
| 48 | |||
| 49 | T& operator[](int pos) { return map[pos]; } | ||
| 50 | const T& operator[](int pos) const { return map[pos]; } | ||
| 51 | |||
| 52 | iterator begin() { return map; } | ||
| 53 | const_iterator begin() const { return map; } | ||
| 54 | |||
| 55 | iterator end() { return map+dim; } | ||
| 56 | const_iterator end() const { return map+dim; } | ||
| 57 | |||
| 58 | T& front() { return map[0]; } | ||
| 59 | const T& front() const { return map[0]; } | ||
| 60 | |||
| 61 | T& back() { return map[dim?dim-1:0]; } | ||
| 62 | const T& back() const { return map[dim?dim-1:0]; } | ||
| 63 | |||
| 64 | //////////////////////////////////////////////////////////////// | ||
| 65 | |||
| 66 | void clear() { dim=0; } | ||
| 67 | |||
| 68 | iterator insert(iterator it,const T& s) { | ||
| 69 | int pos=it-map; ins(pos,1); return &(map[pos]=s); | ||
| 70 | } | ||
| 71 | void insert(iterator it,int n,const T& s) { | ||
| 72 | int pos=it-map; ins(pos,n); while(n--) map[pos++]=s; | ||
| 73 | } | ||
| 74 | void insert(iterator it,const_iterator p,const_iterator e) { | ||
| 75 | int pos=it-map; ins(pos,e-p); while(p<e) map[pos++]=*p++; | ||
| 76 | } | ||
| 77 | iterator erase(iterator it) { | ||
| 78 | int pos=it-map; ins(pos+1,-1); return map+pos; | ||
| 79 | } | ||
| 80 | |||
| 81 | void push_back(const T& s) { reserve(dim+1); map[dim++]=s; } | ||
| 82 | void pop_back(const T& s) { if(dim) --dim; } | ||
| 83 | |||
| 84 | //////////////////////////////////////////////////////////////// | ||
| 85 | |||
| 86 | void reserve(int n) { | ||
| 87 | if(caps<n) { while(caps<n) caps<<=1; map=(T*)realloc(map,caps*sizeof(T)); } | ||
| 88 | } | ||
| 89 | void resize(int n) { reserve(n); dim=n; } | ||
| 90 | |||
| 91 | //////////////////////////////////////////////////////////////// | ||
| 92 | |||
| 93 | protected: | ||
| 94 | mrvec(const mrvec&) {} | ||
| 95 | void operator=(const mrvec&) {} | ||
| 96 | |||
| 97 | void ins(int pos,int n) { | ||
| 98 | if(n) { reserve(dim+n); memmove(map+pos+n,map+pos,(dim-pos)*sizeof(T)); dim+=n; } | ||
| 99 | } | ||
| 100 | |||
| 101 | T* map; | ||
| 102 | int dim,caps; | ||
| 103 | }; | ||
| 104 | |||
| 105 | template <class T> class msvec : public mrvec<T> { | ||
| 106 | public: | ||
| 107 | using mrvec<T>::map; | ||
| 108 | using mrvec<T>::dim; | ||
| 109 | typedef typename mrvec<T>::iterator iterator; | ||
| 110 | typedef typename mrvec<T>::const_iterator const_iterator; | ||
| 111 | |||
| 112 | msvec() : mrvec<T>() {} | ||
| 113 | msvec(int n) : mrvec<T>(n) { for(int i=0;i<dim;i++) new (map+i) T(); } | ||
| 114 | ~msvec() { while(dim) map[--dim].~T(); } | ||
| 115 | |||
| 116 | //////////////////////////////////////////////////////////////// | ||
| 117 | |||
| 118 | void clear() { while(dim) map[--dim].~T(); } | ||
| 119 | |||
| 120 | iterator insert(iterator it,const T& s) { | ||
| 121 | int pos=it-map; mrvec<T>::ins(pos,1); return new(map+pos) T(s); | ||
| 122 | } | ||
| 123 | void insert(iterator it,int n,const T& s) { | ||
| 124 | int pos=it-map; mrvec<T>::ins(pos,n); while(n--) new(map+pos++) T(s); | ||
| 125 | } | ||
| 126 | void insert(iterator it,const_iterator p,const_iterator e) { | ||
| 127 | int pos=it-map; mrvec<T>::ins(pos,e-p); while(p<e) new(map+pos++) T(*p++); | ||
| 128 | } | ||
| 129 | iterator erase(iterator it) { | ||
| 130 | it->~T(); int pos=it-map; mrvec<T>::ins(pos+1,-1); return map+pos; | ||
| 131 | } | ||
| 132 | |||
| 133 | void push_back(const T& s) { reserve(dim+1); new(map+dim++) T(s); } | ||
| 134 | void pop_back(const T& s) { if(dim) map[--dim].~T(); } | ||
| 135 | |||
| 136 | //////////////////////////////////////////////////////////////// | ||
| 137 | |||
| 138 | void resize(int n) { | ||
| 139 | while(dim>n) map[--dim].~T(); | ||
| 140 | mrvec<T>::reserve(n); | ||
| 141 | while(dim<n) new (map+dim++) T(); | ||
| 142 | } | ||
| 143 | |||
| 144 | protected: | ||
| 145 | msvec(const msvec&) {} | ||
| 146 | void operator=(const msvec&) {} | ||
| 147 | }; | ||
| 148 | |||
| 149 | #endif | ||
diff --git a/src/mt/qran.h b/src/mt/qran.h new file mode 100644 index 0000000..10f9a6f --- /dev/null +++ b/src/mt/qran.h | |||
| @@ -0,0 +1,34 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef QRANH | ||
| 21 | #define QRANH | ||
| 22 | |||
| 23 | #include <math.h> | ||
| 24 | |||
| 25 | inline double QUniform(unsigned long& q) { | ||
| 26 | q=1664525L*q+1013904223L; | ||
| 27 | unsigned long long s=q;s<<=20;s|=(1023ULL<<52);return *(double*)&s-1; | ||
| 28 | } | ||
| 29 | inline int QRanBit(unsigned long& q) { | ||
| 30 | if(q&131072U) { q=((q^19U)<<1)|1U; return 1; } | ||
| 31 | else { q<<=1; return 0; } | ||
| 32 | } | ||
| 33 | |||
| 34 | #endif | ||
diff --git a/src/mt/random.cc b/src/mt/random.cc new file mode 100644 index 0000000..87a4c8c --- /dev/null +++ b/src/mt/random.cc | |||
| @@ -0,0 +1,95 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <mt/random.h> | ||
| 21 | #include <mt/mlock.h> | ||
| 22 | #include <time.h> | ||
| 23 | |||
| 24 | ////////////////////////////////////////////////////// | ||
| 25 | // | ||
| 26 | // This file implements some routines from NumRec | ||
| 27 | // | ||
| 28 | |||
| 29 | const int NTAB=32; // NOTE: change in header if changing this | ||
| 30 | |||
| 31 | const int IA=16807; | ||
| 32 | const int IM=2147483647; | ||
| 33 | const float AM=1/float(IM); | ||
| 34 | const int IQ=127773; | ||
| 35 | const int IR=2836; | ||
| 36 | const int NDIV=1+(IM-1)/NTAB; | ||
| 37 | const float EPS=1.2e-7; | ||
| 38 | const float RNMX=1-EPS; | ||
| 39 | |||
| 40 | static int idum,iy,iv[32],flag; | ||
| 41 | static float extra; | ||
| 42 | static int inited; | ||
| 43 | static mutex_t mutex; | ||
| 44 | |||
| 45 | unsigned long RandomInit(unsigned long seed) | ||
| 46 | { | ||
| 47 | inited=1; | ||
| 48 | idum=seed?seed:1; | ||
| 49 | for(int j=NTAB+7;j>=0;j--) { | ||
| 50 | int k=idum/IQ; | ||
| 51 | idum=IA*(idum-k*IQ)-IR*k; | ||
| 52 | if(idum<0) idum+=IM; | ||
| 53 | if(j<NTAB) iv[j]=idum; | ||
| 54 | } | ||
| 55 | iy=iv[0]; | ||
| 56 | return seed; | ||
| 57 | } | ||
| 58 | |||
| 59 | float Uniform() | ||
| 60 | { | ||
| 61 | MLOCK(mutex); | ||
| 62 | if(!inited) RandomInit(time(0)); | ||
| 63 | int k=idum/IQ; | ||
| 64 | idum=IA*(idum-k*IQ)-IR*k; | ||
| 65 | if(idum<0) idum+=IM; | ||
| 66 | int j=iy/NDIV; | ||
| 67 | iy=iv[j]; | ||
| 68 | iv[j]=idum; | ||
| 69 | float temp=AM*iy; if(temp>RNMX) temp=RNMX; | ||
| 70 | return temp; | ||
| 71 | } | ||
| 72 | |||
| 73 | float Exponential() | ||
| 74 | { | ||
| 75 | return -log(Uniform()); | ||
| 76 | } | ||
| 77 | |||
| 78 | float Gaussian() | ||
| 79 | { | ||
| 80 | MLOCK(mutex); | ||
| 81 | float v1,v2,rsq; | ||
| 82 | if(flag) { | ||
| 83 | flag=0; | ||
| 84 | return extra; | ||
| 85 | } else { | ||
| 86 | do { | ||
| 87 | v1=2*Uniform()-1; | ||
| 88 | v2=2*Uniform()-1; | ||
| 89 | rsq=v1*v1+v2*v2; | ||
| 90 | } while(rsq>=1||rsq<=0); | ||
| 91 | float fac=sqrt(-2*log(rsq)/rsq); | ||
| 92 | flag=1; extra=v1*fac; | ||
| 93 | return v2*fac; | ||
| 94 | } | ||
| 95 | } | ||
diff --git a/src/mt/random.h b/src/mt/random.h new file mode 100644 index 0000000..196beae --- /dev/null +++ b/src/mt/random.h | |||
| @@ -0,0 +1,39 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef RANDOMH | ||
| 21 | #define RANDOMH | ||
| 22 | |||
| 23 | #include <mt/qran.h> | ||
| 24 | |||
| 25 | /////////////////////////////////////////////////////////////////// | ||
| 26 | // | ||
| 27 | // Uniform distribution ]x0..x1[ | ||
| 28 | // | ||
| 29 | // Granularity approx 1.2e-7, ie more than 1e6 different values | ||
| 30 | // Perodicity approx 1e8 | ||
| 31 | // | ||
| 32 | |||
| 33 | unsigned long RandomInit(unsigned long seed); | ||
| 34 | |||
| 35 | float Uniform(); | ||
| 36 | float Exponential(); | ||
| 37 | float Gaussian(); | ||
| 38 | |||
| 39 | #endif | ||
diff --git a/src/mt/rfind_not_of.f b/src/mt/rfind_not_of.f new file mode 100644 index 0000000..04a42d6 --- /dev/null +++ b/src/mt/rfind_not_of.f | |||
| @@ -0,0 +1,80 @@ | |||
| 1 | ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc | ||
| 2 | c | ||
| 3 | c HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | c | ||
| 5 | c This program is free software; you can redistribute it and/or modify | ||
| 6 | c it under the terms of the GNU General Public License as published by | ||
| 7 | c the Free Software Foundation; either version 2 of the License, or | ||
| 8 | c (at your option) any later version. | ||
| 9 | c | ||
| 10 | c This program is distributed in the hope that it will be useful, | ||
| 11 | c but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | c GNU General Public License for more details. | ||
| 14 | c | ||
| 15 | c You should have received a copy of the GNU General Public License | ||
| 16 | c along with this program; if not, write to the Free Software | ||
| 17 | c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | c | ||
| 19 | |||
| 20 | integer function rfind_not_of(s,n,c) | ||
| 21 | byte s(0:1),c(0:1) | ||
| 22 | integer i,m,n | ||
| 23 | m=mod(n,16) | ||
| 24 | do 10 i=n-16,m,-16 | ||
| 25 | if(c(s(i+15)).eq.0)go to 115 | ||
| 26 | if(c(s(i+14)).eq.0)go to 114 | ||
| 27 | if(c(s(i+13)).eq.0)go to 113 | ||
| 28 | if(c(s(i+12)).eq.0)go to 112 | ||
| 29 | if(c(s(i+11)).eq.0)go to 111 | ||
| 30 | if(c(s(i+10)).eq.0)go to 110 | ||
| 31 | if(c(s(i+9)).eq.0)go to 109 | ||
| 32 | if(c(s(i+8)).eq.0)go to 108 | ||
| 33 | if(c(s(i+7)).eq.0)go to 107 | ||
| 34 | if(c(s(i+6)).eq.0)go to 106 | ||
| 35 | if(c(s(i+5)).eq.0)go to 105 | ||
| 36 | if(c(s(i+4)).eq.0)go to 104 | ||
| 37 | if(c(s(i+3)).eq.0)go to 103 | ||
| 38 | if(c(s(i+2)).eq.0)go to 102 | ||
| 39 | if(c(s(i+1)).eq.0)go to 101 | ||
| 40 | if(c(s(i)).eq.0)go to 100 | ||
| 41 | 10 continue | ||
| 42 | do 20 i=m-1,0,-1 | ||
| 43 | if(c(s(i)).eq.0)go to 100 | ||
| 44 | 20 continue | ||
| 45 | rfind_not_of=-1 | ||
| 46 | return | ||
| 47 | 100 rfind_not_of=i | ||
| 48 | return | ||
| 49 | 101 rfind_not_of=i+1 | ||
| 50 | return | ||
| 51 | 102 rfind_not_of=i+2 | ||
| 52 | return | ||
| 53 | 103 rfind_not_of=i+3 | ||
| 54 | return | ||
| 55 | 104 rfind_not_of=i+4 | ||
| 56 | return | ||
| 57 | 105 rfind_not_of=i+5 | ||
| 58 | return | ||
| 59 | 106 rfind_not_of=i+6 | ||
| 60 | return | ||
| 61 | 107 rfind_not_of=i+7 | ||
| 62 | return | ||
| 63 | 108 rfind_not_of=i+8 | ||
| 64 | return | ||
| 65 | 109 rfind_not_of=i+9 | ||
| 66 | return | ||
| 67 | 110 rfind_not_of=i+10 | ||
| 68 | return | ||
| 69 | 111 rfind_not_of=i+11 | ||
| 70 | return | ||
| 71 | 112 rfind_not_of=i+12 | ||
| 72 | return | ||
| 73 | 113 rfind_not_of=i+13 | ||
| 74 | return | ||
| 75 | 114 rfind_not_of=i+14 | ||
| 76 | return | ||
| 77 | 115 rfind_not_of=i+15 | ||
| 78 | return | ||
| 79 | end | ||
| 80 | |||
diff --git a/src/mt/rfind_of.f b/src/mt/rfind_of.f new file mode 100644 index 0000000..5fa0931 --- /dev/null +++ b/src/mt/rfind_of.f | |||
| @@ -0,0 +1,80 @@ | |||
| 1 | ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc | ||
| 2 | c | ||
| 3 | c HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | c | ||
| 5 | c This program is free software; you can redistribute it and/or modify | ||
| 6 | c it under the terms of the GNU General Public License as published by | ||
| 7 | c the Free Software Foundation; either version 2 of the License, or | ||
| 8 | c (at your option) any later version. | ||
| 9 | c | ||
| 10 | c This program is distributed in the hope that it will be useful, | ||
| 11 | c but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | c GNU General Public License for more details. | ||
| 14 | c | ||
| 15 | c You should have received a copy of the GNU General Public License | ||
| 16 | c along with this program; if not, write to the Free Software | ||
| 17 | c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | c | ||
| 19 | |||
| 20 | integer function rfind_of(s,n,c) | ||
| 21 | byte s(0:1),c(0:1) | ||
| 22 | integer i,m,n | ||
| 23 | m=mod(n,16) | ||
| 24 | do 10 i=n-16,m,-16 | ||
| 25 | if(c(s(i+15)).ne.0)go to 115 | ||
| 26 | if(c(s(i+14)).ne.0)go to 114 | ||
| 27 | if(c(s(i+13)).ne.0)go to 113 | ||
| 28 | if(c(s(i+12)).ne.0)go to 112 | ||
| 29 | if(c(s(i+11)).ne.0)go to 111 | ||
| 30 | if(c(s(i+10)).ne.0)go to 110 | ||
| 31 | if(c(s(i+9)).ne.0)go to 109 | ||
| 32 | if(c(s(i+8)).ne.0)go to 108 | ||
| 33 | if(c(s(i+7)).ne.0)go to 107 | ||
| 34 | if(c(s(i+6)).ne.0)go to 106 | ||
| 35 | if(c(s(i+5)).ne.0)go to 105 | ||
| 36 | if(c(s(i+4)).ne.0)go to 104 | ||
| 37 | if(c(s(i+3)).ne.0)go to 103 | ||
| 38 | if(c(s(i+2)).ne.0)go to 102 | ||
| 39 | if(c(s(i+1)).ne.0)go to 101 | ||
| 40 | if(c(s(i)).ne.0)go to 100 | ||
| 41 | 10 continue | ||
| 42 | do 20 i=m-1,0,-1 | ||
| 43 | if(c(s(i)).ne.0)go to 100 | ||
| 44 | 20 continue | ||
| 45 | rfind_of=-1 | ||
| 46 | return | ||
| 47 | 100 rfind_of=i | ||
| 48 | return | ||
| 49 | 101 rfind_of=i+1 | ||
| 50 | return | ||
| 51 | 102 rfind_of=i+2 | ||
| 52 | return | ||
| 53 | 103 rfind_of=i+3 | ||
| 54 | return | ||
| 55 | 104 rfind_of=i+4 | ||
| 56 | return | ||
| 57 | 105 rfind_of=i+5 | ||
| 58 | return | ||
| 59 | 106 rfind_of=i+6 | ||
| 60 | return | ||
| 61 | 107 rfind_of=i+7 | ||
| 62 | return | ||
| 63 | 108 rfind_of=i+8 | ||
| 64 | return | ||
| 65 | 109 rfind_of=i+9 | ||
| 66 | return | ||
| 67 | 110 rfind_of=i+10 | ||
| 68 | return | ||
| 69 | 111 rfind_of=i+11 | ||
| 70 | return | ||
| 71 | 112 rfind_of=i+12 | ||
| 72 | return | ||
| 73 | 113 rfind_of=i+13 | ||
| 74 | return | ||
| 75 | 114 rfind_of=i+14 | ||
| 76 | return | ||
| 77 | 115 rfind_of=i+15 | ||
| 78 | return | ||
| 79 | end | ||
| 80 | |||
diff --git a/src/mt/scomptab.f b/src/mt/scomptab.f new file mode 100644 index 0000000..4a8a286 --- /dev/null +++ b/src/mt/scomptab.f | |||
| @@ -0,0 +1,44 @@ | |||
| 1 | ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc | ||
| 2 | c | ||
| 3 | c HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | c | ||
| 5 | c This program is free software; you can redistribute it and/or modify | ||
| 6 | c it under the terms of the GNU General Public License as published by | ||
| 7 | c the Free Software Foundation; either version 2 of the License, or | ||
| 8 | c (at your option) any later version. | ||
| 9 | c | ||
| 10 | c This program is distributed in the hope that it will be useful, | ||
| 11 | c but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | c GNU General Public License for more details. | ||
| 14 | c | ||
| 15 | c You should have received a copy of the GNU General Public License | ||
| 16 | c along with this program; if not, write to the Free Software | ||
| 17 | c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | c | ||
| 19 | |||
| 20 | integer function scomptab(s,c,n,tab) | ||
| 21 | byte s(0:1),c(0:1),tab(0:1) | ||
| 22 | integer i,m,n | ||
| 23 | m=mod(n,4) | ||
| 24 | do 10 i=0,m-1 | ||
| 25 | if(tab(s(i)).ne.tab(c(i)))go to 100 | ||
| 26 | 10 continue | ||
| 27 | do 20 i=m,n-1,4 | ||
| 28 | if(tab(s(i)).ne.tab(c(i)))go to 100 | ||
| 29 | if(tab(s(i+1)).ne.tab(c(i+1)))go to 101 | ||
| 30 | if(tab(s(i+2)).ne.tab(c(i+2)))go to 102 | ||
| 31 | if(tab(s(i+3)).ne.tab(c(i+3)))go to 103 | ||
| 32 | 20 continue | ||
| 33 | scomptab=0 | ||
| 34 | return | ||
| 35 | 100 scomptab=tab(s(i))-tab(c(i)) | ||
| 36 | return | ||
| 37 | 101 scomptab=tab(s(i+1))-tab(c(i+1)) | ||
| 38 | return | ||
| 39 | 102 scomptab=tab(s(i+2))-tab(c(i+2)) | ||
| 40 | return | ||
| 41 | 103 scomptab=tab(s(i+3))-tab(c(i+3)) | ||
| 42 | return | ||
| 43 | end | ||
| 44 | |||
diff --git a/src/mt/sconvert.f b/src/mt/sconvert.f new file mode 100644 index 0000000..e887610 --- /dev/null +++ b/src/mt/sconvert.f | |||
| @@ -0,0 +1,35 @@ | |||
| 1 | ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc | ||
| 2 | c | ||
| 3 | c HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | c | ||
| 5 | c This program is free software; you can redistribute it and/or modify | ||
| 6 | c it under the terms of the GNU General Public License as published by | ||
| 7 | c the Free Software Foundation; either version 2 of the License, or | ||
| 8 | c (at your option) any later version. | ||
| 9 | c | ||
| 10 | c This program is distributed in the hope that it will be useful, | ||
| 11 | c but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | c GNU General Public License for more details. | ||
| 14 | c | ||
| 15 | c You should have received a copy of the GNU General Public License | ||
| 16 | c along with this program; if not, write to the Free Software | ||
| 17 | c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | c | ||
| 19 | |||
| 20 | subroutine sconvert(s,sn,tab) | ||
| 21 | byte s(0:1),tab(0:1) | ||
| 22 | integer i,m,sn | ||
| 23 | m=mod(sn,4) | ||
| 24 | do 10 i=0,m-1 | ||
| 25 | s(i)=tab(s(i)) | ||
| 26 | 10 continue | ||
| 27 | do 20 i=m,sn-1,4 | ||
| 28 | s(i)=tab(s(i)) | ||
| 29 | s(i+1)=tab(s(i+1)) | ||
| 30 | s(i+2)=tab(s(i+2)) | ||
| 31 | s(i+3)=tab(s(i+3)) | ||
| 32 | 20 continue | ||
| 33 | return | ||
| 34 | end | ||
| 35 | |||
diff --git a/src/mt/sfind.f b/src/mt/sfind.f new file mode 100644 index 0000000..2cc2954 --- /dev/null +++ b/src/mt/sfind.f | |||
| @@ -0,0 +1,40 @@ | |||
| 1 | ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc | ||
| 2 | c | ||
| 3 | c HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | c | ||
| 5 | c This program is free software; you can redistribute it and/or modify | ||
| 6 | c it under the terms of the GNU General Public License as published by | ||
| 7 | c the Free Software Foundation; either version 2 of the License, or | ||
| 8 | c (at your option) any later version. | ||
| 9 | c | ||
| 10 | c This program is distributed in the hope that it will be useful, | ||
| 11 | c but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | c GNU General Public License for more details. | ||
| 14 | c | ||
| 15 | c You should have received a copy of the GNU General Public License | ||
| 16 | c along with this program; if not, write to the Free Software | ||
| 17 | c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | c | ||
| 19 | |||
| 20 | integer function sfind(s,sn,c,cn) | ||
| 21 | character s(0:1),c(0:1) | ||
| 22 | integer i,j,m,sn,cn | ||
| 23 | m=mod(cn,4) | ||
| 24 | do 10 i=0,sn-1 | ||
| 25 | do 20 j=0,m-1 | ||
| 26 | if(s(i+j).ne.c(j))go to 50 | ||
| 27 | 20 continue | ||
| 28 | do 30 j=m,cn-1,4 | ||
| 29 | if(s(i+j).ne.c(j))go to 50 | ||
| 30 | if(s(i+j+1).ne.c(j+1))go to 50 | ||
| 31 | if(s(i+j+2).ne.c(j+2))go to 50 | ||
| 32 | if(s(i+j+3).ne.c(j+3))go to 50 | ||
| 33 | 30 continue | ||
| 34 | 50 if(j.eq.cn)go to 100 | ||
| 35 | 10 continue | ||
| 36 | sfind=-1 | ||
| 37 | return | ||
| 38 | 100 sfind=i | ||
| 39 | return | ||
| 40 | end | ||
diff --git a/src/mt/sfindtab.f b/src/mt/sfindtab.f new file mode 100644 index 0000000..b4e148e --- /dev/null +++ b/src/mt/sfindtab.f | |||
| @@ -0,0 +1,40 @@ | |||
| 1 | ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc | ||
| 2 | c | ||
| 3 | c HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | c | ||
| 5 | c This program is free software; you can redistribute it and/or modify | ||
| 6 | c it under the terms of the GNU General Public License as published by | ||
| 7 | c the Free Software Foundation; either version 2 of the License, or | ||
| 8 | c (at your option) any later version. | ||
| 9 | c | ||
| 10 | c This program is distributed in the hope that it will be useful, | ||
| 11 | c but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | c GNU General Public License for more details. | ||
| 14 | c | ||
| 15 | c You should have received a copy of the GNU General Public License | ||
| 16 | c along with this program; if not, write to the Free Software | ||
| 17 | c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | c | ||
| 19 | |||
| 20 | integer function sfindtab(s,sn,c,cn,tab) | ||
| 21 | byte s(0:1),c(0:1),tab(0:1) | ||
| 22 | integer i,j,m,sn,cn | ||
| 23 | m=mod(cn,4) | ||
| 24 | do 10 i=0,sn-1 | ||
| 25 | do 20 j=0,m-1 | ||
| 26 | if(tab(s(i+j)).ne.tab(c(j)))go to 50 | ||
| 27 | 20 continue | ||
| 28 | do 30 j=m,cn-1,4 | ||
| 29 | if(tab(s(i+j)).ne.tab(c(j)))go to 50 | ||
| 30 | if(tab(s(i+j+1)).ne.tab(c(j+1)))go to 50 | ||
| 31 | if(tab(s(i+j+2)).ne.tab(c(j+2)))go to 50 | ||
| 32 | if(tab(s(i+j+3)).ne.tab(c(j+3)))go to 50 | ||
| 33 | 30 continue | ||
| 34 | 50 if(j.eq.cn)go to 100 | ||
| 35 | 10 continue | ||
| 36 | sfindtab=-1 | ||
| 37 | return | ||
| 38 | 100 sfindtab=i | ||
| 39 | return | ||
| 40 | end | ||
diff --git a/src/mt/skip_parentesis.f b/src/mt/skip_parentesis.f new file mode 100644 index 0000000..1104c8f --- /dev/null +++ b/src/mt/skip_parentesis.f | |||
| @@ -0,0 +1,42 @@ | |||
| 1 | ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc | ||
| 2 | c | ||
| 3 | c HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | c | ||
| 5 | c This program is free software; you can redistribute it and/or modify | ||
| 6 | c it under the terms of the GNU General Public License as published by | ||
| 7 | c the Free Software Foundation; either version 2 of the License, or | ||
| 8 | c (at your option) any later version. | ||
| 9 | c | ||
| 10 | c This program is distributed in the hope that it will be useful, | ||
| 11 | c but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | c GNU General Public License for more details. | ||
| 14 | c | ||
| 15 | c You should have received a copy of the GNU General Public License | ||
| 16 | c along with this program; if not, write to the Free Software | ||
| 17 | c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | c | ||
| 19 | |||
| 20 | integer function skip_parentesis(s,n,left,right,esc) | ||
| 21 | character s(0:1),left,right,esc | ||
| 22 | integer i,n,cnt | ||
| 23 | if(n.eq.0)go to 40 | ||
| 24 | if(s(0).ne.left)go to 40 | ||
| 25 | cnt=1 | ||
| 26 | do 10 i=1,n-1 | ||
| 27 | if(s(i-1).eq.esc)go to 10 | ||
| 28 | if(s(i).eq.right)then | ||
| 29 | cnt=cnt-1 | ||
| 30 | if(cnt.eq.0)go to 30 | ||
| 31 | else if(s(i).eq.left)then | ||
| 32 | cnt=cnt+1 | ||
| 33 | end if | ||
| 34 | 10 continue | ||
| 35 | 20 skip_parentesis=-1 | ||
| 36 | return | ||
| 37 | 30 skip_parentesis=i+1 | ||
| 38 | return | ||
| 39 | 40 skip_parentesis=0 | ||
| 40 | return | ||
| 41 | end | ||
| 42 | |||
diff --git a/src/mt/split.h b/src/mt/split.h new file mode 100644 index 0000000..52e66e3 --- /dev/null +++ b/src/mt/split.h | |||
| @@ -0,0 +1,72 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef MSPLITH | ||
| 21 | #define MSPLITH | ||
| 22 | |||
| 23 | #include <mt/stringref.h> | ||
| 24 | |||
| 25 | inline sref Skip(const sref& a,const charset& ws=cset_ws) { | ||
| 26 | return a.right_first_not_of(ws); | ||
| 27 | } | ||
| 28 | |||
| 29 | inline sref Trim(const sref& a,const charset& ws=cset_ws) { | ||
| 30 | return a.right_first_not_of(ws).leftand_last_not_of(ws); | ||
| 31 | } | ||
| 32 | |||
| 33 | inline sref Trim(const sref& a,const bracket& enc,const charset& ws=cset_ws) { | ||
| 34 | sref s=a.right_first_not_of(ws).leftand_last_not_of(ws); | ||
| 35 | while(s.nempty()&&s.skip(enc)==s.size()) | ||
| 36 | s=s(1,-3).right_first_not_of(ws).leftand_last_not_of(ws); | ||
| 37 | return s; | ||
| 38 | } | ||
| 39 | |||
| 40 | inline sref First(const sref& a,const charset& ws=cset_ws) { | ||
| 41 | return a.right_first_not_of(ws).left_first_of(ws); | ||
| 42 | } | ||
| 43 | |||
| 44 | inline sref Rest(const sref& a,const charset& ws=cset_ws) { | ||
| 45 | return a.right_first_not_of(ws).right_first_of(ws).right_first_not_of(ws); | ||
| 46 | } | ||
| 47 | |||
| 48 | inline sref Last(const sref& a,const charset& ws=cset_ws) { | ||
| 49 | sref p=a.leftand_last_not_of(ws); | ||
| 50 | sref e=p.past_last_of(ws); | ||
| 51 | return e.nempty()?e:p; | ||
| 52 | } | ||
| 53 | |||
| 54 | inline int Split(sref& first,sref& rest,const charset& ws=cset_ws) { | ||
| 55 | rest=rest.right_first_not_of(ws); | ||
| 56 | int s=rest.find_of(ws); | ||
| 57 | first=rest.left(s); | ||
| 58 | rest=rest.right(s); | ||
| 59 | return first.nempty(); | ||
| 60 | } | ||
| 61 | |||
| 62 | inline int Splitln(sref& first,sref& rest) { | ||
| 63 | int s=rest.find_of(cset_newl); | ||
| 64 | first=rest.left(s); | ||
| 65 | rest=rest.right(s).past_nl(); | ||
| 66 | return first.begin()!=rest.begin(); | ||
| 67 | } | ||
| 68 | |||
| 69 | typedef int (*split_t)(sref& first,sref& rest); | ||
| 70 | |||
| 71 | #endif | ||
| 72 | |||
diff --git a/src/mt/srfind.f b/src/mt/srfind.f new file mode 100644 index 0000000..24f4fb4 --- /dev/null +++ b/src/mt/srfind.f | |||
| @@ -0,0 +1,40 @@ | |||
| 1 | ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc | ||
| 2 | c | ||
| 3 | c HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | c | ||
| 5 | c This program is free software; you can redistribute it and/or modify | ||
| 6 | c it under the terms of the GNU General Public License as published by | ||
| 7 | c the Free Software Foundation; either version 2 of the License, or | ||
| 8 | c (at your option) any later version. | ||
| 9 | c | ||
| 10 | c This program is distributed in the hope that it will be useful, | ||
| 11 | c but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | c GNU General Public License for more details. | ||
| 14 | c | ||
| 15 | c You should have received a copy of the GNU General Public License | ||
| 16 | c along with this program; if not, write to the Free Software | ||
| 17 | c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | c | ||
| 19 | |||
| 20 | integer function srfind(s,sn,c,cn) | ||
| 21 | character s(0:1),c(0:1) | ||
| 22 | integer i,j,m,sn,cn | ||
| 23 | m=mod(cn,4) | ||
| 24 | do 10 i=sn-1,0,-1 | ||
| 25 | do 20 j=0,m-1 | ||
| 26 | if(s(i+j).ne.c(j))go to 50 | ||
| 27 | 20 continue | ||
| 28 | do 30 j=m,cn-1,4 | ||
| 29 | if(s(i+j).ne.c(j))go to 50 | ||
| 30 | if(s(i+j+1).ne.c(j+1))go to 50 | ||
| 31 | if(s(i+j+2).ne.c(j+2))go to 50 | ||
| 32 | if(s(i+j+3).ne.c(j+3))go to 50 | ||
| 33 | 30 continue | ||
| 34 | 50 if(j.eq.cn)go to 100 | ||
| 35 | 10 continue | ||
| 36 | srfind=-1 | ||
| 37 | return | ||
| 38 | 100 srfind=i | ||
| 39 | return | ||
| 40 | end | ||
diff --git a/src/mt/srfindtab.f b/src/mt/srfindtab.f new file mode 100644 index 0000000..ad5fdd4 --- /dev/null +++ b/src/mt/srfindtab.f | |||
| @@ -0,0 +1,40 @@ | |||
| 1 | ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc | ||
| 2 | c | ||
| 3 | c HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | c | ||
| 5 | c This program is free software; you can redistribute it and/or modify | ||
| 6 | c it under the terms of the GNU General Public License as published by | ||
| 7 | c the Free Software Foundation; either version 2 of the License, or | ||
| 8 | c (at your option) any later version. | ||
| 9 | c | ||
| 10 | c This program is distributed in the hope that it will be useful, | ||
| 11 | c but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | c GNU General Public License for more details. | ||
| 14 | c | ||
| 15 | c You should have received a copy of the GNU General Public License | ||
| 16 | c along with this program; if not, write to the Free Software | ||
| 17 | c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | c | ||
| 19 | |||
| 20 | integer function srfindtab(s,sn,c,cn,tab) | ||
| 21 | byte s(0:1),c(0:1),tab(0:1) | ||
| 22 | integer i,j,m,sn,cn | ||
| 23 | m=mod(cn,4) | ||
| 24 | do 10 i=sn-1,0,-1 | ||
| 25 | do 20 j=0,m-1 | ||
| 26 | if(tab(s(i+j)).ne.tab(c(j)))go to 50 | ||
| 27 | 20 continue | ||
| 28 | do 30 j=m,cn-1,4 | ||
| 29 | if(tab(s(i+j)).ne.tab(c(j)))go to 50 | ||
| 30 | if(tab(s(i+j+1)).ne.tab(c(j+1)))go to 50 | ||
| 31 | if(tab(s(i+j+2)).ne.tab(c(j+2)))go to 50 | ||
| 32 | if(tab(s(i+j+3)).ne.tab(c(j+3)))go to 50 | ||
| 33 | 30 continue | ||
| 34 | 50 if(j.eq.cn)go to 100 | ||
| 35 | 10 continue | ||
| 36 | srfindtab=-1 | ||
| 37 | return | ||
| 38 | 100 srfindtab=i | ||
| 39 | return | ||
| 40 | end | ||
diff --git a/src/mt/stackque.h b/src/mt/stackque.h new file mode 100644 index 0000000..349cb4f --- /dev/null +++ b/src/mt/stackque.h | |||
| @@ -0,0 +1,64 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef STACKQUEH | ||
| 21 | #define STACKQUEH | ||
| 22 | |||
| 23 | #include <mt/mstring.h> | ||
| 24 | #include <mt/mlock.h> | ||
| 25 | |||
| 26 | template <class T> class stackque { | ||
| 27 | public: | ||
| 28 | stackque(int m) { | ||
| 29 | put=get=n=0; | ||
| 30 | base=new T[caps=m]; | ||
| 31 | memset(&mutex,0,sizeof(mutex_t)); | ||
| 32 | } | ||
| 33 | ~stackque() { delete base; } | ||
| 34 | |||
| 35 | int push(const T& a) throw(merror_t) { | ||
| 36 | MLOCK(mutex); | ||
| 37 | if(n>=caps) THROW("stackque: Full"); | ||
| 38 | base[put++]=a; | ||
| 39 | if(put==caps) put=0; | ||
| 40 | return ++n; | ||
| 41 | } | ||
| 42 | |||
| 43 | int pop(T& a) { | ||
| 44 | MLOCK(mutex); | ||
| 45 | if(n) { | ||
| 46 | a=base[get++]; | ||
| 47 | if(get==caps) get=0; | ||
| 48 | return n--; | ||
| 49 | } | ||
| 50 | else return 0; | ||
| 51 | } | ||
| 52 | |||
| 53 | int capacity() const { return caps; } | ||
| 54 | int size() const { return n; } | ||
| 55 | int empty() const { return n==0; } | ||
| 56 | int full() const { return n==caps; } | ||
| 57 | void clear() { put=get=n=0; } | ||
| 58 | private: | ||
| 59 | int put,get,n,caps; | ||
| 60 | T* base; | ||
| 61 | mutex_t mutex; | ||
| 62 | }; | ||
| 63 | |||
| 64 | #endif | ||
diff --git a/src/mt/stringref.cc b/src/mt/stringref.cc new file mode 100644 index 0000000..66b3d3e --- /dev/null +++ b/src/mt/stringref.cc | |||
| @@ -0,0 +1,126 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <mt/stringref.h> | ||
| 21 | #include <unistd.h> | ||
| 22 | #include <fcntl.h> | ||
| 23 | |||
| 24 | extern "C" { | ||
| 25 | int cfind_(const char* s,const int& sn,const char& c); | ||
| 26 | int crfind_(const char* s,const int& sn,const char& c); | ||
| 27 | int sfind_(const char* s,const int& sn,const char* c,const int& cn); | ||
| 28 | int srfind_(const char* s,const int& sn,const char* c,const int& cn); | ||
| 29 | int sfindtab_(const char* s,const int& sn,const char* c,const int& cn,const char* tab); | ||
| 30 | int srfindtab_(const char* s,const int& sn,const char* c,const int& cn,const char* tab); | ||
| 31 | int scomptab_(const char* s,const char* c,const int& n,const char* tab); | ||
| 32 | void sconvert_(char* s,const int& sn,const char* tab); | ||
| 33 | int find_of__(const char* s,const int& sn,const char* set); | ||
| 34 | int rfind_of__(const char* s,const int& sn,const char* set); | ||
| 35 | int find_not_of__(const char* s,const int& sn,const char* set); | ||
| 36 | int rfind_not_of__(const char* s,const int& sn,const char* set); | ||
| 37 | int skip_parentesis__(const char* s,const int& sn, | ||
| 38 | const char& left,const char& right,const char& esc); | ||
| 39 | int strip_(char* s,const char* c,const int& cn,const char& esc); | ||
| 40 | } | ||
| 41 | |||
| 42 | //////////////////////////////////////////////////// | ||
| 43 | |||
| 44 | char* sref::copyto(char* buf,int max) const { | ||
| 45 | if(!dim) buf[0]=0; | ||
| 46 | else if(dim<max) ((char*)memcpy(buf,map,dim))[dim]=0; | ||
| 47 | else ((char*)memcpy(buf,map,max-1))[max-1]=0; | ||
| 48 | return buf; | ||
| 49 | } | ||
| 50 | |||
| 51 | int sref::compare(const sref& s,const charmap& tab) const { | ||
| 52 | int c; if(map==s.map) return dim-s.dim; | ||
| 53 | else return (c=scomptab_(map,s.map,dim<s.dim?dim:s.dim,tab.map))?c:dim-s.dim; | ||
| 54 | } | ||
| 55 | |||
| 56 | //////////////////////////////////////////////////// | ||
| 57 | |||
| 58 | void sref::tolower() { sconvert_(map,dim,cset_lcase.map); } | ||
| 59 | void sref::toupper() { sconvert_(map,dim,cset_ucase.map); } | ||
| 60 | void sref::tosim(const charmap& s) { sconvert_(map,dim,s.map); } | ||
| 61 | |||
| 62 | //////////////////////////////////////////////////// | ||
| 63 | |||
| 64 | sref sref::operator()(int pos,int n) const { | ||
| 65 | if(pos<0) { pos+=dim; if(pos<0) pos=0; } | ||
| 66 | if(pos>=dim) return sref(map+dim,0); | ||
| 67 | else { | ||
| 68 | if(n<0) { n+=dim+1; if(n<0) n=0; } | ||
| 69 | if(n>=dim-pos) return sref(map+pos,dim-pos); | ||
| 70 | else return sref(map+pos,n); | ||
| 71 | } | ||
| 72 | } | ||
| 73 | |||
| 74 | sref sref::left(int n) const { | ||
| 75 | if(n<0) { n+=dim+1; if(n<0) n=0; } | ||
| 76 | if(n>dim) return sref(map,dim); | ||
| 77 | else return sref(map,n); | ||
| 78 | } | ||
| 79 | sref sref::leftand(int n,int m) const { | ||
| 80 | if(n<0) { n+=dim+1; if(n<0) n=0; } | ||
| 81 | if((n+=m)>dim) return sref(map,dim); | ||
| 82 | else return sref(map,n); | ||
| 83 | } | ||
| 84 | sref sref::right(int n) const { | ||
| 85 | if(n<0) { n+=dim+1; if(n<0) n=0; } | ||
| 86 | if(n>dim) return sref(map+dim,0); | ||
| 87 | else return sref(map+n,dim-n); | ||
| 88 | } | ||
| 89 | sref sref::past(int n,int m) const { | ||
| 90 | if(n<0) { n+=dim+1; if(n<0) n=0; } | ||
| 91 | if((n+=m)>dim) return sref(map+dim,0); | ||
| 92 | else return sref(map+n,dim-n); | ||
| 93 | } | ||
| 94 | |||
| 95 | //////////////////////////////////////////////////////////////// | ||
| 96 | |||
| 97 | int sref::find(char c) const { return cfind_(map,dim,c); } | ||
| 98 | int sref::rfind(char c) const { return crfind_(map,dim,c); } | ||
| 99 | int sref::find(const sref& s) const { return sfind_(map,dim,s.map,s.dim); } | ||
| 100 | int sref::rfind(const sref& s) const { return srfind_(map,dim,s.map,s.dim); } | ||
| 101 | int sref::find(const sref& s,const charmap& tab) const { | ||
| 102 | return sfindtab_(map,dim,s.map,s.dim,tab.map); | ||
| 103 | } | ||
| 104 | int sref::rfind(const sref& s,const charmap& tab) const { | ||
| 105 | return srfindtab_(map,dim,s.map,s.dim,tab.map); | ||
| 106 | } | ||
| 107 | |||
| 108 | int sref::find_of(const charset& s) const { return find_of__(map,dim,s.map); } | ||
| 109 | int sref::rfind_of(const charset& s) const { return rfind_of__(map,dim,s.map); } | ||
| 110 | int sref::find_not_of(const charset& s) const { return find_not_of__(map,dim,s.map); } | ||
| 111 | int sref::rfind_not_of(const charset& s) const { return rfind_not_of__(map,dim,s.map); } | ||
| 112 | |||
| 113 | int sref::skip(const bracket& bra) const { | ||
| 114 | return skip_parentesis__(map,dim,bra.left,bra.right,bra.esc); | ||
| 115 | } | ||
| 116 | |||
| 117 | //////////////////////////////////////////////////////////////// | ||
| 118 | |||
| 119 | int sref::save(const sref& s,int prot) const { | ||
| 120 | sref_t path; s.copyto(path); | ||
| 121 | int fd=open(path,O_WRONLY|O_CREAT,prot); | ||
| 122 | if(fd<0) return -1; | ||
| 123 | write(fd,map,dim); | ||
| 124 | close(fd); | ||
| 125 | return dim; | ||
| 126 | } | ||
diff --git a/src/mt/stringref.h b/src/mt/stringref.h new file mode 100644 index 0000000..a66ac21 --- /dev/null +++ b/src/mt/stringref.h | |||
| @@ -0,0 +1,239 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef SREFH | ||
| 21 | #define SREFH | ||
| 22 | |||
| 23 | #include <mt/charset.h> | ||
| 24 | #include <stdlib.h> | ||
| 25 | |||
| 26 | typedef char sref_t[1024]; | ||
| 27 | |||
| 28 | class sref { | ||
| 29 | public: | ||
| 30 | sref() : map((char*)&dim),dim(0) {} | ||
| 31 | explicit sref(char* p) : map(p),dim(strlen(p)) {} | ||
| 32 | explicit sref(const char* p) : map((char*)p),dim(strlen(p)) {} | ||
| 33 | sref(char* p,int n) : map(p),dim(n) {} | ||
| 34 | sref(const char* p,int n) : map((char*)p),dim(n) {} | ||
| 35 | |||
| 36 | int size() const { return dim; } | ||
| 37 | bool empty() const { return dim==0; } | ||
| 38 | bool nempty() const { return dim!=0; } | ||
| 39 | |||
| 40 | char* data() { return map; } | ||
| 41 | const char* data() const { return map; } | ||
| 42 | |||
| 43 | char& operator[](int pos) { return map[pos]; } | ||
| 44 | const char& operator[](int pos) const { return map[pos]; } | ||
| 45 | |||
| 46 | char* begin() { return map; } | ||
| 47 | const char* begin() const { return map; } | ||
| 48 | |||
| 49 | char* end() { return map+dim; } | ||
| 50 | const char* end() const { return map+dim; } | ||
| 51 | |||
| 52 | int operator*() const { return dim?*map:0; } | ||
| 53 | int front() const { return dim?*map:0; } | ||
| 54 | int back() const { return dim?map[dim-1]:0; } | ||
| 55 | |||
| 56 | //////////////////////////////////////////////////////////////// | ||
| 57 | |||
| 58 | sref popf() const { return dim?sref(map+1,dim-1):*this; } | ||
| 59 | sref popb() const { return dim?sref(map,dim-1):*this; } | ||
| 60 | |||
| 61 | sref adv(int n) const { return n>0?(n<dim?sref(map+n,dim-n):sref(map+dim,0)):*this; } | ||
| 62 | |||
| 63 | // NOTE that these functions are LOW LEVEL - no checks! | ||
| 64 | |||
| 65 | sref adv(const sref& s) const { return sref(s.end(),end()-s.end()); } | ||
| 66 | sref operator()(char* p) { return sref(p,map+dim-p); } | ||
| 67 | const sref operator()(const char* p) const { return sref((char*)p,map+dim-p); } | ||
| 68 | |||
| 69 | //////////////////////////////////////////////////////////////// | ||
| 70 | |||
| 71 | char* news() const {char* s=new char[dim+1];s[dim]=0;return (char*)memcpy(s,map,dim); } | ||
| 72 | |||
| 73 | void clear() {dim=0;} | ||
| 74 | |||
| 75 | //////////////////////////////////////////////////////////////// | ||
| 76 | |||
| 77 | void mcopy(const sref& s) { | ||
| 78 | if(s.dim<dim) memmove(map,s.map,dim=s.dim); else memmove(map,s.map,dim); | ||
| 79 | } | ||
| 80 | |||
| 81 | void tolower(); | ||
| 82 | void toupper(); | ||
| 83 | void tosim(const charmap& s=cset_sim); | ||
| 84 | |||
| 85 | //////////////////////////////////////////////////////////////// | ||
| 86 | |||
| 87 | char* copyto(char* buf,int max) const; | ||
| 88 | char* copyto(sref_t& buf) const { return copyto(buf,sizeof(buf)); } | ||
| 89 | |||
| 90 | int compare(const sref& s) const { | ||
| 91 | int c; if(map==s.map) return dim-s.dim; | ||
| 92 | else return (c=memcmp(map,s.map,dim<s.dim?dim:s.dim))?c:dim-s.dim; | ||
| 93 | } | ||
| 94 | int compare(const sref& s,const charmap& tab) const; | ||
| 95 | |||
| 96 | //////////////////////////////////////////////////////////////// | ||
| 97 | |||
| 98 | sref operator()(int pos,int n=-1) const; | ||
| 99 | sref left(int n) const; | ||
| 100 | sref leftand(int n,int m) const; | ||
| 101 | sref right(int n) const; | ||
| 102 | sref past(int n,int m) const; | ||
| 103 | |||
| 104 | sref past_nl() const { return past(find('\n'),1); } | ||
| 105 | |||
| 106 | //////////////////////////////////////////////////////////////// | ||
| 107 | |||
| 108 | int find(char c) const; | ||
| 109 | sref left_first(char c) const { return left(find(c)); } | ||
| 110 | sref leftand_first(char c) const { return leftand(find(c),1); } | ||
| 111 | sref right_first(char c) const { return right(find(c)); } | ||
| 112 | sref past_first(char c) const { return past(find(c),1); } | ||
| 113 | |||
| 114 | int rfind(char c) const; | ||
| 115 | sref left_last(char c) const { return left(rfind(c)); } | ||
| 116 | sref leftand_last(char c) const { return leftand(rfind(c),1); } | ||
| 117 | sref right_last(char c) const { return right(rfind(c)); } | ||
| 118 | sref past_last(char c) const { return past(rfind(c),1); } | ||
| 119 | |||
| 120 | int find(const sref& s) const; | ||
| 121 | sref left_first(const sref& s) const { return left(find(s)); } | ||
| 122 | sref leftand_first(const sref& s) const { return leftand(find(s),s.size()); } | ||
| 123 | sref right_first(const sref& s) const { return right(find(s)); } | ||
| 124 | sref past_first(const sref& s) const { return past(find(s),s.size()); } | ||
| 125 | |||
| 126 | int rfind(const sref& s) const; | ||
| 127 | sref left_last(const sref& s) const { return left(rfind(s)); } | ||
| 128 | sref leftand_last(const sref& s) const { return leftand(rfind(s),s.size()); } | ||
| 129 | sref right_last(const sref& s) const { return right(rfind(s)); } | ||
| 130 | sref past_last(const sref& s) const { return past(rfind(s),s.size()); } | ||
| 131 | |||
| 132 | int find(const sref& s,const charmap& tab) const; | ||
| 133 | sref left_first(const sref& s,const charmap& tab) const { return left(find(s,tab)); } | ||
| 134 | sref leftand_first(const sref& s,const charmap& tab)const{ | ||
| 135 | return leftand(find(s,tab),s.size()); | ||
| 136 | } | ||
| 137 | sref right_first(const sref& s,const charmap& tab) const { return right(find(s,tab)); } | ||
| 138 | sref past_first(const sref& s,const charmap& tab) const { | ||
| 139 | return past(find(s,tab),s.size()); | ||
| 140 | } | ||
| 141 | |||
| 142 | int rfind(const sref& s,const charmap& tab) const; | ||
| 143 | sref left_last(const sref& s,const charmap& tab) const { return left(rfind(s,tab)); } | ||
| 144 | sref leftand_last(const sref& s,const charmap& tab)const{ | ||
| 145 | return leftand(rfind(s,tab),s.size()); | ||
| 146 | } | ||
| 147 | sref right_last(const sref& s,const charmap& tab) const { return right(rfind(s,tab)); } | ||
| 148 | sref past_last(const sref& s,const charmap& tab) const { | ||
| 149 | return past(rfind(s,tab),s.size()); | ||
| 150 | } | ||
| 151 | |||
| 152 | int find_of(const charset& s) const; | ||
| 153 | sref left_first_of(const charset& s) const { return left(find_of(s)); } | ||
| 154 | sref leftand_first_of(const charset& s) const { return leftand(find_of(s),1); } | ||
| 155 | sref right_first_of(const charset& s) const { return right(find_of(s)); } | ||
| 156 | sref past_first_of(const charset& s) const { return past(find_of(s),1); } | ||
| 157 | |||
| 158 | int rfind_of(const charset& s) const; | ||
| 159 | sref left_last_of(const charset& s) const { return left(rfind_of(s)); } | ||
| 160 | sref leftand_last_of(const charset& s) const { return leftand(rfind_of(s),1); } | ||
| 161 | sref right_last_of(const charset& s) const { return right(rfind_of(s)); } | ||
| 162 | sref past_last_of(const charset& s) const { return past(rfind_of(s),1); } | ||
| 163 | |||
| 164 | int find_not_of(const charset& s) const; | ||
| 165 | sref left_first_not_of(const charset& s) const { return left(find_not_of(s)); } | ||
| 166 | sref leftand_first_not_of(const charset& s) const { return leftand(find_not_of(s),1); } | ||
| 167 | sref right_first_not_of(const charset& s) const { return right(find_not_of(s)); } | ||
| 168 | sref past_first_not_of(const charset& s) const { return past(find_not_of(s),1); } | ||
| 169 | |||
| 170 | int rfind_not_of(const charset& s) const; | ||
| 171 | sref left_last_not_of(const charset& s) const { return left(rfind_not_of(s)); } | ||
| 172 | sref leftand_last_not_of(const charset& s) const { return leftand(rfind_not_of(s),1); } | ||
| 173 | sref right_last_not_of(const charset& s) const { return right(rfind_not_of(s)); } | ||
| 174 | sref past_last_not_of(const charset& s) const { return past(rfind_not_of(s),1); } | ||
| 175 | |||
| 176 | int skip(const bracket& bra) const; | ||
| 177 | |||
| 178 | //////////////////////////////////////////////////////////////// | ||
| 179 | |||
| 180 | int save(const sref& path,int prot=0600) const; | ||
| 181 | |||
| 182 | protected: | ||
| 183 | char* map; | ||
| 184 | int dim; | ||
| 185 | }; | ||
| 186 | |||
| 187 | //////////////////////////////////////////////////// | ||
| 188 | |||
| 189 | inline bool operator<(const sref& a,const sref& b) { | ||
| 190 | return a.compare(b)<0; | ||
| 191 | } | ||
| 192 | inline bool operator<=(const sref& a,const sref& b) { | ||
| 193 | return a.compare(b)<=0; | ||
| 194 | } | ||
| 195 | inline bool operator==(const sref& a,const sref& b) { | ||
| 196 | return a.compare(b)==0; | ||
| 197 | } | ||
| 198 | inline bool operator!=(const sref& a,const sref& b) { | ||
| 199 | return a.compare(b)!=0; | ||
| 200 | } | ||
| 201 | inline bool operator>=(const sref& a,const sref& b) { | ||
| 202 | return a.compare(b)>=0; | ||
| 203 | } | ||
| 204 | inline bool operator>(const sref& a,const sref& b) { | ||
| 205 | return a.compare(b)>0; | ||
| 206 | } | ||
| 207 | |||
| 208 | ////////////////////////////////////////////////////////////////////////// | ||
| 209 | |||
| 210 | inline int operator-(const sref& a,const sref& b) { return a.data()-b.data(); } | ||
| 211 | |||
| 212 | ////////////////////////////////////////////////////////////////////////// | ||
| 213 | |||
| 214 | inline int ltn(const sref& a,const sref& b) { | ||
| 215 | return a.compare(b,cset_lcase)<0; | ||
| 216 | } | ||
| 217 | inline int len(const sref& a,const sref& b) { | ||
| 218 | return a.compare(b,cset_lcase)<=0; | ||
| 219 | } | ||
| 220 | inline int eqn(const sref& a,const sref& b) { | ||
| 221 | return a.compare(b,cset_lcase)==0; | ||
| 222 | } | ||
| 223 | inline int nen(const sref& a,const sref& b) { | ||
| 224 | return a.compare(b,cset_lcase)!=0; | ||
| 225 | } | ||
| 226 | inline int gen(const sref& a,const sref& b) { | ||
| 227 | return a.compare(b,cset_lcase)>=0; | ||
| 228 | } | ||
| 229 | inline int gtn(const sref& a,const sref& b) { | ||
| 230 | return a.compare(b,cset_lcase)>0; | ||
| 231 | } | ||
| 232 | |||
| 233 | ////////////////////////////////////////////////////////////////////////// | ||
| 234 | |||
| 235 | inline int atob(const sref& s) { sref_t buf; return atoi(s.copyto(buf))!=0; } | ||
| 236 | inline int atoi(const sref& s) { sref_t buf; return atoi(s.copyto(buf)); } | ||
| 237 | inline double atof(const sref& s) { sref_t buf; return atof(s.copyto(buf)); } | ||
| 238 | |||
| 239 | #endif | ||
diff --git a/src/mt/strip.f b/src/mt/strip.f new file mode 100644 index 0000000..1cca9c4 --- /dev/null +++ b/src/mt/strip.f | |||
| @@ -0,0 +1,31 @@ | |||
| 1 | ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc | ||
| 2 | c | ||
| 3 | c HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | c | ||
| 5 | c This program is free software; you can redistribute it and/or modify | ||
| 6 | c it under the terms of the GNU General Public License as published by | ||
| 7 | c the Free Software Foundation; either version 2 of the License, or | ||
| 8 | c (at your option) any later version. | ||
| 9 | c | ||
| 10 | c This program is distributed in the hope that it will be useful, | ||
| 11 | c but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | c GNU General Public License for more details. | ||
| 14 | c | ||
| 15 | c You should have received a copy of the GNU General Public License | ||
| 16 | c along with this program; if not, write to the Free Software | ||
| 17 | c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | c | ||
| 19 | |||
| 20 | integer function strip(s,c,cn,esc) | ||
| 21 | character s(0:1),c(0:1),esc | ||
| 22 | integer i,j,cn | ||
| 23 | j=0 | ||
| 24 | do 10 i=0,cn-1 | ||
| 25 | if(c(i).eq.esc)go to 10 | ||
| 26 | s(j)=c(i) | ||
| 27 | j=j+1 | ||
| 28 | 10 continue | ||
| 29 | strip=j | ||
| 30 | return | ||
| 31 | end | ||
diff --git a/src/mt/test.cc b/src/mt/test.cc new file mode 100644 index 0000000..5671a33 --- /dev/null +++ b/src/mt/test.cc | |||
| @@ -0,0 +1,337 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <mt/uniheap.h> | ||
| 21 | #include <mt/stackque.h> | ||
| 22 | #include <mt/random.h> | ||
| 23 | #include <mt/lookup.h> | ||
| 24 | #include <mt/mset.h> | ||
| 25 | #include <mt/issue.h> | ||
| 26 | #include <mt/mvec.h> | ||
| 27 | #include <mt/msmap.h> | ||
| 28 | #include <time.h> | ||
| 29 | |||
| 30 | #define GENERAL 0 | ||
| 31 | #define STREAM 1 | ||
| 32 | #define HEAPS 0 | ||
| 33 | #define CHARSET 0 | ||
| 34 | #define RANDOM 0 | ||
| 35 | #define LOOKUP 0 | ||
| 36 | #define ISSUE 1 | ||
| 37 | #define MSET 0 | ||
| 38 | #define CVTS 0 | ||
| 39 | #define VECTOR 0 | ||
| 40 | #define MSMAP 0 | ||
| 41 | |||
| 42 | static fp_stream mout(stdout),merr(stderr); | ||
| 43 | |||
| 44 | main(int argc,char* argv[]) | ||
| 45 | { | ||
| 46 | mstring s; | ||
| 47 | #if GENERAL | ||
| 48 | s="asdfwerfindfindis?? asdf wert nnvnbn\n"; | ||
| 49 | |||
| 50 | mout<<"["<<Trim(s,cset_para)<<"]\n"; | ||
| 51 | |||
| 52 | sref find=sref("find"); | ||
| 53 | sref rfind=sref("rfind"); | ||
| 54 | |||
| 55 | mout<<s.find(find)<<"\n"; | ||
| 56 | mout<<s.rfind(rfind)<<"\n"; | ||
| 57 | mout<<s.find(find,cset_lcase)<<"\n"; | ||
| 58 | mout<<s.rfind(rfind,cset_lcase)<<"\n"; | ||
| 59 | mout<<s.find(find,cset_ucase)<<"\n"; | ||
| 60 | mout<<s.rfind(rfind,cset_ucase)<<"\n"; | ||
| 61 | |||
| 62 | mout<<"****\n"; | ||
| 63 | |||
| 64 | mout<<"["<<s.leftand_last_not_of(cset_ws)<<"]\n"; | ||
| 65 | |||
| 66 | mout<<"****\n"; | ||
| 67 | |||
| 68 | s.tolower(); | ||
| 69 | mout<<"["<<s<<"]\n"; | ||
| 70 | s.toupper(); | ||
| 71 | mout<<"["<<s<<"]\n"; | ||
| 72 | |||
| 73 | mout<<"*****\n"; | ||
| 74 | |||
| 75 | mstring st="abcdefghi2jklmn"; | ||
| 76 | charset stset("123"); | ||
| 77 | mout<<"["<<st.left_first_of(stset)<<"]\n"; | ||
| 78 | mout<<"["<<st.right_first_of(stset)<<"]\n"; | ||
| 79 | mout<<"["<<st.past_first_of(stset)<<"]\n"; | ||
| 80 | |||
| 81 | mout<<"******\n"; | ||
| 82 | |||
| 83 | mstring a=First(s); | ||
| 84 | mstring b=Rest(s); | ||
| 85 | mstring c=Last(s); | ||
| 86 | mout<<"["<<a<<"]\n"; | ||
| 87 | mout<<"["<<b<<"]\n"; | ||
| 88 | mout<<"["<<c<<"]\n"; | ||
| 89 | |||
| 90 | mout<<"******\n"; | ||
| 91 | |||
| 92 | sref first,rest=s; | ||
| 93 | while(Split(first,rest)) { | ||
| 94 | mout<<"["<<first<<"]["<<atoi(first)<<"]\n"; | ||
| 95 | } | ||
| 96 | |||
| 97 | mout<<"*******\n"; | ||
| 98 | |||
| 99 | mout<<"["<<mstring().convert("%d %02X",56,100)<<"]\n"; | ||
| 100 | |||
| 101 | mout<<s.skip(cset_para)<<"\n"; | ||
| 102 | |||
| 103 | mout<<"********\n"; | ||
| 104 | |||
| 105 | //mstring buf; buf.load("tt.cc"); | ||
| 106 | //mout<<"***\n"<<buf<<"***\n"; | ||
| 107 | #endif | ||
| 108 | #if STREAM | ||
| 109 | s="more strange asdf\n"; | ||
| 110 | |||
| 111 | swrite to; | ||
| 112 | mout<<s<<"\n"; | ||
| 113 | to.hold(s)<<" Hello! this is appending "<<4<<" to string\n"; | ||
| 114 | mout<<s<<"\n"; | ||
| 115 | |||
| 116 | mout<<"********\n"; | ||
| 117 | |||
| 118 | mstream mm; mm<<"Hejsan!\n"; | ||
| 119 | |||
| 120 | mout<<"********\n"; | ||
| 121 | |||
| 122 | try { | ||
| 123 | THROW("hello "<<4<<" once more"); | ||
| 124 | } | ||
| 125 | catch(const merror_t& e) { | ||
| 126 | mout<<"Error test: "<<e.num<<"\n"; | ||
| 127 | mout<<e.desc<<"\n"; | ||
| 128 | } | ||
| 129 | |||
| 130 | mout<<"********\n"; | ||
| 131 | |||
| 132 | sref sa=s; | ||
| 133 | sref sb=s; | ||
| 134 | mout<<(sa==sb)<<"\n"; | ||
| 135 | |||
| 136 | mout<<"********\n"; | ||
| 137 | |||
| 138 | mstring tt="(asdf)sdfsdf"; | ||
| 139 | mout<<tt.skip(cset_para)<<"\n"; | ||
| 140 | mout<<"["<<tt(1,tt.skip(cset_para)-2)<<"]\n"; | ||
| 141 | |||
| 142 | mout<<"********\n"; | ||
| 143 | #endif | ||
| 144 | |||
| 145 | #if HEAPS | ||
| 146 | |||
| 147 | uniheap<4> stack; stack.init(); | ||
| 148 | for(int i=0;i<48;i++) { | ||
| 149 | //stack.pop(stack.push()); | ||
| 150 | stack.push(); | ||
| 151 | } | ||
| 152 | mout<<"--\n"; | ||
| 153 | mout<<stack.chunksize()<<"\n"; | ||
| 154 | |||
| 155 | mout<<"********\n"; | ||
| 156 | |||
| 157 | stackque<int> que(8); | ||
| 158 | for(int i=0;i<8;i++) que.push(i); | ||
| 159 | |||
| 160 | try { | ||
| 161 | que.push(5); | ||
| 162 | } | ||
| 163 | catch(const merror_t& e) { | ||
| 164 | merr<<e.num<<"\n"; | ||
| 165 | merr<<e.desc<<"\n"; | ||
| 166 | } | ||
| 167 | |||
| 168 | int pop; | ||
| 169 | while(que.pop(pop)) merr<<pop<<"\n"; | ||
| 170 | |||
| 171 | #endif | ||
| 172 | |||
| 173 | #if CHARSET | ||
| 174 | |||
| 175 | charset set("12345öd"); | ||
| 176 | charset set2("12"); | ||
| 177 | charset set3=set-set2; | ||
| 178 | |||
| 179 | merr<<"* \n"; | ||
| 180 | |||
| 181 | for(int i=-127;i<127;i++) { | ||
| 182 | if(set.map[i]) mout<<i<<"("<<char(i)<<")\n"; | ||
| 183 | } | ||
| 184 | |||
| 185 | merr<<"* \n"; | ||
| 186 | |||
| 187 | for(int i=-127;i<127;i++) { | ||
| 188 | if(set3.map[i]) mout<<i<<"("<<char(i)<<")\n"; | ||
| 189 | } | ||
| 190 | |||
| 191 | merr<<"**\n"; | ||
| 192 | |||
| 193 | mout<<find_of_("ö",1,set.map)<<"\n"; | ||
| 194 | mout<<s.find_of(set)<<"\n"; | ||
| 195 | |||
| 196 | mout<<"***\n"; | ||
| 197 | |||
| 198 | mout<<"["; | ||
| 199 | for(int i=-127;i<128;i++) if(cset_lcase[i]!=i) mout.put(i); | ||
| 200 | mout<<"]\n"; | ||
| 201 | mout<<"["; | ||
| 202 | for(int i=-127;i<128;i++) if(cset_lcase[i]!=i) mout.put(cset_lcase[i]); | ||
| 203 | mout<<"]\n"; | ||
| 204 | |||
| 205 | mout<<"\n"; | ||
| 206 | |||
| 207 | mout<<"["; | ||
| 208 | for(int i=-127;i<128;i++) if(cset_ueqv1[i]!=i) mout.put(i); | ||
| 209 | mout<<"]\n"; | ||
| 210 | mout<<"["; | ||
| 211 | for(int i=-127;i<128;i++) if(cset_ueqv1[i]!=i) mout.put(cset_ueqv1[i]); | ||
| 212 | mout<<"]\n"; | ||
| 213 | |||
| 214 | mout<<"\n"; | ||
| 215 | |||
| 216 | mout<<"["; | ||
| 217 | for(int i=-127;i<128;i++) if(cset_ueqv2[i]!=i) mout.put(i); | ||
| 218 | mout<<"]\n"; | ||
| 219 | mout<<"["; | ||
| 220 | for(int i=-127;i<128;i++) if(cset_ueqv2[i]!=i) mout.put(cset_ueqv2[i]); | ||
| 221 | mout<<"]\n"; | ||
| 222 | |||
| 223 | mout<<"\n"; | ||
| 224 | |||
| 225 | mout<<"["; | ||
| 226 | for(int i=-127;i<128;i++) if(cset_sim[i]!=i) mout.put(i); | ||
| 227 | mout<<"]\n"; | ||
| 228 | mout<<"["; | ||
| 229 | for(int i=-127;i<128;i++) if(cset_sim[i]!=i) mout.put(cset_sim[i]); | ||
| 230 | mout<<"]\n"; | ||
| 231 | #endif | ||
| 232 | |||
| 233 | #if RANDOM | ||
| 234 | RandomInit(13); | ||
| 235 | for(int i=0;i<100;i++) mout<<Uniform()<<"\n"; | ||
| 236 | #endif | ||
| 237 | |||
| 238 | #if LOOKUP | ||
| 239 | |||
| 240 | while(1) { | ||
| 241 | mstring ip; | ||
| 242 | merr<<"addr>"; | ||
| 243 | getline(ip,stdin); | ||
| 244 | IPnode node; | ||
| 245 | for(int i=0;i<4;i++) { | ||
| 246 | if(Lookup(node,ip)) { | ||
| 247 | merr<<node.valid<<"\n"; | ||
| 248 | merr<<node.ip<<"\n"; | ||
| 249 | merr<<node.name<<"\n"; | ||
| 250 | } | ||
| 251 | else { | ||
| 252 | merr<<"Not found\n"; | ||
| 253 | break; | ||
| 254 | } | ||
| 255 | } | ||
| 256 | } | ||
| 257 | |||
| 258 | #endif | ||
| 259 | |||
| 260 | #if ISSUE | ||
| 261 | |||
| 262 | issue_t cmd(sref("/bin/cat")); | ||
| 263 | mswrite out; | ||
| 264 | mstring in="hello world!"; | ||
| 265 | cmd.run(out,in); | ||
| 266 | mout<<"Got ["<<out.str()<<"]\n"; | ||
| 267 | |||
| 268 | cmd.clear(); | ||
| 269 | cmd.add(sref("sadfasfd")); | ||
| 270 | cmd.end(); | ||
| 271 | out.clear(); | ||
| 272 | cmd.run(out,in); | ||
| 273 | mout<<"Got ["<<out.str()<<"]\n"; | ||
| 274 | |||
| 275 | #endif | ||
| 276 | |||
| 277 | #if MSET | ||
| 278 | |||
| 279 | mstring mm="hello world!\n how many items?\n"; | ||
| 280 | mset a=mm; | ||
| 281 | for(int i=0;i<a.size();i++) { | ||
| 282 | mout<<a[i]<<"\n"; | ||
| 283 | } | ||
| 284 | |||
| 285 | mout<<"OR ["<<a<<"]\n"; | ||
| 286 | |||
| 287 | #endif | ||
| 288 | |||
| 289 | #if CVTS | ||
| 290 | |||
| 291 | merr<<"n: "<<itoa(5)<<"\n"; | ||
| 292 | merr<<"f: "<<ftoa(5)<<"\n"; | ||
| 293 | merr<<"f: "<<ftoa(5.7)<<"\n"; | ||
| 294 | merr<<"f: "<<ftoa(-3)<<"\n"; | ||
| 295 | merr<<"f: "<<ftoa(3.78678)<<"\n"; | ||
| 296 | merr<<"f: "<<ftoa(exp(2.1))<<"\n"; | ||
| 297 | merr<<"f: "<<ftoa(time(0))<<"\n"; | ||
| 298 | merr<<"direct: "<<3.40000<<"\n"; | ||
| 299 | |||
| 300 | pipe_stream tout(1); | ||
| 301 | tout<<"How does this one "<<-78.4<<" behave??\n"; | ||
| 302 | |||
| 303 | mstring inp; | ||
| 304 | getline(inp,stdin); | ||
| 305 | merr<<ftoa(atof(inp))<<"\n"; | ||
| 306 | |||
| 307 | #endif | ||
| 308 | |||
| 309 | #if VECTOR | ||
| 310 | |||
| 311 | mrvec<int> v(4); | ||
| 312 | for(int i=0;i<v.size();i++) v[i]=i; | ||
| 313 | |||
| 314 | for(int i=0;i<v.size();i++) merr<<v[i]<<"\n"; | ||
| 315 | |||
| 316 | #endif | ||
| 317 | |||
| 318 | #if MSMAP | ||
| 319 | |||
| 320 | ssmap map; | ||
| 321 | //map.add("hello","world"); | ||
| 322 | //map.add("one","world!"); | ||
| 323 | map.push_back(sstring("one","world!")); | ||
| 324 | map.push_back(sstring("hello","world")); | ||
| 325 | map.sort(); | ||
| 326 | |||
| 327 | for(ssmap::iterator p=map.begin();p!=map.end();p++) { | ||
| 328 | merr<<p->first<<" "<<p->second<<"\n"; | ||
| 329 | } | ||
| 330 | |||
| 331 | const mstring* p=map.get("one"); | ||
| 332 | if(p) merr<<"got "<<*p<<"\n"; | ||
| 333 | |||
| 334 | #endif | ||
| 335 | |||
| 336 | return 0; | ||
| 337 | } | ||
diff --git a/src/mt/uniheap.h b/src/mt/uniheap.h new file mode 100644 index 0000000..39c3d34 --- /dev/null +++ b/src/mt/uniheap.h | |||
| @@ -0,0 +1,65 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef UNIHEAPH | ||
| 21 | #define UNIHEAPH | ||
| 22 | |||
| 23 | #include <mt/mlock.h> | ||
| 24 | #include <malloc.h> | ||
| 25 | #include <string.h> | ||
| 26 | |||
| 27 | // NOTE - must be in extern/static scope, or zeroed before use | ||
| 28 | // by a call to init. constructors will fail badly. | ||
| 29 | // A minimum of sizeof(T)==4 is required. | ||
| 30 | // Furthermore, the upper limit of heap space is 1Gb. | ||
| 31 | |||
| 32 | template <int N> class uniheap { | ||
| 33 | public: | ||
| 34 | static const int maxchunks=24; | ||
| 35 | |||
| 36 | void init() { | ||
| 37 | head=0; | ||
| 38 | chunk=0; | ||
| 39 | nchunks=0; | ||
| 40 | memset(&mutex,0,sizeof(mutex_t)); | ||
| 41 | } | ||
| 42 | |||
| 43 | char* push() { MLOCK(mutex); char* p=news(); head=*(char**)p; return p; } | ||
| 44 | void pop(void* p) { MLOCK(mutex); *((char**)p)=head; head=(char*)p; } | ||
| 45 | int chunksize() const { return chunk; } | ||
| 46 | protected: | ||
| 47 | char* news() { | ||
| 48 | if(!head) { | ||
| 49 | if(!chunk) chunk=N<<4; | ||
| 50 | if(nchunks>=maxchunks) throw((int)0); | ||
| 51 | head=chunks[nchunks++]=(char*)malloc(chunk); | ||
| 52 | if(!head) throw((int)0); | ||
| 53 | for(int i=0;i<chunk-N;i+=N) *((char**)(head+i))=head+i+N; | ||
| 54 | *((char**)(head+chunk-N))=0; | ||
| 55 | chunk<<=1; | ||
| 56 | } | ||
| 57 | return head; | ||
| 58 | } | ||
| 59 | private: | ||
| 60 | char *head,*chunks[maxchunks]; | ||
| 61 | int chunk,nchunks; | ||
| 62 | mutex_t mutex; | ||
| 63 | }; | ||
| 64 | |||
| 65 | #endif | ||
diff --git a/src/net/htcd.cc b/src/net/htcd.cc new file mode 100644 index 0000000..89729e6 --- /dev/null +++ b/src/net/htcd.cc | |||
| @@ -0,0 +1,153 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <net/thrserv.h> | ||
| 21 | |||
| 22 | static fp_stream merr(stderr); | ||
| 23 | |||
| 24 | static mstring PATH; | ||
| 25 | static htcServ* SERV; | ||
| 26 | |||
| 27 | const mstring PIDURI="/sys/htcd"; | ||
| 28 | |||
| 29 | const int BACKLOG=4; | ||
| 30 | const int SERVERS=9; | ||
| 31 | const int LOWER=3; | ||
| 32 | const int UPPER=6; | ||
| 33 | const int KEEPALIVE=300; | ||
| 34 | const int SNDBUFSIZE=16384; | ||
| 35 | const int RCVBUFSIZE=16384; | ||
| 36 | |||
| 37 | /////////////////////////////////////////////////////////// | ||
| 38 | |||
| 39 | static thrServ* server[SERVERS]; | ||
| 40 | static thrCron* crontab; | ||
| 41 | |||
| 42 | extern "C" { | ||
| 43 | static void* thr_handler(void* p) { ((thrServ*)p)->enter(); return 0; } | ||
| 44 | static void* thr_cron(void* p) { ((thrCron*)p)->enter(); return 0; } | ||
| 45 | static void onTERM(int sig) { SERV->htcd.running=0; } | ||
| 46 | static void onHUP(int sig) { if(crontab) crontab->running=0; } | ||
| 47 | typedef void (*disp_t)(int); | ||
| 48 | } | ||
| 49 | |||
| 50 | static void MainProc(isocket& sock) | ||
| 51 | { | ||
| 52 | int keep=1; | ||
| 53 | while(SERV->htcd.running) { | ||
| 54 | int nvacant=0; for(int i=0;i<SERVERS;i++) if(server[i]->vacant()) nvacant++; | ||
| 55 | if(nvacant>UPPER) keep=1; else if(nvacant<=LOWER) keep=0; | ||
| 56 | if(!keep) for(int i=0;i<SERVERS;i++) server[i]->shutdown(); | ||
| 57 | time_t timeout=time(0)-KEEPALIVE; | ||
| 58 | for(int i=0;i<SERVERS;i++) if(timeout>server[i]->last) server[i]->disconnect(); | ||
| 59 | int test=sock.test(); | ||
| 60 | if(test>0) { | ||
| 61 | thrServ* p=0; | ||
| 62 | for(int i=0;i<SERVERS;i++) if(server[i]->vacant()) { p=server[i]; break; } | ||
| 63 | if(!p) for(int i=0;i<SERVERS;i++) if(!p||server[i]->first<p->first) p=server[i]; | ||
| 64 | if(p->shutdown()) { | ||
| 65 | try { | ||
| 66 | isocket* s=sock.accept(); | ||
| 67 | if(s) p->reset(s,keep); | ||
| 68 | } | ||
| 69 | catch(const merror_t& e) { | ||
| 70 | merr<<"SOCKET: "<<e.desc<<"\n"; | ||
| 71 | } | ||
| 72 | } | ||
| 73 | } | ||
| 74 | else if(test<0) SERV->htcd.running=0; | ||
| 75 | } | ||
| 76 | for(int i=0;i<SERVERS;i++) { | ||
| 77 | server[i]->term(); | ||
| 78 | pthread_join(server[i]->ptid,0); | ||
| 79 | } | ||
| 80 | pthread_kill(crontab->tid,SIGHUP); | ||
| 81 | pthread_join(crontab->ptid,0); | ||
| 82 | } | ||
| 83 | |||
| 84 | /////////////////////////////////////////////////////////////// | ||
| 85 | |||
| 86 | static void httpServer(int overport) | ||
| 87 | { | ||
| 88 | isocket sock(SERV->htcd.node.addr,overport,BACKLOG); | ||
| 89 | sock.keepalive(1); | ||
| 90 | sock.sendbufsize(SNDBUFSIZE); | ||
| 91 | sock.recvbufsize(RCVBUFSIZE); | ||
| 92 | |||
| 93 | sigignore(SIGPIPE); | ||
| 94 | disp_t onterm=signal(SIGTERM,onTERM); | ||
| 95 | disp_t onint=signal(SIGINT,onTERM); | ||
| 96 | disp_t onhup=signal(SIGHUP,onHUP); | ||
| 97 | MainProc(sock); | ||
| 98 | signal(SIGHUP,onhup); | ||
| 99 | signal(SIGINT,onint); | ||
| 100 | signal(SIGTERM,onterm); | ||
| 101 | } | ||
| 102 | |||
| 103 | static void Daemon(int overport) try | ||
| 104 | { | ||
| 105 | PROCLOCK(PATH+PIDURI); | ||
| 106 | SERV=new htcServ(PATH); | ||
| 107 | crontab=new thrCron(*SERV); | ||
| 108 | pthread_create(&crontab->ptid,0,thr_cron,crontab); | ||
| 109 | for(int i=0;i<SERVERS;i++) { | ||
| 110 | server[i]=new thrServ(*SERV); | ||
| 111 | pthread_create(&server[i]->ptid,0,thr_handler,server[i]); | ||
| 112 | } | ||
| 113 | merr<<"htcd: "<<PATH<<" started\n"; | ||
| 114 | httpServer(overport<0?0:overport==0?SERV->htcd.port:overport); | ||
| 115 | merr<<"htcd: "<<PATH<<" terminating\n"; | ||
| 116 | for(int i=0;i<SERVERS;i++) delete server[i]; | ||
| 117 | delete crontab; | ||
| 118 | } | ||
| 119 | catch(const merror_t& e) { | ||
| 120 | if(SERV) { | ||
| 121 | SERV->htcd.errlog<<"["<<time(0)<<"][MAIN]["<<e.desc<<"]\n"; | ||
| 122 | merr<<e.desc<<"\n"; | ||
| 123 | } | ||
| 124 | else if(First(e.desc)!=sref("proclock:")) merr<<e.desc<<"\n"; | ||
| 125 | } | ||
| 126 | catch(...) { | ||
| 127 | if(SERV) SERV->htcd.errlog<<"["<<time(0)<<"][MAIN][FATAL]\n"; | ||
| 128 | merr<<"FATAL\n"; | ||
| 129 | } | ||
| 130 | |||
| 131 | main(int argc,char* argv[]) try | ||
| 132 | { | ||
| 133 | if(argc<3) { | ||
| 134 | merr<<"Usage: "<<argv[0]<<" <path> <overport=-1|0|port> [-1|0|1]\n"; | ||
| 135 | return -1; | ||
| 136 | } | ||
| 137 | PATH=argv[1]; if(PATH.back()=='/') PATH=PATH.popb(); | ||
| 138 | setenv("DOCROOT",PATH.c_str(),1); | ||
| 139 | int overport=atoi(argv[2]); | ||
| 140 | int cmd=argc>3?atoi(argv[3]):0; | ||
| 141 | if(cmd) ProcTerminate(PATH+PIDURI); | ||
| 142 | if(cmd>=0) { if(fork()==0) Daemon(overport); } | ||
| 143 | delete SERV; | ||
| 144 | return 0; | ||
| 145 | } | ||
| 146 | catch(const merror_t& e) { | ||
| 147 | merr<<"ERROR: ["<<e.desc<<"]\n"; | ||
| 148 | return -1; | ||
| 149 | } | ||
| 150 | catch(...) { | ||
| 151 | merr<<"ERROR: [FATAL]\n"; | ||
| 152 | return -1; | ||
| 153 | } | ||
diff --git a/src/net/isocket.cc b/src/net/isocket.cc new file mode 100644 index 0000000..af94189 --- /dev/null +++ b/src/net/isocket.cc | |||
| @@ -0,0 +1,58 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <net/isocket.h> | ||
| 21 | #include <errno.h> | ||
| 22 | |||
| 23 | isocket::isocket(const in_addr& ia,int port,int backlog): | ||
| 24 | pipe_stream(-1),rd(-1) | ||
| 25 | { | ||
| 26 | if(port) { | ||
| 27 | fd=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); | ||
| 28 | if(fd<0) THROW("isocket: Could not create"); | ||
| 29 | reuse(1); | ||
| 30 | } | ||
| 31 | else fd=0; | ||
| 32 | sa.sin_family=2; | ||
| 33 | sa.sin_port=htons(port); | ||
| 34 | sa.sin_addr=ia; | ||
| 35 | if(port) { | ||
| 36 | if(bind(fd,(sockaddr*)&sa,sizeof(sa))==-1) THROW("isocket: Could not bind"); | ||
| 37 | } | ||
| 38 | if(listen(fd,backlog)==-1) THROW("isocket: Could not listen"); | ||
| 39 | rd.setfd(fd); | ||
| 40 | } | ||
| 41 | |||
| 42 | isocket::isocket(int f,const sockaddr_in& ia): | ||
| 43 | pipe_stream(f),rd(f) | ||
| 44 | { | ||
| 45 | sa=ia; | ||
| 46 | setflag(O_NONBLOCK|O_NDELAY); | ||
| 47 | nodelay(1); | ||
| 48 | } | ||
| 49 | |||
| 50 | isocket* isocket::accept() throw(merror_t) | ||
| 51 | { | ||
| 52 | sockaddr_in tsa; socklen_t tsalen; | ||
| 53 | memset(&tsa,0,tsalen=sizeof(tsa)); | ||
| 54 | int tfd=::accept(fd,(sockaddr*)&tsa,&tsalen); | ||
| 55 | if(tfd>0) return new isocket(tfd,tsa); | ||
| 56 | if(errno!=EAGAIN) THROW("isocket: could not accept"); | ||
| 57 | return 0; | ||
| 58 | } | ||
diff --git a/src/net/isocket.h b/src/net/isocket.h new file mode 100644 index 0000000..5ca1ec3 --- /dev/null +++ b/src/net/isocket.h | |||
| @@ -0,0 +1,68 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef ISOCKETH | ||
| 21 | #define ISOCKETH | ||
| 22 | |||
| 23 | #include <mt/mread.h> | ||
| 24 | #include <mt/mstring.h> | ||
| 25 | #include <sys/socket.h> | ||
| 26 | #include <arpa/inet.h> | ||
| 27 | #include <netinet/in.h> | ||
| 28 | #include <netinet/tcp.h> | ||
| 29 | |||
| 30 | class isocket : public pipe_stream { | ||
| 31 | public: | ||
| 32 | isocket(const in_addr& ia,int port,int backlog); | ||
| 33 | isocket(int f,const sockaddr_in& ia); | ||
| 34 | ~isocket() { close(); } | ||
| 35 | |||
| 36 | void close() { if(fd>=0) { ::close(fd); fd=-1; }} | ||
| 37 | |||
| 38 | int getfd() const { return fd; } | ||
| 39 | int family() const { return sa.sin_family; } | ||
| 40 | int port() const { return ntohs(sa.sin_port); } | ||
| 41 | in_addr address() const { return sa.sin_addr; } | ||
| 42 | |||
| 43 | void reuse(int ok) { set(SOL_SOCKET,SO_REUSEADDR,ok); } | ||
| 44 | void nodelay(int ok) { set(IPPROTO_TCP,TCP_NODELAY,ok); } | ||
| 45 | void keepalive(int ok) { set(SOL_SOCKET,SO_KEEPALIVE,ok); } | ||
| 46 | void sendbufsize(int s) { set(SOL_SOCKET,SO_SNDBUF,s); } | ||
| 47 | void recvbufsize(int s) { set(SOL_SOCKET,SO_RCVBUF,s); } | ||
| 48 | |||
| 49 | isocket* accept() throw(merror_t); | ||
| 50 | |||
| 51 | int test() { return rd.poll(); } | ||
| 52 | int getsome(char* s,int n) { return rd.read(s,n); } | ||
| 53 | int gethead(char* s,int n) { return rd.readpara(s,n); } | ||
| 54 | int getbody(char* s,int n) { return rd.readx(s,n); } | ||
| 55 | |||
| 56 | protected: | ||
| 57 | void setflag(int f) { fcntl(fd,F_SETFL,f); } | ||
| 58 | int getflag() const { return fcntl(fd,F_GETFL,0); } | ||
| 59 | void set(int lev,int opt,int ok) throw(merror_t) { | ||
| 60 | if(setsockopt(fd,lev,opt,(char*)&ok,sizeof(ok))<0) | ||
| 61 | THROW("isocket: Could not set option"); | ||
| 62 | } | ||
| 63 | private: | ||
| 64 | sockaddr_in sa; | ||
| 65 | mread rd; | ||
| 66 | }; | ||
| 67 | |||
| 68 | #endif | ||
diff --git a/src/net/redirect.cc b/src/net/redirect.cc new file mode 100644 index 0000000..7e07e7c --- /dev/null +++ b/src/net/redirect.cc | |||
| @@ -0,0 +1,185 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <net/isocket.h> | ||
| 21 | #include <mail/res.h> | ||
| 22 | #include <http/http.h> | ||
| 23 | #include <mt/lookup.h> | ||
| 24 | #include <mt/lock.h> | ||
| 25 | #include <sys/utsname.h> | ||
| 26 | #include <signal.h> | ||
| 27 | |||
| 28 | static fp_stream merr(stderr); | ||
| 29 | static IPnode NODE; | ||
| 30 | static int PORT; | ||
| 31 | static mstring URL,PATH,SERVER,URL1,URL2; | ||
| 32 | static int volatile RUNNING; | ||
| 33 | |||
| 34 | const mstring REDIRECT="/tmp/redirect."; | ||
| 35 | const int BACKLOG=4; | ||
| 36 | const int SNDBUFSIZE=16384; | ||
| 37 | const int RCVBUFSIZE=16384; | ||
| 38 | const int MAXHEAD=16384; | ||
| 39 | const int SAFEZONE=4096; | ||
| 40 | |||
| 41 | static void BreakURL() | ||
| 42 | { | ||
| 43 | static const mstring pre="//"; | ||
| 44 | int p=URL.find(pre); | ||
| 45 | if(p>=0) { | ||
| 46 | p+=pre.size(); | ||
| 47 | int q=p+URL.right(p).find('/'); | ||
| 48 | if(q>=p) { | ||
| 49 | URL1=URL.left(q); | ||
| 50 | URL2=URL.right(q); | ||
| 51 | } | ||
| 52 | else { | ||
| 53 | URL1=URL; | ||
| 54 | URL2.clear(); | ||
| 55 | } | ||
| 56 | } | ||
| 57 | else throw(0); | ||
| 58 | } | ||
| 59 | |||
| 60 | static mstring Combine(const sref& uri) | ||
| 61 | { | ||
| 62 | const int ncvt=3; | ||
| 63 | static const mstring cvt[ncvt]={"/BODY","/en","/sv"}; | ||
| 64 | mstring d=uri; | ||
| 65 | mstring s=URL1; | ||
| 66 | for(int i=0;i<ncvt;i++) { | ||
| 67 | int p=d.find(cvt[i]); | ||
| 68 | if(p>=0) { | ||
| 69 | d.erase(p,cvt[i].size()); | ||
| 70 | s+=cvt[i]; | ||
| 71 | } | ||
| 72 | } | ||
| 73 | s+=URL2; | ||
| 74 | s+=d; | ||
| 75 | return s; | ||
| 76 | } | ||
| 77 | |||
| 78 | static int Handle(isocket& sock) | ||
| 79 | { | ||
| 80 | mstring buffer(MAXHEAD+SAFEZONE); | ||
| 81 | int nhead=sock.gethead(buffer.data(),MAXHEAD); | ||
| 82 | if(nhead<=0) return 0; | ||
| 83 | httpReq req(sref(buffer.data(),nhead)); | ||
| 84 | httpResp resp; | ||
| 85 | resp.status=HTTP_301; | ||
| 86 | //resp.location=URL+req.uri; | ||
| 87 | resp.location=Combine(req.uri); | ||
| 88 | if(req.arg.nempty()) { resp.location.append(1,'?'); resp.location+=req.arg; } | ||
| 89 | resp.putHead(sock); | ||
| 90 | putend(sock); | ||
| 91 | sock.close(); | ||
| 92 | return 1; | ||
| 93 | } | ||
| 94 | |||
| 95 | /////////////////////////////////////////////////////////////// | ||
| 96 | |||
| 97 | extern "C" { | ||
| 98 | static void onTERM(int sig) { RUNNING=0; } | ||
| 99 | typedef void (*disp_t)(int); | ||
| 100 | } | ||
| 101 | |||
| 102 | static void MainProc(isocket& sock) | ||
| 103 | { | ||
| 104 | RUNNING=1; | ||
| 105 | while(RUNNING) { | ||
| 106 | int test=sock.test(); | ||
| 107 | if(test>0) { | ||
| 108 | try { | ||
| 109 | isocket* s=sock.accept(); | ||
| 110 | if(s) Handle(*s); | ||
| 111 | } | ||
| 112 | catch(const merror_t& e) { | ||
| 113 | merr<<"SOCKET: "<<e.desc<<"\n"; | ||
| 114 | } | ||
| 115 | } | ||
| 116 | else if(test<0) RUNNING=0; | ||
| 117 | } | ||
| 118 | } | ||
| 119 | |||
| 120 | /////////////////////////////////////////////////////////////// | ||
| 121 | |||
| 122 | static void httpServer() | ||
| 123 | { | ||
| 124 | isocket sock(NODE.addr,PORT,BACKLOG); | ||
| 125 | sock.keepalive(1); | ||
| 126 | sock.sendbufsize(SNDBUFSIZE); | ||
| 127 | sock.recvbufsize(RCVBUFSIZE); | ||
| 128 | sigignore(SIGPIPE); | ||
| 129 | disp_t onterm=signal(SIGTERM,onTERM); | ||
| 130 | disp_t onint=signal(SIGINT,onTERM); | ||
| 131 | MainProc(sock); | ||
| 132 | signal(SIGINT,onint); | ||
| 133 | signal(SIGTERM,onterm); | ||
| 134 | } | ||
| 135 | |||
| 136 | static void Daemon() try | ||
| 137 | { | ||
| 138 | PROCLOCK(PATH); | ||
| 139 | merr<<"redirect: "<<SERVER<<" -> "<<URL<<" started\n"; | ||
| 140 | httpServer(); | ||
| 141 | } | ||
| 142 | catch(const merror_t& e) { | ||
| 143 | if(First(e.desc)!=sref("proclock:")) merr<<e.desc<<"\n"; | ||
| 144 | } | ||
| 145 | catch(...) { | ||
| 146 | merr<<"FATAL\n"; | ||
| 147 | } | ||
| 148 | |||
| 149 | main(int argc,char* argv[]) try | ||
| 150 | { | ||
| 151 | if(argc<3) { | ||
| 152 | merr<<"Usage: "<<argv[0]<<" [host:]<port> <url> [-1|0|1]\n"; | ||
| 153 | return -1; | ||
| 154 | } | ||
| 155 | sref s(argv[1]); | ||
| 156 | mstring host=s.left_last(':'); | ||
| 157 | mstring sport=s.past_last(':'); | ||
| 158 | if(sport.empty()) { | ||
| 159 | sport=host; | ||
| 160 | host.clear(); | ||
| 161 | } | ||
| 162 | PORT=atoi(sport); | ||
| 163 | URL=argv[2]; | ||
| 164 | if(URL.back()=='/') URL=URL.popb(); | ||
| 165 | BreakURL(); | ||
| 166 | if(host.empty()) { | ||
| 167 | struct utsname u; uname(&u); | ||
| 168 | host=u.nodename; | ||
| 169 | } | ||
| 170 | Lookup(NODE,host); | ||
| 171 | SERVER=NODE.name; SERVER.append(1,'-'); SERVER+=itoa(PORT); | ||
| 172 | PATH=REDIRECT; PATH+=SERVER; | ||
| 173 | int cmd=argc>3?atoi(argv[3]):0; | ||
| 174 | if(cmd) ProcTerminate(PATH); | ||
| 175 | if(cmd>=0) { if(fork()==0) Daemon(); } | ||
| 176 | return 0; | ||
| 177 | } | ||
| 178 | catch(const merror_t& e) { | ||
| 179 | merr<<"ERROR: ["<<e.desc<<"]\n"; | ||
| 180 | return -1; | ||
| 181 | } | ||
| 182 | catch(...) { | ||
| 183 | merr<<"ERROR: [FATAL]\n"; | ||
| 184 | return -1; | ||
| 185 | } | ||
diff --git a/src/net/route80.cc b/src/net/route80.cc new file mode 100644 index 0000000..e883aba --- /dev/null +++ b/src/net/route80.cc | |||
| @@ -0,0 +1,64 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <net/isocket.h> | ||
| 21 | #include <mt/lookup.h> | ||
| 22 | #include <sys/utsname.h> | ||
| 23 | |||
| 24 | static fp_stream merr(stderr); | ||
| 25 | static IPnode NODE; | ||
| 26 | static mstring PATH; | ||
| 27 | static int PORT; | ||
| 28 | |||
| 29 | const int BACKLOG=4; | ||
| 30 | const int SNDBUFSIZE=16384; | ||
| 31 | const int RCVBUFSIZE=16384; | ||
| 32 | |||
| 33 | /////////////////////////////////////////////////////////////// | ||
| 34 | |||
| 35 | static void MainProc(isocket& sock) | ||
| 36 | { | ||
| 37 | int fd=dup2(sock.fd,0); | ||
| 38 | if(fd!=0) { merr<<"Not right\n"; return; } | ||
| 39 | execl("htcd","htcd",PATH.c_str(),"-1",0); | ||
| 40 | } | ||
| 41 | |||
| 42 | /////////////////////////////////////////////////////////////// | ||
| 43 | |||
| 44 | static void httpServer() | ||
| 45 | { | ||
| 46 | isocket sock(NODE.addr,PORT,BACKLOG); | ||
| 47 | sock.keepalive(1); | ||
| 48 | sock.sendbufsize(SNDBUFSIZE); | ||
| 49 | sock.recvbufsize(RCVBUFSIZE); | ||
| 50 | MainProc(sock); | ||
| 51 | } | ||
| 52 | |||
| 53 | main(int argc,char* argv[]) | ||
| 54 | { | ||
| 55 | if(argc<3) { merr<<"Usage: "<<argv[0]<<" <path> <port>\n"; return -1; } | ||
| 56 | PATH=argv[1]; if(PATH.back()=='/') PATH=PATH.popb(); | ||
| 57 | PORT=atoi(argv[2]); | ||
| 58 | struct utsname u; uname(&u); | ||
| 59 | Lookup(NODE,sref(u.nodename)); | ||
| 60 | httpServer(); | ||
| 61 | return 0; | ||
| 62 | } | ||
| 63 | |||
| 64 | |||
diff --git a/src/net/server.cc b/src/net/server.cc new file mode 100644 index 0000000..6996b20 --- /dev/null +++ b/src/net/server.cc | |||
| @@ -0,0 +1,75 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <net/server.h> | ||
| 21 | |||
| 22 | const mstring SERVURI="/htc/server.htc"; | ||
| 23 | |||
| 24 | htcServ::htcServ(const sref& path) : htcd(path),user(htcd.toks) | ||
| 25 | { | ||
| 26 | Setup(user,htcd); | ||
| 27 | LoadBuffer(server,path+SERVURI); | ||
| 28 | } | ||
| 29 | |||
| 30 | /////////////////////////////////////////////////////// | ||
| 31 | |||
| 32 | static void Log(fp_stream& tlog,htcd_req& R,const sref& status) | ||
| 33 | { | ||
| 34 | MLOCK(R.htcd()->mutex); | ||
| 35 | tlog<<"["<<time(0)<<"]["<<R.tcp->node.ip<<"][" | ||
| 36 | <<R.tcp->node.name<<":"<<R.tcp->port<<"][" | ||
| 37 | <<R.group<<":"<<R.user.uid()<<"][" | ||
| 38 | <<First(status)<<"]["<<R.req->method<<"][" | ||
| 39 | <<R.req->uri<<"]["<<R.req->arg<<"]\n"; | ||
| 40 | tlog.flush(); | ||
| 41 | } | ||
| 42 | |||
| 43 | /////////////////////////////////////////////////////// | ||
| 44 | |||
| 45 | int SendStatus(isocket& out,htcd_req& R,int keep,const sref& status,const sref& msg) | ||
| 46 | { | ||
| 47 | R.resp.status=status; | ||
| 48 | if(atof(R.req->version.past_first(http_ver))<http_major) R.resp.version=HTTP_V10; | ||
| 49 | if(keep) R.resp.connect=keep_tag; | ||
| 50 | if(R.resp.cont_enc.nempty()|| | ||
| 51 | R.resp.trans_enc.nempty()|| | ||
| 52 | R.resp.status==HTTP_100|| | ||
| 53 | R.resp.status==HTTP_204|| | ||
| 54 | R.resp.status==HTTP_304|| | ||
| 55 | eqn(R.req->method,HTTP_HEAD)) { | ||
| 56 | R.resp.cont_type.clear(); | ||
| 57 | R.resp.cont_length.clear(); | ||
| 58 | } | ||
| 59 | else { | ||
| 60 | if(R.resp.cont_type.empty()) R.resp.cont_type=http_mime_default; | ||
| 61 | R.resp.cont_length=itoa(msg.size()); | ||
| 62 | } | ||
| 63 | Log(R.htcd()->logger,R,status); | ||
| 64 | R.resp.putHead(out); | ||
| 65 | putend(out); | ||
| 66 | out<<msg; | ||
| 67 | #if 0 | ||
| 68 | static fp_stream merr(stderr); | ||
| 69 | merr<<"AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\n"; | ||
| 70 | R.resp.putHead(merr); | ||
| 71 | putend(merr); | ||
| 72 | merr<<"=================================\n"; | ||
| 73 | #endif | ||
| 74 | return out.hup?0:keep; | ||
| 75 | } | ||
diff --git a/src/net/server.h b/src/net/server.h new file mode 100644 index 0000000..65f884c --- /dev/null +++ b/src/net/server.h | |||
| @@ -0,0 +1,46 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef SERVERH | ||
| 21 | #define SERVERH | ||
| 22 | |||
| 23 | #include <serv/htcd.h> | ||
| 24 | #include <hdb/buffer.h> | ||
| 25 | #include <net/isocket.h> | ||
| 26 | #include <mt/lock.h> | ||
| 27 | #include <signal.h> | ||
| 28 | |||
| 29 | const mstring http_ver="HTTP/"; | ||
| 30 | const double http_minor=1.0,http_major=1.1; | ||
| 31 | |||
| 32 | const mstring keep_tag="Keep-Alive"; | ||
| 33 | const mstring close_tag="Close"; | ||
| 34 | const mstring expect_continue_tag="100-continue"; | ||
| 35 | |||
| 36 | struct htcServ { | ||
| 37 | HTCd htcd; | ||
| 38 | tokmap user; | ||
| 39 | mstring server; | ||
| 40 | htcServ(const sref& path); | ||
| 41 | }; | ||
| 42 | |||
| 43 | int SendStatus(isocket& out,htcd_req& R,int keep, | ||
| 44 | const sref& status,const sref& msg=ms_empty); | ||
| 45 | |||
| 46 | #endif | ||
diff --git a/src/net/test.cc b/src/net/test.cc new file mode 100644 index 0000000..c0e3b41 --- /dev/null +++ b/src/net/test.cc | |||
| @@ -0,0 +1,44 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <mt/mlock.h> | ||
| 21 | #include <iostream> | ||
| 22 | using namespace std; | ||
| 23 | |||
| 24 | static mutex_t mutex; | ||
| 25 | static mtcond_t cond; | ||
| 26 | |||
| 27 | static void* thread(void* a) | ||
| 28 | { | ||
| 29 | cerr<<"thread "<<a<<endl; | ||
| 30 | MSUSPEND(mutex,cond); | ||
| 31 | return 0; | ||
| 32 | } | ||
| 33 | |||
| 34 | main() | ||
| 35 | { | ||
| 36 | pthread_t tid; | ||
| 37 | pthread_create(&tid,0,thread,(void*)2); | ||
| 38 | cerr<<"main thread"<<endl; | ||
| 39 | sleep(2); | ||
| 40 | MCONTINUE(cond); | ||
| 41 | pthread_join(tid,0); | ||
| 42 | cerr<<"afer join"<<endl; | ||
| 43 | return 0; | ||
| 44 | } | ||
diff --git a/src/net/thrserv.cc b/src/net/thrserv.cc new file mode 100644 index 0000000..0d91d12 --- /dev/null +++ b/src/net/thrserv.cc | |||
| @@ -0,0 +1,255 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <net/thrserv.h> | ||
| 21 | #include <errno.h> | ||
| 22 | |||
| 23 | const mstring cron_tag="\\run.cron"; | ||
| 24 | const mstring FATAL="FATAL ERROR"; | ||
| 25 | const mstring UNKNOWN="UNKNOWN"; | ||
| 26 | const mstring REJECTED="REJECTED"; | ||
| 27 | |||
| 28 | const int MAXHEAD=16384; | ||
| 29 | const int MAXBODY=2<<21; | ||
| 30 | const int MAXURI=4096; | ||
| 31 | const int MAXARG=4096; | ||
| 32 | const int SAFEZONE=4096; | ||
| 33 | |||
| 34 | /////////////////////////////////////////////////////////////// | ||
| 35 | |||
| 36 | thrServ::thrServ(htcServ& server): | ||
| 37 | pmutex(MUTEX_INIT), | ||
| 38 | pcond(MTCOND_INIT), | ||
| 39 | keepalive(0),running(0),termok(0), | ||
| 40 | first(time(0)),last(time(0)), | ||
| 41 | serv(&server), | ||
| 42 | sock(0), | ||
| 43 | user(server.user,server.htcd.docroot) | ||
| 44 | { | ||
| 45 | } | ||
| 46 | |||
| 47 | thrServ::~thrServ() | ||
| 48 | { | ||
| 49 | delete sock; | ||
| 50 | } | ||
| 51 | |||
| 52 | void thrServ::reset(isocket* s,int keep) | ||
| 53 | { | ||
| 54 | keepalive=keep; | ||
| 55 | running=1; | ||
| 56 | termok=0; | ||
| 57 | first=time(0); | ||
| 58 | last=time(0); | ||
| 59 | sock=s; | ||
| 60 | while(!tid); | ||
| 61 | if(MCONTINUE(pcond)) throw((int)0); | ||
| 62 | } | ||
| 63 | |||
| 64 | void thrServ::Log(const sref& msg) | ||
| 65 | { | ||
| 66 | MLOCK(serv->htcd.mutex); | ||
| 67 | if(sock) serv->htcd.errlog<<"["<<time(0)<<"]["<<tid<<"][" | ||
| 68 | <<inet_ntoa(sock->address())<<":"<<sock->port()<<"][" | ||
| 69 | <<msg<<"]\n"; | ||
| 70 | else serv->htcd.errlog<<"["<<time(0)<<"]["<<tid<<"]["<<msg<<"]\n"; | ||
| 71 | serv->htcd.errlog.flush(); | ||
| 72 | } | ||
| 73 | |||
| 74 | void thrServ::enter() | ||
| 75 | { | ||
| 76 | tid=pthread_self(); | ||
| 77 | MSUSPEND(pmutex,pcond) | ||
| 78 | while(serv->htcd.running&&!termok) { | ||
| 79 | session(); | ||
| 80 | delete sock; | ||
| 81 | sock=0; | ||
| 82 | if(serv->htcd.running&&!termok) { | ||
| 83 | MSUSPEND(pmutex,pcond) | ||
| 84 | } | ||
| 85 | } | ||
| 86 | } | ||
| 87 | |||
| 88 | void thrServ::session() try | ||
| 89 | { | ||
| 90 | int keep=1; | ||
| 91 | while(sock&&keep&&running) { | ||
| 92 | int test=sock->test(); | ||
| 93 | if(test>0) { last=time(0); keep=handle(); } | ||
| 94 | else if(test<0) keep=0; | ||
| 95 | } | ||
| 96 | } | ||
| 97 | catch(const merror_t& e) { | ||
| 98 | Log(e.desc); | ||
| 99 | } | ||
| 100 | catch(...) { | ||
| 101 | Log(FATAL); | ||
| 102 | } | ||
| 103 | |||
| 104 | /////////////////////////////////////////////////////////////// | ||
| 105 | |||
| 106 | thrCron::thrCron(htcServ& server): | ||
| 107 | tid(0),running(0),serv(&server),user(server.user,server.htcd.docroot) | ||
| 108 | { | ||
| 109 | } | ||
| 110 | |||
| 111 | void thrCron::Log(const sref& msg) | ||
| 112 | { | ||
| 113 | MLOCK(serv->htcd.mutex); | ||
| 114 | serv->htcd.errlog<<"["<<time(0)<<"][CRON]["<<msg<<"]\n"; | ||
| 115 | serv->htcd.errlog.flush(); | ||
| 116 | } | ||
| 117 | |||
| 118 | void thrCron::enter() try | ||
| 119 | { | ||
| 120 | tid=pthread_self(); | ||
| 121 | tcpReq tcp; tcp.port=0; | ||
| 122 | httpReq req; | ||
| 123 | mstream devnull; | ||
| 124 | htcd_req R(serv->htcd,user.toks,devnull,tcp,req); | ||
| 125 | Env env(serv->htcd.ops,R,XSYSTEM); | ||
| 126 | env.req->running=&running; | ||
| 127 | running=1; | ||
| 128 | mstream m; | ||
| 129 | env.parse(m,cron_tag); | ||
| 130 | } | ||
| 131 | catch(const merror_t& e) { | ||
| 132 | Log(e.desc); | ||
| 133 | } | ||
| 134 | catch(...) { | ||
| 135 | Log(FATAL); | ||
| 136 | } | ||
| 137 | |||
| 138 | |||
| 139 | /////////////////////////////////////////////////////////////// | ||
| 140 | |||
| 141 | int thrServ::handle() | ||
| 142 | { | ||
| 143 | tcpReq tcp; | ||
| 144 | tcp.port=sock->port(); | ||
| 145 | if(!Lookup(tcp.node,sock->address())) { | ||
| 146 | Log(REJECTED); | ||
| 147 | return 0; | ||
| 148 | } | ||
| 149 | |||
| 150 | ////////////////////////////////////////////////////////////////// | ||
| 151 | |||
| 152 | mstring buffer(MAXHEAD+MAXBODY+SAFEZONE); | ||
| 153 | int nhead=sock->gethead(buffer.data(),MAXHEAD); | ||
| 154 | if(nhead==0) return 0; | ||
| 155 | else if(nhead<0) return 0; | ||
| 156 | |||
| 157 | sref message(buffer.data(),nhead); | ||
| 158 | |||
| 159 | #if 0 | ||
| 160 | static fp_stream merr(stderr); | ||
| 161 | merr<<"QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ\n"; | ||
| 162 | merr<<message<<"\n"; | ||
| 163 | merr<<"=====================================\n"; | ||
| 164 | #endif | ||
| 165 | |||
| 166 | httpReq req(message); | ||
| 167 | |||
| 168 | ////////////////////////////////////////////////////////////////// | ||
| 169 | |||
| 170 | int keep=keepalive; | ||
| 171 | if(!eqn(req.connect,keep_tag)) keep=0; | ||
| 172 | |||
| 173 | mswrite cache; | ||
| 174 | htcd_req R(serv->htcd,user.toks,cache,tcp,req); | ||
| 175 | |||
| 176 | ////////////////////////////////////////////////////////////////// | ||
| 177 | |||
| 178 | if(nhead>=MAXHEAD) return SendStatus(*sock,R,keep,HTTP_413); | ||
| 179 | |||
| 180 | if(eqn(req.method,HTTP_TRACE)) { | ||
| 181 | R.resp.cont_type="message/http"; | ||
| 182 | return SendStatus(*sock,R,keep,HTTP_200,buffer.left(nhead)); | ||
| 183 | } | ||
| 184 | |||
| 185 | if(req.expect.nempty()) { | ||
| 186 | if(eqn(req.expect,expect_continue_tag)) SendStatus(*sock,R,keep,HTTP_100); | ||
| 187 | else return SendStatus(*sock,R,keep,HTTP_417); | ||
| 188 | } | ||
| 189 | |||
| 190 | if(req.trans_enc.nempty()||req.cont_enc.nempty()) return SendStatus(*sock,R,0,HTTP_501); | ||
| 191 | |||
| 192 | ////////////////////////////////////////////////////////////////// | ||
| 193 | |||
| 194 | int ilength=atoi(req.cont_length); | ||
| 195 | if(ilength>MAXBODY) return SendStatus(*sock,R,0,HTTP_413); | ||
| 196 | else if(ilength>0) { | ||
| 197 | int nbody=sock->getbody(buffer.data()+nhead,ilength); | ||
| 198 | if(nbody<0) return 0; | ||
| 199 | else { | ||
| 200 | sref sbody(buffer.data()+nhead,nbody); | ||
| 201 | #if 0 | ||
| 202 | static fp_stream merr(stderr); | ||
| 203 | merr<<"PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP\n"; | ||
| 204 | merr<<sbody<<"\n"; | ||
| 205 | merr<<"=====================================\n"; | ||
| 206 | #endif | ||
| 207 | R.AddBody(sbody); | ||
| 208 | if(req.body.size()!=ilength) return 0; | ||
| 209 | } | ||
| 210 | } | ||
| 211 | |||
| 212 | ////////////////////////////////////////////////////////////////// | ||
| 213 | |||
| 214 | if(eqn(req.method,HTTP_OPTIONS)) { | ||
| 215 | R.resp.allow="HEAD GET PUT POST DELETE"; | ||
| 216 | return SendStatus(*sock,R,keep,HTTP_200); | ||
| 217 | } | ||
| 218 | |||
| 219 | ////////////////////////////////////////////////////////////////// | ||
| 220 | |||
| 221 | if(req.cont_length.empty()&&(eqn(req.method,HTTP_PUT)||eqn(req.method,HTTP_POST))) | ||
| 222 | return SendStatus(*sock,R,0,HTTP_411); | ||
| 223 | |||
| 224 | if(eqn(req.method,HTTP_HEAD)|| | ||
| 225 | eqn(req.method,HTTP_GET)|| | ||
| 226 | eqn(req.method,HTTP_PUT)|| | ||
| 227 | eqn(req.method,HTTP_DELETE)|| | ||
| 228 | eqn(req.method,HTTP_POST)) { | ||
| 229 | R.resp.cont_type=mime_texthtml; | ||
| 230 | R.resp.cont_type_charset=mime_default; | ||
| 231 | try { | ||
| 232 | Env env(serv->htcd.ops,R,XSYSTEM); | ||
| 233 | env.req->running=&running; | ||
| 234 | mstream m; | ||
| 235 | env.parse(m,serv->server); | ||
| 236 | if(!env.req->is_running()) THROW("htc: "<<req.uri<<" ended prematurely; reload"); | ||
| 237 | } | ||
| 238 | catch(const merror_t& e) { | ||
| 239 | Log(e.desc); | ||
| 240 | return SendStatus(*sock,R,0,HTTP_503,e.desc); | ||
| 241 | } | ||
| 242 | } | ||
| 243 | else return SendStatus(*sock,R,keep,HTTP_501); | ||
| 244 | |||
| 245 | if(!keepalive) keep=0; | ||
| 246 | if(req.if_mod.nempty()&&R.resp.lastmod.nempty()) { | ||
| 247 | time_t since=cvtTime(req.if_mod),lst=cvtTime(R.resp.lastmod); | ||
| 248 | if(lst<=since) return SendStatus(*sock,R,keep,HTTP_304); | ||
| 249 | } | ||
| 250 | |||
| 251 | mstring status=R.resp.status; | ||
| 252 | if(eqn(req.method,HTTP_HEAD)) return SendStatus(*sock,R,keep,status); | ||
| 253 | else return SendStatus(*sock,R,keep,status,cache.str()); | ||
| 254 | |||
| 255 | } | ||
diff --git a/src/net/thrserv.h b/src/net/thrserv.h new file mode 100644 index 0000000..09307f6 --- /dev/null +++ b/src/net/thrserv.h | |||
| @@ -0,0 +1,79 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef THRSERVH | ||
| 21 | #define THRSERVH | ||
| 22 | |||
| 23 | #include <net/server.h> | ||
| 24 | #include <mt/lookup.h> | ||
| 25 | #include <mt/mlock.h> | ||
| 26 | |||
| 27 | //////////////////////////////////////////////////////// | ||
| 28 | // | ||
| 29 | // MT - safe | ||
| 30 | // Note that mutexes aren't needed here, since control | ||
| 31 | // is flowing from main to child, with possible child | ||
| 32 | // override in local variables. | ||
| 33 | |||
| 34 | struct thrServ { | ||
| 35 | pthread_t ptid; | ||
| 36 | mutex_t pmutex; | ||
| 37 | mtcond_t pcond; | ||
| 38 | volatile int tid,keepalive,running,termok; | ||
| 39 | time_t first,last; | ||
| 40 | htcServ* serv; | ||
| 41 | isocket* sock; | ||
| 42 | htcd_user user; | ||
| 43 | |||
| 44 | thrServ(htcServ& server); | ||
| 45 | ~thrServ(); | ||
| 46 | |||
| 47 | void Log(const sref& msg); | ||
| 48 | void reset(isocket* s,int keep); | ||
| 49 | |||
| 50 | int vacant() const { return sock==0; } | ||
| 51 | int shutdown() { keepalive=0; return sock==0; } | ||
| 52 | void disconnect() { keepalive=0; running=0; } | ||
| 53 | void term() { | ||
| 54 | keepalive=0; | ||
| 55 | running=0; | ||
| 56 | termok=1; | ||
| 57 | MCONTINUE(pcond); | ||
| 58 | } | ||
| 59 | |||
| 60 | void enter(); | ||
| 61 | void session(); | ||
| 62 | int handle(); | ||
| 63 | }; | ||
| 64 | |||
| 65 | //////////////////////////////////////////////////////// | ||
| 66 | |||
| 67 | struct thrCron { | ||
| 68 | pthread_t ptid; | ||
| 69 | volatile int tid,running; | ||
| 70 | htcServ* serv; | ||
| 71 | htcd_user user; | ||
| 72 | |||
| 73 | thrCron(htcServ& server); | ||
| 74 | |||
| 75 | void Log(const sref& msg); | ||
| 76 | void enter(); | ||
| 77 | }; | ||
| 78 | |||
| 79 | #endif | ||
diff --git a/src/ops/basic.cc b/src/ops/basic.cc new file mode 100644 index 0000000..b30e351 --- /dev/null +++ b/src/ops/basic.cc | |||
| @@ -0,0 +1,269 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <ops/operator.h> | ||
| 21 | #include <math.h> | ||
| 22 | |||
| 23 | OP1_IMPL(exp) { out<<exp(atof(a)); } | ||
| 24 | OP1_IMPL(ln) { out<<log(atof(a)); } | ||
| 25 | OP1_IMPL(abs) { out<<fabs(atof(a)); } | ||
| 26 | OP1_IMPL(int) { out<<int(atof(a)); } | ||
| 27 | |||
| 28 | OP1_IMPL(minus) { out<<-atof(a); } | ||
| 29 | OP2_IMPL(minus) { out<<atof(L)-atof(R); } | ||
| 30 | OP1_IMPL(plus) { out<<atof(a); } | ||
| 31 | OP2_IMPL(plus) { out<<atof(L)+atof(R); } | ||
| 32 | OP2_IMPL(mul) { out<<atof(L)*atof(R); } | ||
| 33 | OP2_IMPL(divide) { out<<atof(L)/atof(R); } | ||
| 34 | OP2_IMPL(mod) { | ||
| 35 | double a=atof(L),b=atof(R); | ||
| 36 | a-=b*int(a/b); | ||
| 37 | if(a<0) a+=fabs(b); | ||
| 38 | out<<a; | ||
| 39 | } | ||
| 40 | OP2_IMPL(imod) { out<<(atoi(L)%atoi(R)); } | ||
| 41 | OP2_IMPL(div) { out<<(atoi(L)/atoi(R)); } | ||
| 42 | OP2_IMPL(pow) { out<<pow(atof(L),atof(R)); } | ||
| 43 | |||
| 44 | OP2_IMPL(eq) {out<<(L==R); } | ||
| 45 | OP2_IMPL(ne) {out<<(L!=R);} | ||
| 46 | OP2_IMPL(eqn) {out<<(L.compare(R,cset_lcase)==0);} | ||
| 47 | OP2_IMPL(nen) {out<<(L.compare(R,cset_lcase)!=0);} | ||
| 48 | OP2_IMPL(eqf) {out<<(atof(L)==atof(R));} | ||
| 49 | OP2_IMPL(nef) {out<<(atof(L)!=atof(R));} | ||
| 50 | |||
| 51 | OP1_IMPL(not) {out<<!atob(a);} | ||
| 52 | OP2_IMPL(and) {out<<(atob(L)&atob(R)); } | ||
| 53 | OP2_IMPL(or) {out<<(atob(L)|atob(R)); } | ||
| 54 | OP2_IMPL(xor) {out<<(atob(L)^atob(R)); } | ||
| 55 | |||
| 56 | OP2_IMPL(shiftleft) {out<<(atoi(L)<<atoi(R));} | ||
| 57 | OP2_IMPL(shiftright) {out<<(atoi(L)>>atoi(R));} | ||
| 58 | |||
| 59 | OP1_IMPL(bitnot) {out<<~atoi(a);} | ||
| 60 | OP2_IMPL(bitand) {out<<(atoi(L)&atoi(R)); } | ||
| 61 | OP2_IMPL(bitor) {out<<(atoi(L)|atoi(R)); } | ||
| 62 | OP2_IMPL(bitxor) {out<<(atoi(L)^atoi(R)); } | ||
| 63 | |||
| 64 | OP2_IMPL(SP) {out<<L<<" "<<R;} | ||
| 65 | |||
| 66 | OP2_IMPL(comma) {out<<R;} | ||
| 67 | |||
| 68 | OP1_IMPL(semi) {} | ||
| 69 | OP2_IMPL(semi) {} | ||
| 70 | |||
| 71 | void opAddBasic(opmap& M) | ||
| 72 | { | ||
| 73 | OP_ADD(32,exp, | ||
| 74 | "C style\n" | ||
| 75 | "Natural exponential function\n" | ||
| 76 | "Syntax: exp (real)\n" | ||
| 77 | "Returns: (real)\n" | ||
| 78 | ); | ||
| 79 | OP_ADD(32,ln, | ||
| 80 | "C style\n" | ||
| 81 | "Natural logarithm function\n" | ||
| 82 | "Syntax: ln (real)\n" | ||
| 83 | "Returns: (real)\n" | ||
| 84 | ); | ||
| 85 | OP_ADD(32,abs, | ||
| 86 | "C style\n" | ||
| 87 | "Absolute value\n" | ||
| 88 | "Syntax: abs (real)\n" | ||
| 89 | "Returns: (real)\n" | ||
| 90 | ); | ||
| 91 | OP_ADD(32,int, | ||
| 92 | "C style\n" | ||
| 93 | "Integer truncation\n" | ||
| 94 | "Syntax: int (real)\n" | ||
| 95 | "Returns: (int)\n" | ||
| 96 | "\n" | ||
| 97 | "Note that truncation is just as when converting to int, not rounding\n" | ||
| 98 | ); | ||
| 99 | |||
| 100 | OP_ADDN(30,bitnot,~, | ||
| 101 | "C style\n" | ||
| 102 | "Bitwise NOT\n" | ||
| 103 | "Syntax: ~ (int)\n" | ||
| 104 | "Returns: (int)\n" | ||
| 105 | ); | ||
| 106 | OP_ADDN(30,not,!, | ||
| 107 | "C style\n" | ||
| 108 | "Logical NOT\n" | ||
| 109 | "Syntax: ! (int)\n" | ||
| 110 | "Returns: (int)\n" | ||
| 111 | ); | ||
| 112 | OP_ADD2(30,24,plus,+, | ||
| 113 | "C style\n" | ||
| 114 | "Addition\n" | ||
| 115 | "Syntax: (real) + (real)\n" | ||
| 116 | "Returns: (real)\n" | ||
| 117 | ); | ||
| 118 | OP_ADD2(30,24,minus,-, | ||
| 119 | "C style\n" | ||
| 120 | "Subtraction\n" | ||
| 121 | "Syntax: (real) - (real)\n" | ||
| 122 | "Returns: (real)\n" | ||
| 123 | ); | ||
| 124 | |||
| 125 | OP_ADDN(27,pow,**, | ||
| 126 | "Power\n" | ||
| 127 | "Syntax: (real) a ** (real) b\n" | ||
| 128 | "Returns: (real) a to the power of b\n" | ||
| 129 | ); | ||
| 130 | |||
| 131 | OP_ADDN(26,mul,*, | ||
| 132 | "C style\n" | ||
| 133 | "Multiplication\n" | ||
| 134 | "Syntax: (real) * (real)\n" | ||
| 135 | "Returns: (real)\n" | ||
| 136 | ); | ||
| 137 | OP_ADDN(26,divide,/, | ||
| 138 | "C style\n" | ||
| 139 | "Division\n" | ||
| 140 | "Syntax: (real) / (real)\n" | ||
| 141 | "Returns: (real)\n" | ||
| 142 | "\n" | ||
| 143 | "Note computerese; same precedence as *\n" | ||
| 144 | ); | ||
| 145 | OP_ADDN(26,imod,%, | ||
| 146 | "C style\n" | ||
| 147 | "Integer modulus\n" | ||
| 148 | "Syntax: (int) % (int)\n" | ||
| 149 | "Returns: (int)\n" | ||
| 150 | ); | ||
| 151 | |||
| 152 | OP_ADD(25,div, | ||
| 153 | "Integer division\n" | ||
| 154 | "Syntax: (int) div (int)\n" | ||
| 155 | "Returns: (int)\n" | ||
| 156 | "\n" | ||
| 157 | "Note that this is the same as integer / in C, but with lower precedence\n" | ||
| 158 | ); | ||
| 159 | // plus/minus 24 | ||
| 160 | OP_ADD(23,mod, | ||
| 161 | "General moulus\n" | ||
| 162 | "Syntax: (real) mod (real)\n" | ||
| 163 | "Returns: (real)\n" | ||
| 164 | "\n" | ||
| 165 | "Modulus on ring; negative vals are mapped onto base\n" | ||
| 166 | ); | ||
| 167 | |||
| 168 | OP_ADDN(22,shiftleft,<<, | ||
| 169 | "C style\n" | ||
| 170 | "Shift left\n" | ||
| 171 | "Syntax: (int) << (int)\n" | ||
| 172 | "Returns: (int)\n" | ||
| 173 | ); | ||
| 174 | OP_ADDN(22,shiftright,>>, | ||
| 175 | "C style\n" | ||
| 176 | "Shift right\n" | ||
| 177 | "Syntax: (int) >> (int)\n" | ||
| 178 | "Returns: (int)\n" | ||
| 179 | ); | ||
| 180 | |||
| 181 | OP_ADD(18,eq, | ||
| 182 | "Lexicographic equal\n" | ||
| 183 | "Syntax: (string) eq (string)\n" | ||
| 184 | "Returns: (int)\n" | ||
| 185 | ); | ||
| 186 | OP_ADD(18,eqn, | ||
| 187 | "Lexicographic equal, case insensitive\n" | ||
| 188 | "Syntax: (string) eqn (string)\n" | ||
| 189 | "Returns: (int)\n" | ||
| 190 | ); | ||
| 191 | OP_ADDN(18,eqf,==, | ||
| 192 | "Arithmetic equal\n" | ||
| 193 | "Syntax: (real) == (real)\n" | ||
| 194 | "Returns: (int)\n" | ||
| 195 | ); | ||
| 196 | OP_ADD(18,ne, | ||
| 197 | "Lexicographic not equal\n" | ||
| 198 | "Syntax: (string) ne (string)\n" | ||
| 199 | "Returns: (int)\n" | ||
| 200 | ); | ||
| 201 | OP_ADD(18,nen, | ||
| 202 | "Lexicographic not equal, case insensitive\n" | ||
| 203 | "Syntax: (string) nen (string)\n" | ||
| 204 | "Returns: (int)\n" | ||
| 205 | ); | ||
| 206 | OP_ADDN(18,nef,!=, | ||
| 207 | "Arithmetic not equal\n" | ||
| 208 | "Syntax: (real) != (real)\n" | ||
| 209 | "Returns: (int)\n" | ||
| 210 | ); | ||
| 211 | |||
| 212 | OP_ADDN(16,bitand,&, | ||
| 213 | "C style\n" | ||
| 214 | "Bitwise AND\n" | ||
| 215 | "Syntax: (int) & (int)\n" | ||
| 216 | "Returns: (int)\n" | ||
| 217 | ); | ||
| 218 | OP_ADDN(14,bitxor,^, | ||
| 219 | "C style\n" | ||
| 220 | "Bitwise XOR\n" | ||
| 221 | "Syntax: (int) ^ (int)\n" | ||
| 222 | "Returns: (int)\n" | ||
| 223 | ); | ||
| 224 | OP_ADDN(12,bitor,|, | ||
| 225 | "C style\n" | ||
| 226 | "Bitwise OR\n" | ||
| 227 | "Syntax: (int) | (int)\n" | ||
| 228 | "Returns: (int)\n" | ||
| 229 | ); | ||
| 230 | |||
| 231 | OP_ADDN(10,and,&&, | ||
| 232 | "C style\n" | ||
| 233 | "Logical AND\n" | ||
| 234 | "Syntax: (int) && (int)\n" | ||
| 235 | "Returns: (int)\n" | ||
| 236 | ); | ||
| 237 | OP_ADDN(9,xor,^^, | ||
| 238 | "Logical XOR\n" | ||
| 239 | "Syntax: (int) ^^ (int)\n" | ||
| 240 | "Returns: (int)\n" | ||
| 241 | ); | ||
| 242 | OP_ADDN(8,or,||, | ||
| 243 | "C style\n" | ||
| 244 | "Logical OR\n" | ||
| 245 | "Syntax: (int) || (int)\n" | ||
| 246 | "Returns: (int)\n" | ||
| 247 | ); | ||
| 248 | |||
| 249 | /* | ||
| 250 | OP_ADD(3,SP, | ||
| 251 | "Whitespace padding\n" | ||
| 252 | "Syntax: a ws OR ws a OR a ws b\n" | ||
| 253 | "Returns: a b\n" | ||
| 254 | ); | ||
| 255 | */ | ||
| 256 | |||
| 257 | M.add(new op_t(",",2,impl_comma, | ||
| 258 | "C style\n" | ||
| 259 | "Separate expression\n" | ||
| 260 | "Syntax: a , b\n" | ||
| 261 | "Returns: b\n" | ||
| 262 | )); | ||
| 263 | OP_ADD2(1,1,semi,;, | ||
| 264 | "C style\n" | ||
| 265 | "End expression\n" | ||
| 266 | "Syntax: a ; OR a ; b\n" | ||
| 267 | "Returns: nothing\n" | ||
| 268 | ); | ||
| 269 | } | ||
diff --git a/src/ops/comp.cc b/src/ops/comp.cc new file mode 100644 index 0000000..aa40246 --- /dev/null +++ b/src/ops/comp.cc | |||
| @@ -0,0 +1,134 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <ops/operator.h> | ||
| 21 | #include <ops/nnstyle.h> | ||
| 22 | |||
| 23 | OP2_IMPL(lt) {out<<(L<R);} | ||
| 24 | OP2_IMPL(le) {out<<(L<=R);} | ||
| 25 | OP2_IMPL(ge) {out<<(L>=R);} | ||
| 26 | OP2_IMPL(gt) {out<<(L>R);} | ||
| 27 | OP2_IMPL(ltn) {out<<(L.compare(R,cset_lcase)<0);} | ||
| 28 | OP2_IMPL(len) {out<<(L.compare(R,cset_lcase)<=0);} | ||
| 29 | OP2_IMPL(gen) {out<<(L.compare(R,cset_lcase)>=0);} | ||
| 30 | OP2_IMPL(gtn) {out<<(L.compare(R,cset_lcase)>0);} | ||
| 31 | OP2_IMPL(ltnn) {out<<(nncomp(L,R)<0);} | ||
| 32 | OP2_IMPL(lenn) {out<<(nncomp(L,R)<=0);} | ||
| 33 | OP2_IMPL(genn) {out<<(nncomp(L,R)>=0);} | ||
| 34 | OP2_IMPL(gtnn) {out<<(nncomp(L,R)>0);} | ||
| 35 | OP2_IMPL(ltf) {out<<(atof(L)<atof(R));} | ||
| 36 | OP2_IMPL(lef) {out<<(atof(L)<=atof(R));} | ||
| 37 | OP2_IMPL(gef) {out<<(atof(L)>=atof(R));} | ||
| 38 | OP2_IMPL(gtf) {out<<(atof(L)>atof(R));} | ||
| 39 | |||
| 40 | void opAddComp(opmap& M) | ||
| 41 | { | ||
| 42 | OP_ADD(20,lt, | ||
| 43 | "Lexicographic less than\n" | ||
| 44 | "Syntax: (string) lt (string)\n" | ||
| 45 | "Returns: (int)\n" | ||
| 46 | ); | ||
| 47 | OP_ADD(20,le, | ||
| 48 | "Lexicographic less or equal\n" | ||
| 49 | "Syntax: (string) le (string)\n" | ||
| 50 | "Returns: (int)\n" | ||
| 51 | ); | ||
| 52 | OP_ADD(20,ge, | ||
| 53 | "Lexicographic greater or equal\n" | ||
| 54 | "Syntax: (string) ge (string)\n" | ||
| 55 | "Returns: (int)\n" | ||
| 56 | ); | ||
| 57 | OP_ADD(20,gt, | ||
| 58 | "Lexicographic greater than\n" | ||
| 59 | "Syntax: (string) gt (string)\n" | ||
| 60 | "Returns: (int)\n" | ||
| 61 | ); | ||
| 62 | |||
| 63 | OP_ADD(20,ltn, | ||
| 64 | "Lexicographic less than, case insensitive\n" | ||
| 65 | "Syntax: (string) ltn (string)\n" | ||
| 66 | "Returns: (int)\n" | ||
| 67 | ); | ||
| 68 | OP_ADD(20,len, | ||
| 69 | "Lexicographic less or equal, case insensitive\n" | ||
| 70 | "Syntax: (string) len (string)\n" | ||
| 71 | "Returns: (int)\n" | ||
| 72 | ); | ||
| 73 | OP_ADD(20,gen, | ||
| 74 | "Lexicographic greater or equal, case insensitive\n" | ||
| 75 | "Syntax: (string) gen (string)\n" | ||
| 76 | "Returns: (int)\n" | ||
| 77 | ); | ||
| 78 | OP_ADD(20,gtn, | ||
| 79 | "Lexicographic greater than, case insensitive\n" | ||
| 80 | "Syntax: (string) gtn (string)\n" | ||
| 81 | "Returns: (int)\n" | ||
| 82 | ); | ||
| 83 | |||
| 84 | OP_ADD(20,ltnn, | ||
| 85 | "Lexicographic less than, NN-style\n" | ||
| 86 | "Syntax: (string) ltnn (string)\n" | ||
| 87 | "Returns: (int)\n" | ||
| 88 | "\n" | ||
| 89 | "NN-style compares names as <lastname> <initials>\n" | ||
| 90 | ); | ||
| 91 | OP_ADD(20,lenn, | ||
| 92 | "Lexicographic less or equal, NN-style\n" | ||
| 93 | "Syntax: (string) lenn (string)\n" | ||
| 94 | "Returns: (int)\n" | ||
| 95 | "\n" | ||
| 96 | "NN-style compares names as <lastname> <initials>\n" | ||
| 97 | ); | ||
| 98 | OP_ADD(20,genn, | ||
| 99 | "Lexicographic greater or equal, NN-style\n" | ||
| 100 | "Syntax: (string) genn (string)\n" | ||
| 101 | "Returns: (int)\n" | ||
| 102 | "\n" | ||
| 103 | "NN-style compares names as <lastname> <initials>\n" | ||
| 104 | ); | ||
| 105 | OP_ADD(20,gtnn, | ||
| 106 | "Lexicographic greater than, NN-style\n" | ||
| 107 | "Syntax: (string) gtnn (string)\n" | ||
| 108 | "Returns: (int)\n" | ||
| 109 | "\n" | ||
| 110 | "NN-style compares names as <lastname> <initials>\n" | ||
| 111 | ); | ||
| 112 | |||
| 113 | OP_ADDN(20,ltf,<, | ||
| 114 | "Arithmetic less than\n" | ||
| 115 | "Syntax: (real) < (real)\n" | ||
| 116 | "Returns: (int)\n" | ||
| 117 | ); | ||
| 118 | OP_ADDN(20,lef,<=, | ||
| 119 | "Arithmetic less or equal\n" | ||
| 120 | "Syntax: (real) <= (real)\n" | ||
| 121 | "Returns: (int)\n" | ||
| 122 | ); | ||
| 123 | OP_ADDN(20,gef,>=, | ||
| 124 | "Arithmetic greater or equal\n" | ||
| 125 | "Syntax: (real) >= (real)\n" | ||
| 126 | "Returns: (int)\n" | ||
| 127 | ); | ||
| 128 | OP_ADDN(20,gtf,>, | ||
| 129 | "Arithmetic greater than\n" | ||
| 130 | "Syntax: (real) > (real)\n" | ||
| 131 | "Returns: (int)\n" | ||
| 132 | ); | ||
| 133 | |||
| 134 | } | ||
diff --git a/src/ops/express.cc b/src/ops/express.cc new file mode 100644 index 0000000..2cd3114 --- /dev/null +++ b/src/ops/express.cc | |||
| @@ -0,0 +1,173 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <ops/express.h> | ||
| 21 | |||
| 22 | const mstring sp_tag="SP"; | ||
| 23 | |||
| 24 | //////////////////////////////////////////////////////////////// | ||
| 25 | |||
| 26 | uniheap<sizeof(expr_t)> expr_t::tree; | ||
| 27 | void* expr_t::operator new(size_t n) { return tree.push(); } | ||
| 28 | void expr_t::operator delete(void* p) { tree.pop(p); } | ||
| 29 | |||
| 30 | //////////////////////////////////////////////////////////////// | ||
| 31 | |||
| 32 | inline int precedence(const expr_t* root,const op_t* op) | ||
| 33 | { | ||
| 34 | if(!root->op) return 1; | ||
| 35 | else if(!op) return 0; | ||
| 36 | else if(root->left) { | ||
| 37 | if(root->right) return op->pre2&&root->op->pre2>=op->pre2; | ||
| 38 | else return root->op->pre2>=op->pre1; | ||
| 39 | } | ||
| 40 | else { | ||
| 41 | if(root->right) return op->pre2&&root->op->pre1>=op->pre2; | ||
| 42 | else return root->op->pre1>=op->pre1; | ||
| 43 | } | ||
| 44 | } | ||
| 45 | |||
| 46 | static int ins_node_sp(expr_t*& root,op_env& env, | ||
| 47 | const sref& in,const op_t* op) throw(merror_t) | ||
| 48 | { | ||
| 49 | if(root==0) { root=new expr_t(in,op); root->expand(env); return 1; } | ||
| 50 | else if(precedence(root,op)) { | ||
| 51 | if(op) { root=new expr_t(in,op,root); return 1; } else return 0; | ||
| 52 | } | ||
| 53 | else return ins_node_sp(root->right,env,in,op); | ||
| 54 | } | ||
| 55 | |||
| 56 | static void ins_node(expr_t*& root,op_env& env,const sref& in) throw(merror_t) | ||
| 57 | { | ||
| 58 | const op_t* op=env.ops->get(in); | ||
| 59 | if(!ins_node_sp(root,env,in,op)) { | ||
| 60 | if(!ins_node_sp(root,env,sp_tag,env.ops->get(sp_tag))) | ||
| 61 | THROW("ops: ("<<root->expr<<" ["<<in<<"]): operator expected"); | ||
| 62 | ins_node_sp(root,env,in,op); | ||
| 63 | } | ||
| 64 | } | ||
| 65 | |||
| 66 | /////////////////////////////////////////////////////////////// | ||
| 67 | |||
| 68 | void expr_t::clear() | ||
| 69 | { | ||
| 70 | expr.clear(); | ||
| 71 | op=0; | ||
| 72 | status=OP_ALL; | ||
| 73 | result.clear(); | ||
| 74 | delete left; left=0; | ||
| 75 | delete right; right=0; | ||
| 76 | } | ||
| 77 | |||
| 78 | void expr_t::copy(const expr_t& x) | ||
| 79 | { | ||
| 80 | expr=x.expr; | ||
| 81 | op=x.op; | ||
| 82 | if(x.left) left=new expr_t(*x.left); | ||
| 83 | if(x.right) right=new expr_t(*x.right); | ||
| 84 | } | ||
| 85 | |||
| 86 | void expr_t::trav(mstream& out,int n) | ||
| 87 | { | ||
| 88 | if(n&&left) left->trav(out,n-1); | ||
| 89 | for(int i=0;i<3*n;i++) out.put(' '); | ||
| 90 | out<<"["<<expr<<"]("<<status<<") -> "<<result<<"\n"; | ||
| 91 | if(n&&right) right->trav(out,n-1); | ||
| 92 | } | ||
| 93 | |||
| 94 | void expr_t::expand(op_env& env) throw(merror_t) | ||
| 95 | { | ||
| 96 | if(!op) { | ||
| 97 | sref first,rest=expr; | ||
| 98 | env.split(first,rest); | ||
| 99 | if(first!=expr) { | ||
| 100 | do ins_node(right,env,first); | ||
| 101 | while(env.split(first,rest)); | ||
| 102 | } | ||
| 103 | } | ||
| 104 | } | ||
| 105 | |||
| 106 | /////////////////////////////////////////////////////////////// | ||
| 107 | |||
| 108 | void expr_t::eval(mstream& out,op_env& env,int opt) throw(merror_t) | ||
| 109 | { | ||
| 110 | if(op) { | ||
| 111 | if(left) { | ||
| 112 | if(op->left>1) { | ||
| 113 | if(left->status&opt) { | ||
| 114 | swrite sw(left->result); | ||
| 115 | left->eval(sw,env,opt); | ||
| 116 | } | ||
| 117 | } | ||
| 118 | else if(!op->left) | ||
| 119 | THROW("ops: ("<<left->expr<<" ["<<expr<<"]): not an L operator") | ||
| 120 | else if(left->op) | ||
| 121 | THROW("ops: (["<<left->expr<<"] "<<expr<<"): Lvalue required") | ||
| 122 | else { | ||
| 123 | left->status=OP_LOCAL; | ||
| 124 | left->result=left->expr; | ||
| 125 | } | ||
| 126 | } | ||
| 127 | if(right) { | ||
| 128 | if(op->right>1) { | ||
| 129 | if(right->status&opt) { | ||
| 130 | swrite sw(right->result); | ||
| 131 | right->eval(sw,env,opt); | ||
| 132 | } | ||
| 133 | } | ||
| 134 | else if(!op->right) | ||
| 135 | THROW("ops: ("<<right->expr<<" ["<<expr<<"]): not an R operator") | ||
| 136 | else if(right->op) | ||
| 137 | THROW("ops: (["<<right->expr<<"] "<<expr<<"): Lvalue required") | ||
| 138 | else { | ||
| 139 | right->status=OP_LOCAL; | ||
| 140 | right->result=right->expr; | ||
| 141 | } | ||
| 142 | } | ||
| 143 | if(left) { | ||
| 144 | if(right) { | ||
| 145 | status=left->status|right->status; | ||
| 146 | if((status&OP_NINIT)==0) op->f2(out,env,left->result,right->result); | ||
| 147 | } | ||
| 148 | else if(!op->f1) | ||
| 149 | THROW("ops: ("<<left->expr<<" "<<expr<<" [R]): missing R argument") | ||
| 150 | else { | ||
| 151 | status=left->status; | ||
| 152 | if((status&OP_NINIT)==0) op->f1(out,env,left->result); | ||
| 153 | } | ||
| 154 | } | ||
| 155 | else if(right) { | ||
| 156 | if(!op->f1) | ||
| 157 | THROW("ops: ([L] "<<expr<<" "<<right->expr<<"): missing L argument") | ||
| 158 | else { | ||
| 159 | status=right->status; | ||
| 160 | if((status&OP_NINIT)==0) op->f1(out,env,right->result); | ||
| 161 | } | ||
| 162 | } | ||
| 163 | else THROW("ops: ["<<expr<<"]: operator not expected"); | ||
| 164 | } | ||
| 165 | else { | ||
| 166 | if(right) { | ||
| 167 | right->eval(out,env,opt); | ||
| 168 | status=right->status; | ||
| 169 | } | ||
| 170 | else env.term(out,this); | ||
| 171 | } | ||
| 172 | if(status&OP_NINIT) THROW("ops: unfinished expression ["<<expr<<"]"); | ||
| 173 | } | ||
diff --git a/src/ops/express.h b/src/ops/express.h new file mode 100644 index 0000000..79148f6 --- /dev/null +++ b/src/ops/express.h | |||
| @@ -0,0 +1,79 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef EXPRESSH | ||
| 21 | #define EXPRESSH | ||
| 22 | |||
| 23 | #include <ops/operator.h> | ||
| 24 | #include <mt/split.h> | ||
| 25 | #include <mt/uniheap.h> | ||
| 26 | |||
| 27 | const int OP_LOCAL=1; | ||
| 28 | const int OP_GLOBAL=2; | ||
| 29 | const int OP_NINIT=4; | ||
| 30 | const int OP_ALL=OP_LOCAL|OP_GLOBAL|OP_NINIT; | ||
| 31 | |||
| 32 | class expr_t { | ||
| 33 | public: | ||
| 34 | sref expr; | ||
| 35 | const op_t* op; | ||
| 36 | int status; | ||
| 37 | mstring result; | ||
| 38 | expr_t *left,*right; | ||
| 39 | |||
| 40 | expr_t(): | ||
| 41 | expr(),op(0),status(OP_ALL),result(),left(0),right(0) {} | ||
| 42 | expr_t(const expr_t& x): | ||
| 43 | expr(),op(0),status(OP_ALL),result(),left(0),right(0) { copy(x); } | ||
| 44 | expr_t(const sref& s): | ||
| 45 | expr(s),op(0),status(OP_ALL),result(),left(0),right(0) {} | ||
| 46 | expr_t(const sref& s,const op_t* o): | ||
| 47 | expr(s),op(o),status(OP_ALL),result(),left(0),right(0) {} | ||
| 48 | expr_t(const sref& s,const op_t* o,expr_t* p): | ||
| 49 | expr(s),op(o),status(OP_ALL),result(),left(p),right(0) {} | ||
| 50 | ~expr_t() { delete left; delete right; } | ||
| 51 | |||
| 52 | void clear(); | ||
| 53 | expr_t& operator=(const expr_t& x) { clear(); copy(x); return *this; } | ||
| 54 | expr_t& operator=(const sref& in) { clear(); expr=in; return *this; } | ||
| 55 | |||
| 56 | void trav(mstream& out,int n); | ||
| 57 | void expand(op_env& env) throw(merror_t); | ||
| 58 | void eval(mstream& out,op_env& env,int opt) throw(merror_t); | ||
| 59 | |||
| 60 | static void* operator new(size_t n); | ||
| 61 | static void operator delete(void* p); | ||
| 62 | protected: | ||
| 63 | void copy(const expr_t& x); | ||
| 64 | static uniheap<36> tree; | ||
| 65 | }; | ||
| 66 | |||
| 67 | //////////////////////////////////////////////////////////// | ||
| 68 | |||
| 69 | struct op_env { | ||
| 70 | opmap* ops; | ||
| 71 | |||
| 72 | op_env() : ops(0) {} | ||
| 73 | op_env(opmap& map) : ops(&map) {} | ||
| 74 | |||
| 75 | virtual int split(sref& first,sref& rest) throw(merror_t) { return 0; } | ||
| 76 | virtual void term(mstream& out,expr_t* x) throw(merror_t) { x->status=0; } | ||
| 77 | }; | ||
| 78 | |||
| 79 | #endif | ||
diff --git a/src/ops/latex.cc b/src/ops/latex.cc new file mode 100644 index 0000000..01ccfc0 --- /dev/null +++ b/src/ops/latex.cc | |||
| @@ -0,0 +1,101 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <ops/express.h> | ||
| 21 | #include <math.h> | ||
| 22 | |||
| 23 | OP1_IMPL(minus) {out<<"-"<<a;} | ||
| 24 | OP1_IMPL(plus) {out<<"+"<<a;} | ||
| 25 | OP1_IMPL(plusminus) {out<<"\\pm"<<a;} | ||
| 26 | OP1_IMPL(minusplus) {out<<"\\mp"<<a;} | ||
| 27 | |||
| 28 | OP2_IMPL(minus) {out<<L<<"-"<<R;} | ||
| 29 | OP2_IMPL(plus) {out<<L<<"+"<<R;} | ||
| 30 | OP2_IMPL(plusminus) {out<<L<<"\\pm"<<R;} | ||
| 31 | OP2_IMPL(minusplus) {out<<L<<"\\mp"<<R;} | ||
| 32 | |||
| 33 | OP2_IMPL(mul) {out<<L<<"\times"<<R;} | ||
| 34 | OP2_IMPL(divide) {out<<L<<"/"<<R;} | ||
| 35 | OP2_IMPL(pow) {out<<L<<"<sup><font size=-1>"<<R<<"</font></sup>";} | ||
| 36 | OP1_IMPL(pow) {out<<"<sup><font size=-1>"<<a<<"</font></sup>";} | ||
| 37 | OP2_IMPL(sub) {out<<L<<"<sub><font size=-1>"<<R<<"</font></sub>";} | ||
| 38 | OP1_IMPL(sub) {out<<"<sub><font size=-1>"<<a<<"</font></sub>";} | ||
| 39 | OP2_IMPL(div) {out<<L<<"\\div"<<R;} | ||
| 40 | |||
| 41 | OP2_IMPL(lt) {out<<L<<"<"<<R;} | ||
| 42 | OP2_IMPL(le) {out<<L<<"\\leq"<<R;} | ||
| 43 | OP2_IMPL(eq) {out<<L<<"="<<R;} | ||
| 44 | OP2_IMPL(ne) {out<<L<<"\\neq"<<R;} | ||
| 45 | OP2_IMPL(ge) {out<<L<<"\\geq"<<R;} | ||
| 46 | OP2_IMPL(gt) {out<<L<<">"<<R;} | ||
| 47 | |||
| 48 | OP2_IMPL(equiv) {out<<L<<"\\equiv"<<R;} | ||
| 49 | OP2_IMPL(sim) {out<<L<<"\\sim"<<R;} | ||
| 50 | OP2_IMPL(simeq) {out<<L<<"\\simeq"<<R;} | ||
| 51 | |||
| 52 | OP1_IMPL(not) {out<<"!"<<a;} | ||
| 53 | OP2_IMPL(and) {out<<L<<" and "<<R;} | ||
| 54 | OP2_IMPL(or) {out<<L<<" or "<<R;} | ||
| 55 | OP2_IMPL(xor) {out<<L<<" xor "<<R;} | ||
| 56 | |||
| 57 | OP2_IMPL(assign) {out<<L<<" = "<<R;} | ||
| 58 | |||
| 59 | OP2_IMPL(SP) {out<<L<<" "<<R;} | ||
| 60 | |||
| 61 | OP1_IMPL(semi) {out<<a;} | ||
| 62 | OP2_IMPL(semi) {out<<L<<R;} | ||
| 63 | |||
| 64 | void opAddLatex(opmap& M) | ||
| 65 | { | ||
| 66 | OP_ADD(30,not,"logic not"); | ||
| 67 | |||
| 68 | OP_ADD2(30,28,sub,_,"sub index"); | ||
| 69 | OP_ADD2(30,27,pow,^,"raised index"); | ||
| 70 | |||
| 71 | OP_ADD2(30,24,plus,+,"plus"); | ||
| 72 | OP_ADD2(30,24,minus,-,"minus"); | ||
| 73 | OP_ADD2(30,24,plusminus,+-,"plusminus"); | ||
| 74 | OP_ADD2(30,24,minusplus,-+,"minusplus"); | ||
| 75 | |||
| 76 | OP_ADDN(26,mul,*,"multiply"); | ||
| 77 | OP_ADDN(25,divide,/,"divide"); | ||
| 78 | OP_ADD(25,div,"divide-sign"); | ||
| 79 | // plus/minus 24 | ||
| 80 | |||
| 81 | OP_ADDN(20,lt,<,"less than"); | ||
| 82 | OP_ADDN(20,le,<=,"less or equal"); | ||
| 83 | OP_ADDN(20,ge,>=,"greater or equal"); | ||
| 84 | OP_ADDN(20,gt,>,"greater than"); | ||
| 85 | |||
| 86 | OP_ADDN(18,eq,==,"equal"); | ||
| 87 | OP_ADDN(18,ne,!=,"not equal"); | ||
| 88 | OP_ADDN(18,equiv,===,"equivalent"); | ||
| 89 | OP_ADDN(18,sim,~,"similar"); | ||
| 90 | OP_ADDN(18,simeq,~=,"similar equal"); | ||
| 91 | |||
| 92 | OP_ADD(10,and,"logic and"); | ||
| 93 | OP_ADD(9,xor,"logic xor"); | ||
| 94 | OP_ADD(8,or,"logic or"); | ||
| 95 | |||
| 96 | OP_ADDN(4,assign,=,"assignment"); | ||
| 97 | |||
| 98 | OP_ADD(3,SP,"Whitespace padding"); | ||
| 99 | |||
| 100 | OP_ADD2(1,1,semi,;,"concatenation"); | ||
| 101 | } | ||
diff --git a/src/ops/nnstyle.h b/src/ops/nnstyle.h new file mode 100644 index 0000000..4b8be5e --- /dev/null +++ b/src/ops/nnstyle.h | |||
| @@ -0,0 +1,53 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef NNSTYLEH | ||
| 21 | #define NNSTYLEH | ||
| 22 | |||
| 23 | #include <mt/split.h> | ||
| 24 | |||
| 25 | const charset cset_wsdot=cset_ws|'.'; | ||
| 26 | |||
| 27 | inline mstring nncase(const sref& b) | ||
| 28 | { | ||
| 29 | static const mstring comma_tag(","),and_tag("and"); | ||
| 30 | mstring acc,a,name; | ||
| 31 | sref next,first,rest=b; | ||
| 32 | while(Split(first,rest,cset_wsdot)) { | ||
| 33 | if(first==comma_tag||eqn(first,and_tag)) continue; | ||
| 34 | (name=first.left_first(comma_tag)).tosim(); | ||
| 35 | name[0]=cset_ucase[name[0]]; | ||
| 36 | next=First(rest); | ||
| 37 | if(first.back()==','||next.empty()||*next==','||eqn(next,and_tag)) { | ||
| 38 | a.insert(0,name); | ||
| 39 | if(acc.nempty()) { acc+=' '; acc+=and_tag; acc+=' '; } | ||
| 40 | acc+=a; | ||
| 41 | a.clear(); | ||
| 42 | } | ||
| 43 | else { a+=' '; a+=name[0]; a+='.'; } | ||
| 44 | } | ||
| 45 | return acc; | ||
| 46 | } | ||
| 47 | |||
| 48 | inline int nncomp(const sref& L,const sref& R) | ||
| 49 | { | ||
| 50 | return nncase(L).compare(nncase(R)); | ||
| 51 | } | ||
| 52 | |||
| 53 | #endif | ||
diff --git a/src/ops/operator.cc b/src/ops/operator.cc new file mode 100644 index 0000000..f668340 --- /dev/null +++ b/src/ops/operator.cc | |||
| @@ -0,0 +1,44 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <ops/operator.h> | ||
| 21 | #include <algorithm> | ||
| 22 | using namespace std; | ||
| 23 | |||
| 24 | void opmap::clear() { | ||
| 25 | for(iterator p=begin();p!=end();p++) delete *p; | ||
| 26 | mrvec<opmap_t>::clear(); | ||
| 27 | } | ||
| 28 | void opmap::erase(iterator p) { | ||
| 29 | delete *p; mrvec<opmap_t>::erase(p); | ||
| 30 | } | ||
| 31 | |||
| 32 | const op_t* opmap::get(const sref& t) const | ||
| 33 | { | ||
| 34 | pair<const_iterator,const_iterator> p= | ||
| 35 | equal_range(begin(),end(),(opmap_t)0,comp_t(t)); | ||
| 36 | return p.first!=p.second?*p.first:0; | ||
| 37 | } | ||
| 38 | |||
| 39 | const op_t* opmap::add(op_t* op) | ||
| 40 | { | ||
| 41 | pair<iterator,iterator> p=equal_range(begin(),end(),(opmap_t)0,comp_t(op->name)); | ||
| 42 | if(p.first!=p.second) { delete *p.first; return *p.first=op; } | ||
| 43 | else return *insert(p.second,op); | ||
| 44 | } | ||
diff --git a/src/ops/operator.h b/src/ops/operator.h new file mode 100644 index 0000000..d4a7af8 --- /dev/null +++ b/src/ops/operator.h | |||
| @@ -0,0 +1,97 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef OPERATORH | ||
| 21 | #define OPERATORH | ||
| 22 | |||
| 23 | #include <mt/mstring.h> | ||
| 24 | #include <mt/mvec.h> | ||
| 25 | |||
| 26 | const mstring lt_tag="lt"; | ||
| 27 | |||
| 28 | /////////////////////////////////////////////// | ||
| 29 | |||
| 30 | class op_env; | ||
| 31 | struct op_t { | ||
| 32 | typedef void (*op1_t)(mstream&,op_env&,const sref&); | ||
| 33 | typedef void (*op2_t)(mstream&,op_env&,const sref&,const sref&); | ||
| 34 | |||
| 35 | mstring name,desc; | ||
| 36 | int pre1,pre2; | ||
| 37 | int left,right; | ||
| 38 | op1_t f1; op2_t f2; | ||
| 39 | |||
| 40 | op_t(const mstring& s,int p1,int p2,int l,int r,op1_t op1,op2_t op2,const mstring& d): | ||
| 41 | name(s),pre1(p1),pre2(p2),left(l),right(r),f1(op1),f2(op2),desc(d) {} | ||
| 42 | op_t(const mstring& s,int p1,int p2,op1_t op1,op2_t op2,const mstring& d): | ||
| 43 | name(s),pre1(p1),pre2(p2),left(2),right(2),f1(op1),f2(op2),desc(d) {} | ||
| 44 | op_t(const mstring& s,int p,op1_t op,const mstring& d): | ||
| 45 | name(s),pre1(p),pre2(0),left(0),right(2),f1(op),f2(0),desc(d) {} | ||
| 46 | op_t(const mstring& s,int p,op2_t op,const mstring& d): | ||
| 47 | name(s),pre1(0),pre2(p),left(2),right(2),f1(0),f2(op),desc(d) {} | ||
| 48 | }; | ||
| 49 | |||
| 50 | #define OP1_IMPL(n) \ | ||
| 51 | static void impl_##n(mstream& out,op_env& env,const sref& a) | ||
| 52 | #define OP2_IMPL(n) \ | ||
| 53 | static void impl_##n(mstream& out,op_env& env,const sref& L,const sref& R) | ||
| 54 | |||
| 55 | //////////////////////////////////////////////////////////// | ||
| 56 | |||
| 57 | typedef op_t* opmap_t; | ||
| 58 | |||
| 59 | struct opmap : public mrvec<opmap_t> { | ||
| 60 | typedef mrvec<opmap_t>::iterator iterator; | ||
| 61 | typedef mrvec<opmap_t>::const_iterator const_iterator; | ||
| 62 | |||
| 63 | struct comp_t { | ||
| 64 | sref key; | ||
| 65 | comp_t(const sref& skey) : key(skey) {} | ||
| 66 | bool operator()(const op_t* a,const op_t* b) const { | ||
| 67 | return (a?((const sref&)a->name):key)<(b?((const sref&)b->name):key); | ||
| 68 | } | ||
| 69 | }; | ||
| 70 | |||
| 71 | opmap() : mrvec<opmap_t>() {} | ||
| 72 | ~opmap() { clear(); } | ||
| 73 | |||
| 74 | void clear(); // overrides parent | ||
| 75 | void erase(iterator p); // overrides parent | ||
| 76 | |||
| 77 | const op_t* get(const sref& t) const; | ||
| 78 | const op_t* add(op_t* op); | ||
| 79 | }; | ||
| 80 | |||
| 81 | #define OP_ADD(p,f,d) M.add(new op_t(#f,p,impl_##f,d)) | ||
| 82 | #define OP_ADDN(p,f,n,d) M.add(new op_t(#n,p,impl_##f,d)) | ||
| 83 | #define OP_ADD2(p1,p2,f,n,d) M.add(new op_t(#n,p1,p2,impl_##f,impl_##f,d)) | ||
| 84 | |||
| 85 | /////////////////////////////////////////// | ||
| 86 | |||
| 87 | void opAddBasic(opmap& map); | ||
| 88 | void opAddComp(opmap& map); | ||
| 89 | void opAddString(opmap& map); | ||
| 90 | inline void opAddHEXP(opmap& map) { | ||
| 91 | opAddBasic(map); | ||
| 92 | opAddComp(map); | ||
| 93 | opAddString(map); | ||
| 94 | } | ||
| 95 | void opAddLatex(opmap& map); | ||
| 96 | |||
| 97 | #endif | ||
diff --git a/src/ops/string.cc b/src/ops/string.cc new file mode 100644 index 0000000..76b7e72 --- /dev/null +++ b/src/ops/string.cc | |||
| @@ -0,0 +1,274 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <ops/operator.h> | ||
| 21 | #include <ops/nnstyle.h> | ||
| 22 | #include <mt/mset.h> | ||
| 23 | |||
| 24 | OP2_IMPL(intersect) { mset a(L),b(R),c; c.Intersection(a,b); out<<c; } | ||
| 25 | OP2_IMPL(union) { mset a(L),b(R),c; c.Union(a,b); out<<c; } | ||
| 26 | OP2_IMPL(difference) { mset a(L),b(R),c; c.Difference(a,b); out<<c; } | ||
| 27 | OP2_IMPL(concats) { | ||
| 28 | if(L.nempty()&&R.nempty()) out<<L<<" "<<R; | ||
| 29 | else if(L.nempty()) out<<L; | ||
| 30 | else out<<R; | ||
| 31 | } | ||
| 32 | |||
| 33 | OP1_IMPL(lcase) {mstring s=a;s.tolower();out<<s;} | ||
| 34 | OP1_IMPL(ucase) {mstring s=a;s.toupper();out<<s;} | ||
| 35 | OP1_IMPL(nncase) {out<<nncase(a);} | ||
| 36 | OP1_IMPL(skipws) {out<<a.right_first_not_of(cset_ws);} | ||
| 37 | |||
| 38 | OP2_IMPL(eqnn) {out<<(nncomp(L,R)==0);} | ||
| 39 | OP2_IMPL(nenn) {out<<(nncomp(L,R)!=0);} | ||
| 40 | |||
| 41 | OP1_IMPL(first) {out<<First(a);} | ||
| 42 | OP1_IMPL(last) {out<<Last(a);} | ||
| 43 | OP1_IMPL(rest) {out<<Rest(a);} | ||
| 44 | |||
| 45 | OP1_IMPL(count) { | ||
| 46 | sref first,rest=a; int n=0; | ||
| 47 | while(Split(first,rest)) n++; | ||
| 48 | out<<n; | ||
| 49 | } | ||
| 50 | |||
| 51 | OP2_IMPL(nth) { | ||
| 52 | sref first,rest=L; int n=atoi(R); | ||
| 53 | while(n-->0&&Split(first,rest)); | ||
| 54 | out<<first; | ||
| 55 | } | ||
| 56 | |||
| 57 | OP2_IMPL(which) { | ||
| 58 | sref first,rest=L; int n=0; | ||
| 59 | while(Split(first,rest)) { n++; if(first==R) { out<<n; return; } } | ||
| 60 | out<<0; | ||
| 61 | } | ||
| 62 | |||
| 63 | OP2_IMPL(cnt) {out<<(L.find(R)>=0);} | ||
| 64 | OP2_IMPL(cntn) {out<<(L.find(R,cset_lcase)>=0);} | ||
| 65 | |||
| 66 | OP2_IMPL(concat) {out<<L<<R;} | ||
| 67 | |||
| 68 | OP2_IMPL(leftand) {out<<L.leftand_first(R);} | ||
| 69 | OP2_IMPL(left) {out<<L.left_first(R);} | ||
| 70 | OP2_IMPL(right) {out<<L.right_first(R);} | ||
| 71 | OP2_IMPL(past) {out<<L.past_first(R);} | ||
| 72 | |||
| 73 | OP2_IMPL(rleftand) {out<<L.leftand_last(R);} | ||
| 74 | OP2_IMPL(rleft) {out<<L.left_last(R);} | ||
| 75 | OP2_IMPL(rright) {out<<L.right_last(R);} | ||
| 76 | OP2_IMPL(rpast) {out<<L.past_last(R);} | ||
| 77 | |||
| 78 | void opAddString(opmap& M) | ||
| 79 | { | ||
| 80 | OP_ADD(32,lcase, | ||
| 81 | "Lower case\n" | ||
| 82 | "Syntax: lcase (string)\n" | ||
| 83 | "Returns: (string)\n" | ||
| 84 | ); | ||
| 85 | OP_ADD(32,ucase, | ||
| 86 | "Upper case\n" | ||
| 87 | "Syntax: ucase (string)\n" | ||
| 88 | "Returns: (string)\n" | ||
| 89 | ); | ||
| 90 | OP_ADD(32,nncase, | ||
| 91 | "NN-style case\n" | ||
| 92 | "Syntax: nncase (string)\n" | ||
| 93 | "Returns: (string)\n" | ||
| 94 | "\n" | ||
| 95 | "NN-style converts names to <lastname> <initials>\n" | ||
| 96 | ); | ||
| 97 | OP_ADD(32,skipws, | ||
| 98 | "Skip whitespace\n" | ||
| 99 | "Syntax: skipws (string)\n" | ||
| 100 | "Returns: (string)\n" | ||
| 101 | "\n" | ||
| 102 | "Skips trailing whitespace\n" | ||
| 103 | ); | ||
| 104 | |||
| 105 | OP_ADD(32,first, | ||
| 106 | "First element in list\n" | ||
| 107 | "Syntax: first (list)\n" | ||
| 108 | "Returns: (string)\n" | ||
| 109 | "\n" | ||
| 110 | "Elements are separated by whitespace\n" | ||
| 111 | ); | ||
| 112 | OP_ADD(32,last, | ||
| 113 | "Last element in list\n" | ||
| 114 | "Syntax: last (list)\n" | ||
| 115 | "Returns: (string)\n" | ||
| 116 | "\n" | ||
| 117 | "Elements are separated by whitespace\n" | ||
| 118 | ); | ||
| 119 | OP_ADD(32,rest, | ||
| 120 | "Rest of elements in list\n" | ||
| 121 | "Syntax: rest (list)\n" | ||
| 122 | "Returns: (list)\n" | ||
| 123 | "\n" | ||
| 124 | "Elements are separated by whitespace\n" | ||
| 125 | ); | ||
| 126 | OP_ADD(32,count, | ||
| 127 | "Count elements in list\n" | ||
| 128 | "Syntax: count (list)\n" | ||
| 129 | "Returns: (int)\n" | ||
| 130 | "\n" | ||
| 131 | "Elements are separated by whitespace\n" | ||
| 132 | ); | ||
| 133 | |||
| 134 | OP_ADD(30,nth, | ||
| 135 | "Nth element in list\n" | ||
| 136 | "Syntax: (list) nth (int)\n" | ||
| 137 | "Returns: (string)\n" | ||
| 138 | "\n" | ||
| 139 | "First element is denoted 1\n" | ||
| 140 | "Elements out of range returns empty\n" | ||
| 141 | "Elements are separated by whitespace\n" | ||
| 142 | ); | ||
| 143 | OP_ADD(30,which, | ||
| 144 | "Which element in list\n" | ||
| 145 | "Syntax: (list) a which (string) b\n" | ||
| 146 | "Returns: (int)\n" | ||
| 147 | "\n" | ||
| 148 | "Which element in a is b (0 if not found)\n" | ||
| 149 | "First element is denoted 1\n" | ||
| 150 | "Elements are separated by whitespace\n" | ||
| 151 | ); | ||
| 152 | |||
| 153 | OP_ADD(28,left, | ||
| 154 | "Left of substring\n" | ||
| 155 | "Syntax: (string) a left (string) b\n" | ||
| 156 | "Returns: (string)\n" | ||
| 157 | "\n" | ||
| 158 | "Everything in a to the left of first b, of a if b not found in a\n" | ||
| 159 | ); | ||
| 160 | OP_ADD(28,leftand, | ||
| 161 | "Left of substring inclusive\n" | ||
| 162 | "Syntax: (string) a leftand (string) b\n" | ||
| 163 | "Returns: (string)\n" | ||
| 164 | "\n" | ||
| 165 | "Everything in a to the left of first b inclusive, of a if b not found in a\n" | ||
| 166 | ); | ||
| 167 | OP_ADD(28,right, | ||
| 168 | "Right of substring inclusive\n" | ||
| 169 | "Syntax: (string) a right (string) b\n" | ||
| 170 | "Returns: (string)\n" | ||
| 171 | "\n" | ||
| 172 | "Everything in a to the right of first b inclusive, of empty if b not found in a\n" | ||
| 173 | ); | ||
| 174 | OP_ADD(28,past, | ||
| 175 | "Right of substring\n" | ||
| 176 | "Syntax: (string) a past (string) b\n" | ||
| 177 | "Returns: (string)\n" | ||
| 178 | "\n" | ||
| 179 | "Everything in a to the right of first b, of empty if b not found in a\n" | ||
| 180 | ); | ||
| 181 | |||
| 182 | OP_ADD(28,rleft, | ||
| 183 | "Left of substring (reversed)\n" | ||
| 184 | "Syntax: (string) a rleft (string) b\n" | ||
| 185 | "Returns: (string)\n" | ||
| 186 | "\n" | ||
| 187 | "Everything in a to the left of last b, of a if b not found in a\n" | ||
| 188 | ); | ||
| 189 | OP_ADD(28,rleftand, | ||
| 190 | "Left of substring inclusive, (reversed)\n" | ||
| 191 | "Syntax: (string) a rleftand (string) b\n" | ||
| 192 | "Returns: (string)\n" | ||
| 193 | "\n" | ||
| 194 | "Everything in a to the left of last b inclusive, of a if b not found in a\n" | ||
| 195 | ); | ||
| 196 | OP_ADD(28,rright, | ||
| 197 | "Right of substring inclusive (reversed)\n" | ||
| 198 | "Syntax: (string) a rright (string) b\n" | ||
| 199 | "Returns: (string)\n" | ||
| 200 | "\n" | ||
| 201 | "Everything in a to the right of last b inclusive, of empty if b not found in a\n" | ||
| 202 | ); | ||
| 203 | OP_ADD(28,rpast, | ||
| 204 | "Right of substring (reversed)\n" | ||
| 205 | "Syntax: (string) a rpast (string) b\n" | ||
| 206 | "Returns: (string)\n" | ||
| 207 | "\n" | ||
| 208 | "Everything in a to the right of last b, of empty if b not found in a\n" | ||
| 209 | ); | ||
| 210 | |||
| 211 | OP_ADDN(24,concat,++, | ||
| 212 | "String concatenation\n" | ||
| 213 | "Syntax: (string) ++ (string)\n" | ||
| 214 | "Returns: (string)\n" | ||
| 215 | ); | ||
| 216 | OP_ADDN(24,concats,+++, | ||
| 217 | "List concatenation\n" | ||
| 218 | "Syntax: (list) +++ (list)\n" | ||
| 219 | "Returns: (list)\n" | ||
| 220 | "\n" | ||
| 221 | "Lists are concatenated with space\n" | ||
| 222 | ); | ||
| 223 | |||
| 224 | OP_ADD(18,cnt, | ||
| 225 | "Contains substring\n" | ||
| 226 | "Syntax: (string) a cnt (string) b\n" | ||
| 227 | "Returns: (int)\n" | ||
| 228 | "\n" | ||
| 229 | "Nonzero if b found in a\n" | ||
| 230 | ); | ||
| 231 | OP_ADD(18,cntn, | ||
| 232 | "Contains substring, case insensitive\n" | ||
| 233 | "Syntax: (string) a cnt (string) b\n" | ||
| 234 | "Returns: (int)\n" | ||
| 235 | "\n" | ||
| 236 | "Nonzero if b found in a\n" | ||
| 237 | ); | ||
| 238 | OP_ADD(18,eqnn, | ||
| 239 | "NN-style equal\n" | ||
| 240 | "Syntax: (string) eqnn (string)\n" | ||
| 241 | "Returns: (int)\n" | ||
| 242 | "\n" | ||
| 243 | "NN-style converts names to <lastname> <initials>\n" | ||
| 244 | ); | ||
| 245 | OP_ADD(18,nenn, | ||
| 246 | "NN-style not equal\n" | ||
| 247 | "Syntax: (string) eqnn (string)\n" | ||
| 248 | "Returns: (int)\n" | ||
| 249 | "\n" | ||
| 250 | "NN-style converts names to <lastname> <initials>\n" | ||
| 251 | ); | ||
| 252 | |||
| 253 | OP_ADDN(10,intersect,&&&, | ||
| 254 | "List intersection\n" | ||
| 255 | "Syntax: (list) a &&& (list) b\n" | ||
| 256 | "Returns: (list)\n" | ||
| 257 | "\n" | ||
| 258 | "Finds the set intersection of a and b\n" | ||
| 259 | ); | ||
| 260 | OP_ADDN(9,difference,---, | ||
| 261 | "List difference\n" | ||
| 262 | "Syntax: (list) a &&& (list) b\n" | ||
| 263 | "Returns: (list)\n" | ||
| 264 | "\n" | ||
| 265 | "Finds the set difference of a and b\n" | ||
| 266 | ); | ||
| 267 | OP_ADDN(9,union,|||, | ||
| 268 | "List union\n" | ||
| 269 | "Syntax: (list) a &&& (list) b\n" | ||
| 270 | "Returns: (list)\n" | ||
| 271 | "\n" | ||
| 272 | "Finds the set union of a and b\n" | ||
| 273 | ); | ||
| 274 | } | ||
diff --git a/src/ops/test.cc b/src/ops/test.cc new file mode 100644 index 0000000..b6058fc --- /dev/null +++ b/src/ops/test.cc | |||
| @@ -0,0 +1,161 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <ops/express.h> | ||
| 21 | #include <mt/msmap.h> | ||
| 22 | #include <iostream> | ||
| 23 | #include <fstream> | ||
| 24 | using namespace std; | ||
| 25 | |||
| 26 | static fp_stream mout(stdout),merr(stderr); | ||
| 27 | |||
| 28 | struct tt_env : public op_env { | ||
| 29 | sspile var; | ||
| 30 | tt_env(opmap& map) : op_env(map) {} | ||
| 31 | int split(sref& first,sref& rest) throw(merror_t) { | ||
| 32 | static const charset spec("+-*%/<=>^_!~&|,?:;"); | ||
| 33 | static const charset delim("()\"\\"); | ||
| 34 | static const charset specws=spec|delim|cset_ws; | ||
| 35 | int s; | ||
| 36 | rest=rest.right_first_not_of(cset_ws); | ||
| 37 | if((s=rest.skip(cset_quotes))>0) { | ||
| 38 | first=rest.left(s); | ||
| 39 | rest=rest.right(s); | ||
| 40 | } | ||
| 41 | else if((s=rest.skip(cset_para))>0) { | ||
| 42 | first=Trim(rest.left(s),cset_para); | ||
| 43 | rest=rest.right(s); | ||
| 44 | } | ||
| 45 | else if((s=rest.skip(cset_braces))>0) { | ||
| 46 | first=rest.left(s); | ||
| 47 | rest=rest.right(s); | ||
| 48 | } | ||
| 49 | else if(spec.test(*rest)) { | ||
| 50 | first=rest.left_first_not_of(spec); | ||
| 51 | rest=rest.adv(first); | ||
| 52 | } | ||
| 53 | else { | ||
| 54 | first=rest.left_first_of(specws); | ||
| 55 | rest=rest.adv(first); | ||
| 56 | } | ||
| 57 | return first.nempty(); | ||
| 58 | } | ||
| 59 | void term(mstream& out,expr_t* x) throw(merror_t) { | ||
| 60 | if(x->expr.empty()) { | ||
| 61 | x->status=0; | ||
| 62 | } | ||
| 63 | else if(x->expr.skip(cset_quotes)==x->expr.size()) { | ||
| 64 | out<<x->expr(1,-3); | ||
| 65 | x->status=0; | ||
| 66 | } | ||
| 67 | else if(x->expr.find_not_of(cset_real)<0) { | ||
| 68 | out<<x->expr; | ||
| 69 | x->status=0; | ||
| 70 | } | ||
| 71 | else { | ||
| 72 | for(sspile::iterator s=var.begin();s!=var.end();s++) | ||
| 73 | if(s->first==x->expr) { out<<s->second; x->status=OP_LOCAL; break; } | ||
| 74 | } | ||
| 75 | } | ||
| 76 | }; | ||
| 77 | |||
| 78 | #define TT_IMPL(n) \ | ||
| 79 | static void impl_##n(mstream& out,tt_env& env,const sref& L,const sref& R) | ||
| 80 | #define TT_ADDN(p,f,n,d) \ | ||
| 81 | M.add(new op_t(#n,0,p,1,2,0,(op_t::op2_t)impl_##f,d)) | ||
| 82 | |||
| 83 | TT_IMPL(assign) { | ||
| 84 | sspile& var=env.var; | ||
| 85 | for(sspile::iterator p=var.begin();p!=var.end();p++) | ||
| 86 | if(p->first==L) { p->second=R; return; } | ||
| 87 | var.push_back(sstring(L,R)); | ||
| 88 | } | ||
| 89 | |||
| 90 | TT_IMPL(incr) { | ||
| 91 | sspile& var=env.var; | ||
| 92 | for(sspile::iterator p=var.begin();p!=var.end();p++) | ||
| 93 | if(p->first==L) { p->second=itoa(atoi(p->second)+atoi(R)); break; } | ||
| 94 | } | ||
| 95 | |||
| 96 | TT_IMPL(decr) { | ||
| 97 | sspile& var=env.var; | ||
| 98 | for(sspile::iterator p=var.begin();p!=var.end();p++) | ||
| 99 | if(p->first==L) { p->second=itoa(atoi(p->second)-atoi(R)); break; } | ||
| 100 | } | ||
| 101 | |||
| 102 | inline void opAddTT(opmap& M) { | ||
| 103 | TT_ADDN(4,assign,=,"C style"); | ||
| 104 | TT_ADDN(4,assign,:=,"new var"); | ||
| 105 | TT_ADDN(4,incr,+=,"C style"); | ||
| 106 | TT_ADDN(4,decr,-=,"C style"); | ||
| 107 | } | ||
| 108 | |||
| 109 | main(int argc,char* argv[]) try | ||
| 110 | { | ||
| 111 | opmap ops; | ||
| 112 | opAddHEXP(ops); | ||
| 113 | opAddTT(ops); | ||
| 114 | tt_env env(ops); | ||
| 115 | mstring buf; | ||
| 116 | sref_t line; | ||
| 117 | expr_t expr; | ||
| 118 | if(argc>1) { | ||
| 119 | buf.load(sref(argv[1])); | ||
| 120 | sref first,rest=buf; | ||
| 121 | Splitln(first,rest); | ||
| 122 | if(first.left(2)!=sref("#!")) rest=buf; | ||
| 123 | (expr=buf).expand(env); | ||
| 124 | expr.eval(mout,env,OP_ALL); | ||
| 125 | mout<<"\n"; | ||
| 126 | } | ||
| 127 | else { | ||
| 128 | while(1) { | ||
| 129 | merr<<"ops>"; | ||
| 130 | cin.getline(line,sizeof(sref_t)); | ||
| 131 | sref first,rest(line); | ||
| 132 | Split(first,rest); | ||
| 133 | if(first==sref("exit")) { | ||
| 134 | break; | ||
| 135 | } | ||
| 136 | else if(first==sref("tree")) { | ||
| 137 | expr.trav(mout,12); | ||
| 138 | } | ||
| 139 | else if(first==sref("eval")) { | ||
| 140 | expr.eval(mout,env,OP_ALL); | ||
| 141 | mout<<"\n"; | ||
| 142 | } | ||
| 143 | else { | ||
| 144 | buf=line; | ||
| 145 | try { | ||
| 146 | (expr=buf).expand(env); | ||
| 147 | expr.eval(mout,env,OP_ALL); | ||
| 148 | mout<<"\n"; | ||
| 149 | } | ||
| 150 | catch(const merror_t& e) { | ||
| 151 | merr<<e.desc<<"\n"; | ||
| 152 | } | ||
| 153 | } | ||
| 154 | } | ||
| 155 | } | ||
| 156 | return 0; | ||
| 157 | } | ||
| 158 | catch(const merror_t& e) { | ||
| 159 | merr<<"ops("<<e.num<<") "<<e.desc<<"\n"; | ||
| 160 | return -1; | ||
| 161 | } | ||
diff --git a/src/serv/auth.cc b/src/serv/auth.cc new file mode 100644 index 0000000..abf16b3 --- /dev/null +++ b/src/serv/auth.cc | |||
| @@ -0,0 +1,162 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <serv/htcd.h> | ||
| 21 | |||
| 22 | const mstring default_tag=".default"; | ||
| 23 | |||
| 24 | ///////////////////////////////////////////////////////////////// | ||
| 25 | |||
| 26 | TOK_IMPL(remote_name) { out<<Reqd(env)->tcp->node.name; } | ||
| 27 | TOK_IMPL(remote_address) { out<<Reqd(env)->tcp->node.ip; } | ||
| 28 | TOK_IMPL(remote_port) { out<<Reqd(env)->tcp->port; } | ||
| 29 | |||
| 30 | ///////////////////////////////////////////////////////////////// | ||
| 31 | |||
| 32 | inline int match(const sref& rem,const sref& longrem,const sref& dom) | ||
| 33 | { | ||
| 34 | if(rem==dom) return 1; | ||
| 35 | if(*dom!='.') return 0; | ||
| 36 | if(longrem.right_last(dom)==dom) return 1; | ||
| 37 | return 0; | ||
| 38 | } | ||
| 39 | |||
| 40 | inline int allow(const sref& uname,const sref& list) | ||
| 41 | { | ||
| 42 | mstring remote=First(uname); | ||
| 43 | mstring longrem=remote; if(longrem.find('.')<0) longrem+=default_tag; | ||
| 44 | if(remote.empty()) return 0; | ||
| 45 | if(First(list).empty()) return 1; | ||
| 46 | sref first,rest=list; | ||
| 47 | while(Split(first,rest)) if(match(remote,longrem,first)) return 1; | ||
| 48 | return 0; | ||
| 49 | } | ||
| 50 | |||
| 51 | TOK_IMPL(remote_allow) { out<<allow(Reqd(env)->tcp->node.name,env[0]); } | ||
| 52 | TOK_IMPL(bindroot) { Reqd(env)->htcd()->bindroot=env[0]; } | ||
| 53 | |||
| 54 | ///////////////////////////////////////////////////////////////// | ||
| 55 | |||
| 56 | TOK_IMPL(user_allow) { | ||
| 57 | htcd_req* htcd=Reqd(env); | ||
| 58 | mstring opt=env.parg(-1); | ||
| 59 | int now=opt.empty()?time(0):atoi(opt); | ||
| 60 | out<<htcd->user.allow_list(env[0],now,htcd->RootAllowed()); | ||
| 61 | } | ||
| 62 | |||
| 63 | TOK_IMPL(on_clear) { | ||
| 64 | htcd_req* htcd=Reqd(env); | ||
| 65 | if(htcd->user.allow_list(env[0],time(0),htcd->RootAllowed())) env.parg(out,1); | ||
| 66 | else env.parg(out,2); | ||
| 67 | } | ||
| 68 | |||
| 69 | ///////////////////////////////////////////////////////////////// | ||
| 70 | |||
| 71 | TOK_IMPL(allowed) { | ||
| 72 | int ok=0; | ||
| 73 | if(!env.db) THROW("htc: no open database"); | ||
| 74 | if(env.dbat>=0&&env.dbat<env.db->size()) { | ||
| 75 | user_t user; | ||
| 76 | env.db->Get(env.dbat,user.list); | ||
| 77 | if(user.list.size()!=user_tabs) | ||
| 78 | THROW("htc: cannot test - probably not a users database"); | ||
| 79 | mstring opt=env.parg(-1); | ||
| 80 | int now=opt.empty()?time(0):atoi(opt); | ||
| 81 | ok=user.allow_list(env[0],now,Reqd(env)->RootAllowed()); | ||
| 82 | } | ||
| 83 | out<<ok; | ||
| 84 | } | ||
| 85 | |||
| 86 | TOK_IMPL(ingroups) { | ||
| 87 | int ok=0; | ||
| 88 | if(!env.db) THROW("htc: no open database"); | ||
| 89 | if(env.dbat>=0&&env.dbat<env.db->size()) { | ||
| 90 | user_t user; | ||
| 91 | env.db->Get(env.dbat,user.list); | ||
| 92 | if(user.list.size()!=user_tabs) | ||
| 93 | THROW("htc: cannot test - probably not a users database"); | ||
| 94 | mstring opt=env.parg(-1); | ||
| 95 | int now=opt.empty()?time(0):atoi(opt); | ||
| 96 | ok=user.allow_list(env[0],now,-1); | ||
| 97 | } | ||
| 98 | out<<ok; | ||
| 99 | } | ||
| 100 | |||
| 101 | ///////////////////////////////////////////////////////////////// | ||
| 102 | |||
| 103 | void envAddAuth(tokmap& T) | ||
| 104 | { | ||
| 105 | TOK_ADD(remote_name,"",tok_t::PUBLIC, | ||
| 106 | "%Remote hostname\n" | ||
| 107 | "%Syntax: \\remote.name\n" | ||
| 108 | ); | ||
| 109 | TOK_ADD(remote_address,"",tok_t::PUBLIC, | ||
| 110 | "%Remote address\n" | ||
| 111 | "%Syntax: \\remote.address\n" | ||
| 112 | ); | ||
| 113 | TOK_ADD(remote_port,"",tok_t::PUBLIC, | ||
| 114 | "%Remote port\n" | ||
| 115 | "%Syntax: \\remote.port\n" | ||
| 116 | ); | ||
| 117 | |||
| 118 | ///////////////////////////////////////////////////////////// | ||
| 119 | |||
| 120 | TOK_ADD(remote_allow,"x",tok_t::PUBLIC, | ||
| 121 | "%True if remote hostname allowed by domain\n" | ||
| 122 | "%Syntax: \\remote.allow{domain list}\n" | ||
| 123 | "%\n" | ||
| 124 | "%May be used to restrict access without any group\n" | ||
| 125 | ); | ||
| 126 | TOK_ADD(bindroot,"x",tok_t::SYSONLY, | ||
| 127 | "%Bind root access to explicit addresses\n" | ||
| 128 | "%Syntax: \\bindroot{address list}\n" | ||
| 129 | "%\n" | ||
| 130 | "%Note that domain syntax does not work here; you\n" | ||
| 131 | "%want to have total control over all root access.\n" | ||
| 132 | ); | ||
| 133 | |||
| 134 | ///////////////////////////////////////////////////////////// | ||
| 135 | |||
| 136 | TOK_ADD(user_allow,"x?",tok_t::SYSONLY, | ||
| 137 | "%Core test on user clearance\n" | ||
| 138 | "%Syntax: \\user.allow{groups}<time>\n" | ||
| 139 | "%\n" | ||
| 140 | "%In case of several groups, all must be allowed.\n" | ||
| 141 | ); | ||
| 142 | TOK_ADD(on_clear,"xr?",tok_t::SYSONLY, | ||
| 143 | "%Do if user is allowed in all groups now\n" | ||
| 144 | "%Syntax: \\on.clear{groups}{body}<else>\n" | ||
| 145 | ); | ||
| 146 | |||
| 147 | ///////////////////////////////////////////////////////////// | ||
| 148 | |||
| 149 | TOK_ADD(allowed,"x?",tok_t::SYSONLY, | ||
| 150 | "%True if the current record is allowed in all groups now\n" | ||
| 151 | "%Syntax: \\allowed{groups}<time>\n" | ||
| 152 | "%\n" | ||
| 153 | "%Only used as a query function\n" | ||
| 154 | ); | ||
| 155 | |||
| 156 | TOK_ADD(ingroups,"x?",tok_t::SYSONLY, | ||
| 157 | "%True if the current record is part of all groups now\n" | ||
| 158 | "%Syntax: \\ingroups{groups}<time>\n" | ||
| 159 | "%\n" | ||
| 160 | "%Only used as a query function\n" | ||
| 161 | ); | ||
| 162 | } | ||
diff --git a/src/serv/const.cc b/src/serv/const.cc new file mode 100644 index 0000000..f252a17 --- /dev/null +++ b/src/serv/const.cc | |||
| @@ -0,0 +1,69 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <serv/htcd.h> | ||
| 21 | |||
| 22 | inline tok_t* Const(tokmap& map,const char* s,const sref& b) throw(merror_t) { | ||
| 23 | return Const(map,sref(s),b,tok_t::PUBLIC); | ||
| 24 | } | ||
| 25 | |||
| 26 | void envAddConst(tokmap& T) | ||
| 27 | { | ||
| 28 | Const(T,"HTTP.100",HTTP_100); | ||
| 29 | Const(T,"HTTP.101",HTTP_101); | ||
| 30 | Const(T,"HTTP.200",HTTP_200); | ||
| 31 | Const(T,"HTTP.201",HTTP_201); | ||
| 32 | Const(T,"HTTP.202",HTTP_202); | ||
| 33 | Const(T,"HTTP.203",HTTP_203); | ||
| 34 | Const(T,"HTTP.204",HTTP_204); | ||
| 35 | Const(T,"HTTP.205",HTTP_205); | ||
| 36 | Const(T,"HTTP.206",HTTP_206); | ||
| 37 | Const(T,"HTTP.300",HTTP_300); | ||
| 38 | Const(T,"HTTP.301",HTTP_301); | ||
| 39 | Const(T,"HTTP.302",HTTP_302); | ||
| 40 | Const(T,"HTTP.303",HTTP_303); | ||
| 41 | Const(T,"HTTP.304",HTTP_304); | ||
| 42 | Const(T,"HTTP.305",HTTP_305); | ||
| 43 | Const(T,"HTTP.306",HTTP_306); | ||
| 44 | Const(T,"HTTP.307",HTTP_307); | ||
| 45 | Const(T,"HTTP.400",HTTP_400); | ||
| 46 | Const(T,"HTTP.401",HTTP_401); | ||
| 47 | Const(T,"HTTP.402",HTTP_402); | ||
| 48 | Const(T,"HTTP.403",HTTP_403); | ||
| 49 | Const(T,"HTTP.404",HTTP_404); | ||
| 50 | Const(T,"HTTP.405",HTTP_405); | ||
| 51 | Const(T,"HTTP.406",HTTP_406); | ||
| 52 | Const(T,"HTTP.407",HTTP_407); | ||
| 53 | Const(T,"HTTP.408",HTTP_408); | ||
| 54 | Const(T,"HTTP.409",HTTP_409); | ||
| 55 | Const(T,"HTTP.410",HTTP_410); | ||
| 56 | Const(T,"HTTP.411",HTTP_411); | ||
| 57 | Const(T,"HTTP.412",HTTP_412); | ||
| 58 | Const(T,"HTTP.413",HTTP_413); | ||
| 59 | Const(T,"HTTP.414",HTTP_414); | ||
| 60 | Const(T,"HTTP.415",HTTP_415); | ||
| 61 | Const(T,"HTTP.416",HTTP_416); | ||
| 62 | Const(T,"HTTP.417",HTTP_417); | ||
| 63 | Const(T,"HTTP.500",HTTP_500); | ||
| 64 | Const(T,"HTTP.501",HTTP_501); | ||
| 65 | Const(T,"HTTP.502",HTTP_502); | ||
| 66 | Const(T,"HTTP.503",HTTP_503); | ||
| 67 | Const(T,"HTTP.504",HTTP_504); | ||
| 68 | Const(T,"HTTP.505",HTTP_505); | ||
| 69 | } | ||
diff --git a/src/serv/direct.cc b/src/serv/direct.cc new file mode 100644 index 0000000..1e7c2d6 --- /dev/null +++ b/src/serv/direct.cc | |||
| @@ -0,0 +1,73 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <serv/htcd.h> | ||
| 21 | #include <mt/dates.h> | ||
| 22 | |||
| 23 | const mstring log_cmd="\\group:\\user.id"; | ||
| 24 | |||
| 25 | TOK_IMPL(error) { | ||
| 26 | throw("htc: 'error' no longer supported"); | ||
| 27 | } | ||
| 28 | |||
| 29 | TOK_IMPL(log) { | ||
| 30 | htcd_req* htc=Reqd(env); | ||
| 31 | MLOCK(htc->htcd()->mutex); | ||
| 32 | fp_stream& tlog=htc->htcd()->errlog; | ||
| 33 | tlog<<"["<<time(0)<<"]["<<htc->tcp->node.ip<<"][" | ||
| 34 | <<htc->tcp->node.name<<":"<<htc->tcp->port<<"][" | ||
| 35 | <<htc->group<<":"<<htc->user.uid()<<"] "; | ||
| 36 | env.parg(tlog,0); | ||
| 37 | tlog<<"\n"; | ||
| 38 | tlog.flush(); | ||
| 39 | } | ||
| 40 | |||
| 41 | TOK_IMPL(output) { | ||
| 42 | env.parg(*Reqd(env)->output,0); | ||
| 43 | } | ||
| 44 | |||
| 45 | void envAddDirect(tokmap& T) | ||
| 46 | { | ||
| 47 | TOK_ADD(output,"r",tok_t::PUBLIC, | ||
| 48 | "%Redirect to output stream\n" | ||
| 49 | "%Syntax: \\output{body}\n" | ||
| 50 | "%\n" | ||
| 51 | "%Normally used on server-level, when output refers\n" | ||
| 52 | "%to a socket.\n" | ||
| 53 | ); | ||
| 54 | |||
| 55 | TOK_ADD(error,"r",tok_t::SYSONLY, | ||
| 56 | "%Redirect to error stream\n" | ||
| 57 | "%Syntax: \\error{body}\n" | ||
| 58 | "%\n" | ||
| 59 | "%Normally used for debugging and loggin of errors.\n" | ||
| 60 | ); | ||
| 61 | |||
| 62 | TOK_ADD(log,"r",tok_t::SYSONLY, | ||
| 63 | "%Message log\n" | ||
| 64 | "%Syntax: \\log{msg}\n" | ||
| 65 | "%\n" | ||
| 66 | "%Outputs to log stream a single line with pre-set information:\n" | ||
| 67 | "%\n" | ||
| 68 | "%IP address\n" | ||
| 69 | "%Time\n" | ||
| 70 | "%Request\n" | ||
| 71 | "%Response\n" | ||
| 72 | ); | ||
| 73 | } | ||
diff --git a/src/serv/form.cc b/src/serv/form.cc new file mode 100644 index 0000000..815f9c4 --- /dev/null +++ b/src/serv/form.cc | |||
| @@ -0,0 +1,102 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <serv/htcd.h> | ||
| 21 | |||
| 22 | const mstring tag="T."; | ||
| 23 | const mstring ncookie_tag="ncookie"; | ||
| 24 | const mstring multipart_tag="multipart"; | ||
| 25 | const mstring body_tag="T.body"; | ||
| 26 | |||
| 27 | static mstring Tag(const sref& in) | ||
| 28 | { | ||
| 29 | mstring name=in; | ||
| 30 | for(int i=0;i<name.size();i++) if(name[i]=='_') name[i]='.'; | ||
| 31 | if(tag.empty()||tag==name.left(tag.size())) return name; | ||
| 32 | name.insert(0,tag); | ||
| 33 | return name; | ||
| 34 | } | ||
| 35 | |||
| 36 | static void AddConst(tokmap& map,const sref& s,const sref& b) throw(merror_t) | ||
| 37 | { | ||
| 38 | tok_t* p=map.get_this(s); | ||
| 39 | if(p) { | ||
| 40 | mstring nb=p->body; nb.append(1,' '); nb+=b; | ||
| 41 | Const(map,s,nb,tok_t::PUBLIC,1); | ||
| 42 | } | ||
| 43 | else Const(map,s,b,tok_t::PUBLIC); | ||
| 44 | } | ||
| 45 | |||
| 46 | static void PushMultipart(tokmap& map,const Mime& root) throw(merror_t) | ||
| 47 | { | ||
| 48 | rpile part; | ||
| 49 | if(root.Multipart(part)) { | ||
| 50 | for(int i=0;i<part.size();i++) { | ||
| 51 | Mime msg(part[i]); | ||
| 52 | if(msg.cont_disp_name.nempty()) { | ||
| 53 | mstring name=Tag(msg.cont_disp_name); | ||
| 54 | if(msg.cont_disp_file.nempty()) { | ||
| 55 | reference_t* tok=Reference(map,name,msg.cont_disp_file,tok_t::PUBLIC); | ||
| 56 | swrite via; | ||
| 57 | if(eqn(msg.cont_trans_enc,trans_base64)) | ||
| 58 | decode64(via(tok->data),msg.body); | ||
| 59 | else if(eqn(msg.cont_trans_enc,trans_quote)) | ||
| 60 | decodeQP(via(tok->data),msg.body); | ||
| 61 | else | ||
| 62 | via(tok->data)<<msg.body; | ||
| 63 | } | ||
| 64 | else AddConst(map,name,msg.body); | ||
| 65 | } | ||
| 66 | } | ||
| 67 | } | ||
| 68 | } | ||
| 69 | |||
| 70 | static void PushWWWForm(tokmap& map,const sref& in) throw(merror_t) | ||
| 71 | { | ||
| 72 | sspile tmp; | ||
| 73 | Unpack(tmp,in); | ||
| 74 | for(int i=0;i<tmp.size();i++) | ||
| 75 | AddConst(map,Tag(tmp[i].first),tmp[i].second); | ||
| 76 | } | ||
| 77 | |||
| 78 | void SetCookies(tokmap& map,const httpReq& req) | ||
| 79 | { | ||
| 80 | Const(map,ncookie_tag,itoa(req.cookies.size()),tok_t::PUBLIC); | ||
| 81 | int n=0; | ||
| 82 | for(sspile::const_iterator p=req.cookies.begin();p!=req.cookies.end();p++) { | ||
| 83 | mstring name,val; | ||
| 84 | name.convert("cookie%d.name",n); | ||
| 85 | val.convert("cookie%d.val",n); | ||
| 86 | Const(map,name,p->first,tok_t::PUBLIC); | ||
| 87 | Const(map,val,p->second,tok_t::PUBLIC); | ||
| 88 | n++; | ||
| 89 | } | ||
| 90 | if(req.arg.nempty()) PushWWWForm(map,req.arg); | ||
| 91 | } | ||
| 92 | |||
| 93 | void envAddForm(tokmap& map,const httpReq& req) | ||
| 94 | { | ||
| 95 | if(req.method==HTTP_POST) { | ||
| 96 | if(req.cont_type.find(multipart_tag,cset_lcase)>=0) PushMultipart(map,req); | ||
| 97 | else PushWWWForm(map,req.body); | ||
| 98 | } | ||
| 99 | else if(req.method==HTTP_PUT) { | ||
| 100 | Const(map,body_tag,req.body,tok_t::PUBLIC); | ||
| 101 | } | ||
| 102 | } | ||
diff --git a/src/serv/htcd.h b/src/serv/htcd.h new file mode 100644 index 0000000..7eaa8dc --- /dev/null +++ b/src/serv/htcd.h | |||
| @@ -0,0 +1,74 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef HTCdH | ||
| 21 | #define HTCdH | ||
| 22 | |||
| 23 | #include <serv/tempmap.h> | ||
| 24 | #include <sh/htc.h> | ||
| 25 | #include <http/http.h> | ||
| 26 | |||
| 27 | /////////////////////////////////////////////////// | ||
| 28 | |||
| 29 | struct HTCd : public HTC { | ||
| 30 | fp_stream logger,errlog; | ||
| 31 | mstring bindroot; | ||
| 32 | mutex_t mutex; | ||
| 33 | |||
| 34 | HTCd(const mstring& path); | ||
| 35 | ~HTCd(); | ||
| 36 | }; | ||
| 37 | |||
| 38 | /////////////////////////////////////////////////// | ||
| 39 | |||
| 40 | struct htcd_user : public htc_user { | ||
| 41 | htcd_user(tokmap& p,const mstring& path); | ||
| 42 | }; | ||
| 43 | |||
| 44 | /////////////////////////////////////////////////// | ||
| 45 | |||
| 46 | struct tcpReq { | ||
| 47 | IPnode node; | ||
| 48 | int port; | ||
| 49 | }; | ||
| 50 | |||
| 51 | /////////////////////////////////////////////////// | ||
| 52 | |||
| 53 | struct htcd_req : public htc_req { | ||
| 54 | mstream* output; | ||
| 55 | tcpReq* tcp; | ||
| 56 | httpReq* req; | ||
| 57 | httpResp resp; | ||
| 58 | |||
| 59 | HTCd* htcd() { return (HTCd*)glob; } | ||
| 60 | |||
| 61 | void AddBody(const sref& body); | ||
| 62 | int RootAllowed(); | ||
| 63 | |||
| 64 | htcd_req(HTCd& g,tokmap& p,mstream& out,tcpReq& trec,httpReq& hrec); | ||
| 65 | }; | ||
| 66 | |||
| 67 | inline htcd_req* Reqd(Env& env) throw(merror_t) { return (htcd_req*)env.req; } | ||
| 68 | |||
| 69 | /////////////////////////////////////////////////// | ||
| 70 | |||
| 71 | void Setup(tokmap& user,HTCd& htcd); | ||
| 72 | |||
| 73 | #endif | ||
| 74 | |||
diff --git a/src/serv/htcs.cc b/src/serv/htcs.cc new file mode 100644 index 0000000..42ac8e3 --- /dev/null +++ b/src/serv/htcs.cc | |||
| @@ -0,0 +1,92 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <serv/htcd.h> | ||
| 21 | #include <hdb/buffer.h> | ||
| 22 | #include <mt/lock.h> | ||
| 23 | |||
| 24 | static fp_stream mout(stdout),merr(stderr); | ||
| 25 | const mstring left="{",right="}"; | ||
| 26 | |||
| 27 | static int unbalanced(const sref& in) | ||
| 28 | { | ||
| 29 | static const charset tag("{[("); | ||
| 30 | if(in.empty()) return 1; | ||
| 31 | sref s=in.right_first_of(tag); | ||
| 32 | while(s.nempty()) { | ||
| 33 | int p=-1; | ||
| 34 | switch(*s) { | ||
| 35 | case '{': p=s.skip(cset_braces); break; | ||
| 36 | case '[': p=s.skip(cset_indices); break; | ||
| 37 | case '(': p=s.skip(cset_para); break; | ||
| 38 | } | ||
| 39 | if(p<0) return 1; | ||
| 40 | s=s.adv(p).right_first_of(tag); | ||
| 41 | } | ||
| 42 | return 0; | ||
| 43 | } | ||
| 44 | |||
| 45 | main(int argc,char* argv[]) try | ||
| 46 | { | ||
| 47 | NODELOCK(USERMAP); | ||
| 48 | if(argc<2) THROW("Usage: "<<argv[0]<<" <docroot>"); | ||
| 49 | mstring path=argv[1]; | ||
| 50 | if(path.back()=='/') path=path.popb(); | ||
| 51 | HTCd htcd(path); | ||
| 52 | tokmap user(htcd.toks); | ||
| 53 | Setup(user,htcd); | ||
| 54 | htcd_user thr(user,path); | ||
| 55 | tcpReq tcp; tcp.port=0; | ||
| 56 | httpReq hreq; hreq.method="GET"; | ||
| 57 | htcd_req req(htcd,thr.toks,mout,tcp,hreq); | ||
| 58 | Env env(htcd.ops,req,XSYSTEM); | ||
| 59 | if(argc>2) { | ||
| 60 | for(int i=3;i<argc;i++) env.xpush(left+sref(argv[i])+right); | ||
| 61 | mstring buffer; LoadBuffer(buffer,argv[2]); | ||
| 62 | if(*buffer=='#') buffer.erase(0,buffer.find('\n')+1); | ||
| 63 | mstream m; | ||
| 64 | env.eval(m,buffer,1); | ||
| 65 | } | ||
| 66 | else { | ||
| 67 | mstring buffer,line; | ||
| 68 | while(!feof(stdin)) { | ||
| 69 | merr<<"htcd>"; | ||
| 70 | buffer.clear(); | ||
| 71 | while(!feof(stdin)&&unbalanced(buffer)) { | ||
| 72 | getline(line,stdin); | ||
| 73 | buffer.append(sref(line)); | ||
| 74 | buffer+='\n'; | ||
| 75 | } | ||
| 76 | try { | ||
| 77 | env.parse(mout,buffer); | ||
| 78 | mout<<"\n"; | ||
| 79 | } | ||
| 80 | catch(const merror_t& e) { | ||
| 81 | merr<<e.desc<<"\n"; | ||
| 82 | } | ||
| 83 | } | ||
| 84 | } | ||
| 85 | return 0; | ||
| 86 | } | ||
| 87 | catch(const merror_t& e) { | ||
| 88 | merr<<"ERROR: ["<<e.desc<<"]\n"; | ||
| 89 | return -1; | ||
| 90 | } | ||
| 91 | |||
| 92 | |||
diff --git a/src/serv/main.cc b/src/serv/main.cc new file mode 100644 index 0000000..f02f10c --- /dev/null +++ b/src/serv/main.cc | |||
| @@ -0,0 +1,122 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <serv/htcd.h> | ||
| 21 | #include <hdb/buffer.h> | ||
| 22 | |||
| 23 | const mstring RCURI="/sys/htcd.rc"; | ||
| 24 | const mstring TREEURI="/sys/sitemap.hdb"; | ||
| 25 | const mstring TEMPURI="/sys/temp.hdb"; | ||
| 26 | |||
| 27 | const mstring LOGURI="/sys/htcd.log"; | ||
| 28 | const mstring ERRURI="/sys/htcd.err"; | ||
| 29 | |||
| 30 | /////////////////////////////////////////////////// | ||
| 31 | |||
| 32 | static void OpenTREE(dbmap& db,const sref& path) | ||
| 33 | { | ||
| 34 | mstring TREEMAP=path+TREEURI; | ||
| 35 | db.Open(TREEMAP,1); | ||
| 36 | if(db.Tables()==0) for(int i=0;i<tree_tabs;i++) db.InsertTable(i,tree_tab[i]); | ||
| 37 | } | ||
| 38 | |||
| 39 | static void OpenTEMP(dbmap& db,const sref& path) | ||
| 40 | { | ||
| 41 | mstring TEMPMAP=path+TEMPURI; | ||
| 42 | db.Open(TEMPMAP,1); | ||
| 43 | if(db.Tables()==0) for(int i=0;i<temp_tabs;i++) db.InsertTable(i,temp_tab[i]); | ||
| 44 | } | ||
| 45 | |||
| 46 | htcd_user::htcd_user(tokmap& p,const mstring& path) : htc_user(p) | ||
| 47 | { | ||
| 48 | OpenTREE(DBRef(toks,TREE_tag,ms_empty,tok_t::SYSONLY)->db,path); | ||
| 49 | OpenTEMP(DBRef(toks,TEMP_tag,ms_empty,tok_t::SYSONLY)->db,path); | ||
| 50 | } | ||
| 51 | |||
| 52 | /////////////////////////////////////////////////// | ||
| 53 | |||
| 54 | void SetCookies(tokmap& map,const httpReq& req); | ||
| 55 | void envAddForm(tokmap& map,const httpReq& req); | ||
| 56 | |||
| 57 | int htcd_req::RootAllowed() | ||
| 58 | { | ||
| 59 | if(htcd()->bindroot.empty()) return 1; | ||
| 60 | sref first,rest=htcd()->bindroot; | ||
| 61 | while(Split(first,rest)) if(first==tcp->node.name) return 1; | ||
| 62 | return 0; | ||
| 63 | } | ||
| 64 | |||
| 65 | htcd_req::htcd_req(HTCd& g,tokmap& p,mstream& out, | ||
| 66 | tcpReq& trec,httpReq& hrec) : htc_req(g,p) | ||
| 67 | { | ||
| 68 | output=&out; | ||
| 69 | tcp=&trec; | ||
| 70 | req=&hrec; | ||
| 71 | SetCookies(toks,hrec); | ||
| 72 | } | ||
| 73 | |||
| 74 | void htcd_req::AddBody(const sref& body) | ||
| 75 | { | ||
| 76 | req->body=body; | ||
| 77 | envAddForm(toks,*req); | ||
| 78 | } | ||
| 79 | |||
| 80 | /////////////////////////////////////////////////// | ||
| 81 | |||
| 82 | void envAddDirect(tokmap& map); | ||
| 83 | void envAddReq(tokmap& map); | ||
| 84 | void envAddConst(tokmap& map); | ||
| 85 | void envAddAuth(tokmap& map); | ||
| 86 | void envAddTemp(tokmap& map); | ||
| 87 | |||
| 88 | HTCd::HTCd(const mstring& path): | ||
| 89 | logger(fopen((path+LOGURI).c_str(),"a+")), | ||
| 90 | errlog(fopen((path+ERRURI).c_str(),"a+")), | ||
| 91 | HTC(path) | ||
| 92 | { | ||
| 93 | envAddDirect(toks); | ||
| 94 | envAddReq(toks); | ||
| 95 | envAddConst(toks); | ||
| 96 | envAddAuth(toks); | ||
| 97 | envAddTemp(toks); | ||
| 98 | |||
| 99 | memset(&mutex,0,sizeof(mutex)); | ||
| 100 | errlog<<"["<<time(0)<<"][MAIN][HTCd started]\n"; | ||
| 101 | errlog.flush(); | ||
| 102 | } | ||
| 103 | |||
| 104 | HTCd::~HTCd() | ||
| 105 | { | ||
| 106 | fclose(errlog.fp); | ||
| 107 | fclose(logger.fp); | ||
| 108 | } | ||
| 109 | |||
| 110 | void Setup(tokmap& user,HTCd& htcd) | ||
| 111 | { | ||
| 112 | tcpReq tcp; tcp.port=0; | ||
| 113 | httpReq hreq; hreq.method="GET"; | ||
| 114 | mstream m1; | ||
| 115 | htcd_req req(htcd,htcd.toks,m1,tcp,hreq); | ||
| 116 | Env env(htcd.ops,req,XSYSTEM); | ||
| 117 | mstring buffer; | ||
| 118 | LoadBuffer(buffer,htcd.docroot+RCURI); | ||
| 119 | Env e(env,user,htcd.docroot+RCURI); | ||
| 120 | mstream m2; | ||
| 121 | e.parse(m2,buffer); | ||
| 122 | } | ||
diff --git a/src/serv/request.cc b/src/serv/request.cc new file mode 100644 index 0000000..163797f --- /dev/null +++ b/src/serv/request.cc | |||
| @@ -0,0 +1,279 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <serv/htcd.h> | ||
| 21 | |||
| 22 | TOK_IMPL(req_mime_version) { out<<Reqd(env)->req->mime_version; } | ||
| 23 | TOK_IMPL(req_cont_type) { out<<Reqd(env)->req->cont_type; } | ||
| 24 | TOK_IMPL(req_cont_type_charset) { out<<Reqd(env)->req->cont_type_charset; } | ||
| 25 | TOK_IMPL(req_cont_type_name) { out<<Reqd(env)->req->cont_type_name; } | ||
| 26 | TOK_IMPL(req_cont_type_boundary) { out<<Reqd(env)->req->cont_type_boundary; } | ||
| 27 | TOK_IMPL(req_cont_id) { out<<Reqd(env)->req->cont_id; } | ||
| 28 | TOK_IMPL(req_cont_desc) { out<<Reqd(env)->req->cont_desc; } | ||
| 29 | TOK_IMPL(req_cont_disp) { out<<Reqd(env)->req->cont_disp; } | ||
| 30 | TOK_IMPL(req_cont_disp_name) { out<<Reqd(env)->req->cont_disp_name; } | ||
| 31 | TOK_IMPL(req_cont_disp_file) { out<<Reqd(env)->req->cont_disp_file; } | ||
| 32 | TOK_IMPL(req_cont_trans_enc) { out<<Reqd(env)->req->cont_trans_enc; } | ||
| 33 | TOK_IMPL(req_cont_length) { out<<Reqd(env)->req->cont_length; } | ||
| 34 | |||
| 35 | TOK_IMPL(req_cache) { out<<Reqd(env)->req->cache; } | ||
| 36 | TOK_IMPL(req_connect) { out<<Reqd(env)->req->connect; } | ||
| 37 | TOK_IMPL(req_date) { out<<Reqd(env)->req->date; } | ||
| 38 | TOK_IMPL(req_pragma) { out<<Reqd(env)->req->pragma; } | ||
| 39 | TOK_IMPL(req_trailer) { out<<Reqd(env)->req->trailer; } | ||
| 40 | TOK_IMPL(req_trans_enc) { out<<Reqd(env)->req->trans_enc; } | ||
| 41 | TOK_IMPL(req_upgrade) { out<<Reqd(env)->req->upgrade; } | ||
| 42 | TOK_IMPL(req_via) { out<<Reqd(env)->req->via; } | ||
| 43 | TOK_IMPL(req_warning) { out<<Reqd(env)->req->warning; } | ||
| 44 | TOK_IMPL(req_allow) { out<<Reqd(env)->req->allow; } | ||
| 45 | TOK_IMPL(req_cont_enc) { out<<Reqd(env)->req->cont_enc; } | ||
| 46 | TOK_IMPL(req_cont_lang) { out<<Reqd(env)->req->cont_lang; } | ||
| 47 | TOK_IMPL(req_cont_location) { out<<Reqd(env)->req->cont_location; } | ||
| 48 | TOK_IMPL(req_cont_md5) { out<<Reqd(env)->req->cont_md5; } | ||
| 49 | TOK_IMPL(req_cont_range) { out<<Reqd(env)->req->cont_range; } | ||
| 50 | TOK_IMPL(req_expires) { out<<Reqd(env)->req->expires; } | ||
| 51 | TOK_IMPL(req_lastmod) { out<<Reqd(env)->req->lastmod; } | ||
| 52 | |||
| 53 | TOK_IMPL(req_method) { out<<Reqd(env)->req->method; } | ||
| 54 | TOK_IMPL(req_uri) { out<<Reqd(env)->req->uri; } | ||
| 55 | TOK_IMPL(req_arg) { out<<Reqd(env)->req->arg; } | ||
| 56 | TOK_IMPL(req_version) { out<<Reqd(env)->req->version; } | ||
| 57 | TOK_IMPL(req_accept) { out<<Reqd(env)->req->accept; } | ||
| 58 | TOK_IMPL(req_accept_charset) { out<<Reqd(env)->req->accept_charset; } | ||
| 59 | TOK_IMPL(req_accept_enc) { out<<Reqd(env)->req->accept_enc; } | ||
| 60 | TOK_IMPL(req_accept_lang) { out<<Reqd(env)->req->accept_lang; } | ||
| 61 | TOK_IMPL(req_accept_range) { out<<Reqd(env)->req->accept_range; } | ||
| 62 | TOK_IMPL(req_auth) { out<<Reqd(env)->req->auth; } | ||
| 63 | TOK_IMPL(req_expect) { out<<Reqd(env)->req->expect; } | ||
| 64 | TOK_IMPL(req_from) { out<<Reqd(env)->req->from; } | ||
| 65 | TOK_IMPL(req_host) { out<<Reqd(env)->req->host; } | ||
| 66 | TOK_IMPL(req_if_match) { out<<Reqd(env)->req->if_match; } | ||
| 67 | TOK_IMPL(req_if_mod) { out<<Reqd(env)->req->if_mod; } | ||
| 68 | TOK_IMPL(req_if_none) { out<<Reqd(env)->req->if_none; } | ||
| 69 | TOK_IMPL(req_if_range) { out<<Reqd(env)->req->if_range; } | ||
| 70 | TOK_IMPL(req_if_unmod) { out<<Reqd(env)->req->if_unmod; } | ||
| 71 | TOK_IMPL(req_max_forwards) { out<<Reqd(env)->req->max_forwards; } | ||
| 72 | TOK_IMPL(req_proxy) { out<<Reqd(env)->req->proxy; } | ||
| 73 | TOK_IMPL(req_range) { out<<Reqd(env)->req->range; } | ||
| 74 | TOK_IMPL(req_referer) { out<<Reqd(env)->req->referer; } | ||
| 75 | TOK_IMPL(req_te) { out<<Reqd(env)->req->te; } | ||
| 76 | TOK_IMPL(req_useragent) { out<<Reqd(env)->req->user_agent; } | ||
| 77 | |||
| 78 | /////////////////////////////////////////////////////////////////// | ||
| 79 | |||
| 80 | TOK_IMPL(resp_cookie) { | ||
| 81 | Reqd(env)->resp.set_cookies.push_back(cookie_t(env[0],env[1],env.parg(2))); | ||
| 82 | } | ||
| 83 | TOK_IMPL(resp_mime_version) { Reqd(env)->resp.mime_version=env[0]; } | ||
| 84 | TOK_IMPL(resp_cont_type) { Reqd(env)->resp.cont_type=env[0]; } | ||
| 85 | TOK_IMPL(resp_cont_type_charset) { Reqd(env)->resp.cont_type_charset=env[0]; } | ||
| 86 | TOK_IMPL(resp_cont_type_name) { Reqd(env)->resp.cont_type_name=env[0]; } | ||
| 87 | TOK_IMPL(resp_cont_type_boundary) { Reqd(env)->resp.cont_type_boundary=env[0]; } | ||
| 88 | TOK_IMPL(resp_cont_id) { Reqd(env)->resp.cont_id=env[0]; } | ||
| 89 | TOK_IMPL(resp_cont_desc) { Reqd(env)->resp.cont_desc=env[0]; } | ||
| 90 | TOK_IMPL(resp_cont_disp) { Reqd(env)->resp.cont_disp=env[0]; } | ||
| 91 | TOK_IMPL(resp_cont_disp_name) { Reqd(env)->resp.cont_disp_name=env[0]; } | ||
| 92 | TOK_IMPL(resp_cont_disp_file) { Reqd(env)->resp.cont_disp_file=env[0]; } | ||
| 93 | TOK_IMPL(resp_cont_trans_enc) { Reqd(env)->resp.cont_trans_enc=env[0]; } | ||
| 94 | TOK_IMPL(resp_cont_length) { Reqd(env)->resp.cont_length=env[0]; } | ||
| 95 | |||
| 96 | TOK_IMPL(resp_cache) { Reqd(env)->resp.cache=env[0]; } | ||
| 97 | TOK_IMPL(resp_connect) { Reqd(env)->resp.connect=env[0]; } | ||
| 98 | TOK_IMPL(resp_date) { Reqd(env)->resp.date=env[0]; } | ||
| 99 | TOK_IMPL(resp_pragma) { Reqd(env)->resp.pragma=env[0]; } | ||
| 100 | TOK_IMPL(resp_trailer) { Reqd(env)->resp.trailer=env[0]; } | ||
| 101 | TOK_IMPL(resp_trans_enc) { Reqd(env)->resp.trans_enc=env[0]; } | ||
| 102 | TOK_IMPL(resp_upgrade) { Reqd(env)->resp.upgrade=env[0]; } | ||
| 103 | TOK_IMPL(resp_via) { Reqd(env)->resp.via=env[0]; } | ||
| 104 | TOK_IMPL(resp_warning) { Reqd(env)->resp.warning=env[0]; } | ||
| 105 | TOK_IMPL(resp_allow) { Reqd(env)->resp.allow=env[0]; } | ||
| 106 | TOK_IMPL(resp_cont_enc) { Reqd(env)->resp.cont_enc=env[0]; } | ||
| 107 | TOK_IMPL(resp_cont_lang) { Reqd(env)->resp.cont_lang=env[0]; } | ||
| 108 | TOK_IMPL(resp_cont_location) { Reqd(env)->resp.cont_location=env[0]; } | ||
| 109 | TOK_IMPL(resp_cont_md5) { Reqd(env)->resp.cont_md5=env[0]; } | ||
| 110 | TOK_IMPL(resp_cont_range) { Reqd(env)->resp.cont_range=env[0]; } | ||
| 111 | TOK_IMPL(resp_expires) { Reqd(env)->resp.expires=env[0]; } | ||
| 112 | TOK_IMPL(resp_lastmod) { Reqd(env)->resp.lastmod=env[0]; } | ||
| 113 | |||
| 114 | TOK_IMPL(resp_version) { Reqd(env)->resp.version=env[0]; } | ||
| 115 | TOK_IMPL(resp_status) { Reqd(env)->resp.status=env[0]; } | ||
| 116 | TOK_IMPL(resp_age) { Reqd(env)->resp.age=env[0]; } | ||
| 117 | TOK_IMPL(resp_etag) { Reqd(env)->resp.etag=env[0]; } | ||
| 118 | TOK_IMPL(resp_location) { Reqd(env)->resp.location=env[0]; } | ||
| 119 | TOK_IMPL(resp_proxy_auth) { Reqd(env)->resp.proxy_authent=env[0]; } | ||
| 120 | TOK_IMPL(resp_retry) { Reqd(env)->resp.retry=env[0]; } | ||
| 121 | TOK_IMPL(resp_server) { Reqd(env)->resp.server=env[0]; } | ||
| 122 | TOK_IMPL(resp_vary) { Reqd(env)->resp.vary=env[0]; } | ||
| 123 | TOK_IMPL(resp_auth) { Reqd(env)->resp.authent=env[0]; } | ||
| 124 | |||
| 125 | TOK_IMPL(resp_accept) { Reqd(env)->resp.accept=env[0]; } | ||
| 126 | TOK_IMPL(resp_accept_charset) { Reqd(env)->resp.accept_charset=env[0]; } | ||
| 127 | TOK_IMPL(resp_accept_enc) { Reqd(env)->resp.accept_enc=env[0]; } | ||
| 128 | TOK_IMPL(resp_accept_lang) { Reqd(env)->resp.accept_lang=env[0]; } | ||
| 129 | TOK_IMPL(resp_accept_range) { Reqd(env)->resp.accept_range=env[0]; } | ||
| 130 | |||
| 131 | /////////////////////////////////////////////////////////////////// | ||
| 132 | |||
| 133 | TOK_IMPL(resp_getstatus) { out<<Reqd(env)->resp.status; } | ||
| 134 | |||
| 135 | /////////////////////////////////////////////////////////////////// | ||
| 136 | |||
| 137 | TOK_IMPL(andarg) { sref s=Reqd(env)->req->arg; if(s.nempty()) out.put('?')<<s; } | ||
| 138 | |||
| 139 | /////////////////////////////////////////////////////////////////// | ||
| 140 | |||
| 141 | const mstring reqhelp="%Request header entry\n"; | ||
| 142 | const mstring resphelp="%Response header entry; takes one argument\n"; | ||
| 143 | const mstring respgethelp="%Get response header entry\n"; | ||
| 144 | const mstring x_tag="x"; | ||
| 145 | |||
| 146 | void envAddReq(tokmap& T) | ||
| 147 | { | ||
| 148 | TOK_ADD(req_mime_version,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 149 | TOK_ADD(req_cont_type,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 150 | TOK_ADD(req_cont_type_charset,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 151 | TOK_ADD(req_cont_type_name,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 152 | TOK_ADD(req_cont_type_boundary,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 153 | TOK_ADD(req_cont_id,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 154 | TOK_ADD(req_cont_desc,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 155 | TOK_ADD(req_cont_disp,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 156 | TOK_ADD(req_cont_disp_name,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 157 | TOK_ADD(req_cont_disp_file,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 158 | TOK_ADD(req_cont_trans_enc,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 159 | TOK_ADD(req_cont_length,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 160 | |||
| 161 | TOK_ADD(req_cache,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 162 | TOK_ADD(req_connect,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 163 | TOK_ADD(req_date,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 164 | TOK_ADD(req_pragma,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 165 | TOK_ADD(req_trailer,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 166 | TOK_ADD(req_trans_enc,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 167 | TOK_ADD(req_upgrade,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 168 | TOK_ADD(req_via,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 169 | TOK_ADD(req_warning,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 170 | TOK_ADD(req_allow,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 171 | TOK_ADD(req_cont_enc,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 172 | TOK_ADD(req_cont_lang,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 173 | TOK_ADD(req_cont_location,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 174 | TOK_ADD(req_cont_md5,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 175 | TOK_ADD(req_cont_range,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 176 | TOK_ADD(req_expires,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 177 | TOK_ADD(req_lastmod,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 178 | |||
| 179 | TOK_ADD(req_method,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 180 | TOK_ADD(req_uri,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 181 | TOK_ADD(req_arg,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 182 | TOK_ADD(req_version,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 183 | TOK_ADD(req_accept,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 184 | TOK_ADD(req_accept_charset,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 185 | TOK_ADD(req_accept_enc,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 186 | TOK_ADD(req_accept_lang,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 187 | TOK_ADD(req_accept_range,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 188 | TOK_ADD(req_auth,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 189 | TOK_ADD(req_expect,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 190 | TOK_ADD(req_from,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 191 | TOK_ADD(req_host,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 192 | TOK_ADD(req_if_match,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 193 | TOK_ADD(req_if_mod,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 194 | TOK_ADD(req_if_none,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 195 | TOK_ADD(req_if_range,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 196 | TOK_ADD(req_if_unmod,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 197 | TOK_ADD(req_max_forwards,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 198 | TOK_ADD(req_proxy,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 199 | TOK_ADD(req_range,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 200 | TOK_ADD(req_referer,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 201 | TOK_ADD(req_te,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 202 | TOK_ADD(req_useragent,ms_empty,tok_t::PUBLIC,reqhelp); | ||
| 203 | |||
| 204 | /////////////////////////////////////////////////////////////// | ||
| 205 | |||
| 206 | TOK_ADD(andarg,ms_empty,tok_t::PUBLIC, | ||
| 207 | "%Conditional output of argument string\n" | ||
| 208 | "%Syntax: \\andarg\n" | ||
| 209 | "%\n" | ||
| 210 | "%Outputs ?\\req.arg if \\req.arg is non-empty.\n" | ||
| 211 | ); | ||
| 212 | |||
| 213 | TOK_ADD(resp_cookie,"xx?",tok_t::SYSONLY, | ||
| 214 | "%Set cookie\n" | ||
| 215 | "%Syntax: \\resp.cookie{name}{val}<options>\n" | ||
| 216 | "%\n" | ||
| 217 | "%Sets the cookie name to value val\n" | ||
| 218 | "%The options field should be on the form expected\n" | ||
| 219 | "%in the HTTP header, for instance\n" | ||
| 220 | "%domain=something; path=/; expires=http-data\n" | ||
| 221 | "%\n" | ||
| 222 | "%No newlines should be added, and remember that ; needs\n" | ||
| 223 | "%to be escaped.\n" | ||
| 224 | ); | ||
| 225 | |||
| 226 | /////////////////////////////////////////////////////////////// | ||
| 227 | |||
| 228 | TOK_ADD(resp_mime_version,x_tag,tok_t::SYSONLY,resphelp); | ||
| 229 | TOK_ADD(resp_cont_type,x_tag,tok_t::SYSONLY,resphelp); | ||
| 230 | TOK_ADD(resp_cont_type_charset,x_tag,tok_t::SYSONLY,resphelp); | ||
| 231 | TOK_ADD(resp_cont_type_name,x_tag,tok_t::SYSONLY,resphelp); | ||
| 232 | TOK_ADD(resp_cont_type_boundary,x_tag,tok_t::SYSONLY,resphelp); | ||
| 233 | TOK_ADD(resp_cont_id,x_tag,tok_t::SYSONLY,resphelp); | ||
| 234 | TOK_ADD(resp_cont_desc,x_tag,tok_t::SYSONLY,resphelp); | ||
| 235 | TOK_ADD(resp_cont_disp,x_tag,tok_t::SYSONLY,resphelp); | ||
| 236 | TOK_ADD(resp_cont_disp_name,x_tag,tok_t::SYSONLY,resphelp); | ||
| 237 | TOK_ADD(resp_cont_disp_file,x_tag,tok_t::SYSONLY,resphelp); | ||
| 238 | TOK_ADD(resp_cont_trans_enc,x_tag,tok_t::SYSONLY,resphelp); | ||
| 239 | TOK_ADD(resp_cont_length,x_tag,tok_t::SYSONLY,resphelp); | ||
| 240 | |||
| 241 | TOK_ADD(resp_cache,x_tag,tok_t::SYSONLY,resphelp); | ||
| 242 | TOK_ADD(resp_connect,x_tag,tok_t::SYSONLY,resphelp); | ||
| 243 | TOK_ADD(resp_date,x_tag,tok_t::SYSONLY,resphelp); | ||
| 244 | TOK_ADD(resp_pragma,x_tag,tok_t::SYSONLY,resphelp); | ||
| 245 | TOK_ADD(resp_trailer,x_tag,tok_t::SYSONLY,resphelp); | ||
| 246 | TOK_ADD(resp_trans_enc,x_tag,tok_t::SYSONLY,resphelp); | ||
| 247 | TOK_ADD(resp_upgrade,x_tag,tok_t::SYSONLY,resphelp); | ||
| 248 | TOK_ADD(resp_via,x_tag,tok_t::SYSONLY,resphelp); | ||
| 249 | TOK_ADD(resp_warning,x_tag,tok_t::SYSONLY,resphelp); | ||
| 250 | TOK_ADD(resp_allow,x_tag,tok_t::SYSONLY,resphelp); | ||
| 251 | TOK_ADD(resp_cont_enc,x_tag,tok_t::SYSONLY,resphelp); | ||
| 252 | TOK_ADD(resp_cont_lang,x_tag,tok_t::SYSONLY,resphelp); | ||
| 253 | TOK_ADD(resp_cont_location,x_tag,tok_t::SYSONLY,resphelp); | ||
| 254 | TOK_ADD(resp_cont_md5,x_tag,tok_t::SYSONLY,resphelp); | ||
| 255 | TOK_ADD(resp_cont_range,x_tag,tok_t::SYSONLY,resphelp); | ||
| 256 | TOK_ADD(resp_expires,x_tag,tok_t::SYSONLY,resphelp); | ||
| 257 | TOK_ADD(resp_lastmod,x_tag,tok_t::SYSONLY,resphelp); | ||
| 258 | |||
| 259 | TOK_ADD(resp_version,x_tag,tok_t::SYSONLY,resphelp); | ||
| 260 | TOK_ADD(resp_status,x_tag,tok_t::SYSONLY,resphelp); | ||
| 261 | TOK_ADD(resp_age,x_tag,tok_t::SYSONLY,resphelp); | ||
| 262 | TOK_ADD(resp_etag,x_tag,tok_t::SYSONLY,resphelp); | ||
| 263 | TOK_ADD(resp_location,x_tag,tok_t::SYSONLY,resphelp); | ||
| 264 | TOK_ADD(resp_proxy_auth,x_tag,tok_t::SYSONLY,resphelp); | ||
| 265 | TOK_ADD(resp_retry,x_tag,tok_t::SYSONLY,resphelp); | ||
| 266 | TOK_ADD(resp_server,x_tag,tok_t::SYSONLY,resphelp); | ||
| 267 | TOK_ADD(resp_vary,x_tag,tok_t::SYSONLY,resphelp); | ||
| 268 | TOK_ADD(resp_auth,x_tag,tok_t::SYSONLY,resphelp); | ||
| 269 | |||
| 270 | TOK_ADD(resp_accept,x_tag,tok_t::SYSONLY,resphelp); | ||
| 271 | TOK_ADD(resp_accept_charset,x_tag,tok_t::SYSONLY,resphelp); | ||
| 272 | TOK_ADD(resp_accept_enc,x_tag,tok_t::SYSONLY,resphelp); | ||
| 273 | TOK_ADD(resp_accept_lang,x_tag,tok_t::SYSONLY,resphelp); | ||
| 274 | TOK_ADD(resp_accept_range,x_tag,tok_t::SYSONLY,resphelp); | ||
| 275 | |||
| 276 | /////////////////////////////////////////////////////////////// | ||
| 277 | |||
| 278 | TOK_ADD(resp_getstatus,ms_empty,tok_t::PUBLIC,respgethelp); | ||
| 279 | } | ||
diff --git a/src/serv/tempmap.cc b/src/serv/tempmap.cc new file mode 100644 index 0000000..43b8732 --- /dev/null +++ b/src/serv/tempmap.cc | |||
| @@ -0,0 +1,82 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <serv/htcd.h> | ||
| 21 | #include <unistd.h> | ||
| 22 | #include <fcntl.h> | ||
| 23 | #include <sys/stat.h> | ||
| 24 | |||
| 25 | const mstring TEMPDIR="/tmp/"; | ||
| 26 | |||
| 27 | inline dbmap* GetDB(Env& env) | ||
| 28 | { | ||
| 29 | dbref_t* p=(dbref_t*)env.toks->get(TEMP_tag); | ||
| 30 | if(!env.is_clear(p)||!p->is_dbref()) THROW("htc: could not find tempfile db"); | ||
| 31 | p->db.remap(); | ||
| 32 | return &p->db; | ||
| 33 | } | ||
| 34 | |||
| 35 | TOK_IMPL(tempfile) | ||
| 36 | { | ||
| 37 | mstring path=Reqd(env)->htcd()->docroot+TEMPDIR; | ||
| 38 | mstring file=Random(8),ext=env[1]; | ||
| 39 | int fd; | ||
| 40 | while((fd=open((path+file+ext).c_str(),O_CREAT|O_EXCL|O_WRONLY|O_TRUNC,0600))==-1) | ||
| 41 | file=Random(8); | ||
| 42 | close(fd); | ||
| 43 | tempmap_t temp; | ||
| 44 | temp.name()=file+ext; | ||
| 45 | temp.start()=itoa(time(0)); | ||
| 46 | temp.stop()=itoa(time(0)+atoi(env[0])); | ||
| 47 | temp.refer()=Reqd(env)->user.uid(); | ||
| 48 | dbmap* db=GetDB(env); | ||
| 49 | if(db->empty()) temp.id()=itoa(1); | ||
| 50 | else temp.id()=itoa(atoi(db->at(db->size()-1,temp_id))+1); | ||
| 51 | int row=db->Insert(temp.list,1); | ||
| 52 | if(row<0) THROW("htc: could not add tempfile - record not unique"); | ||
| 53 | out<<temp.name(); | ||
| 54 | } | ||
| 55 | |||
| 56 | TOK_IMPL(tempfile_update) | ||
| 57 | { | ||
| 58 | mstring path=Reqd(env)->htcd()->docroot+TEMPDIR; | ||
| 59 | time_t now=time(0); | ||
| 60 | dbmap* db=GetDB(env); | ||
| 61 | int n=0; | ||
| 62 | while(n<db->size()) { | ||
| 63 | if(now>atoi(db->at(n,temp_stop))) { | ||
| 64 | remove((path+db->at(n,temp_name)).c_str()); | ||
| 65 | db->Rem(n); | ||
| 66 | } | ||
| 67 | else n++; | ||
| 68 | } | ||
| 69 | } | ||
| 70 | |||
| 71 | void envAddTemp(tokmap& T) | ||
| 72 | { | ||
| 73 | TOK_ADD(tempfile,"xx",tok_t::SYSONLY, | ||
| 74 | "%Create a temporary file" | ||
| 75 | "%Syntax: \\tempfile{duration}{.ext}\n" | ||
| 76 | ); | ||
| 77 | TOK_ADD(tempfile_update,"",tok_t::SYSONLY, | ||
| 78 | "%Update tempfile database\n" | ||
| 79 | "%Syntax: \\tempfile_update\n" | ||
| 80 | ); | ||
| 81 | } | ||
| 82 | |||
diff --git a/src/serv/tempmap.h b/src/serv/tempmap.h new file mode 100644 index 0000000..0b9cf5a --- /dev/null +++ b/src/serv/tempmap.h | |||
| @@ -0,0 +1,57 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef TEMPMAPH | ||
| 21 | #define TEMPMAPH | ||
| 22 | |||
| 23 | #include <sh/htc.h> | ||
| 24 | |||
| 25 | const mstring TEMP_tag="TEMP"; | ||
| 26 | |||
| 27 | const int temp_tabs=5,temp_id=0,temp_name=1,temp_start=2,temp_stop=3; | ||
| 28 | const mstring temp_tab[temp_tabs]={ | ||
| 29 | "ID","NAME","START","STOP","REFER" | ||
| 30 | }; | ||
| 31 | |||
| 32 | struct tempmap_t { | ||
| 33 | spile list; | ||
| 34 | |||
| 35 | tempmap_t() : list(temp_tabs) { reset(); } | ||
| 36 | |||
| 37 | mstring& id() { return list[0]; } | ||
| 38 | mstring& name() { return list[1]; } | ||
| 39 | mstring& start() { return list[2]; } | ||
| 40 | mstring& stop() { return list[3]; } | ||
| 41 | mstring& refer() { return list[4]; } | ||
| 42 | |||
| 43 | void reset() { | ||
| 44 | list.resize(temp_tabs); | ||
| 45 | id()=itoa(0); | ||
| 46 | name().clear(); | ||
| 47 | start()=itoa(0); | ||
| 48 | stop()=itoa(0); | ||
| 49 | refer()=itoa(0); | ||
| 50 | } | ||
| 51 | }; | ||
| 52 | |||
| 53 | ///////////////////////////////////////////////////////// | ||
| 54 | |||
| 55 | void envAddTemp(tokmap& T); | ||
| 56 | |||
| 57 | #endif | ||
diff --git a/src/sh/convert.cc b/src/sh/convert.cc new file mode 100644 index 0000000..8828c34 --- /dev/null +++ b/src/sh/convert.cc | |||
| @@ -0,0 +1,376 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <sh/htc.h> | ||
| 21 | #include <hdb/buffer.h> | ||
| 22 | #include <http/http.h> | ||
| 23 | |||
| 24 | static const charset htcmask("{}\\%&*$;"); | ||
| 25 | static const charset htmlmask("<&>\""); | ||
| 26 | |||
| 27 | static void Mask(mstream& out,const charset& mask,const sref& msg) | ||
| 28 | { | ||
| 29 | sref q,p=msg; | ||
| 30 | while(p.nempty()) { | ||
| 31 | p=p.adv(q=p.left_first_of(mask)); | ||
| 32 | out<<q; | ||
| 33 | while(mask.test(p.front())) { | ||
| 34 | unsigned code=(unsigned char)*p; p=p.popf(); | ||
| 35 | out<<"&#"<<code<<";"; | ||
| 36 | } | ||
| 37 | } | ||
| 38 | } | ||
| 39 | |||
| 40 | TOK_IMPL(mask_htc) { | ||
| 41 | Mask(out,htcmask,env[0]); | ||
| 42 | } | ||
| 43 | |||
| 44 | TOK_IMPL(mask_html) { | ||
| 45 | Mask(out,htmlmask,env[0]); | ||
| 46 | } | ||
| 47 | |||
| 48 | TOK_IMPL(cdata) { | ||
| 49 | out.put('\"'); Mask(out,htmlmask,env[0]); out.put('\"'); | ||
| 50 | } | ||
| 51 | |||
| 52 | ////////////////////////////////////////////////////////// | ||
| 53 | |||
| 54 | TOK_IMPL(wrap) { | ||
| 55 | int num=atoi(env[0]); | ||
| 56 | sref body=env[1]; | ||
| 57 | int col=0; | ||
| 58 | for(int i=0;i<body.size();i++) { | ||
| 59 | if(cset_newl.test(body[i])) col=0; else col++; | ||
| 60 | if(cset_spaces.test(body[i])&&col>num) { out.put('\n'); col=0; } | ||
| 61 | else out.put(body[i]); | ||
| 62 | } | ||
| 63 | } | ||
| 64 | |||
| 65 | TOK_IMPL(htmlize) { | ||
| 66 | sref first,rest=env[0]; | ||
| 67 | while(Splitln(first,rest)) { | ||
| 68 | Mask(out,htmlmask,first); | ||
| 69 | out<<"<br>\n"; | ||
| 70 | } | ||
| 71 | } | ||
| 72 | |||
| 73 | TOK_IMPL(lf2crlf) { | ||
| 74 | LF2CRLF(out,env[0]); | ||
| 75 | } | ||
| 76 | TOK_IMPL(crlf2lf) { | ||
| 77 | CRLF2LF(out,env[0]); | ||
| 78 | } | ||
| 79 | |||
| 80 | ////////////////////////////////////////////////////////// | ||
| 81 | |||
| 82 | TOK_IMPL(twocolumn) { | ||
| 83 | int num=atoi(env[0]); | ||
| 84 | int page=atoi(env[1]); | ||
| 85 | sref head=env[2],mid=env[3],foot=env[4],body=env[5]; | ||
| 86 | int row=0,col=0,pg=1; | ||
| 87 | out<<head; | ||
| 88 | for(int i=0;i<body.size()&&pg<=page;i++) { | ||
| 89 | if(pg==page) out.put(body[i]); | ||
| 90 | if(body[i]=='\n') { | ||
| 91 | row++; | ||
| 92 | if(row>=num) { | ||
| 93 | row=0; | ||
| 94 | col++; | ||
| 95 | if(col>=2) { col=0; pg++; } | ||
| 96 | else if(pg==page) { out<<mid; } | ||
| 97 | } | ||
| 98 | } | ||
| 99 | } | ||
| 100 | out<<foot; | ||
| 101 | } | ||
| 102 | |||
| 103 | ////////////////////////////////////////////////////////// | ||
| 104 | |||
| 105 | TOK_IMPL(encode) { | ||
| 106 | Pack(out,env[0]); | ||
| 107 | } | ||
| 108 | |||
| 109 | TOK_IMPL(decode) { | ||
| 110 | Unpack(out,env[0]); | ||
| 111 | } | ||
| 112 | |||
| 113 | TOK_IMPL(encode_header) { | ||
| 114 | encodeHeader(out,mime_default,env[0]); | ||
| 115 | } | ||
| 116 | |||
| 117 | TOK_IMPL(encode_base64) { | ||
| 118 | mstring buffer,path=DocPath(env,env[0]); | ||
| 119 | LoadBuffer(buffer,path); | ||
| 120 | encode64(out,buffer); | ||
| 121 | } | ||
| 122 | |||
| 123 | TOK_IMPL(pack) { | ||
| 124 | rrpile pile; | ||
| 125 | spile var(env.args); | ||
| 126 | for(int i=0;i<env.args;i++) { | ||
| 127 | env.parg(var[i],i); | ||
| 128 | pile.push_back(rrstring(var[i],env.glob(var[i]))); | ||
| 129 | } | ||
| 130 | Pack(out,pile); | ||
| 131 | } | ||
| 132 | |||
| 133 | ////////////////////////////////////////////////////////// | ||
| 134 | |||
| 135 | TOK_IMPL(decode_base64) { | ||
| 136 | mstring buffer,name=env.parg(-1),uri=env.URI(env[0]),path=DocPath(env,env[0]); | ||
| 137 | LoadBuffer(buffer,path); | ||
| 138 | if(name.nempty()) { | ||
| 139 | swrite sw(Reference(*env.toks,name,uri,1)->data); | ||
| 140 | decode64(sw,buffer); | ||
| 141 | } | ||
| 142 | else decode64(out,buffer); | ||
| 143 | } | ||
| 144 | |||
| 145 | ////////////////////////////////////////////////////////// | ||
| 146 | |||
| 147 | TOK_IMPL(strip) { | ||
| 148 | sref s=env[0],a=env[1]; | ||
| 149 | for(int i=0;i<s.size();i++) if(a.find(s[i])<0) out.put(s[i]); | ||
| 150 | } | ||
| 151 | |||
| 152 | TOK_IMPL(replace) { | ||
| 153 | mstring s=env[0]; sref a=env[1],b=env[2]; | ||
| 154 | if(a!=b) { int p; while((p=s.find(a))>=0) s.replace(p,a.size(),b); } | ||
| 155 | out<<s; | ||
| 156 | } | ||
| 157 | |||
| 158 | ////////////////////////////////////////////////////////// | ||
| 159 | |||
| 160 | TOK_IMPL(left) { | ||
| 161 | int pad=atoi(env[1])-env[0].size(); | ||
| 162 | out<<env[0]; while(pad-->0) out.put(' '); | ||
| 163 | } | ||
| 164 | TOK_IMPL(right) { | ||
| 165 | int pad=atoi(env[1])-env[0].size(); | ||
| 166 | while(pad-->0) out.put(' '); out<<env[0]; | ||
| 167 | } | ||
| 168 | |||
| 169 | TOK_IMPL(sub) {out<<env[0](atoi(env[1]),atoi(env[2]));} | ||
| 170 | |||
| 171 | ////////////////////////////////////////////////////////// | ||
| 172 | |||
| 173 | TOK_IMPL(file2mime) { | ||
| 174 | const sref* p=file2mime(env[0]); | ||
| 175 | if(p) out<<*p; else out<<http_mime_default; | ||
| 176 | } | ||
| 177 | |||
| 178 | ////////////////////////////////////////////////////////// | ||
| 179 | |||
| 180 | TOK_IMPL(minilang) { | ||
| 181 | static const mstring lang_tag("\\lang"); | ||
| 182 | sref p=env[0]; | ||
| 183 | while(p.nempty()) { | ||
| 184 | sref e=p.left_first(lang_tag); | ||
| 185 | out<<e; | ||
| 186 | p=p.adv(e); | ||
| 187 | if(p.nempty()) { | ||
| 188 | p=p.adv(lang_tag.size()); | ||
| 189 | e=p.right_first_not_of(cset_ws); | ||
| 190 | int n=0,s=e.skip(cset_braces); | ||
| 191 | while(s>0) { | ||
| 192 | p=e.adv(s); | ||
| 193 | if(n==env.req->lang) out<<e(1,s-2); | ||
| 194 | e=p.right_first_not_of(cset_ws); | ||
| 195 | s=e.skip(cset_braces); | ||
| 196 | n++; | ||
| 197 | } | ||
| 198 | if(n==0) out<<lang_tag; | ||
| 199 | if(*p==';') p=p.adv(1); | ||
| 200 | } | ||
| 201 | } | ||
| 202 | } | ||
| 203 | |||
| 204 | ////////////////////////////////////////////////////////// | ||
| 205 | |||
| 206 | void envAddConvert(tokmap& T) | ||
| 207 | { | ||
| 208 | TOK_ADD(mask_htc,"x",tok_t::SYSONLY, | ||
| 209 | "%Mask HTC language\n" | ||
| 210 | "%Syntax: \\mask.htc{text}\n" | ||
| 211 | "%\n" | ||
| 212 | "%Converts 'hot' characters to HTML CDATA encoding\n" | ||
| 213 | "%CDATA encoding: &#hex;\n" | ||
| 214 | ); | ||
| 215 | TOK_ADD(mask_html,"x",tok_t::PUBLIC, | ||
| 216 | "%Mask HTML language\n" | ||
| 217 | "%Syntax: \\mask.html{text}\n" | ||
| 218 | "%\n" | ||
| 219 | "%Converts 'hot' characters to HTML CDATA encoding\n" | ||
| 220 | "%CDATA encoding: &#hex;\n" | ||
| 221 | ); | ||
| 222 | TOK_ADD(cdata,"x",tok_t::PUBLIC, | ||
| 223 | "%Convert to CDATA\n" | ||
| 224 | "%Syntax: \\cdata{text}\n" | ||
| 225 | "%\n" | ||
| 226 | "%Converts 'hot' characters to HTML CDATA encoding\n" | ||
| 227 | "%and encloses in \" characters\n" | ||
| 228 | "%\n" | ||
| 229 | "%HTML parsors usually does not nest the \" character,\n" | ||
| 230 | "%so this function is used extensively in arguments to\n" | ||
| 231 | "%HTML commands.\n" | ||
| 232 | ); | ||
| 233 | |||
| 234 | /////////////////////////////////////////////// | ||
| 235 | |||
| 236 | TOK_ADD(wrap,"xx",tok_t::PUBLIC, | ||
| 237 | "%Wrap long lines\n" | ||
| 238 | "%Syntax: \\wrap{at column}{text}\n" | ||
| 239 | "%\n" | ||
| 240 | "%Wraps words that extend the given column by inserting\n" | ||
| 241 | "%newline characters.\n" | ||
| 242 | ); | ||
| 243 | TOK_ADD(htmlize,"x",tok_t::PUBLIC, | ||
| 244 | "%HTMLize plain text\n" | ||
| 245 | "%Syntax: \\htmlize{text}\n" | ||
| 246 | "%\n" | ||
| 247 | "%Inserts a HTML break at each newline.\n" | ||
| 248 | ); | ||
| 249 | TOK_ADD(lf2crlf,"x",tok_t::PUBLIC, | ||
| 250 | "%LF to CRLF\n" | ||
| 251 | "%Syntax: \\lf2crlf{text}\n" | ||
| 252 | "%\n" | ||
| 253 | "%Inserts a carriage return (CR) at each newline.\n" | ||
| 254 | ); | ||
| 255 | TOK_ADD(crlf2lf,"x",tok_t::PUBLIC, | ||
| 256 | "%CRLF to LF\n" | ||
| 257 | "%Syntax: \\crlf2lf{text}\n" | ||
| 258 | "%\n" | ||
| 259 | "%Removes all carriage return (CR) characters.\n" | ||
| 260 | ); | ||
| 261 | |||
| 262 | /////////////////////////////////////////////// | ||
| 263 | |||
| 264 | TOK_ADD(twocolumn,"xxxxxx",tok_t::PUBLIC, | ||
| 265 | "%Output column text\n" | ||
| 266 | "%Syntax: \\twocolumn{rows}{page}{head}{mid}{foot}{body}\n" | ||
| 267 | ); | ||
| 268 | |||
| 269 | /////////////////////////////////////////////// | ||
| 270 | |||
| 271 | TOK_ADD(encode,"x",tok_t::PUBLIC, | ||
| 272 | "%Encode text\n" | ||
| 273 | "%Syntax: \\encode{text}\n" | ||
| 274 | "%\n" | ||
| 275 | "%Encodes text in x-www-form-urlencoded format (RFC HTTP)\n" | ||
| 276 | ); | ||
| 277 | TOK_ADD(decode,"x",tok_t::PUBLIC, | ||
| 278 | "%Decode text\n" | ||
| 279 | "%Syntax: \\decode{text}\n" | ||
| 280 | "%\n" | ||
| 281 | "%Decodes text given in x-www-form-urlencoded format (RFC HTTP)\n" | ||
| 282 | ); | ||
| 283 | |||
| 284 | TOK_ADD(encode_header,"x",tok_t::PUBLIC, | ||
| 285 | "%Encode header\n" | ||
| 286 | "%Syntax: \\encode.header{text}\n" | ||
| 287 | "%\n" | ||
| 288 | "%Encodes text in Quoted-printable header format (RFC MIME)\n" | ||
| 289 | ); | ||
| 290 | TOK_ADD(encode_base64,"x",tok_t::PUBLIC, | ||
| 291 | "%Encode base64\n" | ||
| 292 | "%Syntax: \\encode.base64{uri}\n" | ||
| 293 | "%\n" | ||
| 294 | "%Encodes the uri, possible containing binary data,\n" | ||
| 295 | "%in BASE64 format (RFC MIME)\n" | ||
| 296 | ); | ||
| 297 | TOK_ADD(decode_base64,"?x",tok_t::PUBLIC, | ||
| 298 | "%Decode base64\n" | ||
| 299 | "%Syntax: \\decode.base64{var}{uri}\n" | ||
| 300 | "%\n" | ||
| 301 | "%Encodes the uri, presumed to be in BASE64 format,\n" | ||
| 302 | "%and outputs or saves in var. (RFC MIME)\n" | ||
| 303 | ); | ||
| 304 | TOK_ADD(pack,"*",tok_t::PUBLIC, | ||
| 305 | "%Encode text\n" | ||
| 306 | "%Syntax: \\pack<var><var>..\n" | ||
| 307 | "%\n" | ||
| 308 | "%Encodes a sequence of variables in\n" | ||
| 309 | "%x-www-form-urlencoded format (RFC HTTP)\n" | ||
| 310 | ); | ||
| 311 | |||
| 312 | /////////////////////////////////////////////// | ||
| 313 | |||
| 314 | TOK_ADD(strip,"xx",tok_t::PUBLIC, | ||
| 315 | "%Strip text from special characters\n" | ||
| 316 | "%Syntax: \\stip{text}{chars}\n" | ||
| 317 | ); | ||
| 318 | TOK_ADD(replace,"xxx",tok_t::PUBLIC, | ||
| 319 | "%Replace text\n" | ||
| 320 | "%Syntax: \\replace{text}{string}{subst}\n" | ||
| 321 | "%\n" | ||
| 322 | "%Replaces each occurence of string in text with subst.\n" | ||
| 323 | ); | ||
| 324 | |||
| 325 | /////////////////////////////////////////////// | ||
| 326 | |||
| 327 | TOK_ADD(left,"xx",tok_t::PUBLIC, | ||
| 328 | "%Left-adjust text\n" | ||
| 329 | "%Syntax: \\left{text}{n}\n" | ||
| 330 | "%\n" | ||
| 331 | "%Outputs n characters, padding with spaces to the right.\n" | ||
| 332 | "%\n" | ||
| 333 | "%Writes out the full text if longer than n.\n" | ||
| 334 | ); | ||
| 335 | TOK_ADD(right,"xx",tok_t::PUBLIC, | ||
| 336 | "%Right-adjust text\n" | ||
| 337 | "%Syntax: \\right{text}{n}\n" | ||
| 338 | "%\n" | ||
| 339 | "%Outputs n characters, padding with spaces to the left.\n" | ||
| 340 | "%\n" | ||
| 341 | "%Writes out the full text if longer than n.\n" | ||
| 342 | ); | ||
| 343 | |||
| 344 | /////////////////////////////////////////////// | ||
| 345 | |||
| 346 | TOK_ADD(sub,"xxx",tok_t::PUBLIC, | ||
| 347 | "%Substring\n" | ||
| 348 | "%Syntax: \\sub{string}{pos}{n}\n" | ||
| 349 | "%\n" | ||
| 350 | "%Gets a substring of n characters, beginning at pos, from string.\n" | ||
| 351 | "%\n" | ||
| 352 | "%Negative pos values wraps to end.\n" | ||
| 353 | "%Negative n values wraps to 1+size.\n" | ||
| 354 | ); | ||
| 355 | |||
| 356 | /////////////////////////////////////////////// | ||
| 357 | |||
| 358 | TOK_ADD(file2mime,"x",tok_t::PUBLIC, | ||
| 359 | "%Get MIME type\n" | ||
| 360 | "%Syntax: \\file2mime{path}\n" | ||
| 361 | "%\n" | ||
| 362 | "%Looks up the MIME type mapped to the extension of path.\n" | ||
| 363 | "%\n" | ||
| 364 | "%Defaults to application/octet-stream if not found.\n" | ||
| 365 | ); | ||
| 366 | |||
| 367 | /////////////////////////////////////////////// | ||
| 368 | |||
| 369 | TOK_ADD(minilang,"x",tok_t::PUBLIC, | ||
| 370 | "%Parse lang only\n" | ||
| 371 | "%Syntax: \\minilang{body}\n" | ||
| 372 | "%\n" | ||
| 373 | "%This function is used to enable lang in html files,\n" | ||
| 374 | "%which otherwise are not parsed.\n" | ||
| 375 | ); | ||
| 376 | } | ||
diff --git a/src/sh/dates.cc b/src/sh/dates.cc new file mode 100644 index 0000000..a37103b --- /dev/null +++ b/src/sh/dates.cc | |||
| @@ -0,0 +1,138 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <sh/htc.h> | ||
| 21 | #include <mt/dates.h> | ||
| 22 | #include <limits.h> | ||
| 23 | |||
| 24 | const int ENDTIME=INT_MAX-4*SEC_PER_DAY; | ||
| 25 | |||
| 26 | TOK_IMPL(endtime) { out<<ENDTIME; } | ||
| 27 | TOK_IMPL(now) { out<<Now(); } | ||
| 28 | TOK_IMPL(minutes) { out<<(60*atoi(env[0])); } | ||
| 29 | TOK_IMPL(days) { out<<Days(atoi(env[0])); } | ||
| 30 | TOK_IMPL(today) { out<<Today(atoi(env[0])); } | ||
| 31 | TOK_IMPL(sunday) { out<<Sunday(atoi(env[0])); } | ||
| 32 | TOK_IMPL(week) { out<<Week(env.req->lang,atoi(env[0])); } | ||
| 33 | TOK_IMPL(month) { out<<Month(env.req->lang,atoi(env[0])); } | ||
| 34 | TOK_IMPL(sweek) { out<<SWeek(env.req->lang,atoi(env[0])); } | ||
| 35 | TOK_IMPL(smonth) { out<<SMonth(env.req->lang,atoi(env[0])); } | ||
| 36 | |||
| 37 | //////////////////////////////////////////////////////////// | ||
| 38 | |||
| 39 | TOK_IMPL(time2http) { out<<httpTime(atoi(env[0])); } | ||
| 40 | TOK_IMPL(time2htc) { out<<htcTime(env.req->lang,atoi(env[0])); } | ||
| 41 | TOK_IMPL(htc2time) { out<<htcTime(env.req->lang,env[0]); } | ||
| 42 | TOK_IMPL(cvttime) { out<<cvtTime(env[0]); } | ||
| 43 | |||
| 44 | //////////////////////////////////////////////////////////// | ||
| 45 | |||
| 46 | void envAddDates(tokmap& T) | ||
| 47 | { | ||
| 48 | TOK_ADD(endtime,"",tok_t::PUBLIC, | ||
| 49 | "%Endtime\n" | ||
| 50 | "%Syntax: \\endtime\n" | ||
| 51 | "%\n" | ||
| 52 | "%Last time (safely) representable by internal format\n" | ||
| 53 | ); | ||
| 54 | TOK_ADD(now,"",tok_t::PUBLIC, | ||
| 55 | "%Now\n" | ||
| 56 | "%Syntax: \\now\n" | ||
| 57 | "%\n" | ||
| 58 | "%Current system time. Note that this may be out of\n" | ||
| 59 | "%sync with filesystem.\n" | ||
| 60 | ); | ||
| 61 | TOK_ADD(minutes,"x",tok_t::PUBLIC, | ||
| 62 | "%Minutes in seconds\n" | ||
| 63 | "%Syntax: \\minutes{m}\n" | ||
| 64 | ); | ||
| 65 | TOK_ADD(days,"x",tok_t::PUBLIC, | ||
| 66 | "%Days in seconds\n" | ||
| 67 | "%Syntax: \\days{d}\n" | ||
| 68 | ); | ||
| 69 | TOK_ADD(today,"x",tok_t::PUBLIC, | ||
| 70 | "%Beginning of day\n" | ||
| 71 | "%Syntax: \\today{t}\n" | ||
| 72 | "%\n" | ||
| 73 | "%Get beginning of day.\n" | ||
| 74 | ); | ||
| 75 | TOK_ADD(sunday,"x",tok_t::PUBLIC, | ||
| 76 | "%Last sunday\n" | ||
| 77 | "%Syntax: \\sunday{t}\n" | ||
| 78 | "%\n" | ||
| 79 | "%Get beginning of last sunday.\n" | ||
| 80 | ); | ||
| 81 | TOK_ADD(week,"x",tok_t::PUBLIC, | ||
| 82 | "%Weekday (long)\n" | ||
| 83 | "%Syntax: \\week{t}\n" | ||
| 84 | "%\n" | ||
| 85 | "%Get long weekday format.\n" | ||
| 86 | "%Output in current language.\n" | ||
| 87 | ); | ||
| 88 | TOK_ADD(month,"x",tok_t::PUBLIC, | ||
| 89 | "%Month (long)\n" | ||
| 90 | "%Syntax: \\month{t}\n" | ||
| 91 | "%\n" | ||
| 92 | "%Get long month format.\n" | ||
| 93 | "%Output in current language.\n" | ||
| 94 | ); | ||
| 95 | TOK_ADD(sweek,"x",tok_t::PUBLIC, | ||
| 96 | "%Weekday (short)\n" | ||
| 97 | "%Syntax: \\sweek{t}\n" | ||
| 98 | "%\n" | ||
| 99 | "%Get short weekday format.\n" | ||
| 100 | "%Output in current language.\n" | ||
| 101 | ); | ||
| 102 | TOK_ADD(smonth,"x",tok_t::PUBLIC, | ||
| 103 | "%Month (short)\n" | ||
| 104 | "%Syntax: \\smonth{t}\n" | ||
| 105 | "%\n" | ||
| 106 | "%Get short month format.\n" | ||
| 107 | "%Output in current language.\n" | ||
| 108 | ); | ||
| 109 | |||
| 110 | ////////////////////////////////////////////////////// | ||
| 111 | |||
| 112 | TOK_ADD(time2http,"x",tok_t::PUBLIC, | ||
| 113 | "%HTTP Standard Time (GMT)\n" | ||
| 114 | "%Syntax: \\time2http{t}\n" | ||
| 115 | "%\n" | ||
| 116 | "%Outputs time in standard HTTP format.\n" | ||
| 117 | ); | ||
| 118 | TOK_ADD(time2htc,"x",tok_t::PUBLIC, | ||
| 119 | "%HTC Standard Time (Local)\n" | ||
| 120 | "%Syntax: \\time2htc{t}\n" | ||
| 121 | "%\n" | ||
| 122 | "%Outputs time in standard HTC format, which is local time.\n" | ||
| 123 | "%Output in current language.\n" | ||
| 124 | ); | ||
| 125 | TOK_ADD(htc2time,"x",tok_t::PUBLIC, | ||
| 126 | "%Convert to time from HTC (Local)\n" | ||
| 127 | "%Syntax: \\htc2time{timestring}\n" | ||
| 128 | "%\n" | ||
| 129 | "%Converts text to local time internal format.\n" | ||
| 130 | ); | ||
| 131 | TOK_ADD(cvttime,"x",tok_t::PUBLIC, | ||
| 132 | "%Convert user input time (Local)\n" | ||
| 133 | "%Syntax: \\cvttime{timestring}\n" | ||
| 134 | "%\n" | ||
| 135 | "%Tries to make an intelligent conversion of user input\n" | ||
| 136 | "%under the assumption that a local time is given.\n" | ||
| 137 | ); | ||
| 138 | } | ||
diff --git a/src/sh/file.cc b/src/sh/file.cc new file mode 100644 index 0000000..3d885c5 --- /dev/null +++ b/src/sh/file.cc | |||
| @@ -0,0 +1,367 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <sh/htc.h> | ||
| 21 | #include <hdb/buffer.h> | ||
| 22 | #include <mt/dates.h> | ||
| 23 | #include <dirent.h> | ||
| 24 | #include <sys/stat.h> | ||
| 25 | |||
| 26 | const mstring sdot=".",sdots=".."; | ||
| 27 | |||
| 28 | /////////////////////////////////////////////////////////////////// | ||
| 29 | |||
| 30 | inline void stat(struct stat& fs,Env& env,const sref& path) throw(merror_t) { | ||
| 31 | if(::stat(DocPath(env,path).c_str(),&fs)<0) | ||
| 32 | THROW("htc: could not stat "<<path<<" - not found"); | ||
| 33 | } | ||
| 34 | |||
| 35 | /////////////////////////////////////////////////////////////////// | ||
| 36 | |||
| 37 | TOK_IMPL(remfile) { | ||
| 38 | mstring path=DocPath(env,env[0]); | ||
| 39 | if(remove(path.c_str())<0) THROW("htc: Could not remove "<<path); | ||
| 40 | } | ||
| 41 | |||
| 42 | TOK_IMPL(renfile) { | ||
| 43 | mstring oldpath=DocPath(env,env[0]),newpath=DocPath(env,env[1]); | ||
| 44 | if(rename(oldpath.c_str(),newpath.c_str())<0) | ||
| 45 | THROW("htc: Could not rename "<<oldpath<<" to "<<newpath); | ||
| 46 | } | ||
| 47 | |||
| 48 | TOK_IMPL(filesafe) { | ||
| 49 | static const charset fsafe=cset_alphareal|'_'; | ||
| 50 | mstring file=env[0]; | ||
| 51 | int pos=file.rfind('/'); if(pos>=0) file=file.past(pos,1); | ||
| 52 | pos=file.rfind('\\'); if(pos>=0) file=file.past(pos,1); | ||
| 53 | while((pos=file.find(sdots))>=0) file.erase(pos,2); | ||
| 54 | mstring acc; | ||
| 55 | for(int i=0;i<file.size();i++) if(fsafe.test(file[i])) acc.append(1,file[i]); | ||
| 56 | out<<acc; | ||
| 57 | } | ||
| 58 | |||
| 59 | /////////////////////////////////////////////////////////////////// | ||
| 60 | |||
| 61 | TOK_IMPL(seturi) { | ||
| 62 | Req(env)->uri=env[0]; | ||
| 63 | } | ||
| 64 | |||
| 65 | TOK_IMPL(uri) { | ||
| 66 | out<<Req(env)->uri; | ||
| 67 | } | ||
| 68 | |||
| 69 | TOK_IMPL(pwd) { | ||
| 70 | out<<Req(env)->uri.left_last('/'); | ||
| 71 | } | ||
| 72 | |||
| 73 | TOK_IMPL(npwd) { | ||
| 74 | mstring s=Req(env)->uri.left_last('/'); | ||
| 75 | for(int i=0;i<MAXLANG;i++) { | ||
| 76 | if(s.past_first('/').left_first('/')==LANG[i]) { | ||
| 77 | s=s.past_first('/').right_first('/'); | ||
| 78 | break; | ||
| 79 | } | ||
| 80 | } | ||
| 81 | out<<s; | ||
| 82 | } | ||
| 83 | |||
| 84 | TOK_IMPL(home) { | ||
| 85 | if(Req(env)->htc()->docroot.nempty()) | ||
| 86 | THROW("htc: home only works in absolute file mode"); | ||
| 87 | out<<htchome(); | ||
| 88 | } | ||
| 89 | |||
| 90 | /////////////////////////////////////////////////////////////////// | ||
| 91 | |||
| 92 | TOK_IMPL(load) { | ||
| 93 | mstring name=env.parg(-1),uri=env.URI(env[0]),path=DocPath(env,uri); | ||
| 94 | if(name.nempty()) LoadBuffer(Reference(*env.toks,name,uri,1)->data,path); | ||
| 95 | else { mstring buffer; LoadBuffer(buffer,path); out<<buffer; } | ||
| 96 | } | ||
| 97 | |||
| 98 | TOK_IMPL(open) { | ||
| 99 | mstring name=env[0],uri=env.URI(env[1]),path=DocPath(env,uri); | ||
| 100 | dbref_t* ref=DBRef(*env.toks,env[0],ms_empty,tok_t::PRIVATE,1); | ||
| 101 | ref->db.Open(path,atoi(env.parg(-1))); | ||
| 102 | } | ||
| 103 | |||
| 104 | TOK_IMPL(save) { | ||
| 105 | mstring path=DocPath(env,env[0]),var=env[1]; | ||
| 106 | int prot=atoi(env.parg(2)); if(!prot) prot=0600; | ||
| 107 | tok_t* p=env.toks->get(var); | ||
| 108 | if(!p) THROW("htc: "<<var<<": no such variable"); | ||
| 109 | if(p->is_reference()) SaveBuffer(((reference_t*)p)->data,path,prot); | ||
| 110 | else if(p->is_dbref()) ((dbref_t*)p)->db.Saveas(path,prot); | ||
| 111 | else SaveBuffer(p->body,path,prot); | ||
| 112 | } | ||
| 113 | |||
| 114 | TOK_IMPL(dbmod) { | ||
| 115 | dbref_t* p=(dbref_t*)env.toks->get(env[0]); | ||
| 116 | if(!p&&!p->is_dbref()) THROW("htc: "<<env[0]<<": no such database"); | ||
| 117 | out<<p->db.Lastmod(); | ||
| 118 | } | ||
| 119 | |||
| 120 | /////////////////////////////////////////////////////////////////// | ||
| 121 | |||
| 122 | static void Run(mstream& out,Env& env,const mstring& path) throw(merror_t) { | ||
| 123 | mstring buffer; | ||
| 124 | LoadBuffer(buffer,path); | ||
| 125 | env.parse(out,buffer); | ||
| 126 | } | ||
| 127 | |||
| 128 | TOK_IMPL(include) { | ||
| 129 | mstring cwd=env.URI(env[0]),path=DocPath(env,cwd); | ||
| 130 | if(!env.glob_find(cwd)) { | ||
| 131 | env.toks->add(new tok_t(cwd,ms_empty,tok_t::CONSTANT|tok_t::PRIVATE),0,1); | ||
| 132 | mstream m; | ||
| 133 | Env e(env,env.mod,cwd); | ||
| 134 | Run(m,e,path); | ||
| 135 | } | ||
| 136 | } | ||
| 137 | |||
| 138 | TOK_IMPL(parse) { | ||
| 139 | mstring cwd=env.URI(env[0]),path=DocPath(env,cwd); | ||
| 140 | Env e(env,env.mod,cwd); | ||
| 141 | Run(out,e,path); | ||
| 142 | } | ||
| 143 | |||
| 144 | TOK_IMPL(parse_private) { | ||
| 145 | mstring cwd=env.URI(env[0]),path=DocPath(env,cwd); | ||
| 146 | Env e(env,XPRIVATE,cwd); | ||
| 147 | Run(out,e,path); | ||
| 148 | } | ||
| 149 | |||
| 150 | TOK_IMPL(parse_public) { | ||
| 151 | mstring cwd=env.URI(env[0]),path=DocPath(env,cwd); | ||
| 152 | Env e(env,XPUBLIC,cwd); | ||
| 153 | Run(out,e,path); | ||
| 154 | } | ||
| 155 | |||
| 156 | /////////////////////////////////////////////////////////////////// | ||
| 157 | |||
| 158 | TOK_IMPL(dirent) { | ||
| 159 | mstring uri=env.URI(env[0]); | ||
| 160 | sref uribase=uri.leftand_last('/'),ext=uri.adv(uribase); | ||
| 161 | mstring dirpath=DocPath(env,uribase); | ||
| 162 | DIR* dir=opendir(dirpath.c_str()); | ||
| 163 | if(dir) { | ||
| 164 | dirent* p; | ||
| 165 | while((p=readdir(dir))!=0) { | ||
| 166 | sref name(p->d_name); | ||
| 167 | if(name.empty()||name==sdot||name==sdots) continue; | ||
| 168 | if(ext.empty()||name.right(-ext.size()-1)==ext) out<<uribase<<name<<"\n"; | ||
| 169 | } | ||
| 170 | closedir(dir); | ||
| 171 | } | ||
| 172 | } | ||
| 173 | |||
| 174 | TOK_IMPL(dirmod) { | ||
| 175 | struct stat fs; | ||
| 176 | if(::stat(DocPath(env,env[0]).c_str(),&fs)>=0) out<<fs.st_mode; | ||
| 177 | else out<<(int)0; | ||
| 178 | } | ||
| 179 | |||
| 180 | TOK_IMPL(dirmtime) { struct stat fs; stat(fs,env,env[0]); out<<fs.st_mtime; } | ||
| 181 | TOK_IMPL(diruid) { struct stat fs; stat(fs,env,env[0]); out<<fs.st_uid; } | ||
| 182 | TOK_IMPL(dirgid) { struct stat fs; stat(fs,env,env[0]); out<<fs.st_gid; } | ||
| 183 | TOK_IMPL(filesize) { struct stat fs; stat(fs,env,env[0]); out<<fs.st_size; } | ||
| 184 | |||
| 185 | TOK_IMPL(setperm) { | ||
| 186 | mstring path=DocPath(env,env[0]); | ||
| 187 | if(chmod(path.c_str(),atoi(env[1]))<0) | ||
| 188 | THROW("htc: could not set file permission for "<<path); | ||
| 189 | } | ||
| 190 | |||
| 191 | /////////////////////////////////////////////////////////////////// | ||
| 192 | |||
| 193 | void envAddFile(tokmap& T) | ||
| 194 | { | ||
| 195 | TOK_ADD(remfile,"x",tok_t::SYSONLY, | ||
| 196 | "%Remove file\n" | ||
| 197 | "%Syntax: \\remfile{uri}\n" | ||
| 198 | ); | ||
| 199 | TOK_ADD(renfile,"xx",tok_t::SYSONLY, | ||
| 200 | "%Rename file\n" | ||
| 201 | "%Syntax: \\renfile{olduri}{newuri}\n" | ||
| 202 | ); | ||
| 203 | TOK_ADD(filesafe,"x",tok_t::PUBLIC, | ||
| 204 | "%Transform uri to something safe to save\n" | ||
| 205 | "%Syntax: \\filesafe{uri}\n" | ||
| 206 | "%\n" | ||
| 207 | "%Basically removes eventual path information and\n" | ||
| 208 | "%odd characters.\n" | ||
| 209 | ); | ||
| 210 | |||
| 211 | //////////////////////////////////////////////////////// | ||
| 212 | |||
| 213 | TOK_ADD(seturi,"x",tok_t::SYSONLY, | ||
| 214 | "%Set current uri of current request\n" | ||
| 215 | "%Syntax: \\seturi\n" | ||
| 216 | "%\n" | ||
| 217 | "%Always points to a (virtual) uri.\n" | ||
| 218 | ); | ||
| 219 | TOK_ADD(uri,"",tok_t::PUBLIC, | ||
| 220 | "%uri of current request\n" | ||
| 221 | "%Syntax: \\uri\n" | ||
| 222 | "%\n" | ||
| 223 | "%Always points to a (virtual) uri.\n" | ||
| 224 | ); | ||
| 225 | TOK_ADD(pwd,"",tok_t::PUBLIC, | ||
| 226 | "%uri/directory of current request\n" | ||
| 227 | "%Syntax: \\pwd\n" | ||
| 228 | "%\n" | ||
| 229 | "%Always points to a (virtual) directory, and never contain any\n" | ||
| 230 | "%trailing slashes.\n" | ||
| 231 | ); | ||
| 232 | TOK_ADD(npwd,"",tok_t::PUBLIC, | ||
| 233 | "%uri/directory of current request, without language reference\n" | ||
| 234 | "%Syntax: \\npwd\n" | ||
| 235 | "%\n" | ||
| 236 | "%Always points to a (virtual) directory, and never contain any\n" | ||
| 237 | "%trailing slashes.\n" | ||
| 238 | ); | ||
| 239 | TOK_ADD(home,"",tok_t::PRIVATE, | ||
| 240 | "%Home directory\n" | ||
| 241 | "%Syntax: \\home\n" | ||
| 242 | "%\n" | ||
| 243 | "%Only works in absolute path mode, i.e. when no docroot is set.\n" | ||
| 244 | ); | ||
| 245 | |||
| 246 | //////////////////////////////////////////////////////// | ||
| 247 | |||
| 248 | TOK_ADD(load,"?x",tok_t::PRIVATE, | ||
| 249 | "%Load file directly to output or to variable\n" | ||
| 250 | "%Syntax: \\load<varname>{uri}\n" | ||
| 251 | ); | ||
| 252 | TOK_ADD(open,"xx?",tok_t::SYSONLY, | ||
| 253 | "%Open database to variable\n" | ||
| 254 | "%Syntax: \\load{varname}{uri}<update>\n" | ||
| 255 | "%\n" | ||
| 256 | "%If update is true, the database is opened for reading\n" | ||
| 257 | "%and writing. NOTE that all updates are syncronous and\n" | ||
| 258 | "%instantly - saves or locks are not needed.\n" | ||
| 259 | ); | ||
| 260 | TOK_ADD(save,"xx?",tok_t::SYSONLY, | ||
| 261 | "%Save variable to file\n" | ||
| 262 | "%Syntax: \\save{uri}{varname}<prot>\n" | ||
| 263 | "%\n" | ||
| 264 | "%If the variable points to a reference object, the\n" | ||
| 265 | "%reference is saved. If it points to a database,\n" | ||
| 266 | "%the database is saved. For globals and functions,\n" | ||
| 267 | "%the body is saved.\n" | ||
| 268 | "%\n" | ||
| 269 | "%The optional prot argument is a (base 10) integer\n" | ||
| 270 | "%defining the creation mode mask (unix).\n" | ||
| 271 | ); | ||
| 272 | TOK_ADD(dbmod,"x",tok_t::PUBLIC, | ||
| 273 | "%Get modification time of open database\n" | ||
| 274 | "%Syntax: \\dbmod{var}\n" | ||
| 275 | ); | ||
| 276 | |||
| 277 | //////////////////////////////////////////////////////// | ||
| 278 | |||
| 279 | TOK_ADD(include,"x",tok_t::PRIVATE, | ||
| 280 | "%Include file in current running mode\n" | ||
| 281 | "%Syntax: \\include{uri}\n" | ||
| 282 | "%\n" | ||
| 283 | "%The file is loaded and evaluated, but produces no output\n" | ||
| 284 | "%Any uri can only be included once, so it is safe to use\n" | ||
| 285 | "%include as a precondition.\n" | ||
| 286 | "%\n" | ||
| 287 | "%NOTE that files parsed this way must be known to\n" | ||
| 288 | "%the super-user in order not to create a security hole -\n" | ||
| 289 | "%especially since this command is open in private mode also.\n" | ||
| 290 | ); | ||
| 291 | |||
| 292 | TOK_ADD(parse,"x",tok_t::SYSONLY, | ||
| 293 | "%Parse file in current running mode\n" | ||
| 294 | "%Syntax: \\parse{uri}\n" | ||
| 295 | "%\n" | ||
| 296 | "%The file is loaded and evaluated to output.\n" | ||
| 297 | "%\n" | ||
| 298 | "%NOTE that files parsed this way must be known to\n" | ||
| 299 | "%the super-user in order not to create a security hole.\n" | ||
| 300 | ); | ||
| 301 | |||
| 302 | TOK_ADD(parse_private,"x",tok_t::PRIVATE, | ||
| 303 | "%Parse file in private mode\n" | ||
| 304 | "%Syntax: \\parse.private{uri}\n" | ||
| 305 | "%\n" | ||
| 306 | "%The file is loaded and evaluated to output.\n" | ||
| 307 | "%\n" | ||
| 308 | "%System-mode commands are silently ignored.\n" | ||
| 309 | ); | ||
| 310 | |||
| 311 | TOK_ADD(parse_public,"x",tok_t::PRIVATE, | ||
| 312 | "%Parse file in public mode\n" | ||
| 313 | "%Syntax: \\parse.public{uri}\n" | ||
| 314 | "%\n" | ||
| 315 | "%The file is loaded and evaluated to output.\n" | ||
| 316 | "%\n" | ||
| 317 | "%System/Private mode commands are silently ignored.\n" | ||
| 318 | ); | ||
| 319 | |||
| 320 | //////////////////////////////////////////////////////// | ||
| 321 | |||
| 322 | TOK_ADD(dirent,"x",tok_t::SYSONLY, | ||
| 323 | "%Collect directory entries\n" | ||
| 324 | "%Syntax: \\dirent{uri/match}\n" | ||
| 325 | "%\n" | ||
| 326 | "%An argument of anydir/ collects all files in anydir.\n" | ||
| 327 | "%An argument of anydir/.ext collects all files ending with .ext\n" | ||
| 328 | "%\n" | ||
| 329 | "%Note that an argument of anydir collects files in the parent\n" | ||
| 330 | "%directory of anydir which end whith anydir, which probably is\n" | ||
| 331 | "%not what you want. Trailing slashes are important.\n" | ||
| 332 | ); | ||
| 333 | TOK_ADD(dirmod,"x",tok_t::SYSONLY, | ||
| 334 | "%Return file mode of uri\n" | ||
| 335 | "%Syntax: \\dirmod{uri}\n" | ||
| 336 | "%\n" | ||
| 337 | "%dirmod uses the unix stat function.\n" | ||
| 338 | "%On failure to read, returns zero.\n" | ||
| 339 | ); | ||
| 340 | TOK_ADD(dirmtime,"x",tok_t::SYSONLY, | ||
| 341 | "%Return modification time of uri\n" | ||
| 342 | "%Syntax: \\dirmtime{uri}\n" | ||
| 343 | ); | ||
| 344 | TOK_ADD(diruid,"x",tok_t::SYSONLY, | ||
| 345 | "%Return UNIX uid of uri\n" | ||
| 346 | "%Syntax: \\diruid{uri}\n" | ||
| 347 | "%\n" | ||
| 348 | "%Note that the UNIX uid is different from the HTC one.\n" | ||
| 349 | ); | ||
| 350 | TOK_ADD(dirgid,"x",tok_t::SYSONLY, | ||
| 351 | "%Return UNIX gid of uri\n" | ||
| 352 | "%Syntax: \\dirgid{uri}\n" | ||
| 353 | "%\n" | ||
| 354 | "%Note that the UNIX gid is different from the HTC one.\n" | ||
| 355 | ); | ||
| 356 | TOK_ADD(filesize,"x",tok_t::SYSONLY, | ||
| 357 | "%Return filesize of uri\n" | ||
| 358 | "%Syntax: \\filesize{uri}\n" | ||
| 359 | ); | ||
| 360 | TOK_ADD(setperm,"xx",tok_t::SYSONLY, | ||
| 361 | "%Set file permissions of uri\n" | ||
| 362 | "%Syntax: \\setperm{uri}{mode}\n" | ||
| 363 | "%\n" | ||
| 364 | "%Mode is an integer bitmask compliant with fcntl.\n" | ||
| 365 | ); | ||
| 366 | |||
| 367 | } | ||
diff --git a/src/sh/htc.cc b/src/sh/htc.cc new file mode 100644 index 0000000..9a87f2c --- /dev/null +++ b/src/sh/htc.cc | |||
| @@ -0,0 +1,92 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <sh/htc.h> | ||
| 21 | #include <hdb/buffer.h> | ||
| 22 | #include <mt/lock.h> | ||
| 23 | |||
| 24 | const mstring RCPATH=htchome()+sref("/htc/htc.rc"); | ||
| 25 | const mstring left="{",right="}"; | ||
| 26 | static fp_stream mout(stdout),merr(stderr); | ||
| 27 | |||
| 28 | static int unbalanced(const sref& in) | ||
| 29 | { | ||
| 30 | static const charset tag("{[("); | ||
| 31 | if(in.empty()) return 1; | ||
| 32 | sref s=in.right_first_of(tag); | ||
| 33 | while(s.nempty()) { | ||
| 34 | int p=-1; | ||
| 35 | switch(*s) { | ||
| 36 | case '{': p=s.skip(cset_braces); break; | ||
| 37 | case '[': p=s.skip(cset_indices); break; | ||
| 38 | case '(': p=s.skip(cset_para); break; | ||
| 39 | } | ||
| 40 | if(p<0) return 1; | ||
| 41 | s=s.adv(p).right_first_of(tag); | ||
| 42 | } | ||
| 43 | return 0; | ||
| 44 | } | ||
| 45 | |||
| 46 | main(int argc,char* argv[]) try | ||
| 47 | { | ||
| 48 | NODELOCK(USERMAP); | ||
| 49 | HTC htc(ms_empty); | ||
| 50 | htc_user user(htc.toks); | ||
| 51 | htc_req req(htc,user.toks); req.uri=Cwd(); | ||
| 52 | Env env(htc.ops,req,XSYSTEM); | ||
| 53 | if(argc>1) { | ||
| 54 | for(int i=2;i<argc;i++) env.xpush(left+sref(argv[i])+right); | ||
| 55 | mstring buffer; LoadBuffer(buffer,argv[1]); | ||
| 56 | if(*buffer=='#') buffer.erase(0,buffer.find('\n')+1); | ||
| 57 | env.eval(mout,buffer,1); | ||
| 58 | } | ||
| 59 | else { | ||
| 60 | mstring buffer,line; | ||
| 61 | if(buffer.load(RCPATH.c_str())>=0) { | ||
| 62 | Env e(env,user.toks,RCPATH); | ||
| 63 | mstream m; | ||
| 64 | e.parse(m,buffer); | ||
| 65 | } | ||
| 66 | while(!feof(stdin)) { | ||
| 67 | merr<<"htc>"; | ||
| 68 | buffer.clear(); | ||
| 69 | while(!feof(stdin)&&unbalanced(buffer)) { | ||
| 70 | getline(line,stdin); | ||
| 71 | buffer.append(line); | ||
| 72 | buffer+='\n'; | ||
| 73 | } | ||
| 74 | try { | ||
| 75 | env.parse(mout,buffer); | ||
| 76 | mout<<"\n"; | ||
| 77 | } | ||
| 78 | catch(const merror_t& e) { | ||
| 79 | merr<<e.desc<<"\n"; | ||
| 80 | } | ||
| 81 | } | ||
| 82 | } | ||
| 83 | return 0; | ||
| 84 | } | ||
| 85 | catch(const merror_t& e) { | ||
| 86 | merr<<"ERROR: ["<<e.desc<<"]\n"; | ||
| 87 | return -1; | ||
| 88 | } | ||
| 89 | catch(...) { | ||
| 90 | merr<<"ERROR: [FATAL]\n"; | ||
| 91 | return -1; | ||
| 92 | } | ||
diff --git a/src/sh/htc.h b/src/sh/htc.h new file mode 100644 index 0000000..b566176 --- /dev/null +++ b/src/sh/htc.h | |||
| @@ -0,0 +1,77 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef HTCH | ||
| 21 | #define HTCH | ||
| 22 | |||
| 23 | #include <sh/user.h> | ||
| 24 | #include <lang/env.h> | ||
| 25 | #include <mt/config.h> | ||
| 26 | |||
| 27 | /////////////////////////////////////////////////// | ||
| 28 | |||
| 29 | mstring Cwd(); | ||
| 30 | |||
| 31 | const mstring USERMAP=htchome()+sref("/htc/users.hdb"); | ||
| 32 | |||
| 33 | /////////////////////////////////////////////////// | ||
| 34 | |||
| 35 | struct HTC : public Lang { | ||
| 36 | fp_stream syslog; | ||
| 37 | mstring docroot,username; | ||
| 38 | mstring host,domain,mailer; | ||
| 39 | IPnode node; | ||
| 40 | int port; | ||
| 41 | |||
| 42 | HTC(const sref& root); | ||
| 43 | ~HTC(); | ||
| 44 | |||
| 45 | void setHost(const sref& s); | ||
| 46 | void setDomain(const sref& s); | ||
| 47 | void setPort(int p); | ||
| 48 | void setMailer(const sref& s); | ||
| 49 | }; | ||
| 50 | |||
| 51 | /////////////////////////////////////////////////// | ||
| 52 | |||
| 53 | struct htc_user { | ||
| 54 | tokmap toks; | ||
| 55 | |||
| 56 | htc_user(tokmap& p); | ||
| 57 | }; | ||
| 58 | |||
| 59 | /////////////////////////////////////////////////// | ||
| 60 | |||
| 61 | struct htc_req : public req_env { | ||
| 62 | mstring group; | ||
| 63 | user_t user; | ||
| 64 | |||
| 65 | HTC* htc() { return (HTC*)glob; } | ||
| 66 | |||
| 67 | htc_req(HTC& g,tokmap& p); | ||
| 68 | }; | ||
| 69 | |||
| 70 | inline htc_req* Req(Env& env) { return (htc_req*)env.req; } | ||
| 71 | inline const sref& DocRoot(Env& env) { return Req(env)->htc()->docroot; } | ||
| 72 | inline mstring DocPath(Env& env,const sref& uri) { return DocRoot(env)+env.URI(uri); } | ||
| 73 | |||
| 74 | /////////////////////////////////////////////////// | ||
| 75 | |||
| 76 | #endif | ||
| 77 | |||
diff --git a/src/sh/main.cc b/src/sh/main.cc new file mode 100644 index 0000000..4926b77 --- /dev/null +++ b/src/sh/main.cc | |||
| @@ -0,0 +1,129 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <sh/htc.h> | ||
| 21 | #include <pwd.h> | ||
| 22 | #include <sys/stat.h> | ||
| 23 | #include <sys/utsname.h> | ||
| 24 | |||
| 25 | const mstring PREFSMAP=htchome()+sref("/htc/prefs.hdb"); | ||
| 26 | const mstring SYSLOG=htchome()+sref("/log/htc.log"); | ||
| 27 | |||
| 28 | static fp_stream mout(stdout),merr(stderr); | ||
| 29 | |||
| 30 | /////////////////////////////////////////////////// | ||
| 31 | |||
| 32 | mstring Cwd() { | ||
| 33 | static char buf[1024]; | ||
| 34 | mstring cwd=getcwd(buf,1024); | ||
| 35 | cwd+='/'; | ||
| 36 | return cwd; | ||
| 37 | } | ||
| 38 | |||
| 39 | /////////////////////////////////////////////////// | ||
| 40 | |||
| 41 | static void OpenUSERS(dbmap& db) | ||
| 42 | { | ||
| 43 | db.Open(USERMAP,1); | ||
| 44 | if(db.Tables()==0) for(int i=0;i<user_tabs;i++) db.InsertTable(i,user_tab[i]); | ||
| 45 | } | ||
| 46 | |||
| 47 | static void OpenPREFS(dbmap& db) | ||
| 48 | { | ||
| 49 | db.Open(PREFSMAP,1); | ||
| 50 | if(db.Tables()==0) for(int i=0;i<prefs_tabs;i++) db.InsertTable(i,prefs_tab[i]); | ||
| 51 | } | ||
| 52 | |||
| 53 | htc_user::htc_user(tokmap& p) : toks(p) | ||
| 54 | { | ||
| 55 | OpenUSERS(DBRef(toks,USERS_tag,ms_empty,tok_t::SYSONLY)->db); | ||
| 56 | OpenPREFS(DBRef(toks,PREFS_tag,ms_empty,tok_t::SYSONLY)->db); | ||
| 57 | } | ||
| 58 | |||
| 59 | /////////////////////////////////////////////////// | ||
| 60 | |||
| 61 | htc_req::htc_req(HTC& g,tokmap& p) : req_env(g,p) | ||
| 62 | { | ||
| 63 | user.reset(); | ||
| 64 | } | ||
| 65 | |||
| 66 | /////////////////////////////////////////////////// | ||
| 67 | |||
| 68 | void envAddFile(tokmap& map); | ||
| 69 | void envAddConvert(tokmap& map); | ||
| 70 | void envAddDates(tokmap& map); | ||
| 71 | void envAddUser(tokmap& map) throw(merror_t); | ||
| 72 | void envAddTree(tokmap& map); | ||
| 73 | void envAddSys(tokmap& map); | ||
| 74 | void envAddNet(tokmap& map); | ||
| 75 | |||
| 76 | /////////////////////////////////////////////////// | ||
| 77 | |||
| 78 | HTC::HTC(const sref& root): | ||
| 79 | syslog(fopen(SYSLOG.c_str(),"a+")) | ||
| 80 | { | ||
| 81 | docroot=root; if(docroot.back()=='/') docroot=docroot.popb(); | ||
| 82 | username=getpwuid(getuid())->pw_name; | ||
| 83 | |||
| 84 | envAddFile(toks); | ||
| 85 | envAddConvert(toks); | ||
| 86 | envAddDates(toks); | ||
| 87 | envAddUser(toks); | ||
| 88 | envAddTree(toks); | ||
| 89 | envAddSys(toks); | ||
| 90 | envAddNet(toks); | ||
| 91 | } | ||
| 92 | |||
| 93 | /////////////////////////////////////////////////// | ||
| 94 | |||
| 95 | HTC::~HTC() | ||
| 96 | { | ||
| 97 | fclose(syslog.fp); | ||
| 98 | } | ||
| 99 | |||
| 100 | /////////////////////////////////////////////////// | ||
| 101 | |||
| 102 | void HTC::setHost(const sref& s) | ||
| 103 | { | ||
| 104 | host=s; | ||
| 105 | if(!Lookup(node,host)) THROW("sys: host "<<host<<" not listed in nameserver"); | ||
| 106 | } | ||
| 107 | |||
| 108 | /////////////////////////////////////////////////// | ||
| 109 | |||
| 110 | void HTC::setDomain(const sref& s) | ||
| 111 | { | ||
| 112 | domain=s; | ||
| 113 | } | ||
| 114 | |||
| 115 | /////////////////////////////////////////////////// | ||
| 116 | |||
| 117 | void HTC::setPort(int p) | ||
| 118 | { | ||
| 119 | port=p; | ||
| 120 | } | ||
| 121 | |||
| 122 | /////////////////////////////////////////////////// | ||
| 123 | |||
| 124 | void HTC::setMailer(const sref& s) | ||
| 125 | { | ||
| 126 | mailer=s; | ||
| 127 | } | ||
| 128 | |||
| 129 | /////////////////////////////////////////////////// | ||
diff --git a/src/sh/net.cc b/src/sh/net.cc new file mode 100644 index 0000000..dc03901 --- /dev/null +++ b/src/sh/net.cc | |||
| @@ -0,0 +1,122 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <sh/htc.h> | ||
| 21 | |||
| 22 | ///////////////////////////////////////////////////////////////// | ||
| 23 | |||
| 24 | TOK_IMPL(sethost) | ||
| 25 | { | ||
| 26 | Req(env)->htc()->setHost(env[0]); | ||
| 27 | } | ||
| 28 | TOK_IMPL(setdomain) | ||
| 29 | { | ||
| 30 | Req(env)->htc()->setDomain(env[0]); | ||
| 31 | } | ||
| 32 | TOK_IMPL(setport) | ||
| 33 | { | ||
| 34 | Req(env)->htc()->setPort(atoi(env[0])); | ||
| 35 | } | ||
| 36 | TOK_IMPL(setmailer) | ||
| 37 | { | ||
| 38 | Req(env)->htc()->setMailer(env[0]); | ||
| 39 | } | ||
| 40 | |||
| 41 | ///////////////////////////////////////////////////////////////// | ||
| 42 | |||
| 43 | TOK_IMPL(HOST) { | ||
| 44 | out<<Req(env)->htc()->host; | ||
| 45 | } | ||
| 46 | |||
| 47 | TOK_IMPL(HOSTIP) { | ||
| 48 | out<<Req(env)->htc()->node.ip; | ||
| 49 | } | ||
| 50 | |||
| 51 | TOK_IMPL(DOMAIN) { | ||
| 52 | out<<Req(env)->htc()->domain; | ||
| 53 | } | ||
| 54 | |||
| 55 | TOK_IMPL(ROOT) { | ||
| 56 | out<<Req(env)->htc()->username; | ||
| 57 | if(Req(env)->htc()->domain.size()) out<<"@"<<Req(env)->htc()->domain; | ||
| 58 | } | ||
| 59 | |||
| 60 | TOK_IMPL(ADMIN) { | ||
| 61 | out<<Req(env)->htc()->username; | ||
| 62 | if(Req(env)->htc()->domain.size()) out<<"@"<<Req(env)->htc()->domain; | ||
| 63 | } | ||
| 64 | |||
| 65 | TOK_IMPL(port) | ||
| 66 | { | ||
| 67 | out<<Req(env)->htc()->port; | ||
| 68 | } | ||
| 69 | |||
| 70 | ///////////////////////////////////////////////////////////// | ||
| 71 | |||
| 72 | void envAddNet(tokmap& T) | ||
| 73 | { | ||
| 74 | TOK_ADD(sethost,"x",tok_t::SYSONLY, | ||
| 75 | "%Set host name\n" | ||
| 76 | "%Syntax: \\sethost{host}\n" | ||
| 77 | ); | ||
| 78 | TOK_ADD(setdomain,"x",tok_t::SYSONLY, | ||
| 79 | "%Set default domain\n" | ||
| 80 | "%Syntax: \\setdomain{domain}\n" | ||
| 81 | ); | ||
| 82 | TOK_ADD(setport,"x",tok_t::SYSONLY, | ||
| 83 | "%Set host port number\n" | ||
| 84 | "%Syntax: \\setport{port}\n" | ||
| 85 | ); | ||
| 86 | TOK_ADD(setmailer,"x",tok_t::SYSONLY, | ||
| 87 | "%Set mail program path\n" | ||
| 88 | "%Syntax: \\setmailer{path}\n" | ||
| 89 | ); | ||
| 90 | |||
| 91 | ///////////////////////////////////////////////////////////// | ||
| 92 | |||
| 93 | TOK_ADD(HOST,"",tok_t::PUBLIC, | ||
| 94 | "%Host name\n" | ||
| 95 | "%Syntax: \\HOST\n" | ||
| 96 | ); | ||
| 97 | |||
| 98 | TOK_ADD(HOSTIP,"",tok_t::PUBLIC, | ||
| 99 | "%Host IP address\n" | ||
| 100 | "%Syntax: \\HOSTIP\n" | ||
| 101 | ); | ||
| 102 | |||
| 103 | TOK_ADD(DOMAIN,"",tok_t::PUBLIC, | ||
| 104 | "%Default domain\n" | ||
| 105 | "%Syntax: \\DOMAIN\n" | ||
| 106 | ); | ||
| 107 | |||
| 108 | TOK_ADD(ROOT,"",tok_t::PUBLIC, | ||
| 109 | "%htcroot email address\n" | ||
| 110 | "%Syntax: \\ROOT\n" | ||
| 111 | ); | ||
| 112 | |||
| 113 | TOK_ADD(ADMIN,"",tok_t::PUBLIC, | ||
| 114 | "%admin email address\n" | ||
| 115 | "%Syntax: \\ADMIN\n" | ||
| 116 | ); | ||
| 117 | |||
| 118 | TOK_ADD(port,"",tok_t::PUBLIC, | ||
| 119 | "%Host port number\n" | ||
| 120 | "%Syntax: \\port\n" | ||
| 121 | ); | ||
| 122 | } | ||
diff --git a/src/sh/string.cc b/src/sh/string.cc new file mode 100644 index 0000000..8075a5b --- /dev/null +++ b/src/sh/string.cc | |||
| @@ -0,0 +1,32 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <htc.h> | ||
| 21 | #include <mset.h> | ||
| 22 | |||
| 23 | static mstring empty; | ||
| 24 | |||
| 25 | TOK_IMPL(tolower) {mstring s=env[0];s.tolower();out<<s;} | ||
| 26 | TOK_IMPL(toupper) {mstring s=env[0];s.toupper();out<<s;} | ||
| 27 | |||
| 28 | void envAddString(tokmap& T) | ||
| 29 | { | ||
| 30 | TOK_ADD(tolower,1,0,tok_t::PUBLIC,"%(s)"); | ||
| 31 | TOK_ADD(toupper,1,0,tok_t::PUBLIC,"%(s)"); | ||
| 32 | } | ||
diff --git a/src/sh/sys.cc b/src/sh/sys.cc new file mode 100644 index 0000000..b70991b --- /dev/null +++ b/src/sh/sys.cc | |||
| @@ -0,0 +1,152 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <sh/htc.h> | ||
| 21 | #include <mime/mime.h> | ||
| 22 | #include <mt/lookup.h> | ||
| 23 | #include <mt/issue.h> | ||
| 24 | #include <mt/dates.h> | ||
| 25 | #include <unistd.h> | ||
| 26 | |||
| 27 | //////////////////////////////////////////// | ||
| 28 | |||
| 29 | TOK_IMPL(sleep) { sleep(atoi(env[0])); } | ||
| 30 | TOK_IMPL(throw) { THROW(env[0]); } | ||
| 31 | |||
| 32 | //////////////////////////////////////////// | ||
| 33 | |||
| 34 | TOK_IMPL(sync) { dbmap::Sync(); } | ||
| 35 | |||
| 36 | //////////////////////////////////////////// | ||
| 37 | |||
| 38 | TOK_IMPL(gethost) { | ||
| 39 | IPnode node; if(Lookup(node,env[0])) out<<node.name; else out<<"UNKNOWN"; | ||
| 40 | } | ||
| 41 | |||
| 42 | //////////////////////////////////////////// | ||
| 43 | |||
| 44 | TOK_IMPL(mail) { | ||
| 45 | mswrite ms; | ||
| 46 | if(env[0].size()<2) return; | ||
| 47 | ms<<"From: "; encodeHeader(ms,mime_default,env[3]); ms<<" <"<<env[0]<<">\n"; | ||
| 48 | |||
| 49 | //if(env[1].nempty()) ms<<"Reply-To: "<<env[1]<<"\n"; | ||
| 50 | //!! neat simple hack - never used except as should be | ||
| 51 | if(env[1].nempty()) ms<<"To: "<<env[1]<<"\n"; | ||
| 52 | |||
| 53 | ms<<"Date: "<<httpTime(atoi(env[4]))<<"\n"; | ||
| 54 | ms<<"Subject: "; encodeHeader(ms,mime_default,env[5]); ms<<"\n"; | ||
| 55 | ms<<"MIME-Version: 1.0\n"; | ||
| 56 | ms<<"Content-Transfer-Encoding: Quoted-Printable\n"; | ||
| 57 | ms<<"Content-Type: "<<env[6]<<"\n"; | ||
| 58 | mswrite body; encodeQP(body,env[7]); | ||
| 59 | ms<<"Content-Length: "<<body.str().size()<<"\n"; | ||
| 60 | ms<<"\n"; | ||
| 61 | ms<<body.str(); | ||
| 62 | HTC* htc=Req(env)->htc(); | ||
| 63 | if(htc->mailer.size()) { | ||
| 64 | issue_t cmd(htc->mailer+sref(" ")+env[2]); | ||
| 65 | mstream m; | ||
| 66 | cmd.run(m,ms.str()); | ||
| 67 | htc->syslog<<"["<<time(0)<<"][mail]["<<env[2]<<"]\n"; | ||
| 68 | } | ||
| 69 | else { | ||
| 70 | htc->syslog<<"["<<time(0)<<"][NOT SET]["<<env[2]<<"]\n"; | ||
| 71 | htc->syslog<<"-----------------------------------------\n"; | ||
| 72 | htc->syslog<<ms.str()<<"\n"; | ||
| 73 | htc->syslog<<"=========================================\n"; | ||
| 74 | } | ||
| 75 | htc->syslog.flush(); | ||
| 76 | } | ||
| 77 | |||
| 78 | //////////////////////////////////////////// | ||
| 79 | |||
| 80 | TOK_IMPL(issue) { | ||
| 81 | HTC* htc=Req(env)->htc(); | ||
| 82 | htc->syslog<<"["<<time(0)<<"][issue]["<<env[0]<<"]\n"; | ||
| 83 | htc->syslog.flush(); | ||
| 84 | issue_t cmd(DocPath(env,env[0])); | ||
| 85 | cmd.run(out,env[1]); | ||
| 86 | htc->syslog<<"["<<time(0)<<"][finish]["<<env[0]<<"]\n"; | ||
| 87 | htc->syslog.flush(); | ||
| 88 | } | ||
| 89 | |||
| 90 | ////////////////////////////////////////////////////////// | ||
| 91 | |||
| 92 | void envAddSys(tokmap& T) | ||
| 93 | { | ||
| 94 | TOK_ADD(sleep,"x",tok_t::SYSONLY, | ||
| 95 | "%Sleep for seconds\n" | ||
| 96 | "%Syntax: \\sleep{t}\n" | ||
| 97 | "%\n" | ||
| 98 | "%This one works just like the UNIX command\n" | ||
| 99 | ); | ||
| 100 | TOK_ADD(throw,"x",tok_t::SYSONLY, | ||
| 101 | "%Throw an exception\n" | ||
| 102 | "%Syntax: \\throw{text}\n" | ||
| 103 | "%\n" | ||
| 104 | "%Throw a, for the HTC system, standard error\n" | ||
| 105 | "%expection, which also many of the built-in\n" | ||
| 106 | "%do. Enables well-behaved error handling.\n" | ||
| 107 | ); | ||
| 108 | |||
| 109 | ///////////////////////////////////////////////////////////// | ||
| 110 | |||
| 111 | TOK_ADD(sync,"",tok_t::SYSONLY, | ||
| 112 | "%Syncronize all open writable databases\n" | ||
| 113 | "%Syntax: \\sync\n" | ||
| 114 | "%\n" | ||
| 115 | "%Use in crontab only.\n" | ||
| 116 | ); | ||
| 117 | |||
| 118 | ///////////////////////////////////////////////////////////// | ||
| 119 | |||
| 120 | TOK_ADD(gethost,"x",tok_t::SYSONLY, | ||
| 121 | "%Lookup hostname on nameserver\n" | ||
| 122 | "%Syntax: \\gethost{IP address}\n" | ||
| 123 | "%\n" | ||
| 124 | "%Normally performed automatically by the server.\n" | ||
| 125 | ); | ||
| 126 | |||
| 127 | ///////////////////////////////////////////////////////////// | ||
| 128 | |||
| 129 | TOK_ADD(mail,"xxxxxxxx",tok_t::SYSONLY, | ||
| 130 | "%System mail\n" | ||
| 131 | "%Syntax: \\mail{from}{replyto}{to}{fromname}{date}{subject}{mime}{body}\n" | ||
| 132 | "%\n" | ||
| 133 | "%This mail command can do almost anything, so be careful!\n" | ||
| 134 | "%Usually there are several htc commands simplifying the use\n" | ||
| 135 | "%of this one.\n" | ||
| 136 | ); | ||
| 137 | |||
| 138 | ///////////////////////////////////////////////////////////// | ||
| 139 | |||
| 140 | TOK_ADD(issue,"xx",tok_t::SYSONLY, | ||
| 141 | "%Issue piped command\n" | ||
| 142 | "%Syntax: \\issue{uri}{stdin}\n" | ||
| 143 | "%\n" | ||
| 144 | "%Pipes stdin to cmd and output stdout.\n" | ||
| 145 | "%An extremely powerful command that may be used\n" | ||
| 146 | "%to run external programs via the web.\n" | ||
| 147 | "%\n" | ||
| 148 | "%Note that the normal uri handling is performed.\n" | ||
| 149 | ); | ||
| 150 | |||
| 151 | ///////////////////////////////////////////////////////////// | ||
| 152 | } | ||
diff --git a/src/sh/tree.cc b/src/sh/tree.cc new file mode 100644 index 0000000..0ec8f16 --- /dev/null +++ b/src/sh/tree.cc | |||
| @@ -0,0 +1,304 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <sh/htc.h> | ||
| 21 | #include <sh/user.h> | ||
| 22 | #include <hdb/buffer.h> | ||
| 23 | #include <http/http.h> | ||
| 24 | #include <mt/dates.h> | ||
| 25 | #include <sys/stat.h> | ||
| 26 | |||
| 27 | const mstring index_tag="index.htc"; | ||
| 28 | const mstring sindex_tag="/index.htc"; | ||
| 29 | const mstring htc_mime="text/x-htc"; | ||
| 30 | const mstring htx_mime="text/x-htx"; | ||
| 31 | const mstring html_mime="text/html"; | ||
| 32 | |||
| 33 | const mstring uri_tag="stat.URI"; | ||
| 34 | const mstring refer_tag="stat.REFER"; | ||
| 35 | const mstring parent_tag="stat.PARENT"; | ||
| 36 | const mstring mime_tag="stat.MIME"; | ||
| 37 | |||
| 38 | const mstring mod_tag="stat.MOD"; | ||
| 39 | const mstring mtime_tag="stat.LASTMOD"; | ||
| 40 | const mstring uid_tag="stat.UID"; | ||
| 41 | const mstring gid_tag="stat.GID"; | ||
| 42 | const mstring size_tag="stat.SIZE"; | ||
| 43 | |||
| 44 | const mstring alias_tag="stat.ALIAS"; | ||
| 45 | const mstring banner_tag="stat.BANNER"; | ||
| 46 | |||
| 47 | const mstring xclear_tag="stat.X.CLEAR"; | ||
| 48 | const mstring xcookie_tag="stat.X.COOKIE"; | ||
| 49 | const mstring domain_tag="stat.X.DOMAIN"; | ||
| 50 | const mstring user_tag="stat.X.USER"; | ||
| 51 | const mstring xcache_tag="stat.X.CACHE"; | ||
| 52 | |||
| 53 | const mstring xmod_tag="stat.XMOD"; | ||
| 54 | |||
| 55 | ///////////////////////////////////////////////////////////////// | ||
| 56 | |||
| 57 | TOK_IMPL(alias) { | ||
| 58 | mstring acc; | ||
| 59 | Env nenv(env,XSYSTEM,env.pwd); | ||
| 60 | acc=env.arg(0)->expr; | ||
| 61 | nenv.sloc(alias_tag,acc); | ||
| 62 | } | ||
| 63 | |||
| 64 | TOK_IMPL(banner) { | ||
| 65 | mstring acc1; | ||
| 66 | Env nenv(env,XSYSTEM,env.pwd); | ||
| 67 | swrite sw(acc1); | ||
| 68 | nenv.parse(sw,env.arg(0)); | ||
| 69 | acc1+=' '; acc1+=env.arg(1)->expr; | ||
| 70 | nenv.sloc(banner_tag,acc1); | ||
| 71 | } | ||
| 72 | |||
| 73 | ///////////////////////////////////////////////////////////////// | ||
| 74 | |||
| 75 | TOK_IMPL(clearance) { | ||
| 76 | mstring acc; | ||
| 77 | Env nenv(env,XSYSTEM,env.pwd); | ||
| 78 | swrite sw(acc); | ||
| 79 | nenv.parse(sw,env.arg(0)); | ||
| 80 | sref first,rest=acc; | ||
| 81 | while(Split(first,rest)) | ||
| 82 | if(first==root_tag) THROW("user: ROOT group not allowed in clearance"); | ||
| 83 | nenv.sloc(xclear_tag,acc); | ||
| 84 | } | ||
| 85 | |||
| 86 | TOK_IMPL(clearance_cookie) { | ||
| 87 | mstring acc1,acc2; | ||
| 88 | Env nenv(env,XSYSTEM,env.pwd); | ||
| 89 | swrite sw1(acc1); | ||
| 90 | nenv.parse(sw1,env.arg(0)); | ||
| 91 | swrite sw2(acc2); | ||
| 92 | nenv.parse(sw2,env.arg(1)); | ||
| 93 | acc1+=' '; acc1+=acc2; | ||
| 94 | nenv.sloc(xcookie_tag,acc1); | ||
| 95 | } | ||
| 96 | |||
| 97 | TOK_IMPL(clearance_domain) { | ||
| 98 | mstring acc; | ||
| 99 | Env nenv(env,XSYSTEM,env.pwd); | ||
| 100 | swrite sw(acc); | ||
| 101 | nenv.parse(sw,env.arg(0)); | ||
| 102 | nenv.sloc(domain_tag,acc); | ||
| 103 | } | ||
| 104 | |||
| 105 | TOK_IMPL(clearance_user) { | ||
| 106 | mstring acc; | ||
| 107 | Env nenv(env,XSYSTEM,env.pwd); | ||
| 108 | swrite sw(acc); | ||
| 109 | nenv.parse(sw,env.arg(0)); | ||
| 110 | nenv.sloc(user_tag,acc); | ||
| 111 | } | ||
| 112 | |||
| 113 | TOK_IMPL(cache) { | ||
| 114 | mstring acc; | ||
| 115 | Env nenv(env,XSYSTEM,env.pwd); | ||
| 116 | swrite sw(acc); | ||
| 117 | nenv.parse(sw,env.arg(0)); | ||
| 118 | nenv.sloc(xcache_tag,acc); | ||
| 119 | } | ||
| 120 | |||
| 121 | ///////////////////////////////////////////////////////////////// | ||
| 122 | |||
| 123 | inline int reachable(const sref& uri) | ||
| 124 | { | ||
| 125 | static const mstring sys_tag="/sys/"; | ||
| 126 | static const mstring bin_tag="/bin/"; | ||
| 127 | static const mstring htc_tag="/htc/"; | ||
| 128 | static const mstring sccs_tag="/SCCS/"; | ||
| 129 | static const mstring cvs_tag="/CVS/"; | ||
| 130 | if(uri.right_last(sindex_tag)==sindex_tag) return 0; | ||
| 131 | if(uri.find(sys_tag)>=0) return 0; | ||
| 132 | if(uri.find(bin_tag)>=0) return 0; | ||
| 133 | if(uri.find(htc_tag)>=0) return 0; | ||
| 134 | if(uri.find(sccs_tag)>=0) return 0; | ||
| 135 | if(uri.find(cvs_tag)>=0) return 0; | ||
| 136 | return 1; | ||
| 137 | } | ||
| 138 | |||
| 139 | TOK_IMPL(staturi) { | ||
| 140 | struct stat fs; int ok=0; | ||
| 141 | mstring parent,refer,uri=env.URI(env[0]); | ||
| 142 | if(reachable(uri)) { | ||
| 143 | refer=uri; parent=refer.leftand_last('/'); | ||
| 144 | if(refer.back()=='/') { refer+=index_tag; parent=parent.popb().leftand_last('/'); } | ||
| 145 | int s=stat(DocPath(env,refer).c_str(),&fs); | ||
| 146 | if(s>=0) { | ||
| 147 | if(fs.st_mode&24576) { | ||
| 148 | uri+='/'; refer=uri+index_tag; | ||
| 149 | s=stat(DocPath(env,refer).c_str(),&fs); | ||
| 150 | } | ||
| 151 | if(s>=0) { | ||
| 152 | const sref* pmime=file2mime(refer); | ||
| 153 | mstring mime=pmime?*pmime:http_mime_default; | ||
| 154 | mstring index=refer.leftand_last('/')+index_tag; | ||
| 155 | |||
| 156 | Env nenv(env); | ||
| 157 | nenv.aloc(uri_tag,uri); | ||
| 158 | nenv.aloc(refer_tag,refer); | ||
| 159 | nenv.aloc(parent_tag,parent); | ||
| 160 | nenv.aloc(mime_tag,mime); | ||
| 161 | |||
| 162 | nenv.aloc(mod_tag,itoa(fs.st_mode)); | ||
| 163 | nenv.aloc(uid_tag,itoa(fs.st_uid)); | ||
| 164 | nenv.aloc(gid_tag,itoa(fs.st_gid)); | ||
| 165 | nenv.aloc(size_tag,itoa(fs.st_size)); | ||
| 166 | nenv.aloc(mtime_tag,itoa(fs.st_mtime)); | ||
| 167 | |||
| 168 | nenv.aloc(alias_tag,ms_empty); | ||
| 169 | nenv.aloc(banner_tag,ms_empty); | ||
| 170 | |||
| 171 | nenv.aloc(xclear_tag,root_tag); | ||
| 172 | nenv.aloc(xcookie_tag,ms_empty); | ||
| 173 | nenv.aloc(domain_tag,ms_empty); | ||
| 174 | nenv.aloc(user_tag,ms_empty); | ||
| 175 | nenv.aloc(xcache_tag,ms_empty); | ||
| 176 | |||
| 177 | nenv.aloc(xmod_tag,itoa(time(0))); | ||
| 178 | |||
| 179 | mstring buffer; | ||
| 180 | if(mime==htc_mime||mime==htx_mime||mime==html_mime) { | ||
| 181 | LoadBuffer(buffer,DocPath(nenv,refer)); | ||
| 182 | try { | ||
| 183 | Env e(nenv,XINIT,refer); | ||
| 184 | mstream m; | ||
| 185 | e.parse(m,buffer); | ||
| 186 | } | ||
| 187 | catch(const merror_t& e) { | ||
| 188 | THROW(refer<<": "<<e.desc); | ||
| 189 | } | ||
| 190 | } | ||
| 191 | if(mime!=htc_mime&&nenv.gloc(xclear_tag)==root_tag) { | ||
| 192 | if(buffer.load(DocPath(nenv,index).c_str())>=0) { | ||
| 193 | try { | ||
| 194 | Env e(nenv,XINIT,index); | ||
| 195 | mstream m; | ||
| 196 | e.parse(m,buffer); | ||
| 197 | nenv.sloc(alias_tag,ms_empty); | ||
| 198 | nenv.sloc(banner_tag,ms_empty); | ||
| 199 | } | ||
| 200 | catch(const merror_t& e) { | ||
| 201 | THROW(index<<": "<<e.desc); | ||
| 202 | } | ||
| 203 | } | ||
| 204 | } | ||
| 205 | nenv.parse(out,env.arg(1)); | ||
| 206 | ok=1; | ||
| 207 | } | ||
| 208 | } | ||
| 209 | } | ||
| 210 | if(!ok) env.parg(out,2); | ||
| 211 | } | ||
| 212 | |||
| 213 | ///////////////////////////////////////////////////////////////// | ||
| 214 | |||
| 215 | void envAddTree(tokmap& T) | ||
| 216 | { | ||
| 217 | TOK_ADD(alias,"r",tok_t::INIT, | ||
| 218 | "%Set alias used in sitemap\n" | ||
| 219 | "%Syntax: \\alias{name}\n" | ||
| 220 | "%\n" | ||
| 221 | "%If set, the URI appears in the automatic tree system.\n" | ||
| 222 | ); | ||
| 223 | |||
| 224 | TOK_ADD(banner,"rr",tok_t::INIT, | ||
| 225 | "%Set banner used in layout\n" | ||
| 226 | "%Syntax: \\banner{height}{body}\n" | ||
| 227 | "%\n" | ||
| 228 | "%If set in index file, all URI descendants will use it.\n" | ||
| 229 | ); | ||
| 230 | |||
| 231 | /////////////////////////////////////////////////////// | ||
| 232 | |||
| 233 | TOK_ADD(clearance,"r",tok_t::INIT, | ||
| 234 | "%Set clearance\n" | ||
| 235 | "%Syntax: \\clearance{group list}\n" | ||
| 236 | "%\n" | ||
| 237 | "%A user must have clearance to all groups in order\n" | ||
| 238 | "%to get access.\n" | ||
| 239 | ); | ||
| 240 | TOK_ADD(clearance_domain,"r",tok_t::INIT, | ||
| 241 | "%Restrict clearance to domain\n" | ||
| 242 | "%Syntax: \\clearance.domain{domain list}\n" | ||
| 243 | "%\n" | ||
| 244 | "%A user must have clearance to at least one domain\n" | ||
| 245 | "%in order to get access.\n" | ||
| 246 | ); | ||
| 247 | TOK_ADD(clearance_cookie,"rr",tok_t::INIT, | ||
| 248 | "%Restrict by cookie\n" | ||
| 249 | "%Syntax: \\clearance.cookie{name}{value}\n" | ||
| 250 | "%\n" | ||
| 251 | "%A user must have the cookie set to get access.\n" | ||
| 252 | ); | ||
| 253 | TOK_ADD(clearance_user,"r",tok_t::INIT, | ||
| 254 | "%Restrict by user\n" | ||
| 255 | "%Syntax: \\clearance.user{user list}\n" | ||
| 256 | "%\n" | ||
| 257 | "%A user must appear in the list in order to get access.\n" | ||
| 258 | ); | ||
| 259 | |||
| 260 | /////////////////////////////////////////////////////// | ||
| 261 | |||
| 262 | TOK_ADD(cache,"r",tok_t::INIT, | ||
| 263 | "%Set cache time in seconds\n" | ||
| 264 | "%Syntax: \\cache{t}\n" | ||
| 265 | "%\n" | ||
| 266 | "%If set, normal output is cached for the given time.\n" | ||
| 267 | "%\n" | ||
| 268 | "%There are a number of advantages of caching, the most\n" | ||
| 269 | "%pronounced being server load. Appropriate cache time\n" | ||
| 270 | "%is crucial to get a smooth server.\n" | ||
| 271 | ); | ||
| 272 | |||
| 273 | /////////////////////////////////////////////////////// | ||
| 274 | |||
| 275 | TOK_ADD(staturi,"xr?",tok_t::SYSONLY, | ||
| 276 | "%Retrieve STAT and INIT information for URI\n" | ||
| 277 | "%Syntax: \\staturi{uri}{body}<else>\n" | ||
| 278 | "%\n" | ||
| 279 | "%Do body if a reference to uri is found.\n" | ||
| 280 | "%In the body environment, the record stat. is set\n" | ||
| 281 | "%with the following variables:\n" | ||
| 282 | "%\n" | ||
| 283 | "%URI the canonized URI\n" | ||
| 284 | "%REFER the file uri it refers to\n" | ||
| 285 | "%PARENT the parent uri\n" | ||
| 286 | "%MOD the file mode bits (unix)\n" | ||
| 287 | "%UID the file uid (unix)\n" | ||
| 288 | "%GID the file gid (unix)\n" | ||
| 289 | "%SIZE the file size (unix)\n" | ||
| 290 | "%LASTMOD the file modification time (unix)\n" | ||
| 291 | "%MIME the MIME type\n" | ||
| 292 | "%ALIAS alias used in tree\n" | ||
| 293 | "%X.CLEAR clerarance\n" | ||
| 294 | "%X.COOKIE cookie clearance\n" | ||
| 295 | "%X.DOMAIN domain clearance\n" | ||
| 296 | "%X.USER user clearance\n" | ||
| 297 | "%X.CACHE cache time in seconds\n" | ||
| 298 | "%\n" | ||
| 299 | "%The X. variables are inherited from index.htc\n" | ||
| 300 | "%if X.CLEAR remains equal to ROOT after init.\n" | ||
| 301 | "%\n" | ||
| 302 | "%Unreachable directories: /sys/, /bin/, /htc/, /SCCS/ and /CVS/.\n" | ||
| 303 | ); | ||
| 304 | } | ||
diff --git a/src/sh/user.cc b/src/sh/user.cc new file mode 100644 index 0000000..94285ef --- /dev/null +++ b/src/sh/user.cc | |||
| @@ -0,0 +1,445 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #include <sh/htc.h> | ||
| 21 | |||
| 22 | int allow(const sref& s,const sref& grp,time_t now,int rootok) | ||
| 23 | { | ||
| 24 | if(grp.empty()) return 1; | ||
| 25 | int n=s.find(':'); | ||
| 26 | sref a=s.left(n); | ||
| 27 | if(rootok>=0&&a==root_tag) return rootok; | ||
| 28 | else if(grp==root_tag||a!=grp) return 0; | ||
| 29 | n=(a=s.past(n,1)).find(':'); sref b=a.past(n,1); a=a.left(n); | ||
| 30 | return (a.empty()||atoi(a)<=now)&&(b.empty()||now<atoi(b)); | ||
| 31 | } | ||
| 32 | |||
| 33 | //////////////////////////////////////////////////////////////////////// | ||
| 34 | |||
| 35 | user_t::user_t(const user_t& us) : list(user_tabs) | ||
| 36 | { | ||
| 37 | for(int i=0;i<user_tabs;i++) list[i]=us.list[i]; | ||
| 38 | } | ||
| 39 | |||
| 40 | void user_t::operator=(const user_t& us) | ||
| 41 | { | ||
| 42 | list.resize(user_tabs); | ||
| 43 | for(int i=0;i<user_tabs;i++) list[i]=us.list[i]; | ||
| 44 | } | ||
| 45 | |||
| 46 | void user_t::reset() | ||
| 47 | { | ||
| 48 | list.resize(user_tabs); | ||
| 49 | uid()=itoa(0); | ||
| 50 | group()=itoa(0); | ||
| 51 | fail()=itoa(0); | ||
| 52 | pin().clear(); | ||
| 53 | alias().clear(); | ||
| 54 | email().clear(); | ||
| 55 | name().clear(); | ||
| 56 | last()=itoa(0); | ||
| 57 | lastin()=lastin_def; | ||
| 58 | access().clear(); | ||
| 59 | } | ||
| 60 | |||
| 61 | int user_t::allow(const sref& grp,time_t now,int rootok) | ||
| 62 | { | ||
| 63 | sref first,rest=access(); | ||
| 64 | while(Split(first,rest)) if(::allow(first,grp,now,rootok)) return 1; | ||
| 65 | return 0; | ||
| 66 | } | ||
| 67 | |||
| 68 | int user_t::allow_list(const sref& grps,time_t now,int rootok) | ||
| 69 | { | ||
| 70 | sref first,rest=grps; | ||
| 71 | while(Split(first,rest)) if(!allow(first,now,rootok)) return 0; | ||
| 72 | return 1; | ||
| 73 | } | ||
| 74 | |||
| 75 | void user_t::add(const sref& grp) | ||
| 76 | { | ||
| 77 | sref first,rest=access(); | ||
| 78 | while(Split(first,rest)) if(first.left_first(':')==grp.left_first(':')) return; | ||
| 79 | mstring clear=grp; | ||
| 80 | if(clear.find(':')<0) { clear+=':'; clear+=itoa(time(0)); } | ||
| 81 | if(access().nempty()) access()+=' '; access()+=clear; | ||
| 82 | } | ||
| 83 | |||
| 84 | void user_t::add_list(const sref& grps) { | ||
| 85 | sref first,rest=grps; | ||
| 86 | while(Split(first,rest)) add(first); | ||
| 87 | } | ||
| 88 | |||
| 89 | void user_t::rem(const sref& grp) | ||
| 90 | { | ||
| 91 | mstring m; | ||
| 92 | sref first,rest=access(); | ||
| 93 | while(Split(first,rest)) | ||
| 94 | if(first.left_first(':')!=grp) { if(m.nempty()) m+=' '; m+=first; } | ||
| 95 | access()=m; | ||
| 96 | } | ||
| 97 | |||
| 98 | void user_t::rem_list(const sref& grps) | ||
| 99 | { | ||
| 100 | sref first,rest=grps; | ||
| 101 | while(Split(first,rest)) rem(first); | ||
| 102 | } | ||
| 103 | |||
| 104 | //////////////////////////////////////////////////////////////////////// | ||
| 105 | |||
| 106 | static dbmap* GetDB(Env& env,const sref& name) | ||
| 107 | { | ||
| 108 | dbref_t* p=(dbref_t*)env.toks->get(name); | ||
| 109 | if(!env.is_clear(p)||!p->is_dbref()) THROW("htc: could not find system db "<<name); | ||
| 110 | p->db.remap(); | ||
| 111 | return &p->db; | ||
| 112 | } | ||
| 113 | |||
| 114 | static int FindUser(Env& env,const sref& name) | ||
| 115 | { | ||
| 116 | dbmap* users=GetDB(env,USERS_tag); | ||
| 117 | for(int i=0;i<users->size();i++) { | ||
| 118 | if(users->at(i,user_alias)==name) return atoi(users->at(i,user_uid)); | ||
| 119 | sref first,rest=users->at(i,user_email); | ||
| 120 | while(Split(first,rest)) if(eqn(first,name)) return atoi(users->at(i,user_uid)); | ||
| 121 | } | ||
| 122 | return 0; | ||
| 123 | } | ||
| 124 | |||
| 125 | //////////////////////////////////////////////////////////////////////// | ||
| 126 | |||
| 127 | TOK_IMPL(setgroup) { Req(env)->group=First(env[0]); } | ||
| 128 | TOK_IMPL(group) { out<<Req(env)->group; } | ||
| 129 | |||
| 130 | TOK_IMPL(getgroups) { | ||
| 131 | dbmap* users=GetDB(env,USERS_tag); | ||
| 132 | mset m; | ||
| 133 | for(int i=0;i<users->size();i++) { | ||
| 134 | sref first,rest=users->at(i,user_access); | ||
| 135 | while(Split(first,rest)) m.insert(first.left_first(':')); | ||
| 136 | } | ||
| 137 | out<<m; | ||
| 138 | } | ||
| 139 | |||
| 140 | //////////////////////////////////////////////////////////////////////// | ||
| 141 | |||
| 142 | TOK_IMPL(getuser) { | ||
| 143 | out<<FindUser(env,env[0]); | ||
| 144 | } | ||
| 145 | |||
| 146 | TOK_IMPL(setuser) { | ||
| 147 | dbmap* users=GetDB(env,USERS_tag); | ||
| 148 | int row=users->Find(env[0]); | ||
| 149 | if(row>=0) users->Get(row,Req(env)->user.list); | ||
| 150 | else Req(env)->user.reset(); | ||
| 151 | } | ||
| 152 | |||
| 153 | TOK_IMPL(remuser) { | ||
| 154 | dbmap* users=GetDB(env,USERS_tag); | ||
| 155 | int row=users->Find(env[0]); | ||
| 156 | if(row>=0) users->Rem(row); | ||
| 157 | } | ||
| 158 | |||
| 159 | TOK_IMPL(newuser) { | ||
| 160 | static const charset namends("*@.+"); | ||
| 161 | user_t user; | ||
| 162 | sref first,rest=env[0]; | ||
| 163 | Split(first,rest); | ||
| 164 | user.group()=first.left_first(':'); | ||
| 165 | do user.add(first); | ||
| 166 | while(Split(first,rest)); | ||
| 167 | user.pin()=Random(4); | ||
| 168 | user.email()=env[1]; | ||
| 169 | rest=env[1]; while(Split(first,rest)) if(FindUser(env,first)) { out<<0; return; } | ||
| 170 | mstring tag,alias=env[1].left_first_of(namends); | ||
| 171 | while(FindUser(env,alias+tag)) tag=itoa(atoi(tag)+1); | ||
| 172 | user.alias()=alias+tag; | ||
| 173 | user.name()=env[2]; | ||
| 174 | dbmap* users=GetDB(env,USERS_tag); | ||
| 175 | if(users->empty()) user.uid()=itoa(1); | ||
| 176 | else user.uid()=itoa(atoi(users->at(users->size()-1,user_uid))+1); | ||
| 177 | int row=users->Insert(user.list,1); | ||
| 178 | if(row<0) THROW("htc: could not add user - record not unique"); | ||
| 179 | out<<user.uid(); | ||
| 180 | } | ||
| 181 | |||
| 182 | ////////////////////////////////////////////////////////////////////////// | ||
| 183 | |||
| 184 | TOK_IMPL(user_id) { out<<Req(env)->user.uid(); } | ||
| 185 | TOK_IMPL(user_group) { out<<Req(env)->user.group(); } | ||
| 186 | TOK_IMPL(user_access) { out<<Req(env)->user.access(); } | ||
| 187 | TOK_IMPL(user_clear) { | ||
| 188 | sref first,rest=Req(env)->user.access(); int n=0; | ||
| 189 | while(Split(first,rest)) { if(n++) out.put(' '); out<<first.left_first(':'); } | ||
| 190 | } | ||
| 191 | |||
| 192 | TOK_IMPL(user_fail) { out<<Req(env)->user.fail(); } | ||
| 193 | TOK_IMPL(user_pin) { out<<Req(env)->user.pin(); } | ||
| 194 | TOK_IMPL(user_alias) { out<<Req(env)->user.alias(); } | ||
| 195 | TOK_IMPL(user_email) { out<<First(Req(env)->user.email()); } | ||
| 196 | TOK_IMPL(user_emails) { out<<Req(env)->user.email(); } | ||
| 197 | TOK_IMPL(user_name) { out<<Req(env)->user.name(); } | ||
| 198 | TOK_IMPL(user_last) { out<<Req(env)->user.last(); } | ||
| 199 | TOK_IMPL(user_lastin) { out<<Req(env)->user.lastin(); } | ||
| 200 | |||
| 201 | ////////////////////////////////////////////////////////////////////////// | ||
| 202 | |||
| 203 | TOK_IMPL(user_group_set) { Req(env)->user.group()=env[0]; } | ||
| 204 | TOK_IMPL(user_access_add) { Req(env)->user.add_list(env[0]); } | ||
| 205 | TOK_IMPL(user_access_rem) { Req(env)->user.rem_list(env[0]); } | ||
| 206 | TOK_IMPL(user_fail_set) { Req(env)->user.fail()=env[0]; } | ||
| 207 | TOK_IMPL(user_pin_set) { Req(env)->user.pin()=env[0]; } | ||
| 208 | TOK_IMPL(user_alias_set) { Req(env)->user.alias()=env[0]; } | ||
| 209 | TOK_IMPL(user_emails_set) { Req(env)->user.email()=env[0]; } | ||
| 210 | TOK_IMPL(user_name_set) { Req(env)->user.name()=env[0]; } | ||
| 211 | TOK_IMPL(user_last_set) { Req(env)->user.last()=env[0]; } | ||
| 212 | TOK_IMPL(user_lastin_set) { Req(env)->user.lastin()=env[0]; } | ||
| 213 | |||
| 214 | ////////////////////////////////////////////////////////// | ||
| 215 | |||
| 216 | TOK_IMPL(user_update) { | ||
| 217 | htc_req* htc=Req(env); | ||
| 218 | int uid=atoi(htc->user.uid()); | ||
| 219 | int who=FindUser(env,htc->user.alias()); | ||
| 220 | if(who&&who!=uid) return; | ||
| 221 | sref first,rest=htc->user.email(); | ||
| 222 | while(Split(first,rest)) { | ||
| 223 | who=FindUser(env,first); | ||
| 224 | if(who&&who!=uid) return; | ||
| 225 | } | ||
| 226 | dbmap* users=GetDB(env,USERS_tag); | ||
| 227 | int row=users->Find(htc->user.uid()); | ||
| 228 | if(row>=0) users->Set(row,htc->user.list); | ||
| 229 | } | ||
| 230 | |||
| 231 | ////////////////////////////////////////////////////////// | ||
| 232 | |||
| 233 | TOK_IMPL(su) { | ||
| 234 | htc_req* htc=Req(env); | ||
| 235 | user_t tmp(htc->user); | ||
| 236 | dbmap* users=GetDB(env,USERS_tag); | ||
| 237 | int row=users->Find(env[0]); | ||
| 238 | if(row>=0) { | ||
| 239 | try { | ||
| 240 | users->Get(row,htc->user.list); | ||
| 241 | env.parg(out,1); | ||
| 242 | htc->user=tmp; | ||
| 243 | } | ||
| 244 | catch(...) { | ||
| 245 | htc->user=tmp; | ||
| 246 | throw; | ||
| 247 | } | ||
| 248 | } | ||
| 249 | else env.parg(out,2); | ||
| 250 | } | ||
| 251 | |||
| 252 | ////////////////////////////////////////////////////////// | ||
| 253 | |||
| 254 | void envAddUser(tokmap& T) throw(merror_t) | ||
| 255 | { | ||
| 256 | TOK_ADD(setgroup,"x",tok_t::SYSONLY, | ||
| 257 | "%Set current group\n" | ||
| 258 | "%Syntax: \\setgroup{group}\n" | ||
| 259 | "%\n" | ||
| 260 | "%Nop function; only for logging and structure.\n" | ||
| 261 | ); | ||
| 262 | TOK_ADD(group,"",tok_t::PUBLIC, | ||
| 263 | "%Get current group\n" | ||
| 264 | "%Syntax: \\group\n" | ||
| 265 | "%\n" | ||
| 266 | "%Nop function; only for logging and structure.\n" | ||
| 267 | ); | ||
| 268 | |||
| 269 | TOK_ADD(getgroups,"",tok_t::PUBLIC, | ||
| 270 | "%Get all groups\n" | ||
| 271 | "%Syntax: \\getgroups\n" | ||
| 272 | "%\n" | ||
| 273 | "%Scans users db for all groups used\n" | ||
| 274 | ); | ||
| 275 | |||
| 276 | /////////////////////////////////////////////////// | ||
| 277 | |||
| 278 | TOK_ADD(getuser,"x",tok_t::SYSONLY, | ||
| 279 | "%Get user ID\n" | ||
| 280 | "%Syntax: \\getuser{alias/email}\n" | ||
| 281 | "%\n" | ||
| 282 | "%Returns the uid if found, or zero if not found\n" | ||
| 283 | ); | ||
| 284 | TOK_ADD(setuser,"x",tok_t::SYSONLY, | ||
| 285 | "%Set current user\n" | ||
| 286 | "%Syntax: \\setuser{uid}\n" | ||
| 287 | ); | ||
| 288 | TOK_ADD(remuser,"x",tok_t::SYSONLY, | ||
| 289 | "%Remove user\n" | ||
| 290 | "%Syntax: \\remuser{uid}\n" | ||
| 291 | ); | ||
| 292 | TOK_ADD(newuser,"xxx",tok_t::SYSONLY, | ||
| 293 | "%Add a new user\n" | ||
| 294 | "%Syntax: \\newuser{clear}{email}{name}\n" | ||
| 295 | "%\n" | ||
| 296 | "%Returns the new uid if successful, otherwise zero.\n" | ||
| 297 | ); | ||
| 298 | |||
| 299 | /////////////////////////////////////////////////// | ||
| 300 | |||
| 301 | TOK_ADD(user_id,"",tok_t::PUBLIC, | ||
| 302 | "%Get uid of current user\n" | ||
| 303 | "%Syntax: \\user.id\n" | ||
| 304 | ); | ||
| 305 | TOK_ADD(user_group,"",tok_t::PUBLIC, | ||
| 306 | "%Get group of current user\n" | ||
| 307 | "%Syntax: \\user.group\n" | ||
| 308 | ); | ||
| 309 | TOK_ADD(user_access,"",tok_t::PUBLIC, | ||
| 310 | "%Get access of current user\n" | ||
| 311 | "%Syntax: \\user.access\n" | ||
| 312 | ); | ||
| 313 | TOK_ADD(user_clear,"",tok_t::PUBLIC, | ||
| 314 | "%Get clearance of current user\n" | ||
| 315 | "%Syntax: \\user.clear\n" | ||
| 316 | "%\n" | ||
| 317 | "%This is a compiled list, without the time info.\n" | ||
| 318 | ); | ||
| 319 | TOK_ADD(user_fail,"",tok_t::PUBLIC, | ||
| 320 | "%Get fail number of current user\n" | ||
| 321 | "%Syntax: \\user.fail\n" | ||
| 322 | ); | ||
| 323 | TOK_ADD(user_pin,"",tok_t::SYSONLY, | ||
| 324 | "%Get pin of current user\n" | ||
| 325 | "%Syntax: \\user.pin\n" | ||
| 326 | ); | ||
| 327 | TOK_ADD(user_alias,"",tok_t::PUBLIC, | ||
| 328 | "%Get alias of current user\n" | ||
| 329 | "%Syntax: \\user.alias\n" | ||
| 330 | ); | ||
| 331 | TOK_ADD(user_email,"",tok_t::PUBLIC, | ||
| 332 | "%Get email of current user\n" | ||
| 333 | "%Syntax: \\user.email\n" | ||
| 334 | "%\n" | ||
| 335 | "%Note that the email list may contain several addresses;\n" | ||
| 336 | "%this function returns the first in the list.\n" | ||
| 337 | ); | ||
| 338 | TOK_ADD(user_emails,"",tok_t::PUBLIC, | ||
| 339 | "%Get all email addresses of current user\n" | ||
| 340 | "%Syntax: \\user.emails\n" | ||
| 341 | ); | ||
| 342 | TOK_ADD(user_name,"",tok_t::PUBLIC, | ||
| 343 | "%Get name of current user\n" | ||
| 344 | "%Syntax: \\user.name\n" | ||
| 345 | ); | ||
| 346 | TOK_ADD(user_last,"",tok_t::PUBLIC, | ||
| 347 | "%Get last time logged in of current user\n" | ||
| 348 | "%Syntax: \\user.last\n" | ||
| 349 | ); | ||
| 350 | TOK_ADD(user_lastin,"",tok_t::PUBLIC, | ||
| 351 | "%Get last IP address of current user\n" | ||
| 352 | "%Syntax: \\user.lastin\n" | ||
| 353 | ); | ||
| 354 | |||
| 355 | /////////////////////////////////////////////////// | ||
| 356 | |||
| 357 | TOK_ADD(user_group_set,"x",tok_t::SYSONLY, | ||
| 358 | "%Set group of current user\n" | ||
| 359 | "%Syntax: \\user.group.set{group}\n" | ||
| 360 | "%\n" | ||
| 361 | "%Note that the changes take effect after a \\user.update\n" | ||
| 362 | ); | ||
| 363 | TOK_ADD(user_access_add,"x",tok_t::SYSONLY, | ||
| 364 | "%Add access to current user\n" | ||
| 365 | "%Syntax: \\user.access.add{group:start:stop}\n" | ||
| 366 | "%\n" | ||
| 367 | "%The :start:stop part may be omitted, in which case\n" | ||
| 368 | "%a start value of now, and a stop value of nil is set.\n" | ||
| 369 | "%\n" | ||
| 370 | "%In case of several group strings, they are all added.\n" | ||
| 371 | "%\n" | ||
| 372 | "%Note that the changes take effect after a \\user.update\n" | ||
| 373 | ); | ||
| 374 | TOK_ADD(user_access_rem,"x",tok_t::SYSONLY, | ||
| 375 | "%Remove access from current user\n" | ||
| 376 | "%Syntax: \\user.access.rem{group}\n" | ||
| 377 | "%\n" | ||
| 378 | "%In case of several groups, they are all removed.\n" | ||
| 379 | "%\n" | ||
| 380 | "%Note that the changes take effect after a \\user.update\n" | ||
| 381 | ); | ||
| 382 | TOK_ADD(user_fail_set,"x",tok_t::SYSONLY, | ||
| 383 | "%Set fail number of current user\n" | ||
| 384 | "%Syntax: \\user.fail.set{fail}\n" | ||
| 385 | "%\n" | ||
| 386 | "%Note that the changes take effect after a \\user.update\n" | ||
| 387 | ); | ||
| 388 | TOK_ADD(user_pin_set,"x",tok_t::SYSONLY, | ||
| 389 | "%Set pin of current user\n" | ||
| 390 | "%Syntax: \\user.pin.set{pin}\n" | ||
| 391 | "%\n" | ||
| 392 | "%Note that the changes take effect after a \\user.update\n" | ||
| 393 | ); | ||
| 394 | TOK_ADD(user_alias_set,"x",tok_t::SYSONLY, | ||
| 395 | "%Set alias of current user\n" | ||
| 396 | "%Syntax: \\user.alias.set{alias}\n" | ||
| 397 | "%\n" | ||
| 398 | "%Note that the changes take effect after a \\user.update\n" | ||
| 399 | ); | ||
| 400 | TOK_ADD(user_emails_set,"x",tok_t::SYSONLY, | ||
| 401 | "%Set all email addresses of current user\n" | ||
| 402 | "%Syntax: \\user.emails.set{emails}\n" | ||
| 403 | "%\n" | ||
| 404 | "%Note that the changes take effect after a \\user.update\n" | ||
| 405 | ); | ||
| 406 | TOK_ADD(user_name_set,"x",tok_t::SYSONLY, | ||
| 407 | "%Set name of current user\n" | ||
| 408 | "%Syntax: \\user.name.set{name}\n" | ||
| 409 | "%\n" | ||
| 410 | "%Note that the changes take effect after a \\user.update\n" | ||
| 411 | ); | ||
| 412 | TOK_ADD(user_last_set,"x",tok_t::SYSONLY, | ||
| 413 | "%Set last time logged in of current user\n" | ||
| 414 | "%Syntax: \\user.last.set{last}\n" | ||
| 415 | "%\n" | ||
| 416 | "%Note that the changes take effect after a \\user.update\n" | ||
| 417 | ); | ||
| 418 | TOK_ADD(user_lastin_set,"x",tok_t::SYSONLY, | ||
| 419 | "%Set last IP address of current user\n" | ||
| 420 | "%Syntax: \\user.lastin.set{addr}\n" | ||
| 421 | "%\n" | ||
| 422 | "%Note that the changes take effect after a \\user.update\n" | ||
| 423 | ); | ||
| 424 | |||
| 425 | /////////////////////////////////////////////////// | ||
| 426 | |||
| 427 | TOK_ADD(user_update,"",tok_t::SYSONLY, | ||
| 428 | "%Update the current user\n" | ||
| 429 | "%Syntax: \\user.update\n" | ||
| 430 | "%\n" | ||
| 431 | "%All changes a synchronous and immediately available.\n" | ||
| 432 | ); | ||
| 433 | |||
| 434 | /////////////////////////////////////////////////// | ||
| 435 | |||
| 436 | TOK_ADD(su,"xr?",tok_t::SYSONLY, | ||
| 437 | "%Set user temporary\n" | ||
| 438 | "%Syntax: \\su{uid}{body}<else>\n" | ||
| 439 | "%\n" | ||
| 440 | "%If set successfully, evaluates body, otherwise <else>.\n" | ||
| 441 | ); | ||
| 442 | |||
| 443 | /////////////////////////////////////////////////// | ||
| 444 | |||
| 445 | } | ||
diff --git a/src/sh/user.h b/src/sh/user.h new file mode 100644 index 0000000..cc00e21 --- /dev/null +++ b/src/sh/user.h | |||
| @@ -0,0 +1,92 @@ | |||
| 1 | /************************************************************************* | ||
| 2 | * | ||
| 3 | * HTCd - Copyright (C) 1998-2006 Henrik Rydberg | ||
| 4 | * | ||
| 5 | * This program is free software; you can redistribute it and/or modify | ||
| 6 | * it under the terms of the GNU General Public License as published by | ||
| 7 | * the Free Software Foundation; either version 2 of the License, or | ||
| 8 | * (at your option) any later version. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | * | ||
| 15 | * You should have received a copy of the GNU General Public License | ||
| 16 | * along with this program; if not, write to the Free Software | ||
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA | ||
| 18 | */ | ||
| 19 | |||
| 20 | #ifndef USERH | ||
| 21 | #define USERH | ||
| 22 | |||
| 23 | #include <lang/env.h> | ||
| 24 | #include <mt/lookup.h> | ||
| 25 | |||
| 26 | ///////////////////////////////////////////////////////// | ||
| 27 | |||
| 28 | const mstring root_tag="ROOT"; | ||
| 29 | const mstring lastin_def="0.0.0.0"; | ||
| 30 | |||
| 31 | const mstring USERS_tag="USERS"; | ||
| 32 | const mstring PREFS_tag="PREFS"; | ||
| 33 | const mstring TREE_tag="TREE"; | ||
| 34 | |||
| 35 | const int user_tabs=10,user_uid=0,user_alias=4,user_email=5,user_access=9; | ||
| 36 | const mstring user_tab[user_tabs]={ | ||
| 37 | "UID","GROUP","FAIL","PIN","ALIAS","EMAIL","NAME","LAST","LASTIN","ACCESS" | ||
| 38 | }; | ||
| 39 | |||
| 40 | const int prefs_tabs=8; | ||
| 41 | const mstring prefs_tab[prefs_tabs]={ | ||
| 42 | "ID","EXT","ROOM","URL","POSIT","NOTE","ABSTRACT","LASTMOD" | ||
| 43 | }; | ||
| 44 | |||
| 45 | const int tree_tabs=17; | ||
| 46 | const mstring tree_tab[tree_tabs]={ | ||
| 47 | "URI","REFER","PARENT","MIME", | ||
| 48 | "MOD","UID","GID","SIZE","LASTMOD", | ||
| 49 | "ALIAS","BANNER", | ||
| 50 | "X.CLEAR","X.COOKIE","X.DOMAIN","X.USER","X.CACHE", | ||
| 51 | "XMOD" | ||
| 52 | }; | ||
| 53 | |||
| 54 | int allow(const sref& s,const sref& grp,time_t now,int rootok=0); | ||
| 55 | |||
| 56 | struct user_t { | ||
| 57 | spile list; | ||
| 58 | |||
| 59 | user_t() : list(user_tabs) {} | ||
| 60 | user_t(const user_t& us); | ||
| 61 | |||
| 62 | void operator=(const user_t&); | ||
| 63 | |||
| 64 | mstring& uid() { return list[0]; } | ||
| 65 | mstring& group() { return list[1]; } | ||
| 66 | mstring& fail() { return list[2]; } | ||
| 67 | mstring& pin() { return list[3]; } | ||
| 68 | mstring& alias() { return list[4]; } | ||
| 69 | mstring& email() { return list[5]; } | ||
| 70 | mstring& name() { return list[6]; } | ||
| 71 | mstring& last() { return list[7]; } | ||
| 72 | mstring& lastin() { return list[8]; } | ||
| 73 | mstring& access() { return list[9]; } | ||
| 74 | |||
| 75 | void reset(); | ||
| 76 | int allow(const sref& grp,time_t now,int rootok=0); | ||
| 77 | int allow_list(const sref& grps,time_t now,int rootok=0); | ||
| 78 | // rootok<0 -> ignore special root handling (new; should not interfere) | ||
| 79 | // rootok==0 -> root not allowed here | ||
| 80 | // rootok>0 -> root always allowed here | ||
| 81 | |||
| 82 | void add(const sref& grp); | ||
| 83 | void add_list(const sref& grps); | ||
| 84 | void rem(const sref& grp); | ||
| 85 | void rem_list(const sref& grps); | ||
| 86 | }; | ||
| 87 | |||
| 88 | ///////////////////////////////////////////////////////// | ||
| 89 | |||
| 90 | void envAddUser(tokmap& T) throw(merror_t); | ||
| 91 | |||
| 92 | #endif | ||
diff --git a/src/test/EXPECTED.mt b/src/test/EXPECTED.mt new file mode 100644 index 0000000..57ac1b2 --- /dev/null +++ b/src/test/EXPECTED.mt | |||
| @@ -0,0 +1,17 @@ | |||
| 1 | more strange asdf | ||
| 2 | |||
| 3 | more strange asdf | ||
| 4 | Hello! this is appending 4 to string | ||
| 5 | |||
| 6 | ******** | ||
| 7 | ******** | ||
| 8 | Error test: 0 | ||
| 9 | hello 4 once more | ||
| 10 | ******** | ||
| 11 | 1 | ||
| 12 | ******** | ||
| 13 | 6 | ||
| 14 | [asdf] | ||
| 15 | ******** | ||
| 16 | Got [hello world!] | ||
| 17 | Got [] | ||
diff --git a/src/test/EXPECTED.ops b/src/test/EXPECTED.ops new file mode 100644 index 0000000..f6bb64a --- /dev/null +++ b/src/test/EXPECTED.ops | |||
| @@ -0,0 +1 @@ | |||
| 403.428793492735 | |||
diff --git a/src/test/cmd.hexp b/src/test/cmd.hexp new file mode 100644 index 0000000..de16627 --- /dev/null +++ b/src/test/cmd.hexp | |||
| @@ -0,0 +1,4 @@ | |||
| 1 | 1+2, | ||
| 2 | a=6, | ||
| 3 | 1+a, | ||
| 4 | exp a | ||
diff --git a/src/test/run.sh b/src/test/run.sh new file mode 100755 index 0000000..01591bf --- /dev/null +++ b/src/test/run.sh | |||
| @@ -0,0 +1,6 @@ | |||
| 1 | #!/bin/sh | ||
| 2 | bin=`which $0`; cd `dirname $bin` | ||
| 3 | echo "mt:" | ||
| 4 | ../tmp/bin/mt/test | diff -a EXPECTED.mt - | ||
| 5 | echo "ops:" | ||
| 6 | ../tmp/bin/ops/test cmd.hexp | diff -a EXPECTED.ops - | ||
