From 5df79c53745fde5d6c3340a2979b1429cd5892c1 Mon Sep 17 00:00:00 2001 From: Henrik Rydberg Date: Sat, 8 Oct 2011 20:30:28 +0200 Subject: Initial import of htcd system 1.0 Signed-off-by: Henrik Rydberg --- src/LICENSE | 356 ++++++++++++++ src/hdb/README | 154 ++++++ src/hdb/buffer.h | 38 ++ src/hdb/comp.cc | 78 +++ src/hdb/cvt.cc | 83 ++++ src/hdb/db.cc | 276 +++++++++++ src/hdb/db.h | 129 +++++ src/hdb/filemap.cc | 302 ++++++++++++ src/hdb/filemap.h | 196 ++++++++ src/hdb/hdbcvt.cc | 50 ++ src/hdb/hdbfix.cc | 140 ++++++ src/hdb/hdbtest.cc | 153 ++++++ src/hdb/sortable.cc | 81 ++++ src/hdb/sortable.h | 138 ++++++ src/hdb/test.cc | 52 ++ src/hed/edit.cc | 262 +++++++++++ src/hed/edit.h | 61 +++ src/hed/hed.cc | 56 +++ src/hed/input.cc | 107 +++++ src/hed/input.h | 52 ++ src/hed/tables.cc | 442 +++++++++++++++++ src/hed/tables.h | 61 +++ src/hed/test.cc | 33 ++ src/http/http.h | 144 ++++++ src/http/mime.cc | 92 ++++ src/http/mime.h | 99 ++++ src/http/req.cc | 100 ++++ src/http/resp.cc | 79 ++++ src/http/test.cc | 28 ++ src/labat/README | 49 ++ src/labat/adensin.dat | 0 src/labat/adensout.dat | 402 ++++++++++++++++ src/labat/apotin.dat | 0 src/labat/apotout.dat | 402 ++++++++++++++++ src/labat/aprtout.dat | 1175 ++++++++++++++++++++++++++++++++++++++++++++++ src/labat/atomctrl.dat | 15 + src/labat/atomdens.dat | 401 ++++++++++++++++ src/labat/atomlab.cc | 187 ++++++++ src/labat/deriv.f | 65 +++ src/labat/exchen.f | 21 + src/labat/exchpt.f | 33 ++ src/labat/gcor.f | 15 + src/labat/gga.f | 45 ++ src/labat/ggaec.f | 43 ++ src/labat/ggaexc.f | 76 +++ src/labat/ggauc.f | 96 ++++ src/labat/ggauxc.f | 82 ++++ src/labat/grabgr.f | 32 ++ src/labat/grad.f | 26 + src/labat/labat.f | 587 +++++++++++++++++++++++ src/labat/laplac.f | 41 ++ src/labat/laplac2.f | 11 + src/labat/ldaec.f | 21 + src/labat/ldauc.f | 32 ++ src/labat/resten.f | 634 +++++++++++++++++++++++++ src/labat/spline.f | 34 ++ src/labat/splint.f | 37 ++ src/lang/basic.cc | 315 +++++++++++++ src/lang/db.cc | 237 ++++++++++ src/lang/env.cc | 308 ++++++++++++ src/lang/env.h | 156 ++++++ src/lang/flow.cc | 198 ++++++++ src/lang/func.cc | 249 ++++++++++ src/lang/help.cc | 140 ++++++ src/lang/lang.cc | 39 ++ src/lang/latex.cc | 152 ++++++ src/lang/ops.cc | 150 ++++++ src/lang/parse.cc | 453 ++++++++++++++++++ src/lang/test.cc | 45 ++ src/lang/token.cc | 268 +++++++++++ src/lang/token.h | 230 +++++++++ src/mail/inbox.cc | 36 ++ src/mail/list.cc | 52 ++ src/mail/move.cc | 60 +++ src/mail/res.h | 30 ++ src/makefile | 177 +++++++ src/mime/base64.cc | 132 ++++++ src/mime/def.cc | 149 ++++++ src/mime/enc.h | 36 ++ src/mime/mailbox.cc | 137 ++++++ src/mime/mailbox.h | 60 +++ src/mime/mime.cc | 188 ++++++++ src/mime/mime.h | 99 ++++ src/mime/pack.cc | 143 ++++++ src/mime/pack.h | 48 ++ src/mime/qp.cc | 150 ++++++ src/mime/test.cc | 108 +++++ src/mt/cfind.f | 80 ++++ src/mt/charset.h | 131 ++++++ src/mt/config.cc | 33 ++ src/mt/config.h | 27 ++ src/mt/crfind.f | 80 ++++ src/mt/dates.cc | 207 ++++++++ src/mt/dates.h | 49 ++ src/mt/find_not_of.f | 80 ++++ src/mt/find_of.f | 80 ++++ src/mt/issue.cc | 51 ++ src/mt/issue.h | 55 +++ src/mt/lock.cc | 114 +++++ src/mt/lock.h | 72 +++ src/mt/lookup.cc | 88 ++++ src/mt/lookup.h | 32 ++ src/mt/mlock.h | 48 ++ src/mt/mread.cc | 135 ++++++ src/mt/mread.h | 63 +++ src/mt/mset.cc | 81 ++++ src/mt/mset.h | 62 +++ src/mt/msmap.cc | 84 ++++ src/mt/msmap.h | 89 ++++ src/mt/mstream.cc | 72 +++ src/mt/mstream.h | 103 ++++ src/mt/mstring.cc | 139 ++++++ src/mt/mstring.h | 222 +++++++++ src/mt/mvec.h | 149 ++++++ src/mt/qran.h | 34 ++ src/mt/random.cc | 95 ++++ src/mt/random.h | 39 ++ src/mt/rfind_not_of.f | 80 ++++ src/mt/rfind_of.f | 80 ++++ src/mt/scomptab.f | 44 ++ src/mt/sconvert.f | 35 ++ src/mt/sfind.f | 40 ++ src/mt/sfindtab.f | 40 ++ src/mt/skip_parentesis.f | 42 ++ src/mt/split.h | 72 +++ src/mt/srfind.f | 40 ++ src/mt/srfindtab.f | 40 ++ src/mt/stackque.h | 64 +++ src/mt/stringref.cc | 126 +++++ src/mt/stringref.h | 239 ++++++++++ src/mt/strip.f | 31 ++ src/mt/test.cc | 337 +++++++++++++ src/mt/uniheap.h | 65 +++ src/net/htcd.cc | 153 ++++++ src/net/isocket.cc | 58 +++ src/net/isocket.h | 68 +++ src/net/redirect.cc | 185 ++++++++ src/net/route80.cc | 64 +++ src/net/server.cc | 75 +++ src/net/server.h | 46 ++ src/net/test.cc | 44 ++ src/net/thrserv.cc | 255 ++++++++++ src/net/thrserv.h | 79 ++++ src/ops/basic.cc | 269 +++++++++++ src/ops/comp.cc | 134 ++++++ src/ops/express.cc | 173 +++++++ src/ops/express.h | 79 ++++ src/ops/latex.cc | 101 ++++ src/ops/nnstyle.h | 53 +++ src/ops/operator.cc | 44 ++ src/ops/operator.h | 97 ++++ src/ops/string.cc | 274 +++++++++++ src/ops/test.cc | 161 +++++++ src/serv/auth.cc | 162 +++++++ src/serv/const.cc | 69 +++ src/serv/direct.cc | 73 +++ src/serv/form.cc | 102 ++++ src/serv/htcd.h | 74 +++ src/serv/htcs.cc | 92 ++++ src/serv/main.cc | 122 +++++ src/serv/request.cc | 279 +++++++++++ src/serv/tempmap.cc | 82 ++++ src/serv/tempmap.h | 57 +++ src/sh/convert.cc | 376 +++++++++++++++ src/sh/dates.cc | 138 ++++++ src/sh/file.cc | 367 +++++++++++++++ src/sh/htc.cc | 92 ++++ src/sh/htc.h | 77 +++ src/sh/main.cc | 129 +++++ src/sh/net.cc | 122 +++++ src/sh/string.cc | 32 ++ src/sh/sys.cc | 152 ++++++ src/sh/tree.cc | 304 ++++++++++++ src/sh/user.cc | 445 ++++++++++++++++++ src/sh/user.h | 92 ++++ src/test/EXPECTED.mt | 17 + src/test/EXPECTED.ops | 1 + src/test/cmd.hexp | 4 + src/test/run.sh | 6 + 179 files changed, 22796 insertions(+) create mode 100644 src/LICENSE create mode 100644 src/hdb/README create mode 100644 src/hdb/buffer.h create mode 100644 src/hdb/comp.cc create mode 100644 src/hdb/cvt.cc create mode 100644 src/hdb/db.cc create mode 100644 src/hdb/db.h create mode 100644 src/hdb/filemap.cc create mode 100644 src/hdb/filemap.h create mode 100644 src/hdb/hdbcvt.cc create mode 100644 src/hdb/hdbfix.cc create mode 100644 src/hdb/hdbtest.cc create mode 100644 src/hdb/sortable.cc create mode 100644 src/hdb/sortable.h create mode 100644 src/hdb/test.cc create mode 100644 src/hed/edit.cc create mode 100644 src/hed/edit.h create mode 100644 src/hed/hed.cc create mode 100644 src/hed/input.cc create mode 100644 src/hed/input.h create mode 100644 src/hed/tables.cc create mode 100644 src/hed/tables.h create mode 100644 src/hed/test.cc create mode 100644 src/http/http.h create mode 100644 src/http/mime.cc create mode 100644 src/http/mime.h create mode 100644 src/http/req.cc create mode 100644 src/http/resp.cc create mode 100644 src/http/test.cc create mode 100644 src/labat/README create mode 100644 src/labat/adensin.dat create mode 100644 src/labat/adensout.dat create mode 100644 src/labat/apotin.dat create mode 100644 src/labat/apotout.dat create mode 100644 src/labat/aprtout.dat create mode 100644 src/labat/atomctrl.dat create mode 100644 src/labat/atomdens.dat create mode 100644 src/labat/atomlab.cc create mode 100644 src/labat/deriv.f create mode 100644 src/labat/exchen.f create mode 100644 src/labat/exchpt.f create mode 100644 src/labat/gcor.f create mode 100644 src/labat/gga.f create mode 100644 src/labat/ggaec.f create mode 100644 src/labat/ggaexc.f create mode 100644 src/labat/ggauc.f create mode 100644 src/labat/ggauxc.f create mode 100644 src/labat/grabgr.f create mode 100644 src/labat/grad.f create mode 100644 src/labat/labat.f create mode 100644 src/labat/laplac.f create mode 100644 src/labat/laplac2.f create mode 100644 src/labat/ldaec.f create mode 100644 src/labat/ldauc.f create mode 100644 src/labat/resten.f create mode 100644 src/labat/spline.f create mode 100644 src/labat/splint.f create mode 100644 src/lang/basic.cc create mode 100644 src/lang/db.cc create mode 100644 src/lang/env.cc create mode 100644 src/lang/env.h create mode 100644 src/lang/flow.cc create mode 100644 src/lang/func.cc create mode 100644 src/lang/help.cc create mode 100644 src/lang/lang.cc create mode 100644 src/lang/latex.cc create mode 100644 src/lang/ops.cc create mode 100644 src/lang/parse.cc create mode 100644 src/lang/test.cc create mode 100644 src/lang/token.cc create mode 100644 src/lang/token.h create mode 100644 src/mail/inbox.cc create mode 100644 src/mail/list.cc create mode 100644 src/mail/move.cc create mode 100644 src/mail/res.h create mode 100644 src/makefile create mode 100644 src/mime/base64.cc create mode 100644 src/mime/def.cc create mode 100644 src/mime/enc.h create mode 100644 src/mime/mailbox.cc create mode 100644 src/mime/mailbox.h create mode 100644 src/mime/mime.cc create mode 100644 src/mime/mime.h create mode 100644 src/mime/pack.cc create mode 100644 src/mime/pack.h create mode 100644 src/mime/qp.cc create mode 100644 src/mime/test.cc create mode 100644 src/mt/cfind.f create mode 100644 src/mt/charset.h create mode 100644 src/mt/config.cc create mode 100644 src/mt/config.h create mode 100644 src/mt/crfind.f create mode 100644 src/mt/dates.cc create mode 100644 src/mt/dates.h create mode 100644 src/mt/find_not_of.f create mode 100644 src/mt/find_of.f create mode 100644 src/mt/issue.cc create mode 100644 src/mt/issue.h create mode 100644 src/mt/lock.cc create mode 100644 src/mt/lock.h create mode 100644 src/mt/lookup.cc create mode 100644 src/mt/lookup.h create mode 100644 src/mt/mlock.h create mode 100644 src/mt/mread.cc create mode 100644 src/mt/mread.h create mode 100644 src/mt/mset.cc create mode 100644 src/mt/mset.h create mode 100644 src/mt/msmap.cc create mode 100644 src/mt/msmap.h create mode 100644 src/mt/mstream.cc create mode 100644 src/mt/mstream.h create mode 100644 src/mt/mstring.cc create mode 100644 src/mt/mstring.h create mode 100644 src/mt/mvec.h create mode 100644 src/mt/qran.h create mode 100644 src/mt/random.cc create mode 100644 src/mt/random.h create mode 100644 src/mt/rfind_not_of.f create mode 100644 src/mt/rfind_of.f create mode 100644 src/mt/scomptab.f create mode 100644 src/mt/sconvert.f create mode 100644 src/mt/sfind.f create mode 100644 src/mt/sfindtab.f create mode 100644 src/mt/skip_parentesis.f create mode 100644 src/mt/split.h create mode 100644 src/mt/srfind.f create mode 100644 src/mt/srfindtab.f create mode 100644 src/mt/stackque.h create mode 100644 src/mt/stringref.cc create mode 100644 src/mt/stringref.h create mode 100644 src/mt/strip.f create mode 100644 src/mt/test.cc create mode 100644 src/mt/uniheap.h create mode 100644 src/net/htcd.cc create mode 100644 src/net/isocket.cc create mode 100644 src/net/isocket.h create mode 100644 src/net/redirect.cc create mode 100644 src/net/route80.cc create mode 100644 src/net/server.cc create mode 100644 src/net/server.h create mode 100644 src/net/test.cc create mode 100644 src/net/thrserv.cc create mode 100644 src/net/thrserv.h create mode 100644 src/ops/basic.cc create mode 100644 src/ops/comp.cc create mode 100644 src/ops/express.cc create mode 100644 src/ops/express.h create mode 100644 src/ops/latex.cc create mode 100644 src/ops/nnstyle.h create mode 100644 src/ops/operator.cc create mode 100644 src/ops/operator.h create mode 100644 src/ops/string.cc create mode 100644 src/ops/test.cc create mode 100644 src/serv/auth.cc create mode 100644 src/serv/const.cc create mode 100644 src/serv/direct.cc create mode 100644 src/serv/form.cc create mode 100644 src/serv/htcd.h create mode 100644 src/serv/htcs.cc create mode 100644 src/serv/main.cc create mode 100644 src/serv/request.cc create mode 100644 src/serv/tempmap.cc create mode 100644 src/serv/tempmap.h create mode 100644 src/sh/convert.cc create mode 100644 src/sh/dates.cc create mode 100644 src/sh/file.cc create mode 100644 src/sh/htc.cc create mode 100644 src/sh/htc.h create mode 100644 src/sh/main.cc create mode 100644 src/sh/net.cc create mode 100644 src/sh/string.cc create mode 100644 src/sh/sys.cc create mode 100644 src/sh/tree.cc create mode 100644 src/sh/user.cc create mode 100644 src/sh/user.h create mode 100644 src/test/EXPECTED.mt create mode 100644 src/test/EXPECTED.ops create mode 100644 src/test/cmd.hexp create mode 100755 src/test/run.sh (limited to 'src') diff --git a/src/LICENSE b/src/LICENSE new file mode 100644 index 0000000..f6e636c --- /dev/null +++ b/src/LICENSE @@ -0,0 +1,356 @@ + + This copyright does not cover server HTC code that use the system + by normal system calls - this is merely considered normal use of the + system, and does not fall under the heading of "derived work". Also + note that the GPL below is copyrighted by the Free Software + Foundation, but the instance of code that it refers to (the htcd + system) is copyrighted by me. + + Also note that the only valid version of the GPL as far as the kernel + is concerned is _this_ particular version of the license (ie v2, not + v2.2 or v3.x or whatever), unless explicitly otherwise stated. + + Henrik Rydberg (rydberg@euromail.se) + +---------------------------------------- + + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + + Copyright (C) + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + , 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +HDB/1.2 FILE FORMAT SPECIFICATION Sat Feb 24 18:38:25 MET 2001 + +MT AND MP SAFE + +One single format utilizing memory maps, and which is designed to +work safely between processes and within a multi-threading process. +To accomplish this, there are two types of locking mechanisms - +one inter-process lock in the file header, and one MT lock implemented +the usual way. + +The format is robust within each thread, except for changes in the +table structure, which generates fatal error_t errors. + +The format includes a finite (32) number of tables, which should not +be a real problem. Besides, a possible change is to move the frame +pointer to a position inside, so that additional header could be +added if needed. + +FILEFORMAT in HDB/1.2 + +BYTES 1.2 NAME DESCRIPTION +32 IDENT Identification header +4 LOCK Inter-process lock +4 MINOR Minor modification state number +4 MAJOR Major modification state number +4 FATAL Fatal modification state number +4 FILESIZE Size of file +4 FILETOP Size of used part +4 TABLES Number of table name strings +4 INDEX Which column is the order column. +32 COMPNAME Comparison name +32*32 TABLENAMES Table names +4 FRAME Start of record data +* RECORDS Record list + 4 mem amount of memory for this record + 4 caps the capacity of this record - 0 means deleted + mem-8 data The data follows +0 ZEROS The rest of the file is padded with zeros. + +The records are always staying where they land; a minor change means +a change in-place, a major change means a change leading to an index +update, which could be a deletion, an insertion. Those are updated at +will, and not seen until wanted. A fatal change is a change in the +table structure, i.e., an insertion or deletion of a table. Also a +table name change counts as fatal. The filesize used to be (earlier +versions) a state needing attention as well, but not anymore. + +-- + +HDB/1.11 FILE FORMAT SPECIFICATION Mon Jan 29 03:51:41 MET 2001 + +STATIC/DYNAMIC mapping + +The header field determines whether the mapping is dynamic or static, +i.e., static mapping creates a shared mmap and edits the records +directly, whereas the dynamic mapping creates a private map and +stores the changes on save only. + +The format changed quite a lot after all... + +FILEFORMAT in HDB/1.11 + +BYTES 1.11 NAME DESCRIPTION +32 IDENT Identification header +4 MODNUM Modification number +4 LOCK Soft lock +4 FILESIZE Size of file +4 FILETOP Size of used part +4 FIXED Whether fixed mapping or not +4 TABLES Number of table name strings +4 INDEX Which column is the order column. +32 COMPNAME Comparison name +4 RECORDS Number of records in file. + tables + 4,* name table name + 4,* defaults default string + 4 caps default sizes + [4],* records TABLES[RECORDS] + +Size info [4] always refers to the stringref-size, but the number of +bytes actually written is as follows: for fixed maps, it is tabs[].caps, +and for dynamic maps, it is capsize(), which is defined as (n=stringref-size) +(4+n)&~3. + +-- + +HDB/1.10 FILE FORMAT SPECIFICATION Thu Jan 25 00:42:49 MET 2001 + +The HDB/1.0 format has been used widely in the software +for our group (MST) during the last three years of so. +The HDB/1.1 file format is binary compatible with 1.0, +and merely consists of a formalization, along with a +change in the internal manipulation scheme and a new +hdb editor. + +FILE FORMAT IN 1.0 and 1.1 + +BYTES 1.0/1.1 NAME DESCRIPTION +32/variable HEAD Identification header. + Used to be exactly 32 bytes, + but see no point in that. +4 TABLES Number of table name strings + 4 dim bytes in string + * data string data +4 DEFAULTS Number of default strings + 4 dim bytes in string + * data string data +4 ORDERBY Which column is the order column. +4 dim Number of bytes in compname. +* data string data +4 RECORDS Number of records in file. + 4 tables + 4 dim + * data +0/variable FOOTER File ends. Simple Footer. + +ADDITIONAL CHANGES BETWEEN 1.0 and 1.1 + +The major difference - and the rationale for 1.1 - is +the possiblity to edit files directly, as in mmap. +To be able to do this, there is a need to force a minimum +size to each field. This is done by padding the data +with trailing zeros. This is ok since only string data +is stored in the fields, and never binary data. Just think +of it; if it was binary data, it would not be replaced +by something the same size anyways, so thats forbidden +in the direct-editing mode. It makes no difference to +the normal operation. + +The default sizes for new fields are taken from the defaults +table, which again is completely compatible. The only +difference is that the zeros are stored as well, and hence +cannot be defined just by the default string, but need an editor +that specifies the sizes. + 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef BUFFERH +#define BUFFERH + +#include +#include + +inline void LoadBuffer(mstring& buffer,const mstring& path) + throw(merror_t) +{ + if(buffer.load(path.c_str())<0) THROW("file: Could not load "< +using namespace std; + +const mstring compat="(compatibility)"; +const int zkey=0; + +OP2_IMPL(lti) {out<<(atoi(L)=atoi(R));} +OP2_IMPL(gti) {out<<(atoi(L)>atoi(R));} + +void dbmap::setup() +{ + MLOCK(mutex); + if(M.empty()) { + opAddComp(M); + OP_ADDN(20,lti,lt.int,compat); + OP_ADDN(20,lei,le.int,compat); + OP_ADDN(20,gei,ge.int,compat); + OP_ADDN(20,gti,gt.int,compat); + + M.add(new op_t("lt.case",20,M.get(sref("lt"))->f2,compat)); + M.add(new op_t("gt.case",20,M.get(sref("gt"))->f2,compat)); + M.add(new op_t("lt.nocase",20,M.get(sref("ltn"))->f2,compat)); + M.add(new op_t("gt.nocase",20,M.get(sref("gtn"))->f2,compat)); + } +} + +const op_t* dbmap::CompOperator(const sref& s) +{ + if(M.empty()) setup(); + const op_t* p=M.get(s); + if(!p) THROW("dbmap: could not find operator "<head()->setcomp(index,compname); + remap_tabs(); + } +} + 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +using namespace std; + +const mstring HEAD10="HTC DB File Format version 1.0\n"; +const mstring HEAD11="HDB/1.1"; + +static fp_stream merr(stderr); + +static void Read(FILE* fp,mstring& s,int version) { + int n; fread(&n,4,1,fp); + switch(version) { + case 10: + s.resize(n); + fread(s.data(),1,n,fp); + break; + case 11: + s.resize(n-1); + fread(s.data(),1,n,fp); + s.resize(strlen(s.data())); + if(s.size()>=n) THROW("dbmap: assertion failed on dimension"); + break; + default: + THROW("read: bad HDB version"); + break; + } +} + +void Convert(dbmap& db,const char* path) +{ + FILE* fp=fopen(path,"rb"); + char line[1024]; + fgets(line,1000,fp); + int version=0; + if(sref(line)==HEAD10) { fgetc(fp); version=10; } + else if(First(sref(line))==HEAD11) { version=11; } + if(version==0) THROW("hdbcvt: unknown HDB format"); + int tables; + mstring s; + fread(&tables,4,1,fp); + for(int i=0;i +#include + +filemap* dbmap::flist; +mutex_t dbmap::mutex; +opmap dbmap::M; + +/////////////////////////////////////////////////////////////////////// + +dbmap::dbmap(): + wok(0),fatal(0),index(0), + compname(),file(0),tmap(),recs() +{ + minor=0; + major=0; +} + +dbmap::~dbmap() +{ + Close(); +} + +/////////////////////////////////////////////////////////////////////// + +void dbmap::remap_tabs() +{ + fatal=head()->fatal.get(); + tmap.clear(); + for(int i=0;itabs[i]),i); +} + +void dbmap::remap_recs() +{ + major=head()->major.get(); + recs.clear(); + int p=file->recs(); + while(file->size(p)) { + record_t* rec=(record_t*)file->at(p); + if(rec->caps.get()) + recs.push_back(idx_t(rec->at(index),rec)); + p+=rec->mem.get(); + } + recs.sort(CompOperator(compname)); +} + +int dbmap::remap() +{ + int state=0; + if(fatal!=head()->fatal.get()) { remap_tabs(); state|=4; } + if(major!=head()->major.get()) { remap_recs(); state|=2; } + if(minor!=head()->minor.get()) { minor=head()->minor.get(); state|=1; } + return state; +} + +/////////////////////////////////////////////////////////////////////// + +void Open(const mstring& path,int update=0,int prot=0600) throw(merror_t); +void Saveas(const mstring& path,int prot=0600) throw(merror_t); +void Close(); + +void dbmap::Open(const mstring& path,int update,int prot) throw(merror_t) +{ + Close(); + wok=update?1:0; + { + MLOCK(mutex); + for(filemap* p=flist;p;p=p->next) + if(p->Pathname()==path&&p->writable()==wok) { (file=p)->pushref(); break; } + if(!file) { + filemap* fm=new filemap(flist); + try { fm->open(path,wok,prot); fm->check(); file=flist=fm; } + catch(...) { delete fm; wok=0; throw; } + } + } + index=head()->index.get(); + compname=head()->compname; + remap_tabs(); + remap_recs(); + minor=head()->minor.get(); +} + +void dbmap::Saveas(const mstring& path,int prot) throw(merror_t) +{ + file->save(path,prot); +} + +void dbmap::Close() +{ + wok=0; + minor=0; + major=0; + fatal=0; + index=0; + compname.clear(); + recs.clear(); + tmap.clear(); + if(file) { + MLOCK(mutex); + if(file->reference()) file->popref(); + else { + if(flist==file) flist=file->next; + else for(filemap* p=flist;p;p=p->next) + if(p->next==file) { p->next=file->next; break; } + delete file; + } + file=0; + } +} + +void dbmap::Sync() +{ + MLOCK(mutex); + for(filemap* p=flist;p;p=p->next) { + if(p->writable()) p->sync(); + } +} + +/////////////////////////////////////////////////////////////////////// + +void dbmap::SetTable(int col,const sref& name) throw(merror_t) +{ + check(); + if(!wok) THROW("db: cannot set table - readonly"); + if(col<0||col>=Tables()) THROW("db: bad column"); + HEADLOCK(file); + head()->set(col,name); + remap(); +} + +void dbmap::InsertTable(int col,const sref& name) throw(merror_t) +{ + check(); + if(!wok) THROW("db: cannot insert table - readonly"); + if(Tables()+1>file->maxtabs) THROW("db: too many tables"); + if(col<0||col>Tables()) THROW("db: bad column"); + { + HEADLOCK(file); + head()->insert(col,name); + int p=file->recs(); + while(file->size(p)) { + record_t* rec=(record_t*)file->at(p); + if(rec->caps.get()) rec->insert(col); + p+=rec->mem.get(); + } + head()->major.add(1); + } + index=head()->index.get(); + compname=head()->compname; + remap(); +} + +void dbmap::RemTable(int col) throw(merror_t) +{ + check(); + if(!wok) THROW("db: cannot remove table - readonly"); + if(col<0||col>=Tables()) THROW("db: bad column"); + if(col==head()->index.get()) THROW("db: cannot remove index table"); + { + HEADLOCK(file); + head()->remove(col); + int p=file->recs(); + while(file->size(p)) { + record_t* rec=(record_t*)file->at(p); + if(rec->caps.get()) rec->remove(col); + p+=rec->mem.get(); + } + head()->major.add(1); + } + index=head()->index.get(); + compname=head()->compname; + remap(); +} + +/////////////////////////////////////////////////////////////////////// + +void dbmap::Get(int row,spile& list) throw(merror_t) +{ + check(); + if(row<0||row>=recs.size()) THROW("db: not a valid record"); + list.resize(Tables()); + recs[row].rec->get(list); +} + +void dbmap::Set(int row,int col,const sref& s) throw(merror_t) +{ + check(); + if(!wok) THROW("db: cannot set - readonly"); + if(row<0||row>=recs.size()) THROW("db: not a valid record"); + if(col==index) THROW("db: cannot set index"); + HEADLOCK(file); + record_t* rec=recs[row].rec; + int dim=rec->setreq(col,s); + if(dim>rec->caps.get()) { + rec=new(file->add(dim)) record_t(*rec); + file->rem(recs[row].rec); + recs[row].rec=rec; + head()->major.add(1); + major++; + } + rec->set(col,s); + head()->minor.add(1); + minor++; +} + +void dbmap::Set(int row,const spile& list) throw(merror_t) +{ + check(); + if(!wok) THROW("db: cannot set - readonly"); + if(row<0||row>=recs.size()) THROW("db: not a valid record"); + if(list.size()!=Tables()) + THROW("db: wrong number of tables - "<at(index)!=list[index]) THROW("db: cannot set index"); + int dim=record_t::req(list); + if(dim>rec->caps.get()) { + rec=new(file->add(dim)) record_t(*rec); + file->rem(recs[row].rec); + recs[row].rec=rec; + head()->major.add(1); + major++; + } + rec->set(list); + head()->minor.add(1); + minor++; +} + +/////////////////////////////////////////////////////////////////////// + +void dbmap::Rem(int row) throw(merror_t) +{ + if(!wok) THROW("db: cannot delete - readonly"); + if(row<0||row>=recs.size()) THROW("db: not a valid record"); + HEADLOCK(file); + file->rem(recs[row].rec); + recs.erase(recs.begin()+row); + head()->major.add(1); + major++; +} + +int dbmap::Insert(const spile& list,int unique) throw(merror_t) +{ + check(); + if(!wok) THROW("db: cannot insert - readonly"); + if(index!=head()->index.get()) + THROW("db: can only insert under normal order"); + HEADLOCK(file); + remap(); + int row=recs.get(list[index]); + if(row<0) { + record_t* rec=new(file->add(record_t::req(list))) record_t(list); + row=recs.add(rec->at(index),rec); + head()->major.add(1); + major++; + } + return row; +} 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef DBH +#define DBH + +#include +#include + +//////////////////////////////////////////////////// +// +// OK for MT and MP +// + +class dbmap { +public: + dbmap(); + ~dbmap(); + + filemap::head_t* head() { return file->head(); } + const filemap::head_t* head() const { return file->head(); } + + int remap(); + + int size() const { return recs.size(); } + int empty() const { return recs.empty(); } + + const sref operator()(int row,int col) const throw(merror_t) { + check(); return recs[row].rec->at(col); + } + const sref at(int row,int col) const throw(merror_t) { + check(); return recs[row].rec->at(col); + } + + /////////////////////////////////////////////////////// + + void Get(int row,spile& list) throw(merror_t); + void Set(int row,int col,const sref& s) throw(merror_t); + void Set(int row,const spile& list) throw(merror_t); + + /////////////////////////////////////////////////////// + + void Rem(int row) throw(merror_t); + int Insert(const spile& list,int unique) throw(merror_t); + + /////////////////////////////////////////////////////// + + int Tables() const { return head()->tables.get(); } + const sref Table(int col) const { check(); return head()->get(col); } + + /////////////////////////////////////////////////////// + + void SetTable(int col,const sref& name) throw(merror_t); + void RemTable(int col) throw(merror_t); + void InsertTable(int col,const sref& name) throw(merror_t); + + /////////////////////////////////////////////////////// + + int Index() const { return index; } + int FindIndex(const sref& tab) const { return tmap.get(tab); } + int Index(const sref& tab) const throw(merror_t) { + int p=FindIndex(tab); + if(p<0) THROW("db: table ["<Lastmod(); } + void Close(); + + static void Sync(); + +protected: + dbmap(const dbmap& db) {} + void operator=(const dbmap& db) {} + + void check() const { + if(fatal!=head()->fatal.get()) THROW("db: fatal state change") + } + + void remap_recs(); + void remap_tabs(); + + static void setup(); + static const op_t* CompOperator(const sref& s); + + static filemap* flist; + static mutex_t mutex; + static opmap M; +private: + int wok,minor,major,fatal,index; + mstring compname; + filemap* file; + rimap tmap; + indexmap recs; +}; + +void Convert(dbmap& db,const char* path); + +#endif + 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +using namespace std; + +const int PAGESIZE=getpagesize(); +const filemap::char32 HEADNAME="HDB/1.2\n"; +const filemap::char32 COMPNAME="lt"; +const mstring dev_tag="/dev/"; + +const int TIMEOUT=20; + +/////////////////////////////////////////////////// + +filemap::head_t::head_t() +{ + memcpy(ident,HEADNAME,sizeof(char32)); + lock.set(0); + minor.set(0); + major.set(0); + fatal.set(0); + filesize.set(PAGESIZE); + filetop.set(sizeof(head_t)); + tables.set(0); + index.set(0); + memcpy(compname,COMPNAME,sizeof(char32)); + memset(tabs,0,maxtabs*sizeof(char32)); + frame.set(sizeof(head_t)); +} + +filemap::head_t::head_t(const head_t* hd,int mem) +{ + memcpy(ident,HEADNAME,sizeof(char32)); + lock.set(0); + minor.set(0); + major.set(0); + fatal.set(0); + filetop.set(sizeof(head_t)+mem); + filesize.set(PAGESIZE*int((filetop.get()+PAGESIZE)/PAGESIZE)); + tables=hd->tables; + index=hd->index; + memcpy(compname,hd->compname,sizeof(char32)); + memset(tabs,0,maxtabs*sizeof(char32)); + for(int i=0;itabs[i],sizeof(char32)); + frame.set(sizeof(head_t)); +} + +void filemap::head_t::setcomp(int idx,const sref& s) +{ + index.set(idx); + s.copyto(compname,sizeof(char32)); + fatal.add(1); +} + +void filemap::head_t::set(int col,const sref& s) +{ + s.copyto(tabs[col],sizeof(char32)); + fatal.add(1); +} + +void filemap::head_t::insert(int col,const sref& s) +{ + for(int i=maxtabs-1;i>col;i--) + memcpy(tabs[i],tabs[i-1],sizeof(char32)); + if(index.get()>=col&&index.get()col) index.set(index.get()-1); + tables.add(-1); + fatal.add(1); + } +} + +/////////////////////////////////////////////////////// + +filemap::chunk_t::chunk_t(chunk_t* p,int fd,int wok,int off,int size) +{ + next=p; + end=(begin=off)+size; + map=(char*)mmap(0,size,PROT_READ|(wok?PROT_WRITE:0),MAP_SHARED,fd,off); + if(map==MAP_FAILED) { map=0; THROW("filemap: could not map chunk") } +} + +filemap::chunk_t::~chunk_t() +{ + if(map) munmap(map,end-begin); +} + +int filemap::chunk_t::fill(int off) +{ + if(own(off)) { + at(off)->mem.set(end-off); + at(off)->caps.set(0); + return end; + } + else return off; +} + +void filemap::chunk_t::sync() +{ + msync(map,end-begin,MS_SYNC); +} + +/////////////////////////////////////////////////////// + +void filemap::remap() +{ + while(mem->endfilesize.get()) { + mem=new chunk_t(mem,fd,wok,mem->end,mem->size()<<1); + } +} + +filemap::rec_t* filemap::add(int n) +{ + int caps=sizeof(rec_t),dim=caps+n; + while(capsfilesize.get()end) { + ftruncate(fd,mem->end); + hd->filesize.set(mem->end); + } + while(hd->filetop.get()+caps>mem->end) { + hd->filetop.set(mem->fill(hd->filetop.get())); + mem=new chunk_t(mem,fd,wok,mem->end,mem->size()<<1); + ftruncate(fd,mem->end); + hd->filesize.set(mem->end); + } + rec_t* rec=at(hd->filetop.get()); + hd->filetop.add(caps); + rec->mem.set(caps); + rec->caps.set(n); + return rec; +} + +void filemap::rem(rec_t* rec) +{ + rec->caps.set(0); +} + +/////////////////////////////////////////////////////// + +filemap::filemap(filemap* p): + next(p),fd(-1),wok(0),refs(0),pathname(),hd(0),mem(0),nodelock(0) +{ + memset(&mutex,0,sizeof(mutex_t)); +} + +filemap::filemap(filemap* p,const mstring& path,int update,int prot): + next(p),fd(-1),wok(0),refs(0),pathname(),hd(0),mem(0),nodelock(0) +{ + memset(&mutex,0,sizeof(mutex_t)); + open(path,update,prot); +} + +filemap::~filemap() +{ + close(); +} + +/////////////////////////////////////////////////////// + +void filemap::open(const mstring& path,int update,int prot) throw(merror_t) +{ + close(); + if(update) { + if(path.left(5)!=dev_tag) nodelock=new nodelock_t(path); + else nodelock=0; + wok=1; + } + else { + nodelock=0; + wok=0; + } + fd=::open(path.c_str(),wok?O_RDWR|O_CREAT:O_RDONLY,prot); + if(fd<0) THROW("filemap: could not open "<map; + if(fsizeident))!=First(sref(HEADNAME))) THROW("filemap: bad version"); + remap(); + if(fsize!=hd->filesize.get()) + THROW("filemap: "<filetop.get(); + while(size(p)) { + rec_t* rec=at(p); + p+=rec->mem.get(); + } + if(pft. +} + +void filemap::save(const mstring& path,int prot) throw(merror_t) +{ + if(path==pathname) THROW("filemap: cannot overwrite current file"); + int mfd=::open(path.c_str(),O_RDWR|O_CREAT|O_TRUNC,prot); + if(mfd<0) THROW("filemap: could not open "<caps.get()) caps+=rec->mem.get(); + p+=rec->mem.get(); + } + head_t mhd(hd,caps); + ::write(mfd,&mhd,sizeof(head_t)); + p=recs(); + while(size(p)) { + rec_t* rec=at(p); + if(rec->caps.get()) ::write(mfd,rec,rec->mem.get()); + p+=rec->mem.get(); + } + ftruncate(mfd,mhd.filesize.get()); + ::close(mfd); +} + +void filemap::close() +{ + while(mem) { chunk_t* p=mem->next; delete mem; mem=p; } + hd=0; + wok=0; + refs=0; + if(fd>=0) { ::close(fd); fd=-1; } + delete nodelock; nodelock=0; + pathname.clear(); +} + +void filemap::sync() +{ + for(chunk_t* p=mem;p;p=p->next) p->sync(); +} + +/////////////////////////////////////////////////////// + +void filemap::lock() +{ + if(hd) { + MLOCK(mutex); + if((volatile long&)hd->lock) { + time_t end=time(0)+TIMEOUT; + while((volatile long&)hd->lock&&time(0)lock.set(1); + } +} + +void filemap::unlock() +{ + if(hd) hd->lock.set(0); +} + +/////////////////////////////////////////////////////// + +time_t filemap::Lastmod() const +{ + struct stat fs; fstat(fd,&fs); return fs.st_mtime; +} + 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef FILEMAPH +#define FILEMAPH + +#include +#include +#include +#include +#include + +////////////////////////////////////////////// +// +// NOTE that filemap is MT unsafe: +// it needs to be called from dbmap +// +// The exception is when filelocking; +// that's MT safe per filemap, and hence +// should not be locked further +// + +#define HEADLOCK(fm) headlock_t headlock(fm) + +////////////////////////////////////////////////////// + +// network byteorder +class byte4 { +public: + byte4() {} // must be uninitialized + explicit byte4(int h): n(htonl(h)) {} + void set(int h) { n=htonl(h); } + void add(int h) { n=htonl(ntohl(n)+h); } + int get() const { return ntohl(n); } +private: + long n; +}; + +////////////////////////////////////////////////////// + +class filemap { +public: + typedef char char32[32]; + static const int maxtabs=32; + + //////////////////////////////////////////////////// + + struct head_t { + char32 ident; + byte4 lock; + byte4 minor; + byte4 major; + byte4 fatal; + byte4 filesize; + byte4 filetop; + byte4 tables; + byte4 index; + char32 compname; + char32 tabs[maxtabs]; + byte4 frame; + + head_t(); + head_t(const head_t* hd,int mem); + + void setcomp(int idx, const sref& cp); + + sref get(int col) const { return sref(tabs[col]); } + void set(int col,const sref& s); + void insert(int col,const sref& s); + void remove(int col); + }; + + head_t* head() { return hd; } + const head_t* head() const { return hd; } + + /////////////////////////////////////////////////////// + + struct rec_t { + byte4 mem; + byte4 caps; + }; + + rec_t* at(int off) { + for(chunk_t* p=mem;p;p=p->next) if(p->own(off)) return p->at(off); return 0; + } + const rec_t* at(int off) const { + for(const chunk_t* p=mem;p;p=p->next) if(p->own(off)) return p->at(off); + return 0; + } + + int recs() const { return hd->frame.get(); } + int size(int off) const { + if(offfiletop.get()) { + for(const chunk_t* p=mem;p;p=p->next) + if(p->own(off)) return p->at(off)->mem.get(); + } + return 0; + } + + /////////////////////////////////////////////////////// + + void remap(); + + rec_t* add(int n); + void rem(rec_t* rec); + + /////////////////////////////////////////////////////// + + filemap(filemap* p); + filemap(filemap* p,const mstring& path,int update=0,int prot=0600); + ~filemap(); + + filemap* next; + + /////////////////////////////////////////////////////// + + void open(const mstring& path,int update=0,int prot=0600) throw(merror_t); + void save(const mstring& path,int prot=0600) throw(merror_t); + void check() throw(merror_t); + void close(); + void sync(); + + const mstring& Pathname() const { return pathname; } + time_t Lastmod() const; + + int reference() const { return refs; } + int writable() const { return wok; } + + void pushref() { refs++; } + void popref() { refs--; } + + /////////////////////////////////////////////////////// + + void lock(); + void unlock(); + + /////////////////////////////////////////////////////// + +protected: + struct chunk_t { + chunk_t* next; + long begin; + long end; + char* map; + + int size() const { return end-begin; } + + chunk_t(chunk_t* p,int fd,int wok,int off,int size); + ~chunk_t(); + + int own(int off) const { return off>=begin&&offlock(); } + ~headlock_t() { if(fm) fm->unlock(); } +}; + +#endif + 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +static fp_stream mout(stdout),merr(stderr); + +main(int argc,char* argv[]) throw(merror_t) try +{ + if(argc<2) { + merr<<"Usage: "< [ ]\n"; + return -1; + } + mstring newfile=argv[1]; + mstring oldfile=newfile+sref(".bak"); + rename(newfile.c_str(),oldfile.c_str()); + dbmap db; + try { + db.Open(oldfile); + if(argc>3) db.Sort(sref(argv[2]),sref(argv[3])); + db.Saveas(newfile); + } + catch(const merror_t& e) { + merr<<"Opened as newfile, old version\n"; + db.Open(newfile,1); + Convert(db,oldfile.c_str()); + } + return 0; +} +catch(const merror_t& e) { + merr< + +static fp_stream mout(stdout),merr(stderr); + +main(int argc,char* argv[]) try +{ + if(argc<2) { + mout<<"Usage: "<\n"; + return -1; + } + mstring path; int silent; + if(argc>2) { silent=1; path=argv[2]; } + else { silent=0; path=argv[1]; } + mstring map; if(map.load(path)<0) THROW("hdbfix: could not open "<mem.get()<=0) { + if(!silent&&rec->mem.get()<0) + mout<<"ending mem: "<mem.get()<<"\n"; + break; + } + last=top; + top+=rec->mem.get(); + } + if(top==head.filetop.get()&&head.filesize.get()==map.size()) { + if(!silent) mout<=last;p-=4){ + int val=ntohl(*(long*)(map.data()+p)); + if(p+val==end) { nend++; end=p; } + } + int gap=end-top; + + mout<<"GAP DATA\n"; + mout<<"==============================\n"; + for(int i=top;i0) { + mout<<"Do you want to mark the gap as deleted?\n"; + getline(answer,stdin); answer.tolower(); + if(*answer=='y') { + filemap::rec_t* rec=(filemap::rec_t*)(map.data()+top); + rec->mem.set(gap); + rec->caps.set(0); + save=1; + mout<<"Done.\n"; + } + else { + mout<<"No change - quitting.\n"; + return 0; + } + } + } + } + + if(save) map.save(path); + + return 0; +} +catch(const merror_t& e) { + merr< + +static fp_stream mout(stdout),merr(stderr); + +main(int argc,char* argv[]) try +{ + if(argc<2) { + mout<<"Usage: "<\n"; + return -1; + } + mstring path; int silent; + if(argc>2) { silent=atoi(argv[1]); path=argv[2]; } + else { silent=0; path=argv[1]; } + mstring map; if(map.load(path)<0) THROW("hdbfix: could not open "<mem.get()<=0) break; + if(silent) { + if(silent==top) { + mout<mem.get(); + } + if(top==head.filetop.get()&&head.filesize.get()==map.size()) { + if(!silent) mout<=last;p-=4){ + unsigned val=*(unsigned*)(map.data()+p); + if(p+val==end) { nend++; end=p; } + } + int gap=end-top; + + mout<<"GAP DATA\n"; + mout<<"==============================\n"; + for(int i=top;i0) { + mout<<"Do you want to mark the gap as deleted?\n"; + getline(answer,stdin); answer.tolower(); + if(*answer=='y') { + filemap::rec_t* rec=(filemap::rec_t*)(map.data()+top); + rec->mem.set(gap); + rec->caps.set(0); + save=1; + mout<<"Done.\n"; + } + else { + mout<<"No change - quitting.\n"; + return 0; + } + } + } + } + + if(save) map.save(path); + + return 0; +} +catch(const merror_t& e) { + merr< +#include +using namespace std; + +int int_stream::appc(char c) { return val=c,1; } +int int_stream::appi(int i) { return val=i,1; } +int int_stream::appf(double f) { return val=(int)f,1; } +int int_stream::apps(const sref& s) { return val=atoi(s),s.size(); } + +/////////////////////////////////////////////////// + +record_t::record_t(const spile& list) +{ + pos[0].set(0); + for(int i=0;i p=equal_range(begin(),end(),idx_t(t,0),comp); + return p.first!=p.second?p.first-begin():-1; +} + +int indexmap::add(const sref& t,record_t* rec) +{ + idx_t tmp(t,rec); + pair p=equal_range(begin(),end(),tmp,comp); + if(p.first!=p.second) return &(*p.first=tmp)-begin(); + else return insert(p.second,tmp)-begin(); +} + +void indexmap::sort(const op_t* op) +{ + comp.func=op->f2; + ::sort(begin(),end(),comp); +} 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef SORTABLEH +#define SORTABLEH + +#include +#include +#include + +//////////////////////////////////////////////////// +// +// NOTE that these classes are not MT safe: +// need to be called from dbamp +// + +struct record_t : public filemap::rec_t { + static const int maxtabs=filemap::maxtabs; + static const int recsize=(maxtabs+1)*sizeof(long); + + byte4 pos[maxtabs+1]; + char data[sizeof(byte4)]; + + int size() const { return pos[maxtabs].get()-pos[0].get(); } + int size(int i) const { return pos[i+1].get()-pos[i].get(); } + + sref at(int i) const { return sref(data+pos[i].get(),size(i)); } + + ///////////////////////////////////////////////// + + record_t(const record_t& rec) { + for(int i=0;i<=maxtabs;i++) pos[i]=rec.pos[i]; + memcpy(data,rec.data,rec.caps.get()); + } + record_t(const spile& list); + + ///////////////////////////////////////////////// + + void get(spile& list) const { + for(int i=0;icol;i--) pos[i]=pos[i-1]; + } + void remove(int col) { + resize(col,0); + for(int i=col;i { +public: + typedef mrvec::iterator iterator; + typedef mrvec::const_iterator const_iterator; + + struct comp_t { + op_t::op2_t func; + comp_t() : func(0) {} + comp_t(const op_t* op) : func(op->f2) {} + bool operator()(const idx_t& a,const idx_t& b) const { + int_stream res; + op_env env; + func(res,env,a.key,b.key); + return res.val; + } + }; + + int get(const sref& t) const; + int add(const sref& t,record_t* rec); + void sort(const op_t* op); +private: + comp_t comp; +}; + +#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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +static fp_stream merr(stderr); + +main(int argc,char* argv[]) throw(merror_t) try +{ + if(argc<2) { + merr<<"Usage: "<\n"; + return -1; + } + dbmap m; + m.Open(argv[1]); + + merr<filesize.get()<<"\n"; + merr<filetop.get()<<"\n"; + merr<frame.get()<<"\n"; + + for(int j=0;j +#include +#include +#include + +const mstring end_tag="~"; + +Editor::Line::Line() +{ + line=(char*)malloc(MAXCOLS); + line[0]=0; + dim=1; +} +Editor::Line::Line(char* p,int s) +{ + line=(char*)malloc(MAXCOLS); + memcpy(line,p,s); + dim=s; +} +Editor::Line::~Line() +{ + delete line; +} +int Editor::Line::Insert(int pos,char c) +{ + if(pos>=dim) pos=dim-1; + if(dimdim<=MAXCOLS) { + memcpy(line+dim-1,p->line,p->dim); + dim+=p->dim-1; + return 1; + } + else return 0; +} +Editor::Line* Editor::Line::Break(int pos) +{ + if(pos>=dim) pos=dim-1; + Line* p=new Line(line+pos,dim-pos); + line[pos]=0; + dim=pos+1; + return p; +} +void Editor::Line::Delete(int pos) +{ + if(dim-1>pos) { + memmove(line+pos,line+pos+1,dim-pos-1); + dim--; + } +} + +///////////////////////////////////////////////////////////////////////// + +Editor::Editor(const mstring& s,int ex) : + path(s), + from(0),lines(Lines()),atline(0),size(0), + tab(0),cols(Columns()),atcol(0),exclusive(ex) +{ + memset(map,0,sizeof(Line*)*MAXLINES); + map[0]=new Line(); + size=1; + caption=path; + caption+=sref(" ok (ESC to go back)"); + if(!exclusive) caption+=sref(" (readonly)"); +} +Editor::~Editor() +{ + for(int i=0;idim) { + if(i==size-1) { + if(tabdim-1) + OutputField(i-from,0,cols,sref(map[i]->line+tab,map[i]->dim-tab-1)); + OutputField(i-from,map[i]->dim-tab-1,1,end_tag); + } + else { + OutputField(i-from,0,cols,sref(map[i]->line+tab,map[i]->dim-tab)); + } + } + } + Reverse(1); + OutputField(lines,0,cols,caption); + Reverse(0); + MoveCursor(atline-from,atcol-tab); + Refresh(); +} + +void Editor::Move(int i,int j) +{ + atline+=i; + atcol+=j; + if(atline<0) atline=0; else if(atline>=size) atline=size-1; + if(atline=from+lines) from=atline+1-lines; + if(atcol<0) atcol=0; else if(atcol>=map[atline]->dim) atcol=map[atline]->dim-1; + if(atcol=tab+cols) tab=atcol+1-cols; +} + +void Editor::Home() +{ + atline=from=atcol=tab=0; +} + +void Editor::Navigate() +{ + int c; + while(1) { + Show(); + switch(c=Input()) { + case KK_UP: + case 16: + Move(-1,0); + break; + case KK_DOWN: + case 14: + Move(1,0); + break; + case KK_LEFT: + case 2: + Move(0,-1); break; + case KK_RIGHT: + case 6: + Move(0,1); + break; + case KK_NPAGE: + Move(lines/2,0); + break; + case KK_PPAGE: + Move(-lines/2,0); + break; + case KK_HOME: + case 1: + Move(0,-map[atline]->dim); + break; + case KK_END: + case 5: + Move(0,map[atline]->dim); + break; + case 127: + case 4: + if(exclusive) Delete(); + break; + case 8: + if(exclusive) Backspace(); + break; + case 13: + if(exclusive) BreakLine(); + break; + case KK_F(1): + if(exclusive) Insert('å'); + break; + case KK_F(2): + if(exclusive) Insert('ä'); + break; + case KK_F(3): + if(exclusive) Insert('ö'); + break; + case 9: + if(exclusive) Insert('\t'); + break; + default: + if(exclusive) if(c>=32&&c<127) Insert(c); + break; + case 27: + return; + } + } +} + +void Editor::Insert(int c) +{ + if(map[atline]->Insert(atcol,c)) Move(0,1); +} + +void Editor::BreakLine() +{ + if(sizeBreak(atcol); + memmove(map+atline+2,map+atline+1,sizeof(Line*)*(size-atline-1)); + map[atline+1]=p; + size++; + Move(1,-atcol); + } +} + +void Editor::Delete() +{ + if(map[atline]->dim-1>atcol) { + map[atline]->Delete(atcol); + } + else if(size-1>atline) { + delete map[atline]; + memmove(map+atline,map+atline+1,sizeof(Line*)*(size-atline-1)); + size--; + } +} + +void Editor::Backspace() +{ + if(atcol>0) { + Move(0,-1); + map[atline]->Delete(atcol); + } + else if(atline>0) { + int pos=map[atline-1]->dim-1; + if(map[atline-1]->Append(map[atline])) { + delete map[atline]; + memmove(map+atline,map+atline+1,sizeof(Line*)*(size-atline-1)); + size--; + Move(-1,pos-atcol); + } + } +} + +void Editor::Paste(const mstring& s) +{ + for(int i=0;iline,map[i]->dim-1); + if(i + +struct Editor { + static const int MAXLINES=1024; + static const int MAXCOLS=256; + struct Line { + Line(); + Line(char* p,int s); + ~Line(); + int Insert(int pos,char c); + int Append(const Line* p); + Line* Break(int pos); + void Delete(int pos); + char* line; + int dim; + }; + + Editor(const mstring& path,int ex); + ~Editor(); + + void Copy(mstring& s); + void Paste(const mstring& s); + + void Show(); + void Home(); + void Move(int i,int j); + void Navigate(); + void Insert(int c); + void BreakLine(); + void Delete(); + void Backspace(); + + mstring path,caption; + Line* map[MAXLINES]; + int from,lines,atline,size; + int tab,cols,atcol,exclusive; +}; + +#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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "tables.h" +#include "input.h" +#include + +static fp_stream merr(stderr); + +main(int argc,char* argv[]) +{ + if(argc<2) { + merr<<"Usage: "< [exclusive]\n"; + return -1; + } + char* path=argv[1]; + int excl=argc>2?atoi(argv[2]):0; + mstring err; + sleep(1); + InitCurses(); + Tables tab; + try { + tab.Open(path,excl); + tab.Setup(20); + tab.Navigate(); + } + catch(const merror_t& e) { + err=e.desc; + } + catch(...) { + err="hdb: Unexpected error"; + } + tab.Close(); + EndCurses(); + if(err.nempty()) { + merr< +#include +#include +#include +#include + +int Lines() { return LINES-1; } +int Columns() { return COLS-1; } + +void ClearScreen() { erase(); } +void MoveCursor(int i,int j) { move(i,j); } + +void InitCurses() +{ + initscr(); + nodelay(stdscr,1); + raw(); + noecho(); + nonl(); + keypad(stdscr,1); + intrflush(stdscr,FALSE); +} + +void EndCurses() +{ + endwin(); +} + +void OutputField(int row,int col,int field,const sref& in) +{ + mstring tmp=in.left_first_of(cset_newl); + int cut=tmp.size()!=in.size(); + if(tmp.size()field) { tmp.resize(field-1); tmp.append(1,'\\'); } + mvaddstr(row,col,(char*)tmp.c_str()); +} + +void Reverse(int n) +{ + if(n) attron(A_REVERSE); else attroff(A_REVERSE); +} +void Bold(int n) +{ + if(n) attron(A_BOLD); else attroff(A_BOLD); +} + +void Refresh() +{ + refresh(); +} + +int RawInput() { + int c=getch(); + if(c>0) return c; + struct pollfd ps={fileno(stdin),POLLIN,0}; + poll(&ps,1,1000); + return getch(); +} + +int Input() { + int c=RawInput(); +#if 0 + if(c==27) { + napms(1); + int c2=getch(); + if(c2!=-1) { + switch(c2) { + default: return 0; + case 91: + switch(RawInput()) { + default: return 0; + case '2': + RawInput(); + switch(RawInput()) { + default: return 0; + case 52: return RawInput()==122?KEY_HOME:0; + case 54: return RawInput()==122?KEY_PPAGE:0; + case 48: return RawInput()==122?KEY_END:0; + case 50: return RawInput()==122?KEY_NPAGE:0; + } + } + } + } + } +#endif + return c; +} + 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#ifndef INPUTH +#define INPUTH + +#define KK_DOWN 0402 +#define KK_UP 0403 +#define KK_LEFT 0404 +#define KK_RIGHT 0405 +#define KK_HOME 0406 +#define KK_F0 0410 +#define KK_F(n) (KK_F0+(n)) +#define KK_NPAGE 0522 +#define KK_PPAGE 0523 +#define KK_END 0550 + +int Input(); +int RawInput(); + +int Lines(); +int Columns(); + +void ClearScreen(); +void MoveCursor(int i,int j); +void OutputField(int row,int col,int field,const sref& p); +void Reverse(int n); +void Bold(int n); +void Refresh(); + +void InitCurses(); +void EndCurses(); + +#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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "tables.h" +#include "input.h" +#include +#include +#include + +const mstring star_tag="*"; + +const int PAD=2; +const mstring HELP= +"Commands from record page:\n" +"\n" +"DEL - Delete record\n" +"RET - Edit record\n" +"n - New record\n" +"s - Sort by table\n" +"o - Order by table\n" +"c - Check for duplicates\n" +"f - Filename for map\n" +"r - Remove table\n" +"a - Add table\n"; + +Tables::Tables() : + from(0),lines(Lines()-1),atline(0),writable(0), + tab(0),space(10),cols(Columns()),atcol(0), + lastfrom(-1),lasttab(-1),lastline(0),lastcol(0) +{ + dispcols=cols/space; +} + +Tables::~Tables() +{ +} + +void Tables::Setup(int sp) +{ + space=sp; + dispcols=cols/space; + Home(); +} + +void Tables::Show() +{ + if(db.remap()) { + lastfrom=-1; + caption.convert("%d, %d, %d, %d", + db.head()->filesize.get(), + db.head()->fatal.get(), + db.head()->major.get(), + db.head()->minor.get()); + } + if(from!=lastfrom||tab!=lasttab) { + ClearScreen(); + Bold(1); + for(int j=tab;j=0&&i<=db.size()&&j>=0&&j<=db.Tables()) { + sref tmp; if(i=0&&i<=db.size()&&j>=0&&j<=db.Tables()) { + sref tmp; if(i=db.size()) atline=db.size(); + if(atline<0) atline=0; + if(atline>=from+lines) from=atline+1-lines; + if(atline=db.Tables()) atcol=db.Tables(); + if(atcol<0) atcol=0; + if(atcol>=tab+dispcols) tab=atcol+1-dispcols; + if(atcol=0) { + caption.convert("%s - added record",path.c_str()); + Move(row-atline,0); + } + else { + caption.convert("%s - record nonunique - not added",path.c_str()); + Move(0,0); + } + } + catch(const merror_t& e) { + caption=e.desc; + Move(0,0); + } + lastfrom=-1; +} + +void Tables::Delete() +{ + if(db.remap()) lastfrom=-1; + if(atline +#include + +struct Tables { + Tables(); + ~Tables(); + + void Open(const mstring& path,int ex=0); + void Save(); + void Close(); + + void Setup(int sp); + + void Show(); + void Home(); + void Move(int i,int j); + void Navigate(); + int Command(); + + void Sort(); + void Order(); + void Check(); + + void Edit(); + void Insert(); + void Delete(); + void FileName(); + void AddTable(); + void RemTable(); + void Help(); + + dbmap db; + mstring path,caption; + int from,lines,atline,writable; + int tab,space,cols,dispcols,dim,atcol; + int lastfrom,lasttab,lastline,lastcol; +}; + +#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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "input.h" +#include + +main(int argc,char* argv[]) +{ + InitCurses(); + while(1) { + int c=RawInput(); + fprintf(stderr,"%d\r\n",c); + if(c==27) break; + } + EndCurses(); + return 0; +} 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef HTTPH +#define HTTPH + +#include + +/////////////////////////////////////////////////////////////////// + +const mstring http_mime_default="application/octet-stream"; + +const mstring HTTP_V10="HTTP/1.0"; +const mstring HTTP_V11="HTTP/1.1"; + +/////////////////////////////////////////////////////////////////// +// Request types +const mstring HTTP_OPTIONS="OPTIONS"; +const mstring HTTP_GET="GET"; +const mstring HTTP_HEAD="HEAD"; +const mstring HTTP_POST="POST"; +const mstring HTTP_PUT="PUT"; +const mstring HTTP_DELETE="DELETE"; +const mstring HTTP_TRACE="TRACE"; +const mstring HTTP_CONNECT="CONNECT"; + +class httpReq : public HTTP { +public: + httpReq(); + httpReq(const sref& msg) { Init(msg); } + + mstring method,uri,arg,version; + mstring auth,expect,from,host; + mstring if_match,if_mod,if_none,if_range,if_unmod; + mstring max_forwards,proxy,range; + mstring referer,te,user_agent; + sspile cookies; + + void putHead(mstream& out) const; +protected: + int Special(sref line); + int Handle(const sref& name, + const sref& rawval, + const sref& val, + const rrpile& opts); +}; + +/////////////////////////////////////////////////////////////////// + +/////////////////////////////////////////////////////////////////// +// Informational 1xx +const mstring HTTP_100="100 Continue"; +const mstring HTTP_101="101 Switching Protocols"; +// Successful 2xx +const mstring HTTP_200="200 OK"; +const mstring HTTP_201="201 Created"; +const mstring HTTP_202="202 Accepted"; +const mstring HTTP_203="203 Non-Authoritative Information"; +const mstring HTTP_204="204 No Content"; +const mstring HTTP_205="205 Reset Content"; +const mstring HTTP_206="206 Partial Content"; +// Redirection 3xx +const mstring HTTP_300="300 Multiple Choices"; +const mstring HTTP_301="301 Moved Permanently"; +const mstring HTTP_302="302 Found"; +const mstring HTTP_303="303 See Other"; +const mstring HTTP_304="304 Not Modified"; +const mstring HTTP_305="305 Use Proxy"; +const mstring HTTP_306="306 (Unused)"; +const mstring HTTP_307="307 Temporary Redirect"; +// Client Error 4xx +const mstring HTTP_400="400 Bad Request"; +const mstring HTTP_401="401 Unauthorized"; +const mstring HTTP_402="402 Payment Required"; +const mstring HTTP_403="403 Forbidden"; +const mstring HTTP_404="404 Not Found"; +const mstring HTTP_405="405 Method Not Allowed"; +const mstring HTTP_406="406 Not Acceptable"; +const mstring HTTP_407="407 Proxy Authentication Required"; +const mstring HTTP_408="408 Request Timeout"; +const mstring HTTP_409="409 Conflict"; +const mstring HTTP_410="410 Gone"; +const mstring HTTP_411="411 Length Required"; +const mstring HTTP_412="412 Precondition Failed"; +const mstring HTTP_413="413 Request Entity Too Large"; +const mstring HTTP_414="414 Request-URI Too Long"; +const mstring HTTP_415="415 Unsupported Media Type"; +const mstring HTTP_416="416 Requested Range Not Satisfiable"; +const mstring HTTP_417="417 Expectation Failed"; +// Server Error 5xx +const mstring HTTP_500="500 Internal Server Error"; +const mstring HTTP_501="501 Not Implemented"; +const mstring HTTP_502="502 Bad Gateway"; +const mstring HTTP_503="503 Service Unavailable"; +const mstring HTTP_504="504 Gateway Timeout"; +const mstring HTTP_505="505 HTTP Version Not Supported"; + +struct cookie_t { + mstring name,val,options; + cookie_t() {} + cookie_t(const sref& n,const sref& v) : name(n),val(v) {} + cookie_t(const sref& n,const sref& v,const sref& o) : + name(n),val(v),options(o) {} +}; + +class httpResp : public HTTP { +public: + httpResp(); + httpResp(const sref& msg) { Init(msg); } + + mstring version,status; + mstring age,etag,location; + mstring proxy_authent,retry,server,vary,authent; + msvec set_cookies; + + void putHead(mstream& out) const; +protected: + int Special(sref line); + int Handle(const sref& name, + const sref& rawval, + const sref& val, + const rrpile& opts); +}; + +/////////////////////////////////////////////////////////////////// + +#endif + 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +HTTP::HTTP() +{ + connect="close"; + pragma="no-cache"; + date=httpTime(idate=Now()); +} + +int HTTP::Special(sref line) +{ + return 1; +} + +int HTTP::Handle(const sref& name, + const sref& rawval, + const sref& val, + const rrpile& opts) +{ + if(Mime::Handle(name,rawval,val,opts)) return 1; + else if(eqn(name,cache_tag)) cache=val; + else if(eqn(name,connect_tag)) connect=val; + else if(eqn(name,date_tag)) date=val; + else if(eqn(name,pragma_tag)) pragma=val; + else if(eqn(name,trailer_tag)) trailer=val; + else if(eqn(name,trans_enc_tag)) trans_enc=val; + else if(eqn(name,upgrade_tag)) upgrade=val; + else if(eqn(name,via_tag)) via=val; + else if(eqn(name,warning_tag)) warning=val; + else if(eqn(name,allow_tag)) allow=val; + else if(eqn(name,cont_enc_tag)) cont_enc=val; + else if(eqn(name,cont_lang_tag)) cont_lang=val; + else if(eqn(name,cont_location_tag)) cont_location=val; + else if(eqn(name,cont_md5_tag)) cont_md5=val; + else if(eqn(name,cont_range_tag)) cont_range=val; + else if(eqn(name,expires_tag)) expires=val; + else if(eqn(name,lastmod_tag)) lastmod=val; + else if(eqn(name,accept_tag)) accept=val; + else if(eqn(name,accept_charset_tag)) accept_charset=val; + else if(eqn(name,accept_enc_tag)) accept_enc=val; + else if(eqn(name,accept_lang_tag)) accept_lang=val; + else if(eqn(name,accept_range_tag)) accept_range=val; + else return 0; + return 1; +} + +void HTTP::putHead(mstream& out) const +{ + if(putval(out,cache_tag,cache)) putend(out); + if(putval(out,connect_tag,connect)) putend(out); + if(putval(out,date_tag,date)) putend(out); + if(putval(out,pragma_tag,pragma)) putend(out); + if(putval(out,trailer_tag,trailer)) putend(out); + if(putval(out,trans_enc_tag,trans_enc)) putend(out); + if(putval(out,upgrade_tag,upgrade)) putend(out); + if(putval(out,via_tag,via)) putend(out); + if(putval(out,warning_tag,warning)) putend(out); + if(putval(out,allow_tag,allow)) putend(out); + if(putval(out,cont_enc_tag,cont_enc)) putend(out); + if(putval(out,cont_lang_tag,cont_lang)) putend(out); + if(putval(out,cont_location_tag,cont_location)) putend(out); + if(putval(out,cont_md5_tag,cont_md5)) putend(out); + if(putval(out,cont_range_tag,cont_range)) putend(out); + if(putval(out,expires_tag,expires)) putend(out); + if(putval(out,lastmod_tag,lastmod)) putend(out); + if(putval(out,accept_tag,accept)) putend(out); + if(putval(out,accept_charset_tag,accept_charset)) putend(out); + if(putval(out,accept_enc_tag,accept_enc)) putend(out); + if(putval(out,accept_lang_tag,accept_lang)) putend(out); + if(putval(out,accept_range_tag,accept_range)) putend(out); + Mime::putHead(out); +} + 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef MIMEHTTPH +#define MIMEHTTPH + +#include +#include + +// Entity Headers +const mstring allow_tag="Allow"; +const mstring accept_tag="Accept"; +const mstring accept_charset_tag="Accept-Charset"; +const mstring accept_enc_tag="Accept-Encoding"; +const mstring accept_lang_tag="Accept-Language"; +const mstring accept_range_tag="Accept-Ranges"; +const mstring cont_enc_tag="Content-Encoding"; +const mstring cont_lang_tag="Content-Language"; +const mstring cont_location_tag="Content-Location"; +const mstring cont_md5_tag="Content-MD5"; +const mstring cont_range_tag="Content-Range"; +const mstring expires_tag="Expires"; +const mstring lastmod_tag="Last-Modified"; +// General headers +const mstring cache_tag="Cache-Control"; +const mstring connect_tag="Connection"; +const mstring date_tag="Date"; +const mstring pragma_tag="Pragma"; +const mstring trailer_tag="Trailer"; +const mstring trans_enc_tag="Transfer-Encoding"; +const mstring upgrade_tag="Upgrade"; +const mstring via_tag="Via"; +const mstring warning_tag="Warning"; +// Request headers +const mstring auth_tag="Authorization"; +const mstring expect_tag="Expect"; +const mstring host_tag="Host"; +const mstring if_match_tag="If-Match"; +const mstring if_mod_tag="If-Modified-Since"; +const mstring if_none_tag="If-None-Match"; +const mstring if_range_tag="If-Range"; +const mstring if_unmod_tag="If-Unmodified-Since"; +const mstring max_forwards_tag="Max-Forwards"; +const mstring proxy_tag="Proxy-Authorization"; +const mstring range_tag="Range"; +const mstring referer_tag="Referer"; +const mstring te_tag="TE"; +const mstring user_agent_tag="User-Agent"; +const mstring cookie_tag="Cookie"; +// Response headers +const mstring age_tag="Age"; +const mstring etag_tag="ETag"; +const mstring location_tag="Location"; +const mstring proxy_authent_tag="Proxy-Authenticate"; +const mstring retry_tag="Retry-After"; +const mstring server_tag="Server"; +const mstring vary_tag="Vary"; +const mstring authent_tag="WWW-Authenticate"; +const mstring set_cookie_tag="Set-Cookie"; + +class HTTP : public Mime { +public: + HTTP(); + HTTP(const sref& msg) { Init(msg); } + + mstring cache,connect,date,pragma; + mstring trailer,trans_enc,upgrade,via,warning; + mstring allow,cont_enc,cont_lang,cont_location; + mstring cont_md5,cont_range,expires,lastmod; + mstring accept,accept_charset,accept_enc,accept_lang,accept_range; + + time_t idate; + void putHead(mstream& out) const; +protected: + int Special(sref line); + int Handle(const sref& name, + const sref& rawval, + const sref& val, + const rrpile& opts); +}; + +#endif + 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +httpReq::httpReq() +{ +} + +int httpReq::Special(sref line) +{ + sref first,rest=line; + Split(first,rest); + method=first; + Split(first,rest); + uri=first; + arg.clear(); + Split(first,rest); + version=first; + int pos=uri.find('?'); + if(pos>=0) { arg=uri.right(pos+1); uri.resize(pos); } + return 1; +} + +int httpReq::Handle(const sref& name, + const sref& rawval, + const sref& val, + const rrpile& opts) +{ + if(HTTP::Handle(name,rawval,val,opts)) return 1; + else if(eqn(name,auth_tag)) auth=val; + else if(eqn(name,expect_tag)) expect=val; + else if(eqn(name,from_tag)) from=val; + else if(eqn(name,host_tag)) host=val; + else if(eqn(name,if_match_tag)) if_match=val; + else if(eqn(name,if_mod_tag)) if_mod=val; + else if(eqn(name,if_none_tag)) if_none=val; + else if(eqn(name,if_range_tag)) if_range=val; + else if(eqn(name,if_unmod_tag)) if_unmod=val; + else if(eqn(name,max_forwards_tag)) max_forwards=val; + else if(eqn(name,proxy_tag)) proxy=val; + else if(eqn(name,range_tag)) range=val; + else if(eqn(name,referer_tag)) referer=val; + else if(eqn(name,te_tag)) te=val; + else if(eqn(name,user_agent_tag)) user_agent=val; + else if(eqn(name,cookie_tag)) { + for(rrpile::const_iterator p=opts.begin();p!=opts.end();p++) + cookies.push_back(sstring(p->first,p->second)); + } + else return 0; + return 1; +} + +void httpReq::putHead(mstream& out) const +{ + out<first,p->second); + else putopt(out,p->first,p->second); + } + putend(out); + } +} 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +httpResp::httpResp() +{ + server="HTCd/1.2 MT (Unix)"; + version="HTTP/1.1"; + status=HTTP_200; + mime_version.clear(); + //accept="*/*"; + //this is non-standard in response headers - now... +} + +int httpResp::Special(sref line) +{ + version=First(line); + status=Rest(line); + return 1; +} + +int httpResp::Handle(const sref& name, + const sref& rawval, + const sref& val, + const rrpile& opts) +{ + if(HTTP::Handle(name,rawval,val,opts)) return 1; + else if(eqn(name,age_tag)) age=val; + else if(eqn(name,etag_tag)) etag=val; + else if(eqn(name,location_tag)) location=val; + else if(eqn(name,proxy_authent_tag)) proxy_authent=val; + else if(eqn(name,retry_tag)) retry=val; + else if(eqn(name,server_tag)) server=val; + else if(eqn(name,vary_tag)) vary=val; + else if(eqn(name,authent_tag)) authent=val; + else if(eqn(name,set_cookie_tag)) { + for(rrpile::const_iterator p=opts.begin();p!=opts.end();p++) + set_cookies.push_back(cookie_t(p->first,p->second)); + } + else return 0; + return 1; +} + +void httpResp::putHead(mstream& out) const +{ + out<::const_iterator p=set_cookies.begin();p!=set_cookies.end();p++) { + out<name,p->val); + if(p->options.nempty()) out<<"; "<options; + putend(out); + } +} 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +static fp_stream mout(stdout),merr(stderr); + +main(int argc,char* argv[]) +{ + return 0; +} 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 @@ + +KORT BESKRIVNING AV 'labat' +=========================== + +Indata ('atomctrl.dat') foer Al till 'labat' (Boer vara identisk med +tidigare versioner). + +13 0 +10 40 0.2000 +0.5000 0.00001 0.005 +30 0 0 0 +5 2 0<--------------- 0, 1 & 2 foer respektive: lda, barth-hedin & GGA +100 -84.5000 1 1 0 (knapp finns redan) +200 -16.2450 1 1 0 +210 -5.3356 3 1 0 +300 -0.7812 1 1 0 +310 -0.2312 1 1 0 +100 -84.5000 1 1 0 +200 -16.2450 1 1 0 +210 -5.3356 3 1 0 +300 -0.7812 1 1 0 +310 -0.2312 0 1 0 + + +Skall ge foeljande resultat: +(De utdata filer som finns i biblioteket aer fraan LDA-exemplet nedan) + +LDA + + Total energy starts + iter: 22 total ch: 13.00 total en: -241.3129 + Coulomb potential + NEW ITERATION + +GGA + + Total energy starts + iter: 22 total ch: 13.00 total en: -242.3491 + Coulomb potential + NEW ITERATION + Note: the following IEEE floating-point arithmetic exceptions + occurred and were never cleared; see ieee_flags(3M): + Inexact; Underflow; + Sun's implementation of IEEE arithmetic is discussed in + the Numerical Computation Guide. + +Inte saa snyggt med flyttalsfelen, men ... + +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 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 @@ + 23 z,ion: 13. 0. jblock,nbl,c: 10 40 0.2000000 + -0.1300000E+02 0.0000000E+00 0.0000000E+00 0.1388390E+04 0.0000000E+00 + -0.2595549E+05 -0.2603599E+05 -0.2603598E+05 0.1388390E+04 0.5000000E-03 + -0.1295549E+05 -0.1300223E+05 -0.1300222E+05 0.1370416E+04 0.1000000E-02 + -0.8622160E+04 -0.8657409E+04 -0.8657408E+04 0.1352672E+04 0.1500000E-02 + -0.6455499E+04 -0.6484424E+04 -0.6484424E+04 0.1335159E+04 0.2000000E-02 + -0.5155505E+04 -0.5180875E+04 -0.5180875E+04 0.1317873E+04 0.2500000E-02 + -0.4288846E+04 -0.4311748E+04 -0.4311748E+04 0.1300813E+04 0.3000000E-02 + -0.3669807E+04 -0.3690957E+04 -0.3690957E+04 0.1283975E+04 0.3500000E-02 + -0.3205532E+04 -0.3225349E+04 -0.3225349E+04 0.1267356E+04 0.4000000E-02 + -0.2844432E+04 -0.2863203E+04 -0.2863204E+04 0.1250953E+04 0.4500000E-02 + -0.2555556E+04 -0.2573482E+04 -0.2573482E+04 0.1234765E+04 0.5000000E-02 + -0.2319206E+04 -0.2336431E+04 -0.2336432E+04 0.1218787E+04 0.5500000E-02 + -0.2122252E+04 -0.2138886E+04 -0.2138887E+04 0.1203018E+04 0.6000000E-02 + -0.1955601E+04 -0.1971728E+04 -0.1971729E+04 0.1187454E+04 0.6500000E-02 + -0.1812762E+04 -0.1828448E+04 -0.1828448E+04 0.1172094E+04 0.7000000E-02 + -0.1688971E+04 -0.1704268E+04 -0.1704268E+04 0.1156933E+04 0.7500000E-02 + -0.1580658E+04 -0.1595610E+04 -0.1595610E+04 0.1141971E+04 0.8000000E-02 + -0.1485089E+04 -0.1499732E+04 -0.1499732E+04 0.1127204E+04 0.8500000E-02 + -0.1400144E+04 -0.1414506E+04 -0.1414507E+04 0.1112629E+04 0.9000000E-02 + -0.1324143E+04 -0.1338250E+04 -0.1338250E+04 0.1098245E+04 0.9500000E-02 + -0.1255747E+04 -0.1269619E+04 -0.1269619E+04 0.1084048E+04 0.1000000E-01 + -0.1193866E+04 -0.1207523E+04 -0.1207523E+04 0.1070036E+04 0.1050000E-01 + -0.1137615E+04 -0.1151072E+04 -0.1151072E+04 0.1056208E+04 0.1100000E-01 + -0.1086258E+04 -0.1099528E+04 -0.1099528E+04 0.1042559E+04 0.1150000E-01 + -0.1039185E+04 -0.1052280E+04 -0.1052281E+04 0.1029089E+04 0.1200000E-01 + -0.9958791E+03 -0.1008811E+04 -0.1008812E+04 0.1015795E+04 0.1250000E-01 + -0.9559090E+03 -0.9686865E+03 -0.9686870E+03 0.1002675E+04 0.1300000E-01 + -0.9189016E+03 -0.9315332E+03 -0.9315337E+03 0.9897252E+03 0.1350000E-01 + -0.8845416E+03 -0.8970348E+03 -0.8970353E+03 0.9769449E+03 0.1400000E-01 + -0.8525533E+03 -0.8649147E+03 -0.8649152E+03 0.9643314E+03 0.1450000E-01 + -0.8227014E+03 -0.8349372E+03 -0.8349377E+03 0.9518826E+03 0.1500000E-01 + -0.7947774E+03 -0.8068931E+03 -0.8068936E+03 0.9395963E+03 0.1550000E-01 + -0.7686024E+03 -0.7806030E+03 -0.7806036E+03 0.9274705E+03 0.1600000E-01 + -0.7440157E+03 -0.7559058E+03 -0.7559063E+03 0.9155030E+03 0.1650000E-01 + -0.7208790E+03 -0.7326628E+03 -0.7326633E+03 0.9036917E+03 0.1700000E-01 + -0.6990662E+03 -0.7107476E+03 -0.7107481E+03 0.8920347E+03 0.1750000E-01 + -0.6784689E+03 -0.6900513E+03 -0.6900518E+03 0.8805299E+03 0.1800000E-01 + -0.6589867E+03 -0.6704735E+03 -0.6704740E+03 0.8691753E+03 0.1850000E-01 + -0.6405335E+03 -0.6519276E+03 -0.6519282E+03 0.8579690E+03 0.1900000E-01 + -0.6230283E+03 -0.6343326E+03 -0.6343331E+03 0.8469091E+03 0.1950000E-01 + -0.6064018E+03 -0.6176191E+03 -0.6176196E+03 0.8359936E+03 0.2000000E-01 + -0.5755291E+03 -0.5865791E+03 -0.5865796E+03 0.8145883E+03 0.2100000E-01 + -0.5474761E+03 -0.5583670E+03 -0.5583675E+03 0.7937385E+03 0.2200000E-01 + -0.5218688E+03 -0.5326084E+03 -0.5326089E+03 0.7734297E+03 0.2300000E-01 + -0.4984078E+03 -0.5090028E+03 -0.5090033E+03 0.7536478E+03 0.2400000E-01 + -0.4768298E+03 -0.4872860E+03 -0.4872865E+03 0.7343792E+03 0.2500000E-01 + -0.4569235E+03 -0.4672462E+03 -0.4672466E+03 0.7156106E+03 0.2600000E-01 + -0.4384975E+03 -0.4486914E+03 -0.4486919E+03 0.6973290E+03 0.2700000E-01 + -0.4213989E+03 -0.4314685E+03 -0.4314689E+03 0.6795216E+03 0.2800000E-01 + -0.4054850E+03 -0.4154341E+03 -0.4154346E+03 0.6621763E+03 0.2900000E-01 + -0.3906428E+03 -0.4004751E+03 -0.4004756E+03 0.6452810E+03 0.3000000E-01 + -0.3767633E+03 -0.3864822E+03 -0.3864826E+03 0.6288239E+03 0.3100000E-01 + -0.3637615E+03 -0.3733700E+03 -0.3733704E+03 0.6127938E+03 0.3200000E-01 + -0.3515527E+03 -0.3610536E+03 -0.3610541E+03 0.5971795E+03 0.3300000E-01 + -0.3400718E+03 -0.3494678E+03 -0.3494682E+03 0.5819701E+03 0.3400000E-01 + -0.3292517E+03 -0.3385452E+03 -0.3385456E+03 0.5671553E+03 0.3500000E-01 + -0.3190419E+03 -0.3282353E+03 -0.3282357E+03 0.5527246E+03 0.3600000E-01 + -0.3093885E+03 -0.3184839E+03 -0.3184843E+03 0.5386682E+03 0.3700000E-01 + -0.3002519E+03 -0.3092515E+03 -0.3092519E+03 0.5249762E+03 0.3800000E-01 + -0.2915882E+03 -0.3004938E+03 -0.3004942E+03 0.5116393E+03 0.3900000E-01 + -0.2833661E+03 -0.2921795E+03 -0.2921799E+03 0.4986481E+03 0.4000000E-01 + -0.2755491E+03 -0.2842721E+03 -0.2842724E+03 0.4859937E+03 0.4100000E-01 + -0.2681122E+03 -0.2767465E+03 -0.2767468E+03 0.4736674E+03 0.4200000E-01 + -0.2610252E+03 -0.2695722E+03 -0.2695725E+03 0.4616606E+03 0.4300000E-01 + -0.2542678E+03 -0.2627292E+03 -0.2627295E+03 0.4499649E+03 0.4400000E-01 + -0.2478145E+03 -0.2561915E+03 -0.2561919E+03 0.4385724E+03 0.4500000E-01 + -0.2416489E+03 -0.2499431E+03 -0.2499434E+03 0.4274751E+03 0.4600000E-01 + -0.2357492E+03 -0.2439618E+03 -0.2439621E+03 0.4166653E+03 0.4700000E-01 + -0.2301022E+03 -0.2382345E+03 -0.2382347E+03 0.4061357E+03 0.4800000E-01 + -0.2246890E+03 -0.2327421E+03 -0.2327424E+03 0.3958788E+03 0.4900000E-01 + -0.2194988E+03 -0.2274741E+03 -0.2274743E+03 0.3858877E+03 0.5000000E-01 + -0.2145153E+03 -0.2224138E+03 -0.2224140E+03 0.3761553E+03 0.5100000E-01 + -0.2097297E+03 -0.2175525E+03 -0.2175527E+03 0.3666751E+03 0.5200000E-01 + -0.2051276E+03 -0.2128759E+03 -0.2128761E+03 0.3574404E+03 0.5300000E-01 + -0.2007019E+03 -0.2083766E+03 -0.2083768E+03 0.3484449E+03 0.5400000E-01 + -0.1964400E+03 -0.2040421E+03 -0.2040423E+03 0.3396823E+03 0.5500000E-01 + -0.1923359E+03 -0.1998664E+03 -0.1998666E+03 0.3311466E+03 0.5600000E-01 + -0.1883786E+03 -0.1958384E+03 -0.1958385E+03 0.3228319E+03 0.5700000E-01 + -0.1845630E+03 -0.1919531E+03 -0.1919532E+03 0.3147325E+03 0.5800000E-01 + -0.1808793E+03 -0.1882005E+03 -0.1882006E+03 0.3068428E+03 0.5900000E-01 + -0.1773235E+03 -0.1845771E+03 -0.1845772E+03 0.2991574E+03 0.6000000E-01 + -0.1705632E+03 -0.1776836E+03 -0.1776837E+03 0.2843782E+03 0.6200000E-01 + -0.1642440E+03 -0.1712338E+03 -0.1712338E+03 0.2703541E+03 0.6400000E-01 + -0.1583165E+03 -0.1651794E+03 -0.1651794E+03 0.2570466E+03 0.6600000E-01 + -0.1527544E+03 -0.1594933E+03 -0.1594932E+03 0.2444189E+03 0.6800000E-01 + -0.1475181E+03 -0.1541359E+03 -0.1541358E+03 0.2324363E+03 0.7000000E-01 + -0.1425878E+03 -0.1490873E+03 -0.1490871E+03 0.2210658E+03 0.7200000E-01 + -0.1379313E+03 -0.1443151E+03 -0.1443149E+03 0.2102760E+03 0.7400000E-01 + -0.1335335E+03 -0.1398043E+03 -0.1398041E+03 0.2000373E+03 0.7600000E-01 + -0.1293678E+03 -0.1355281E+03 -0.1355278E+03 0.1903216E+03 0.7800000E-01 + -0.1254229E+03 -0.1314751E+03 -0.1314748E+03 0.1811020E+03 0.8000000E-01 + -0.1216763E+03 -0.1276228E+03 -0.1276224E+03 0.1723534E+03 0.8200000E-01 + -0.1181193E+03 -0.1239626E+03 -0.1239621E+03 0.1640515E+03 0.8400000E-01 + -0.1147332E+03 -0.1204754E+03 -0.1204749E+03 0.1561737E+03 0.8600000E-01 + -0.1115112E+03 -0.1171545E+03 -0.1171540E+03 0.1486982E+03 0.8800000E-01 + -0.1084373E+03 -0.1139839E+03 -0.1139833E+03 0.1416045E+03 0.9000000E-01 + -0.1055064E+03 -0.1109583E+03 -0.1109576E+03 0.1348732E+03 0.9200000E-01 + -0.1027046E+03 -0.1080640E+03 -0.1080632E+03 0.1284857E+03 0.9400000E-01 + -0.1000279E+03 -0.1052968E+03 -0.1052960E+03 0.1224246E+03 0.9600000E-01 + -0.9746453E+02 -0.1026449E+03 -0.1026440E+03 0.1166731E+03 0.9800000E-01 + -0.9501135E+02 -0.1001051E+03 -0.1001042E+03 0.1112155E+03 0.1000000E+00 + -0.9265802E+02 -0.9766714E+02 -0.9766614E+02 0.1060368E+03 0.1020000E+00 + -0.9040218E+02 -0.9532851E+02 -0.9532743E+02 0.1011228E+03 0.1040000E+00 + -0.8823479E+02 -0.9308017E+02 -0.9307902E+02 0.9645988E+02 0.1060000E+00 + -0.8615402E+02 -0.9092026E+02 -0.9091904E+02 0.9203535E+02 0.1080000E+00 + -0.8415194E+02 -0.8884081E+02 -0.8883952E+02 0.8783700E+02 0.1100000E+00 + -0.8222714E+02 -0.8684041E+02 -0.8683904E+02 0.8385332E+02 0.1120000E+00 + -0.8037265E+02 -0.8491201E+02 -0.8491058E+02 0.8007333E+02 0.1140000E+00 + -0.7858737E+02 -0.8305453E+02 -0.8305302E+02 0.7648665E+02 0.1160000E+00 + -0.7686513E+02 -0.8126175E+02 -0.8126016E+02 0.7308341E+02 0.1180000E+00 + -0.7520512E+02 -0.7953283E+02 -0.7953116E+02 0.6985425E+02 0.1200000E+00 + -0.7360184E+02 -0.7786223E+02 -0.7786049E+02 0.6679027E+02 0.1220000E+00 + -0.7205467E+02 -0.7624934E+02 -0.7624752E+02 0.6388304E+02 0.1240000E+00 + -0.7055874E+02 -0.7468921E+02 -0.7468732E+02 0.6112455E+02 0.1260000E+00 + -0.6911358E+02 -0.7318138E+02 -0.7317942E+02 0.5850720E+02 0.1280000E+00 + -0.6771482E+02 -0.7172144E+02 -0.7171940E+02 0.5602376E+02 0.1300000E+00 + -0.6636214E+02 -0.7030904E+02 -0.7030693E+02 0.5366739E+02 0.1320000E+00 + -0.6505161E+02 -0.6894022E+02 -0.6893804E+02 0.5143159E+02 0.1340000E+00 + -0.6378303E+02 -0.6761476E+02 -0.6761251E+02 0.4931018E+02 0.1360000E+00 + -0.6255284E+02 -0.6632897E+02 -0.6632666E+02 0.4729730E+02 0.1380000E+00 + -0.6136093E+02 -0.6508333E+02 -0.6508094E+02 0.4538738E+02 0.1400000E+00 + -0.5908087E+02 -0.6269912E+02 -0.6269661E+02 0.4185559E+02 0.1440000E+00 + -0.5693497E+02 -0.6045311E+02 -0.6045048E+02 0.3867568E+02 0.1480000E+00 + -0.5490706E+02 -0.5833048E+02 -0.5832774E+02 0.3581240E+02 0.1520000E+00 + -0.5299250E+02 -0.5632548E+02 -0.5632265E+02 0.3323396E+02 0.1560000E+00 + -0.5117801E+02 -0.5442476E+02 -0.5442185E+02 0.3091174E+02 0.1600000E+00 + -0.4946011E+02 -0.5262454E+02 -0.5262154E+02 0.2881991E+02 0.1640000E+00 + -0.4782780E+02 -0.5091357E+02 -0.5091048E+02 0.2693524E+02 0.1680000E+00 + -0.4627845E+02 -0.4928903E+02 -0.4928587E+02 0.2523676E+02 0.1720000E+00 + -0.4480284E+02 -0.4774149E+02 -0.4773825E+02 0.2370561E+02 0.1760000E+00 + -0.4339903E+02 -0.4626887E+02 -0.4626555E+02 0.2232476E+02 0.1800000E+00 + -0.4205917E+02 -0.4486324E+02 -0.4485982E+02 0.2107891E+02 0.1840000E+00 + -0.4078187E+02 -0.4352312E+02 -0.4351958E+02 0.1995424E+02 0.1880000E+00 + -0.3956040E+02 -0.4224178E+02 -0.4223812E+02 0.1893833E+02 0.1920000E+00 + -0.3839376E+02 -0.4101827E+02 -0.4101445E+02 0.1801999E+02 0.1960000E+00 + -0.3727616E+02 -0.3984685E+02 -0.3984286E+02 0.1718915E+02 0.2000000E+00 + -0.3620690E+02 -0.3872696E+02 -0.3872277E+02 0.1643673E+02 0.2040000E+00 + -0.3518093E+02 -0.3765367E+02 -0.3764925E+02 0.1575459E+02 0.2080000E+00 + -0.3419781E+02 -0.3662670E+02 -0.3662203E+02 0.1513536E+02 0.2120000E+00 + -0.3325310E+02 -0.3564173E+02 -0.3563679E+02 0.1457246E+02 0.2160000E+00 + -0.3234658E+02 -0.3469866E+02 -0.3469345E+02 0.1405994E+02 0.2200000E+00 + -0.3147428E+02 -0.3379361E+02 -0.3378811E+02 0.1359246E+02 0.2240000E+00 + -0.3063618E+02 -0.3292656E+02 -0.3292078E+02 0.1316524E+02 0.2280000E+00 + -0.2982870E+02 -0.3209392E+02 -0.3208788E+02 0.1277395E+02 0.2320000E+00 + -0.2905197E+02 -0.3129569E+02 -0.3128939E+02 0.1241474E+02 0.2360000E+00 + -0.2830276E+02 -0.3052846E+02 -0.3052194E+02 0.1208412E+02 0.2400000E+00 + -0.2758130E+02 -0.2979222E+02 -0.2978550E+02 0.1177899E+02 0.2440000E+00 + -0.2688467E+02 -0.2908371E+02 -0.2907684E+02 0.1149654E+02 0.2480000E+00 + -0.2621319E+02 -0.2840292E+02 -0.2839591E+02 0.1123428E+02 0.2520000E+00 + -0.2556417E+02 -0.2774676E+02 -0.2773967E+02 0.1098997E+02 0.2560000E+00 + -0.2493803E+02 -0.2711527E+02 -0.2710811E+02 0.1076160E+02 0.2600000E+00 + -0.2433227E+02 -0.2650557E+02 -0.2649839E+02 0.1054737E+02 0.2640000E+00 + -0.2374739E+02 -0.2591779E+02 -0.2591062E+02 0.1034570E+02 0.2680000E+00 + -0.2318108E+02 -0.2534931E+02 -0.2534218E+02 0.1015514E+02 0.2720000E+00 + -0.2263386E+02 -0.2480036E+02 -0.2479329E+02 0.9974424E+01 0.2760000E+00 + -0.2210359E+02 -0.2426857E+02 -0.2426158E+02 0.9802422E+01 0.2800000E+00 + -0.2159086E+02 -0.2375429E+02 -0.2374740E+02 0.9638125E+01 0.2840000E+00 + -0.2109364E+02 -0.2325536E+02 -0.2324860E+02 0.9480637E+01 0.2880000E+00 + -0.2061255E+02 -0.2277227E+02 -0.2276563E+02 0.9329166E+01 0.2920000E+00 + -0.2014569E+02 -0.2230305E+02 -0.2229655E+02 0.9183009E+01 0.2960000E+00 + -0.1969372E+02 -0.2184864E+02 -0.2184228E+02 0.9041547E+01 0.3000000E+00 + -0.1882853E+02 -0.2097648E+02 -0.2097040E+02 0.8770583E+01 0.3080000E+00 + -0.1801631E+02 -0.2015516E+02 -0.2014935E+02 0.8512650E+01 0.3160000E+00 + -0.1724865E+02 -0.1937739E+02 -0.1937184E+02 0.8264966E+01 0.3240000E+00 + -0.1652664E+02 -0.1864364E+02 -0.1863834E+02 0.8025424E+01 0.3320000E+00 + -0.1584281E+02 -0.1794675E+02 -0.1794167E+02 0.7792449E+01 0.3400000E+00 + -0.1519858E+02 -0.1728820E+02 -0.1728334E+02 0.7564891E+01 0.3480000E+00 + -0.1458727E+02 -0.1666144E+02 -0.1665678E+02 0.7341929E+01 0.3560000E+00 + -0.1401053E+02 -0.1606820E+02 -0.1606374E+02 0.7122998E+01 0.3640000E+00 + -0.1346233E+02 -0.1550256E+02 -0.1549828E+02 0.6907731E+01 0.3720000E+00 + -0.1294447E+02 -0.1496642E+02 -0.1496230E+02 0.6695913E+01 0.3800000E+00 + -0.1245148E+02 -0.1445440E+02 -0.1445044E+02 0.6487436E+01 0.3880000E+00 + -0.1198522E+02 -0.1396847E+02 -0.1396467E+02 0.6282279E+01 0.3960000E+00 + -0.1154073E+02 -0.1350375E+02 -0.1350009E+02 0.6080477E+01 0.4040000E+00 + -0.1111990E+02 -0.1306222E+02 -0.1305869E+02 0.5882104E+01 0.4120000E+00 + -0.1071819E+02 -0.1263941E+02 -0.1263602E+02 0.5687258E+01 0.4200000E+00 + -0.1033748E+02 -0.1223727E+02 -0.1223401E+02 0.5496050E+01 0.4280000E+00 + -0.9973640E+01 -0.1185173E+02 -0.1184860E+02 0.5308597E+01 0.4360000E+00 + -0.9628498E+01 -0.1148468E+02 -0.1148168E+02 0.5125013E+01 0.4440000E+00 + -0.9298274E+01 -0.1113239E+02 -0.1112950E+02 0.4945404E+01 0.4520000E+00 + -0.8984746E+01 -0.1079667E+02 -0.1079390E+02 0.4769869E+01 0.4600000E+00 + -0.8684450E+01 -0.1047411E+02 -0.1047145E+02 0.4598492E+01 0.4680000E+00 + -0.8399097E+01 -0.1016644E+02 -0.1016390E+02 0.4431345E+01 0.4760000E+00 + -0.8125514E+01 -0.9870523E+01 -0.9868100E+01 0.4268486E+01 0.4840000E+00 + -0.7865330E+01 -0.9588022E+01 -0.9585710E+01 0.4109956E+01 0.4920000E+00 + -0.7615641E+01 -0.9316053E+01 -0.9313852E+01 0.3955783E+01 0.5000000E+00 + -0.7377991E+01 -0.9056183E+01 -0.9054090E+01 0.3805983E+01 0.5080000E+00 + -0.7149719E+01 -0.8805770E+01 -0.8803785E+01 0.3660556E+01 0.5160000E+00 + -0.6932283E+01 -0.8566289E+01 -0.8564411E+01 0.3519490E+01 0.5240000E+00 + -0.6723244E+01 -0.8335320E+01 -0.8333546E+01 0.3382762E+01 0.5320000E+00 + -0.6523973E+01 -0.8114244E+01 -0.8112573E+01 0.3250338E+01 0.5400000E+00 + -0.6332238E+01 -0.7900843E+01 -0.7899275E+01 0.3122174E+01 0.5480000E+00 + -0.6149320E+01 -0.7696410E+01 -0.7694942E+01 0.2998219E+01 0.5560000E+00 + -0.5973176E+01 -0.7498912E+01 -0.7497543E+01 0.2878412E+01 0.5640000E+00 + -0.5805002E+01 -0.7309553E+01 -0.7308282E+01 0.2762685E+01 0.5720000E+00 + -0.5642928E+01 -0.7126472E+01 -0.7125297E+01 0.2650967E+01 0.5800000E+00 + -0.5488069E+01 -0.6950791E+01 -0.6949710E+01 0.2543178E+01 0.5880000E+00 + -0.5338712E+01 -0.6780801E+01 -0.6779813E+01 0.2439236E+01 0.5960000E+00 + -0.5195893E+01 -0.6617551E+01 -0.6616654E+01 0.2339055E+01 0.6040000E+00 + -0.5058045E+01 -0.6459456E+01 -0.6458647E+01 0.2242546E+01 0.6120000E+00 + -0.4926129E+01 -0.6307589E+01 -0.6306867E+01 0.2149616E+01 0.6200000E+00 + -0.4675622E+01 -0.6017721E+01 -0.6017166E+01 0.1974121E+01 0.6360000E+00 + -0.4445670E+01 -0.5749102E+01 -0.5748706E+01 0.1811812E+01 0.6520000E+00 + -0.4230526E+01 -0.5496313E+01 -0.5496065E+01 0.1661919E+01 0.6680000E+00 + -0.4032409E+01 -0.5261418E+01 -0.5261306E+01 0.1523682E+01 0.6840000E+00 + -0.3846543E+01 -0.5039689E+01 -0.5039701E+01 0.1396350E+01 0.7000000E+00 + -0.3674838E+01 -0.4833033E+01 -0.4833155E+01 0.1279196E+01 0.7160000E+00 + -0.3513323E+01 -0.4637484E+01 -0.4637700E+01 0.1171518E+01 0.7320000E+00 + -0.3363636E+01 -0.4454678E+01 -0.4454972E+01 0.1072643E+01 0.7480000E+00 + -0.3222470E+01 -0.4281309E+01 -0.4281661E+01 0.9819290E+00 0.7640000E+00 + -0.3091222E+01 -0.4118767E+01 -0.4119158E+01 0.8987705E+00 0.7800000E+00 + -0.2967138E+01 -0.3964298E+01 -0.3964704E+01 0.8225939E+00 0.7960000E+00 + -0.2851403E+01 -0.3819079E+01 -0.3819475E+01 0.7528608E+00 0.8120000E+00 + -0.2741725E+01 -0.3680812E+01 -0.3681172E+01 0.6890664E+00 0.8280000E+00 + -0.2639104E+01 -0.3550493E+01 -0.3550789E+01 0.6307393E+00 0.8440000E+00 + -0.2541630E+01 -0.3426204E+01 -0.3426405E+01 0.5774399E+00 0.8600000E+00 + -0.2450147E+01 -0.3308787E+01 -0.3308860E+01 0.5287596E+00 0.8760000E+00 + -0.2363061E+01 -0.3196638E+01 -0.3196549E+01 0.4843190E+00 0.8920000E+00 + -0.2281084E+01 -0.3090467E+01 -0.3090180E+01 0.4437668E+00 0.9080000E+00 + -0.2202882E+01 -0.2988933E+01 -0.2988411E+01 0.4067778E+00 0.9240000E+00 + -0.2129056E+01 -0.2892634E+01 -0.2891840E+01 0.3730519E+00 0.9400000E+00 + -0.2058489E+01 -0.2800443E+01 -0.2799340E+01 0.3423121E+00 0.9560000E+00 + -0.1991689E+01 -0.2712863E+01 -0.2711416E+01 0.3143033E+00 0.9720000E+00 + -0.1927716E+01 -0.2628944E+01 -0.2627118E+01 0.2887906E+00 0.9880000E+00 + -0.1867000E+01 -0.2549106E+01 -0.2546871E+01 0.2655581E+00 0.1004000E+01 + -0.1808751E+01 -0.2472542E+01 -0.2469873E+01 0.2444075E+00 0.1020000E+01 + -0.1753332E+01 -0.2399598E+01 -0.2396476E+01 0.2251568E+00 0.1036000E+01 + -0.1700075E+01 -0.2329581E+01 -0.2325996E+01 0.2076389E+00 0.1052000E+01 + -0.1649290E+01 -0.2262775E+01 -0.2258726E+01 0.1917008E+00 0.1068000E+01 + -0.1600410E+01 -0.2198578E+01 -0.2194075E+01 0.1772025E+00 0.1084000E+01 + -0.1553701E+01 -0.2137216E+01 -0.2132284E+01 0.1640157E+00 0.1100000E+01 + -0.1508678E+01 -0.2078159E+01 -0.2072837E+01 0.1520230E+00 0.1116000E+01 + -0.1465571E+01 -0.2021586E+01 -0.2015928E+01 0.1411172E+00 0.1132000E+01 + -0.1423964E+01 -0.1967027E+01 -0.1961103E+01 0.1312003E+00 0.1148000E+01 + -0.1384055E+01 -0.1914622E+01 -0.1908519E+01 0.1221829E+00 0.1164000E+01 + -0.1345487E+01 -0.1863954E+01 -0.1857772E+01 0.1139832E+00 0.1180000E+01 + -0.1308434E+01 -0.1815136E+01 -0.1808990E+01 0.1065267E+00 0.1196000E+01 + -0.1272584E+01 -0.1767803E+01 -0.1761817E+01 0.9974546E-01 0.1212000E+01 + -0.1238091E+01 -0.1722058E+01 -0.1716363E+01 0.9357756E-01 0.1228000E+01 + -0.1204683E+01 -0.1677566E+01 -0.1672305E+01 0.8796654E-01 0.1244000E+01 + -0.1172496E+01 -0.1634699E+01 -0.1629912E+01 0.8286100E-01 0.1260000E+01 + -0.1111034E+01 -0.1552141E+01 -0.1548759E+01 0.7398329E-01 0.1292000E+01 + -0.1053781E+01 -0.1473828E+01 -0.1472483E+01 0.6661834E-01 0.1324000E+01 + -0.9997888E+00 -0.1400499E+01 -0.1401124E+01 0.6049638E-01 0.1356000E+01 + -0.9493000E+00 -0.1332437E+01 -0.1334992E+01 0.5539439E-01 0.1388000E+01 + -0.9015512E+00 -0.1269951E+01 -0.1273997E+01 0.5112811E-01 0.1420000E+01 + -0.8567650E+00 -0.1213951E+01 -0.1218776E+01 0.4754545E-01 0.1452000E+01 + -0.8143093E+00 -0.1164221E+01 -0.1168861E+01 0.4452084E-01 0.1484000E+01 + -0.7743937E+00 -0.1120850E+01 -0.1124218E+01 0.4195074E-01 0.1516000E+01 + -0.7364808E+00 -0.1082695E+01 -0.1083725E+01 0.3974985E-01 0.1548000E+01 + -0.7007718E+00 -0.1049020E+01 -0.1046827E+01 0.3784805E-01 0.1580000E+01 + -0.6667987E+00 -0.1018339E+01 -0.1012329E+01 0.3618785E-01 0.1612000E+01 + -0.6347570E+00 -0.9899549E+00 -0.9798729E+00 0.3472230E-01 0.1644000E+01 + -0.6042310E+00 -0.9628122E+00 -0.9487126E+00 0.3341320E-01 0.1676000E+01 + -0.5754114E+00 -0.9367280E+00 -0.9189042E+00 0.3222963E-01 0.1708000E+01 + -0.5479233E+00 -0.9111737E+00 -0.8900652E+00 0.3114664E-01 0.1740000E+01 + -0.5219526E+00 -0.8863284E+00 -0.8624346E+00 0.3014423E-01 0.1772000E+01 + -0.4971574E+00 -0.8619231E+00 -0.8357382E+00 0.2920641E-01 0.1804000E+01 + -0.4737188E+00 -0.8382449E+00 -0.8102159E+00 0.2832052E-01 0.1836000E+01 + -0.4513220E+00 -0.8150882E+00 -0.7855948E+00 0.2747653E-01 0.1868000E+01 + -0.4301432E+00 -0.7927277E+00 -0.7620769E+00 0.2666662E-01 0.1900000E+01 + -0.4098909E+00 -0.7709543E+00 -0.7393852E+00 0.2588470E-01 0.1932000E+01 + -0.3907354E+00 -0.7500038E+00 -0.7176972E+00 0.2512610E-01 0.1964000E+01 + -0.3724062E+00 -0.7296567E+00 -0.6967459E+00 0.2438728E-01 0.1996000E+01 + -0.3550673E+00 -0.7101160E+00 -0.6766974E+00 0.2366561E-01 0.2028000E+01 + -0.3384670E+00 -0.6911601E+00 -0.6573023E+00 0.2295918E-01 0.2060000E+01 + -0.3227623E+00 -0.6729690E+00 -0.6387208E+00 0.2226662E-01 0.2092000E+01 + -0.3077190E+00 -0.6553265E+00 -0.6207223E+00 0.2158701E-01 0.2124000E+01 + -0.2934872E+00 -0.6383971E+00 -0.6034618E+00 0.2091978E-01 0.2156000E+01 + -0.2798485E+00 -0.6219742E+00 -0.5867265E+00 0.2026461E-01 0.2188000E+01 + -0.2669456E+00 -0.6062106E+00 -0.5706650E+00 0.1962136E-01 0.2220000E+01 + -0.2545754E+00 -0.5909118E+00 -0.5550803E+00 0.1899002E-01 0.2252000E+01 + -0.2428730E+00 -0.5762208E+00 -0.5401141E+00 0.1837071E-01 0.2284000E+01 + -0.2316495E+00 -0.5619556E+00 -0.5255836E+00 0.1776357E-01 0.2316000E+01 + -0.2210324E+00 -0.5482501E+00 -0.5116226E+00 0.1716881E-01 0.2348000E+01 + -0.2108462E+00 -0.5349346E+00 -0.4980613E+00 0.1658662E-01 0.2380000E+01 + -0.2012111E+00 -0.5221348E+00 -0.4850254E+00 0.1601722E-01 0.2412000E+01 + -0.1919639E+00 -0.5096924E+00 -0.4723569E+00 0.1546081E-01 0.2444000E+01 + -0.1832175E+00 -0.4977253E+00 -0.4601740E+00 0.1491755E-01 0.2476000E+01 + -0.1748207E+00 -0.4860862E+00 -0.4483281E+00 0.1438759E-01 0.2508000E+01 + -0.1668792E+00 -0.4748784E+00 -0.4369330E+00 0.1387106E-01 0.2540000E+01 + -0.1519300E+00 -0.4533747E+00 -0.4150697E+00 0.1287855E-01 0.2604000E+01 + -0.1385606E+00 -0.4334250E+00 -0.3947919E+00 0.1194032E-01 0.2668000E+01 + -0.1262177E+00 -0.4144804E+00 -0.3755696E+00 0.1105607E-01 0.2732000E+01 + -0.1151813E+00 -0.3968488E+00 -0.3576985E+00 0.1022509E-01 0.2796000E+01 + -0.1049818E+00 -0.3800720E+00 -0.3407204E+00 0.9446185E-02 0.2860000E+01 + -0.9586293E-01 -0.3644036E+00 -0.3248878E+00 0.8717863E-02 0.2924000E+01 + -0.8742742E-01 -0.3494545E+00 -0.3098101E+00 0.8038327E-02 0.2988000E+01 + -0.7988579E-01 -0.3354404E+00 -0.2957027E+00 0.7405589E-02 0.3052000E+01 + -0.7290285E-01 -0.3220310E+00 -0.2822344E+00 0.6817501E-02 0.3116000E+01 + -0.6665946E-01 -0.3094103E+00 -0.2695892E+00 0.6271827E-02 0.3180000E+01 + -0.6087338E-01 -0.2972994E+00 -0.2574886E+00 0.5766276E-02 0.3244000E+01 + -0.5569926E-01 -0.2858555E+00 -0.2460910E+00 0.5298551E-02 0.3308000E+01 + -0.5089992E-01 -0.2748450E+00 -0.2351639E+00 0.4866365E-02 0.3372000E+01 + -0.4660712E-01 -0.2644031E+00 -0.2248447E+00 0.4467480E-02 0.3436000E+01 + -0.4262181E-01 -0.2543353E+00 -0.2149415E+00 0.4099715E-02 0.3500000E+01 + -0.3905594E-01 -0.2447585E+00 -0.2055748E+00 0.3760969E-02 0.3564000E+01 + -0.3574266E-01 -0.2355122E+00 -0.1965873E+00 0.3449222E-02 0.3628000E+01 + -0.3277686E-01 -0.2266977E+00 -0.1880852E+00 0.3162550E-02 0.3692000E+01 + -0.3001881E-01 -0.2181828E+00 -0.1799408E+00 0.2899126E-02 0.3756000E+01 + -0.2754880E-01 -0.2100555E+00 -0.1722479E+00 0.2657222E-02 0.3820000E+01 + -0.2524987E-01 -0.2022069E+00 -0.1649028E+00 0.2435210E-02 0.3884000E+01 + -0.2318989E-01 -0.1947127E+00 -0.1579876E+00 0.2231562E-02 0.3948000E+01 + -0.2127099E-01 -0.1874827E+00 -0.1514179E+00 0.2044845E-02 0.4012000E+01 + -0.1955048E-01 -0.1805814E+00 -0.1452648E+00 0.1873723E-02 0.4076000E+01 + -0.1794647E-01 -0.1739333E+00 -0.1394586E+00 0.1716950E-02 0.4140000E+01 + -0.1650734E-01 -0.1675924E+00 -0.1340594E+00 0.1573368E-02 0.4204000E+01 + -0.1516454E-01 -0.1614947E+00 -0.1290088E+00 0.1441900E-02 0.4268000E+01 + -0.1395892E-01 -0.1556847E+00 -0.1243564E+00 0.1321551E-02 0.4332000E+01 + -0.1283309E-01 -0.1501076E+00 -0.1200515E+00 0.1211399E-02 0.4396000E+01 + -0.1182151E-01 -0.1447993E+00 -0.1161341E+00 0.1110594E-02 0.4460000E+01 + -0.1087613E-01 -0.1397124E+00 -0.1125590E+00 0.1018350E-02 0.4524000E+01 + -0.1002603E-01 -0.1348758E+00 -0.1093569E+00 0.9339444E-03 0.4588000E+01 + -0.9230932E-02 -0.1302480E+00 -0.1064866E+00 0.8567129E-03 0.4652000E+01 + -0.8515411E-02 -0.1258518E+00 -0.1039701E+00 0.7860439E-03 0.4716000E+01 + -0.7845663E-02 -0.1216511E+00 -0.1017683E+00 0.7213763E-03 0.4780000E+01 + -0.7242465E-02 -0.1176638E+00 -0.9989635E-01 0.6621957E-03 0.4844000E+01 + -0.6677425E-02 -0.1138581E+00 -0.9831432E-01 0.6080303E-03 0.4908000E+01 + -0.6168124E-02 -0.1102479E+00 -0.9703127E-01 0.5584483E-03 0.4972000E+01 + -0.5690686E-02 -0.1068102E+00 -0.9602603E-01 0.5130545E-03 0.5036000E+01 + -0.5260000E-02 -0.1034991E+00 -0.9505341E-01 0.4714874E-03 0.5100000E+01 + -0.4477611E-02 -0.9738560E-01 -0.9418036E-01 0.3985415E-03 0.5228000E+01 + -0.3839408E-02 -0.9208111E-01 -0.9434847E-01 0.3372963E-03 0.5356000E+01 + -0.3276214E-02 -0.8712605E-01 -0.9447003E-01 0.2858183E-03 0.5484000E+01 + -0.2815384E-02 -0.8275498E-01 -0.9470701E-01 0.2425016E-03 0.5612000E+01 + -0.2407649E-02 -0.7880597E-01 -0.9443366E-01 0.2060095E-03 0.5740000E+01 + -0.2073021E-02 -0.7530793E-01 -0.9316562E-01 0.1752304E-03 0.5868000E+01 + -0.1776219E-02 -0.7218882E-01 -0.9039150E-01 0.1492396E-03 0.5996000E+01 + -0.1531937E-02 -0.6944847E-01 -0.8585081E-01 0.1272676E-03 0.6124000E+01 + -0.1314767E-02 -0.6703940E-01 -0.7957347E-01 0.1086725E-03 0.6252000E+01 + -0.1135546E-02 -0.6495564E-01 -0.7195440E-01 0.9291864E-04 0.6380000E+01 + -0.9758780E-03 -0.6316060E-01 -0.6356518E-01 0.7955734E-04 0.6508000E+01 + -0.8437878E-03 -0.6164610E-01 -0.5502886E-01 0.6821233E-04 0.6636000E+01 + -0.7258824E-03 -0.6038230E-01 -0.4683629E-01 0.5856753E-04 0.6764000E+01 + -0.6281358E-03 -0.5936004E-01 -0.3932925E-01 0.5035729E-04 0.6892000E+01 + -0.5407396E-03 -0.5855440E-01 -0.3267298E-01 0.4335820E-04 0.7020000E+01 + -0.4681628E-03 -0.5795552E-01 -0.2692364E-01 0.3738247E-04 0.7148000E+01 + -0.4031804E-03 -0.5754156E-01 -0.2204530E-01 0.3227223E-04 0.7276000E+01 + -0.3491509E-03 -0.5730096E-01 -0.1796735E-01 0.2789478E-04 0.7404000E+01 + -0.3007215E-03 -0.5721191E-01 -0.1459036E-01 0.2413855E-04 0.7532000E+01 + -0.2604263E-03 -0.5725804E-01 -0.1181837E-01 0.2090971E-04 0.7660000E+01 + -0.2242786E-03 -0.5741189E-01 -0.9553631E-02 0.1812931E-04 0.7788000E+01 + -0.1941961E-03 -0.5764507E-01 -0.7713419E-02 0.1573087E-04 0.7916000E+01 + -0.1671959E-03 -0.5791416E-01 -0.6221017E-02 0.1365834E-04 0.8044000E+01 + -0.1447322E-03 -0.5816658E-01 -0.5015104E-02 0.1186447E-04 0.8172000E+01 + -0.1245648E-03 -0.5832927E-01 -0.4040885E-02 0.1030935E-04 0.8300000E+01 + -0.1077970E-03 -0.5831462E-01 -0.3255975E-02 0.8959263E-05 0.8428000E+01 + -0.9274227E-04 -0.5801756E-01 -0.2623018E-02 0.7785684E-05 0.8556000E+01 + -0.8023715E-04 -0.5733050E-01 -0.2113778E-02 0.6764473E-05 0.8684000E+01 + -0.6901030E-04 -0.5615555E-01 -0.1703398E-02 0.5875158E-05 0.8812000E+01 + -0.5969468E-04 -0.5442941E-01 -0.1373437E-02 0.5100342E-05 0.8940000E+01 + -0.5133223E-04 -0.5213802E-01 -0.1107546E-02 0.4425190E-05 0.9068000E+01 + -0.4440046E-04 -0.4932734E-01 -0.8937972E-03 0.3836992E-05 0.9196000E+01 + -0.3817843E-04 -0.4609416E-01 -0.7214846E-03 0.3324793E-05 0.9324000E+01 + -0.3302527E-04 -0.4256982E-01 -0.5829321E-03 0.2879091E-05 0.9452000E+01 + -0.2839972E-04 -0.3889556E-01 -0.4711485E-03 0.2491593E-05 0.9580000E+01 + -0.2457111E-04 -0.3520294E-01 -0.3811972E-03 0.2155026E-05 0.9708000E+01 + -0.2113409E-04 -0.3160316E-01 -0.3085691E-03 0.1862988E-05 0.9836000E+01 + -0.1829022E-04 -0.2817333E-01 -0.2499891E-03 0.1609836E-05 0.9964000E+01 + -0.1573666E-04 -0.2497170E-01 -0.2027310E-03 0.1390594E-05 0.1009200E+02 + -0.1362402E-04 -0.2210784E-01 -0.1652864E-03 0.1200876E-05 0.1022000E+02 + -0.1003603E-04 -0.1699821E-01 -0.1084125E-03 0.8950437E-06 0.1047600E+02 + -0.7578580E-05 -0.1282903E-01 -0.7098972E-04 0.6668682E-06 0.1073200E+02 + -0.5593245E-05 -0.9722369E-02 -0.4731680E-04 0.4969029E-06 0.1098800E+02 + -0.4231523E-05 -0.7312414E-02 -0.3158502E-04 0.3703987E-06 0.1124400E+02 + -0.3129260E-05 -0.5490480E-02 -0.2113629E-04 0.2762676E-06 0.1150000E+02 + -0.2371758E-05 -0.4114605E-02 -0.1424593E-04 0.2062147E-06 0.1175600E+02 + -0.1757350E-05 -0.3081342E-02 -0.9610490E-05 0.1540572E-06 0.1201200E+02 + -0.1334218E-05 -0.2306980E-02 -0.6544879E-05 0.1151978E-06 0.1226800E+02 + -0.9903398E-06 -0.1727497E-02 -0.4462305E-05 0.8622252E-07 0.1252400E+02 + -0.7530195E-06 -0.1294164E-02 -0.3079240E-05 0.6459763E-07 0.1278000E+02 + -0.5597898E-06 -0.9701390E-03 -0.2129932E-05 0.4844297E-07 0.1303600E+02 + -0.4261723E-06 -0.7278158E-03 -0.1496628E-05 0.3636283E-07 0.1329200E+02 + -0.3171916E-06 -0.5464862E-03 -0.1056886E-05 0.2732050E-07 0.1354800E+02 + -0.2416965E-06 -0.4107180E-03 -0.7620499E-06 0.2054534E-07 0.1380400E+02 + -0.1800252E-06 -0.3089713E-03 -0.5546206E-06 0.1546393E-07 0.1406000E+02 + -0.1372363E-06 -0.2326598E-03 -0.4147161E-06 0.1164921E-07 0.1431600E+02 + -0.1022343E-06 -0.1753656E-03 -0.3147953E-06 0.8782751E-08 0.1457200E+02 + -0.7791838E-07 -0.1323115E-03 -0.2468912E-06 0.6626895E-08 0.1482800E+02 + -0.5800449E-07 -0.9992339E-04 -0.1975415E-06 0.5004068E-08 0.1508400E+02 + -0.4415836E-07 -0.7553729E-04 -0.1636582E-06 0.3781453E-08 0.1534000E+02 + -0.3280884E-07 -0.5715659E-04 -0.1385254E-06 0.2859604E-08 0.1559600E+02 + -0.2491523E-07 -0.4329052E-04 -0.1210146E-06 0.2163988E-08 0.1585200E+02 + -0.1844174E-07 -0.3281947E-04 -0.1077074E-06 0.1638689E-08 0.1610800E+02 + -0.1394203E-07 -0.2490580E-04 -0.9823689E-07 0.1241718E-08 0.1636400E+02 + -0.1025218E-07 -0.1891908E-04 -0.9082938E-07 0.9415138E-09 0.1662000E+02 + -0.7692438E-08 -0.1438669E-04 -0.8539718E-07 0.7143355E-09 0.1687600E+02 + -0.5595531E-08 -0.1095216E-04 -0.8100327E-07 0.5423066E-09 0.1713200E+02 + -0.4147089E-08 -0.8347732E-05 -0.7765120E-07 0.4119569E-09 0.1738800E+02 + -0.2963576E-08 -0.6371051E-05 -0.7483810E-07 0.3131281E-09 0.1764400E+02 + -0.2152832E-08 -0.4869813E-05 -0.7258860E-07 0.2381534E-09 0.1790000E+02 + -0.1493862E-08 -0.3728723E-05 -0.7063156E-07 0.1812426E-09 0.1815600E+02 + -0.1049466E-08 -0.2860763E-05 -0.6898356E-07 0.1380194E-09 0.1841200E+02 + -0.6919968E-09 -0.2200249E-05 -0.6751792E-07 0.1051739E-09 0.1866800E+02 + -0.4581243E-09 -0.1696551E-05 -0.6621113E-07 0.8020129E-10 0.1892400E+02 + -0.2739404E-09 -0.1314388E-05 -0.6501141E-07 0.6120459E-10 0.1918000E+02 + -0.1609299E-09 -0.1017272E-05 -0.6392195E-07 0.4674641E-10 0.1943600E+02 + -0.7618943E-10 -0.8068822E-06 -0.6289578E-07 0.3573691E-10 0.1969200E+02 + -0.3236183E-10 -0.6020435E-06 -0.6193826E-07 0.2734932E-10 0.1994800E+02 + -0.4470313E-11 -0.5522402E-06 -0.6102801E-07 0.2095607E-10 0.2020400E+02 + 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 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 @@ + 23 z,ion: 13. 0. jblock,nbl,c: 10 40 0.2000000 + 0. -13. 0. 1388.3896 + 0.0005 -25955.4876 -26035.9849 1388.3896 + 0.001 -12955.4904 -13002.2249 1370.4157 + 0.0015 -8622.15995 -8657.40852 1352.67242 + 0.002 -6455.49896 -6484.42383 1335.15901 + 0.0025 -5155.50461 -5180.8752 1317.87344 + 0.003 -4288.84631 -4311.74825 1300.81287 + 0.0035 -3669.807 -3690.95678 1283.97453 + 0.004 -3205.53222 -3225.34899 1267.35557 + 0.0045 -2844.43198 -2863.20362 1250.9532 + 0.005 -2555.5565 -2573.48224 1234.76462 + 0.0055 -2319.20618 -2336.43164 1218.7871 + 0.006 -2122.25227 -2138.88651 1203.01789 + 0.0065 -1955.60128 -1971.72833 1187.45432 + 0.007 -1812.7622 -1828.44808 1172.09372 + 0.0075 -1688.97061 -1704.26822 1156.93347 + 0.008 -1580.65752 -1595.60984 1141.97097 + 0.0085 -1485.0894 -1499.73187 1127.20367 + 0.009 -1400.14442 -1414.50662 1112.62903 + 0.0095 -1324.14322 -1338.25008 1098.24456 + 0.01 -1255.74651 -1269.61925 1084.04779 + 0.0105 -1193.86593 -1207.52278 1070.03628 + 0.011 -1137.61514 -1151.07185 1056.20763 + 0.0115 -1086.25784 -1099.52814 1042.55946 + 0.012 -1039.1845 -1052.28042 1029.08944 + 0.0125 -995.879101 -1008.81125 1015.79523 + 0.013 -955.908974 -968.686775 1002.67457 + 0.0135 -918.901619 -931.533454 989.725183 + 0.014 -884.541644 -897.03502 976.944851 + 0.0145 -852.553298 -864.914965 964.331372 + 0.015 -822.701413 -834.937463 951.882574 + 0.0155 -794.777386 -806.893339 939.596312 + 0.016 -768.602423 -780.603299 927.470469 + 0.0165 -744.015705 -755.906084 915.502957 + 0.017 -720.878987 -732.66306 903.691711 + 0.0175 -699.066205 -710.747819 892.034694 + 0.018 -678.468878 -690.051574 880.529897 + 0.0185 -658.986714 -670.473757 869.175334 + 0.019 -640.533471 -651.927899 857.969045 + 0.0195 -623.0283 -634.332869 846.909096 + 0.02 -606.401847 -617.619387 835.993579 + 0.021 -575.529149 -586.579343 814.58832 + 0.022 -547.476089 -558.367253 793.738484 + 0.023 -521.868786 -532.608675 773.429655 + 0.024 -498.407843 -509.003021 753.647795 + 0.025 -476.829838 -487.286223 734.37922 + 0.026 -456.92351 -467.246399 715.610606 + 0.027 -438.497498 -448.691673 697.328962 + 0.028 -421.398897 -431.468693 679.52164 + 0.029 -405.485005 -415.434375 662.176315 + 0.03 -390.642765 -400.475327 645.280982 + 0.031 -376.76332 -386.482402 628.823944 + 0.032 -363.761548 -373.37022 612.793809 + 0.033 -351.552739 -361.05385 597.179478 + 0.034 -340.071808 -349.468005 581.970143 + 0.035 -329.251666 -338.545419 567.155272 + 0.036 -319.041882 -328.235504 552.724611 + 0.037 -309.388483 -318.484145 538.668167 + 0.038 -300.251946 -309.251693 524.976213 + 0.039 -291.588234 -300.493996 511.639269 + 0.04 -283.366067 -292.17967 498.648106 + 0.041 -275.549056 -284.272233 485.993731 + 0.042 -268.112233 -276.746632 473.66739 + 0.043 -261.025184 -269.572375 461.660553 + 0.044 -254.267834 -262.729315 449.964914 + 0.045 -247.814496 -256.191702 438.572383 + 0.046 -241.648926 -249.94323 427.475082 + 0.047 -235.749227 -243.961948 416.665337 + 0.048 -230.102184 -238.23459 406.135674 + 0.049 -224.688965 -232.742278 395.878815 + 0.05 -219.498776 -227.474172 385.887672 + 0.051 -214.515292 -222.41391 376.155341 + 0.052 -209.729663 -217.552602 366.675098 + 0.053 -205.127637 -212.875962 357.440396 + 0.054 -200.701935 -208.376678 348.444857 + 0.055 -196.440033 -204.042195 339.682271 + 0.056 -192.335932 -199.866487 331.14659 + 0.057 -188.37856 -195.83845 322.831922 + 0.058 -184.562965 -191.95313 314.732531 + 0.059 -180.879305 -188.200564 306.842829 + 0.06 -177.323488 -184.577119 299.157376 + 0.062 -170.563242 -177.68364 284.378151 + 0.064 -164.243976 -171.233797 270.354108 + 0.066 -158.31648 -165.179383 257.04658 + 0.068 -152.754381 -159.49325 244.418904 + 0.07 -147.518073 -154.13582 232.436292 + 0.072 -142.587816 -149.087217 221.065756 + 0.074 -137.931267 -144.315012 210.275993 + 0.076 -133.533522 -139.804212 200.037321 + 0.078 -129.367834 -135.527992 190.321573 + 0.08 -125.422866 -131.474943 181.102036 + 0.082 -121.676257 -127.622637 172.353361 + 0.084 -118.119334 -123.962337 164.051505 + 0.086 -114.733219 -120.475109 156.173655 + 0.088 -111.511247 -117.154234 148.698169 + 0.09 -108.437347 -113.983587 141.604509 + 0.092 -105.506378 -110.957984 134.873195 + 0.094 -102.704554 -108.063593 128.485738 + 0.096 -100.027905 -105.296401 122.424596 + 0.098 -97.4645262 -102.644462 116.673124 + 0.1 -95.0113453 -100.104668 111.215528 + 0.102 -92.6580213 -97.666641 106.036817 + 0.104 -90.4021799 -95.3279715 101.122768 + 0.106 -88.2347892 -93.0795947 96.4598809 + 0.108 -86.1540174 -90.9196464 92.0353461 + 0.11 -84.151938 -88.840169 87.8370041 + 0.112 -82.2271432 -86.8397243 83.8533162 + 0.114 -80.3726458 -84.9112952 80.0733299 + 0.116 -78.5873706 -83.0537776 76.4866505 + 0.118 -76.8651328 -81.2609577 73.0834112 + 0.12 -75.2051194 -79.5319941 69.8542473 + 0.122 -73.6018352 -77.8613631 66.7902694 + 0.124 -72.0546739 -76.24843 63.8830401 + 0.126 -70.5587356 -74.6882666 61.1245496 + 0.128 -69.113578 -73.1804017 58.5071955 + 0.13 -67.7148172 -71.7204225 56.0237603 + 0.132 -66.362141 -70.307988 53.6673935 + 0.134 -65.0516147 -68.9391302 51.4315911 + 0.136 -63.7830296 -67.6136311 49.3101797 + 0.138 -62.5528436 -66.327814 47.2972981 + 0.14 -61.3609303 -65.0821349 45.387383 + 0.144 -59.0808659 -62.6978646 41.8555907 + 0.148 -56.9349658 -60.4517957 38.6756821 + 0.152 -54.9070555 -58.3291087 35.8123973 + 0.156 -52.9924951 -56.3240681 33.2339623 + 0.16 -51.178006 -54.4233072 30.9117391 + 0.164 -49.4601134 -52.6230381 28.8199127 + 0.168 -47.8277963 -50.9120235 26.9352389 + 0.172 -46.2784539 -49.287447 25.2367647 + 0.176 -44.802842 -47.7398693 23.7056094 + 0.18 -43.3990267 -46.2672108 22.3247649 + 0.184 -42.0591742 -44.8615294 21.0789087 + 0.188 -40.7818674 -43.5213485 19.954241 + 0.192 -39.5604007 -42.2399508 18.9383331 + 0.196 -38.3937632 -41.0163602 18.0199949 + 0.2 -37.2761582 -39.8448573 17.1891513 + 0.204 -36.2068987 -38.7248663 16.4367349 + 0.208 -35.1809254 -37.6514634 15.754585 + 0.212 -34.1978119 -36.6243676 15.1353604 + 0.216 -33.2531013 -35.6392628 14.572457 + 0.22 -32.3465793 -34.6960538 14.0599373 + 0.224 -31.474284 -33.7908604 13.5924632 + 0.228 -30.6361756 -32.9236715 13.165238 + 0.232 -29.8287018 -32.0908994 12.7739526 + 0.236 -29.0519663 -31.2925408 12.414738 + 0.24 -28.3027584 -30.5252037 12.0841211 + 0.244 -27.5813012 -29.7888603 11.7789869 + 0.248 -26.8846701 -29.0802754 11.4965419 + 0.252 -26.2131874 -28.3994151 11.2342835 + 0.256 -25.5641709 -27.743215 10.9899705 + 0.26 -24.938025 -27.1116894 10.7615981 + 0.264 -24.3322739 -26.501982 10.5473736 + 0.268 -23.7473903 -25.914208 10.3456962 + 0.272 -23.1810754 -25.3457431 10.1551372 + 0.276 -22.6338585 -24.7968282 9.97442364 + 0.28 -22.1035942 -24.2650724 9.802422 + 0.284 -21.5908578 -23.7508434 9.63812469 + 0.288 -21.093638 -23.251979 9.48063693 + 0.292 -20.6125475 -22.768953 9.32916572 + 0.296 -20.145693 -22.2997973 9.18300901 + 0.3 -19.6937169 -21.8454622 9.04154678 + 0.308 -18.8285251 -20.9734428 8.77058317 + 0.316 -18.0163073 -20.1522563 8.51265026 + 0.324 -17.2486506 -19.3746181 8.26496577 + 0.332 -16.5266385 -18.6409913 8.0254235 + 0.34 -15.8428052 -17.9442094 7.79244879 + 0.348 -15.1985765 -17.285773 7.56489148 + 0.356 -14.5872668 -16.6591098 7.34192906 + 0.364 -14.0105277 -16.0659685 7.12299838 + 0.372 -13.4623317 -15.5004216 6.90773143 + 0.38 -12.944469 -14.9643603 6.69591252 + 0.388 -12.4514775 -14.4524224 6.48743584 + 0.396 -11.985221 -13.9665684 6.28227942 + 0.404 -11.5407318 -13.5019216 6.08047725 + 0.412 -11.119898 -13.0604543 5.88210419 + 0.42 -10.7181896 -12.637713 5.68725782 + 0.428 -10.337483 -12.235643 5.49605039 + 0.436 -9.97363998 -11.8501679 5.30859716 + 0.444 -9.62849844 -11.4831807 5.12501283 + 0.452 -9.29827352 -11.1309458 4.94540415 + 0.46 -8.98474556 -10.7952873 4.76986906 + 0.468 -8.68445022 -10.4727802 4.59849215 + 0.476 -8.39909707 -10.1651686 4.43134544 + 0.484 -8.12551375 -9.86931144 4.26848561 + 0.492 -7.86533024 -9.58686623 4.10995565 + 0.5 -7.61564097 -9.3149522 3.95578333 + 0.508 -7.37799103 -9.05513641 3.80598319 + 0.516 -7.14971907 -8.8047773 3.66055579 + 0.524 -6.93228265 -8.56534991 3.51948982 + 0.532 -6.72324432 -8.33443262 3.38276174 + 0.54 -6.52397342 -8.11340872 3.2503379 + 0.548 -6.33223792 -7.90005883 3.12217443 + 0.556 -6.14931982 -7.6956761 2.99821919 + 0.564 -5.97317563 -7.49822714 2.8784118 + 0.572 -5.80500198 -7.30891749 2.76268542 + 0.58 -5.64292843 -7.12588467 2.65096684 + 0.588 -5.48806909 -6.95025023 2.54317799 + 0.596 -5.3387123 -6.78030731 2.43923614 + 0.604 -5.195893 -6.61710268 2.33905514 + 0.612 -5.05804527 -6.45905125 2.2425456 + 0.62 -4.92612862 -6.30722765 2.14961601 + 0.636 -4.67562195 -6.01744374 1.97412109 + 0.652 -4.44566994 -5.74890413 1.81181156 + 0.668 -4.23052624 -5.49618914 1.66191892 + 0.684 -4.03240949 -5.26136188 1.52368165 + 0.7 -3.8465426 -5.03969472 1.39634993 + 0.716 -3.67483817 -4.833094 1.27919637 + 0.732 -3.51332341 -4.63759222 1.17151799 + 0.748 -3.36363591 -4.45482501 1.07264259 + 0.764 -3.22247032 -4.28148507 0.981929034 + 0.78 -3.09122154 -4.11896256 0.898770548 + 0.796 -2.96713792 -3.96450079 0.822593918 + 0.812 -2.85140313 -3.81927694 0.752860843 + 0.828 -2.74172462 -3.6809921 0.689066436 + 0.844 -2.63910413 -3.5506409 0.630739347 + 0.86 -2.54162963 -3.42630476 0.57743993 + 0.876 -2.45014743 -3.30882321 0.528759622 + 0.892 -2.36306077 -3.19659337 0.484319004 + 0.908 -2.28108404 -3.0903235 0.443766759 + 0.924 -2.20288158 -2.98867227 0.406777764 + 0.94 -2.12905644 -2.89223684 0.373051862 + 0.956 -2.0584891 -2.79989167 0.342312061 + 0.972 -1.99168909 -2.71213938 0.314303251 + 0.988 -1.9277158 -2.62803134 0.288790558 + 1.004 -1.86700047 -2.54798889 0.2655581 + 1.02 -1.80875054 -2.47120717 0.244407506 + 1.036 -1.75333198 -2.39803675 0.225156752 + 1.052 -1.7000747 -2.32778845 0.207638859 + 1.068 -1.64929043 -2.26075065 0.191700832 + 1.084 -1.60041039 -2.19632655 0.177202523 + 1.1 -1.55370134 -2.13474992 0.164015687 + 1.116 -1.50867833 -2.07549783 0.152022997 + 1.132 -1.46557091 -2.01875707 0.141117213 + 1.148 -1.42396353 -1.96406511 0.131200335 + 1.164 -1.38405502 -1.91157044 0.122182882 + 1.18 -1.34548726 -1.86086279 0.113983169 + 1.196 -1.30843378 -1.81206267 0.106526681 + 1.212 -1.27258406 -1.76480959 0.099745456 + 1.228 -1.2380908 -1.7192104 0.0935775561 + 1.244 -1.20468294 -1.67493554 0.0879665378 + 1.26 -1.17249605 -1.63230557 0.0828609995 + 1.292 -1.1110338 -1.55045023 0.0739832945 + 1.324 -1.05378121 -1.47315545 0.0666183437 + 1.356 -0.999788814 -1.40081147 0.0604963825 + 1.388 -0.949300004 -1.33371461 0.0553943894 + 1.42 -0.901551246 -1.27197391 0.0511281129 + 1.452 -0.856765003 -1.2163633 0.0475454497 + 1.484 -0.814309323 -1.16654104 0.0445208384 + 1.516 -0.7743937 -1.12253391 0.0419507429 + 1.548 -0.736480777 -1.08320985 0.0397498527 + 1.58 -0.700771753 -1.0479237 0.0378480528 + 1.612 -0.666798697 -1.01533405 0.03618785 + 1.644 -0.634756994 -0.98491388 0.0347222995 + 1.676 -0.604231022 -0.955762397 0.0334132007 + 1.708 -0.57541142 -0.927816107 0.0322296281 + 1.74 -0.547923251 -0.900619444 0.0311466379 + 1.772 -0.521952624 -0.874381494 0.0301442262 + 1.804 -0.49715736 -0.848830643 0.029206412 + 1.836 -0.473718787 -0.824230381 0.0283205168 + 1.868 -0.451322038 -0.800341498 0.0274765291 + 1.9 -0.430143189 -0.777402298 0.0266666175 + 1.932 -0.409890891 -0.755169751 0.0258846952 + 1.964 -0.390735421 -0.733850502 0.0251260965 + 1.996 -0.372406246 -0.713201294 0.0243872797 + 2.028 -0.355067324 -0.693406724 0.0236656139 + 2.06 -0.338466953 -0.6742312 0.0229591768 + 2.092 -0.322762323 -0.655844908 0.0222666158 + 2.124 -0.307719043 -0.638024436 0.0215870105 + 2.156 -0.293487193 -0.620929444 0.0209197841 + 2.188 -0.27984847 -0.604350316 0.0202646099 + 2.22 -0.26694561 -0.588437767 0.019621356 + 2.252 -0.254575371 -0.572996059 0.0189900228 + 2.284 -0.242873011 -0.558167472 0.0183707096 + 2.316 -0.23164945 -0.543769585 0.017763573 + 2.348 -0.221032434 -0.529936372 0.0171688084 + 2.38 -0.210846222 -0.516497961 0.0165866224 + 2.412 -0.201211097 -0.503580143 0.0160172241 + 2.444 -0.19196389 -0.491024674 0.0154608071 + 2.476 -0.183217543 -0.478949667 0.0149175474 + 2.508 -0.174820728 -0.46720714 0.0143875912 + 2.54 -0.166879229 -0.4559057 0.0138710569 + 2.604 -0.151929988 -0.434222199 0.0128785532 + 2.668 -0.138560595 -0.414108452 0.0119403188 + 2.732 -0.126217715 -0.395025007 0.0110560748 + 2.796 -0.115181289 -0.377273651 0.0102250884 + 2.86 -0.104981819 -0.36039622 0.00944618503 + 2.924 -0.0958629313 -0.344645705 0.00871786277 + 2.988 -0.0874274208 -0.329632317 0.00803832713 + 3.052 -0.0798857884 -0.315571534 0.00740558938 + 3.116 -0.0729028537 -0.3021327 0.00681750058 + 3.18 -0.0666594558 -0.289499771 0.00627182705 + 3.244 -0.0608733757 -0.277394018 0.00576627626 + 3.308 -0.0556992609 -0.265973254 0.00529855068 + 3.372 -0.0508999204 -0.255004458 0.00486636454 + 3.436 -0.0466071215 -0.244623904 0.00446747976 + 3.5 -0.042621813 -0.234638428 0.00409971514 + 3.564 -0.039055943 -0.225166652 0.00376096883 + 3.628 -0.0357426604 -0.21604973 0.0034492217 + 3.692 -0.0327768615 -0.207391423 0.00316255027 + 3.756 -0.030018806 -0.199061826 0.00289912613 + 3.82 -0.027548798 -0.191151679 0.0026572223 + 3.884 -0.0252498699 -0.18355483 0.00243521024 + 3.948 -0.0231898935 -0.176350116 0.00223156185 + 4.012 -0.0212709928 -0.169450326 0.00204484511 + 4.076 -0.0195504845 -0.162923103 0.00187372338 + 4.14 -0.0179464726 -0.156695965 0.00171695032 + 4.204 -0.0165073374 -0.150825919 0.00157336764 + 4.268 -0.0151645426 -0.145251747 0.00144189977 + 4.332 -0.0139589185 -0.140020527 0.00132155074 + 4.396 -0.0128330872 -0.135079525 0.00121139894 + 4.46 -0.0118215111 -0.130466681 0.00111059354 + 4.524 -0.0108761264 -0.126135728 0.00101834962 + 4.588 -0.0100260305 -0.122116377 0.000933944425 + 4.652 -0.00923093195 -0.118367297 0.000856712853 + 4.716 -0.00851541128 -0.114910969 0.000786043851 + 4.78 -0.00784566261 -0.111709715 0.000721376309 + 4.844 -0.007242465 -0.10878006 0.000662195676 + 4.908 -0.00667742537 -0.106086191 0.0006080303 + 4.972 -0.00616812367 -0.103639571 0.000558448336 + 5.036 -0.00569068627 -0.10141813 0.000513054515 + 5.1 -0.00526000025 -0.0992762735 0.000471487394 + 5.228 -0.00447761068 -0.095782979 0.000398541493 + 5.356 -0.00383940848 -0.0932147911 0.0003372963 + 5.484 -0.00327621448 -0.0907980421 0.000285818263 + 5.612 -0.0028153837 -0.0887309954 0.000242501611 + 5.74 -0.00240764875 -0.0866198114 0.000206009491 + 5.868 -0.00207302125 -0.0842367752 0.000175230412 + 5.996 -0.00177621909 -0.0812901623 0.000149239647 + 6.124 -0.00153193652 -0.0776496372 0.000127267556 + 6.252 -0.00131476745 -0.0733064333 0.000108672511 + 6.38 -0.00113554625 -0.0684550186 9.29186434E-05 + 6.508 -0.00097587795 -0.0633628896 7.95573376E-05 + 6.636 -0.000843787789 -0.0583374804 6.82123256E-05 + 6.764 -0.00072588243 -0.0536092996 5.85675348E-05 + 6.892 -0.000628135765 -0.0493446456 5.03572882E-05 + 7.02 -0.000540739576 -0.0456136891 4.33581998E-05 + 7.148 -0.000468162817 -0.0424395841 3.73824711E-05 + 7.276 -0.000403180398 -0.039793429 3.22722304E-05 + 7.404 -0.000349150908 -0.0376341537 2.78947771E-05 + 7.532 -0.000300721511 -0.0359011349 2.41385453E-05 + 7.66 -0.000260426344 -0.0345382078 2.09097083E-05 + 7.788 -0.000224278582 -0.0334827596 1.81293111E-05 + 7.916 -0.000194196146 -0.032679244 1.57308675E-05 + 8.044 -0.000167195916 -0.032067589 1.36583436E-05 + 8.172 -0.000144732221 -0.0315908422 1.18644738E-05 + 8.3 -0.000124564766 -0.0311850752 1.03093533E-05 + 8.428 -0.000107797002 -0.0307852986 8.95926276E-06 + 8.556 -9.27422736E-05 -0.0303202886 7.78568407E-06 + 8.684 -8.02371475E-05 -0.0297221369 6.76447296E-06 + 8.812 -6.90103045E-05 -0.028929475 5.87515777E-06 + 8.94 -5.96946823E-05 -0.0279014228 5.10034163E-06 + 9.068 -5.13322329E-05 -0.026622781 4.42518973E-06 + 9.196 -4.44004582E-05 -0.0251105685 3.83699167E-06 + 9.324 -3.81784313E-05 -0.0234078245 3.32479279E-06 + 9.452 -3.30252738E-05 -0.0215763769 2.87909088E-06 + 9.58 -2.83997197E-05 -0.0196833543 2.49159314E-06 + 9.708 -2.45711067E-05 -0.0177920682 2.15502603E-06 + 9.836 -2.11340862E-05 -0.0159558646 1.86298825E-06 + 9.964 -1.82902227E-05 -0.0142116609 1.60983627E-06 + 10.092 -1.57366592E-05 -0.0125872179 1.39059377E-06 + 10.22 -1.36240196E-05 -0.0111365643 1.20087597E-06 + 10.476 -1.00360257E-05 -0.00855331294 8.95043669E-07 + 10.732 -7.57858023E-06 -0.00645001052 6.66868225E-07 + 10.988 -5.59324512E-06 -0.00488484266 4.9690287E-07 + 11.244 -4.2315225E-06 -0.0036719993 3.70398737E-07 + 11.5 -3.12926032E-06 -0.00275580821 2.76267649E-07 + 11.756 -2.37175827E-06 -0.00206442544 2.06214669E-07 + 12.012 -1.75734979E-06 -0.00154547605 1.54057202E-07 + 12.268 -1.33421838E-06 -0.0011567623 1.15197825E-07 + 12.524 -9.90339825E-07 -0.000865979602 8.62225224E-08 + 12.78 -7.53019451E-07 -0.000648621482 6.4597635E-08 + 13.036 -5.59789793E-07 -0.000486134457 4.8442975E-08 + 13.292 -4.26172329E-07 -0.000364656213 3.63628311E-08 + 13.548 -3.17191632E-07 -0.000273771529 2.73205026E-08 + 13.804 -2.41696471E-07 -0.00020574002 2.05453389E-08 + 14.06 -1.80025182E-07 -0.000154762947 1.54639331E-08 + 14.316 -1.37236292E-07 -0.000116537277 1.16492103E-08 + 14.572 -1.02234269E-07 -8.78401813E-05 8.78275108E-09 + 14.828 -7.7918381E-08 -6.62792088E-05 6.62689483E-09 + 15.084 -5.80044889E-08 -5.00604659E-05 5.004068E-09 + 15.34 -4.41583574E-08 -3.78504749E-05 3.78145267E-09 + 15.596 -3.28088435E-08 -2.86475556E-05 2.85960361E-09 + 15.852 -2.49152294E-08 -2.17057681E-05 2.16398781E-09 + 16.108 -1.84417362E-08 -1.64635883E-05 1.63868893E-09 + 16.364 -1.3942026E-08 -1.25020194E-05 1.24171762E-09 + 16.62 -1.02521781E-08 -9.50495421E-06 9.41513835E-10 + 16.876 -7.69243803E-09 -7.23604132E-06 7.14335481E-10 + 17.132 -5.59553062E-09 -5.51657994E-06 5.42306598E-10 + 17.388 -4.1470892E-09 -4.2126917E-06 4.11956927E-10 + 17.644 -2.96357552E-09 -3.22294475E-06 3.13128071E-10 + 17.9 -2.15283223E-09 -2.47120067E-06 2.381534E-10 + 18.156 -1.4938624E-09 -1.89967742E-06 1.81242601E-10 + 18.412 -1.04946643E-09 -1.46487347E-06 1.38019384E-10 + 18.668 -6.91996791E-10 -1.13388331E-06 1.05173916E-10 + 18.924 -4.58124333E-10 -8.81381236E-07 8.02012948E-11 + 19.18 -2.73940422E-10 -6.89699784E-07 6.12045912E-11 + 19.436 -1.6092993E-10 -5.40597174E-07 4.67464071E-11 + 19.692 -7.61894269E-11 -4.34889002E-07 3.57369105E-11 + 19.948 -3.23618296E-11 -3.31990888E-07 2.7349321E-11 + 20.204 -4.47031275E-12 -3.06634084E-07 2.09560724E-11 + 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 @@ + + atom number: 13. ionicity: 0. + + perdew - wang xc + + hermann-skillmann mesh + blocks, nbl, c: 10, 40, 0.2000000 + first interval, last interval, final r: 0.000500, 0.256000, 20.460000 + + energy eigenvalue threshold, screening parameter, feedback: 0.000010, 0.005000, 0.500 + + + initial bound state configuration + nlm energy occup. val.el. d-band el. + 100 -0.8450E+02 1.00 1 0 + 200 -0.1625E+02 1.00 1 0 + 210 -0.5336E+01 3.00 1 0 + 300 -0.7812E+00 1.00 1 0 + 310 -0.2312E+00 1.00 1 0 + 100 -0.8450E+02 1.00 1 0 + 200 -0.1625E+02 1.00 1 0 + 210 -0.5336E+01 3.00 1 0 + 300 -0.7812E+00 1.00 1 0 + 310 -0.2312E+00 0.00 1 0 + + number of valence electrons: 13.0 + + initial potentials + + + + + ********************* iteration: 1 *********************** + + l = 0, 3 bound states + l = 1, 1 bound states + l = 0, 3 bound states + l = 1, 1 bound states + + + bound states + + 100 energy: -51.97833 iteration loops: 7 + 200 energy: -3.47892 iteration loops: 10 + 300 energy: -0.08955 iteration loops: 15 + 210 energy: -2.09653 iteration loops: 13 + 100 energy: -51.97833 iteration loops: 7 + 200 energy: -3.47892 iteration loops: 10 + 300 energy: -0.08955 iteration loops: 15 + 210 energy: -2.09653 iteration loops: 13 + + integr charges: total 12.0000000 valence: 12.0000000 0.0000000 + induced moment: 0.00000 + + energy terms + energy eigenvalue sum: -0.123673E+03 + kin: 0.175039E+03 0.175039E+03 coul: -0.451615E+03 exc: -0.175124E+02 + + total energy: -0.2427229E+03 + + charge and spin density profiles + + valence energy: -0.2423878E+03 +0 + potentials vs. distance after 1 iterations + + 0.00050 -0.25944E+05 -0.81015E+02 -0.81015E+02 -0.25978E+05 -0.25978E+05 + 0.00100 -0.12948E+05 -0.46840E+02 -0.46840E+02 -0.12967E+05 -0.12967E+05 + 0.00150 -0.86168E+04 -0.35293E+02 -0.35293E+02 -0.86307E+04 -0.86307E+04 + 0.00200 -0.64512E+04 -0.28887E+02 -0.28887E+02 -0.64625E+04 -0.64625E+04 + 0.00250 -0.51519E+04 -0.25299E+02 -0.25299E+02 -0.51618E+04 -0.51618E+04 + 0.00300 -0.42858E+04 -0.22804E+02 -0.22804E+02 -0.42947E+04 -0.42947E+04 + 0.00350 -0.36672E+04 -0.21035E+02 -0.21035E+02 -0.36755E+04 -0.36755E+04 + 0.00400 -0.32033E+04 -0.19689E+02 -0.19689E+02 -0.32111E+04 -0.32111E+04 + 0.00450 -0.28425E+04 -0.18635E+02 -0.18635E+02 -0.28499E+04 -0.28499E+04 + 0.00500 -0.25539E+04 -0.17782E+02 -0.17782E+02 -0.25610E+04 -0.25610E+04 + 0.00550 -0.23178E+04 -0.17076E+02 -0.17076E+02 -0.23246E+04 -0.23246E+04 + 0.00600 -0.21210E+04 -0.16480E+02 -0.16480E+02 -0.21277E+04 -0.21277E+04 + 0.00650 -0.19546E+04 -0.15970E+02 -0.15970E+02 -0.19611E+04 -0.19611E+04 + 0.00700 -0.18119E+04 -0.15526E+02 -0.15526E+02 -0.18183E+04 -0.18183E+04 + 0.00750 -0.16883E+04 -0.15135E+02 -0.15135E+02 -0.16945E+04 -0.16945E+04 + 0.00800 -0.15801E+04 -0.14788E+02 -0.14788E+02 -0.15862E+04 -0.15862E+04 + 0.00850 -0.14847E+04 -0.14477E+02 -0.14477E+02 -0.14907E+04 -0.14907E+04 + 0.00900 -0.13998E+04 -0.14196E+02 -0.14196E+02 -0.14058E+04 -0.14058E+04 + 0.00950 -0.13239E+04 -0.13940E+02 -0.13940E+02 -0.13298E+04 -0.13298E+04 + 0.01000 -0.12556E+04 -0.13705E+02 -0.13705E+02 -0.12615E+04 -0.12615E+04 + 0.01050 -0.11939E+04 -0.13489E+02 -0.13489E+02 -0.11996E+04 -0.11996E+04 + 0.01100 -0.11377E+04 -0.13289E+02 -0.13289E+02 -0.11434E+04 -0.11434E+04 + 0.01150 -0.10864E+04 -0.13102E+02 -0.13102E+02 -0.10921E+04 -0.10921E+04 + 0.01200 -0.10394E+04 -0.12928E+02 -0.12928E+02 -0.10451E+04 -0.10451E+04 + 0.01250 -0.99622E+03 -0.12764E+02 -0.12764E+02 -0.10018E+04 -0.10018E+04 + 0.01300 -0.95632E+03 -0.12610E+02 -0.12610E+02 -0.96186E+03 -0.96186E+03 + 0.01350 -0.91938E+03 -0.12465E+02 -0.12465E+02 -0.92489E+03 -0.92489E+03 + 0.01400 -0.88509E+03 -0.12327E+02 -0.12327E+02 -0.89056E+03 -0.89056E+03 + 0.01450 -0.85317E+03 -0.12195E+02 -0.12195E+02 -0.85860E+03 -0.85860E+03 + 0.01500 -0.82337E+03 -0.12070E+02 -0.12070E+02 -0.82878E+03 -0.82878E+03 + 0.01550 -0.79551E+03 -0.11951E+02 -0.11951E+02 -0.80089E+03 -0.80089E+03 + 0.01600 -0.76939E+03 -0.11836E+02 -0.11836E+02 -0.77474E+03 -0.77474E+03 + 0.01650 -0.74485E+03 -0.11727E+02 -0.11727E+02 -0.75018E+03 -0.75018E+03 + 0.01700 -0.72177E+03 -0.11621E+02 -0.11621E+02 -0.72706E+03 -0.72706E+03 + 0.01750 -0.70000E+03 -0.11519E+02 -0.11519E+02 -0.70527E+03 -0.70527E+03 + 0.01800 -0.67945E+03 -0.11421E+02 -0.11421E+02 -0.68470E+03 -0.68470E+03 + 0.01850 -0.66002E+03 -0.11327E+02 -0.11327E+02 -0.66524E+03 -0.66524E+03 + 0.01900 -0.64161E+03 -0.11235E+02 -0.11235E+02 -0.64680E+03 -0.64680E+03 + 0.01950 -0.62414E+03 -0.11146E+02 -0.11146E+02 -0.62932E+03 -0.62932E+03 + 0.02000 -0.60756E+03 -0.11060E+02 -0.11060E+02 -0.61271E+03 -0.61271E+03 + 0.02100 -0.57676E+03 -0.10894E+02 -0.10894E+02 -0.58187E+03 -0.58187E+03 + 0.02200 -0.54877E+03 -0.10737E+02 -0.10737E+02 -0.55384E+03 -0.55384E+03 + 0.02300 -0.52323E+03 -0.10588E+02 -0.10588E+02 -0.52826E+03 -0.52826E+03 + 0.02400 -0.49983E+03 -0.10445E+02 -0.10445E+02 -0.50482E+03 -0.50482E+03 + 0.02500 -0.47831E+03 -0.10308E+02 -0.10308E+02 -0.48326E+03 -0.48326E+03 + 0.02600 -0.45845E+03 -0.10177E+02 -0.10177E+02 -0.46337E+03 -0.46337E+03 + 0.02700 -0.44008E+03 -0.10050E+02 -0.10050E+02 -0.44495E+03 -0.44495E+03 + 0.02800 -0.42302E+03 -0.99279E+01 -0.99279E+01 -0.42786E+03 -0.42786E+03 + 0.02900 -0.40715E+03 -0.98095E+01 -0.98095E+01 -0.41195E+03 -0.41195E+03 + 0.03000 -0.39234E+03 -0.96948E+01 -0.96948E+01 -0.39711E+03 -0.39711E+03 + 0.03100 -0.37850E+03 -0.95835E+01 -0.95835E+01 -0.38323E+03 -0.38323E+03 + 0.03200 -0.36553E+03 -0.94752E+01 -0.94752E+01 -0.37023E+03 -0.37023E+03 + 0.03300 -0.35335E+03 -0.93697E+01 -0.93697E+01 -0.35801E+03 -0.35801E+03 + 0.03400 -0.34190E+03 -0.92669E+01 -0.92669E+01 -0.34653E+03 -0.34653E+03 + 0.03500 -0.33111E+03 -0.91665E+01 -0.91665E+01 -0.33570E+03 -0.33570E+03 + 0.03600 -0.32092E+03 -0.90685E+01 -0.90685E+01 -0.32548E+03 -0.32548E+03 + 0.03700 -0.31129E+03 -0.89726E+01 -0.89726E+01 -0.31581E+03 -0.31581E+03 + 0.03800 -0.30217E+03 -0.88787E+01 -0.88787E+01 -0.30666E+03 -0.30666E+03 + 0.03900 -0.29353E+03 -0.87868E+01 -0.87868E+01 -0.29798E+03 -0.29798E+03 + 0.04000 -0.28532E+03 -0.86967E+01 -0.86967E+01 -0.28974E+03 -0.28974E+03 + 0.04100 -0.27752E+03 -0.86083E+01 -0.86083E+01 -0.28191E+03 -0.28191E+03 + 0.04200 -0.27010E+03 -0.85215E+01 -0.85215E+01 -0.27445E+03 -0.27445E+03 + 0.04300 -0.26302E+03 -0.84363E+01 -0.84363E+01 -0.26734E+03 -0.26734E+03 + 0.04400 -0.25627E+03 -0.83525E+01 -0.83525E+01 -0.26056E+03 -0.26056E+03 + 0.04500 -0.24983E+03 -0.82702E+01 -0.82702E+01 -0.25408E+03 -0.25408E+03 + 0.04600 -0.24367E+03 -0.81892E+01 -0.81892E+01 -0.24789E+03 -0.24789E+03 + 0.04700 -0.23778E+03 -0.81096E+01 -0.81096E+01 -0.24197E+03 -0.24197E+03 + 0.04800 -0.23214E+03 -0.80312E+01 -0.80312E+01 -0.23629E+03 -0.23629E+03 + 0.04900 -0.22673E+03 -0.79540E+01 -0.79540E+01 -0.23085E+03 -0.23085E+03 + 0.05000 -0.22155E+03 -0.78779E+01 -0.78779E+01 -0.22563E+03 -0.22563E+03 + 0.05100 -0.21657E+03 -0.78030E+01 -0.78030E+01 -0.22062E+03 -0.22062E+03 + 0.05200 -0.21179E+03 -0.77291E+01 -0.77291E+01 -0.21581E+03 -0.21581E+03 + 0.05300 -0.20719E+03 -0.76563E+01 -0.76563E+01 -0.21117E+03 -0.21117E+03 + 0.05400 -0.20276E+03 -0.75845E+01 -0.75845E+01 -0.20672E+03 -0.20672E+03 + 0.05500 -0.19850E+03 -0.75137E+01 -0.75137E+01 -0.20242E+03 -0.20242E+03 + 0.05600 -0.19440E+03 -0.74438E+01 -0.74438E+01 -0.19829E+03 -0.19829E+03 + 0.05700 -0.19044E+03 -0.73749E+01 -0.73749E+01 -0.19430E+03 -0.19430E+03 + 0.05800 -0.18662E+03 -0.73068E+01 -0.73068E+01 -0.19045E+03 -0.19045E+03 + 0.05900 -0.18294E+03 -0.72396E+01 -0.72396E+01 -0.18673E+03 -0.18673E+03 + 0.06000 -0.17938E+03 -0.71736E+01 -0.71736E+01 -0.18314E+03 -0.18314E+03 + 0.06200 -0.17261E+03 -0.70436E+01 -0.70436E+01 -0.17631E+03 -0.17631E+03 + 0.06400 -0.16628E+03 -0.69162E+01 -0.69162E+01 -0.16992E+03 -0.16992E+03 + 0.06600 -0.16035E+03 -0.67924E+01 -0.67924E+01 -0.16392E+03 -0.16392E+03 + 0.06800 -0.15477E+03 -0.66713E+01 -0.66713E+01 -0.15828E+03 -0.15828E+03 + 0.07000 -0.14952E+03 -0.65531E+01 -0.65531E+01 -0.15298E+03 -0.15298E+03 + 0.07200 -0.14458E+03 -0.64375E+01 -0.64375E+01 -0.14797E+03 -0.14797E+03 + 0.07400 -0.13991E+03 -0.63245E+01 -0.63245E+01 -0.14324E+03 -0.14324E+03 + 0.07600 -0.13549E+03 -0.62141E+01 -0.62141E+01 -0.13877E+03 -0.13877E+03 + 0.07800 -0.13131E+03 -0.61061E+01 -0.61061E+01 -0.13453E+03 -0.13453E+03 + 0.08000 -0.12735E+03 -0.60004E+01 -0.60004E+01 -0.13051E+03 -0.13051E+03 + 0.08200 -0.12359E+03 -0.58971E+01 -0.58971E+01 -0.12669E+03 -0.12669E+03 + 0.08400 -0.12001E+03 -0.57959E+01 -0.57959E+01 -0.12306E+03 -0.12306E+03 + 0.08600 -0.11661E+03 -0.56970E+01 -0.56970E+01 -0.11960E+03 -0.11960E+03 + 0.08800 -0.11337E+03 -0.56001E+01 -0.56001E+01 -0.11631E+03 -0.11631E+03 + 0.09000 -0.11028E+03 -0.55053E+01 -0.55053E+01 -0.11316E+03 -0.11316E+03 + 0.09200 -0.10733E+03 -0.54126E+01 -0.54126E+01 -0.11016E+03 -0.11016E+03 + 0.09400 -0.10451E+03 -0.53218E+01 -0.53218E+01 -0.10729E+03 -0.10729E+03 + 0.09600 -0.10181E+03 -0.52330E+01 -0.52330E+01 -0.10455E+03 -0.10455E+03 + 0.09800 -0.99229E+02 -0.51460E+01 -0.51460E+01 -0.10192E+03 -0.10192E+03 + 0.10000 -0.96757E+02 -0.50609E+01 -0.50609E+01 -0.99396E+02 -0.99396E+02 + 0.10200 -0.94386E+02 -0.49776E+01 -0.49776E+01 -0.96978E+02 -0.96978E+02 + 0.10400 -0.92112E+02 -0.48961E+01 -0.48961E+01 -0.94657E+02 -0.94657E+02 + 0.10600 -0.89927E+02 -0.48164E+01 -0.48164E+01 -0.92427E+02 -0.92427E+02 + 0.10800 -0.87828E+02 -0.47384E+01 -0.47384E+01 -0.90283E+02 -0.90283E+02 + 0.11000 -0.85809E+02 -0.46621E+01 -0.46621E+01 -0.88221E+02 -0.88221E+02 + 0.11200 -0.83867E+02 -0.45874E+01 -0.45874E+01 -0.86236E+02 -0.86236E+02 + 0.11400 -0.81996E+02 -0.45144E+01 -0.45144E+01 -0.84324E+02 -0.84324E+02 + 0.11600 -0.80194E+02 -0.44430E+01 -0.44430E+01 -0.82481E+02 -0.82481E+02 + 0.11800 -0.78456E+02 -0.43732E+01 -0.43732E+01 -0.80703E+02 -0.80703E+02 + 0.12000 -0.76780E+02 -0.43049E+01 -0.43049E+01 -0.78987E+02 -0.78987E+02 + 0.12200 -0.75162E+02 -0.42382E+01 -0.42382E+01 -0.77331E+02 -0.77331E+02 + 0.12400 -0.73600E+02 -0.41730E+01 -0.41730E+01 -0.75731E+02 -0.75731E+02 + 0.12600 -0.72089E+02 -0.41092E+01 -0.41092E+01 -0.74185E+02 -0.74185E+02 + 0.12800 -0.70630E+02 -0.40469E+01 -0.40469E+01 -0.72689E+02 -0.72689E+02 + 0.13000 -0.69217E+02 -0.39861E+01 -0.39861E+01 -0.71242E+02 -0.71242E+02 + 0.13200 -0.67851E+02 -0.39266E+01 -0.39266E+01 -0.69842E+02 -0.69842E+02 + 0.13400 -0.66528E+02 -0.38685E+01 -0.38685E+01 -0.68486E+02 -0.68486E+02 + 0.13600 -0.65246E+02 -0.38118E+01 -0.38118E+01 -0.67172E+02 -0.67172E+02 + 0.13800 -0.64004E+02 -0.37563E+01 -0.37563E+01 -0.65898E+02 -0.65898E+02 + 0.14000 -0.62800E+02 -0.37027E+01 -0.37027E+01 -0.64664E+02 -0.64664E+02 + 0.14400 -0.60498E+02 -0.35986E+01 -0.35986E+01 -0.62303E+02 -0.62303E+02 + 0.14800 -0.58330E+02 -0.34985E+01 -0.34985E+01 -0.60079E+02 -0.60079E+02 + 0.15200 -0.56283E+02 -0.34037E+01 -0.34037E+01 -0.57980E+02 -0.57980E+02 + 0.15600 -0.54350E+02 -0.33131E+01 -0.33131E+01 -0.55996E+02 -0.55996E+02 + 0.16000 -0.52519E+02 -0.32267E+01 -0.32267E+01 -0.54118E+02 -0.54118E+02 + 0.16400 -0.50786E+02 -0.31442E+01 -0.31442E+01 -0.52339E+02 -0.52339E+02 + 0.16800 -0.49140E+02 -0.30654E+01 -0.30654E+01 -0.50651E+02 -0.50651E+02 + 0.17200 -0.47577E+02 -0.29900E+01 -0.29900E+01 -0.49048E+02 -0.49048E+02 + 0.17600 -0.46090E+02 -0.29178E+01 -0.29178E+01 -0.47523E+02 -0.47523E+02 + 0.18000 -0.44676E+02 -0.28487E+01 -0.28487E+01 -0.46072E+02 -0.46072E+02 + 0.18400 -0.43327E+02 -0.27823E+01 -0.27823E+01 -0.44689E+02 -0.44689E+02 + 0.18800 -0.42041E+02 -0.27188E+01 -0.27188E+01 -0.43370E+02 -0.43370E+02 + 0.19200 -0.40812E+02 -0.26578E+01 -0.26578E+01 -0.42111E+02 -0.42111E+02 + 0.19600 -0.39638E+02 -0.25995E+01 -0.25995E+01 -0.40908E+02 -0.40908E+02 + 0.20000 -0.38515E+02 -0.25437E+01 -0.25437E+01 -0.39758E+02 -0.39758E+02 + 0.20400 -0.37441E+02 -0.24906E+01 -0.24906E+01 -0.38657E+02 -0.38657E+02 + 0.20800 -0.36411E+02 -0.24402E+01 -0.24402E+01 -0.37603E+02 -0.37603E+02 + 0.21200 -0.35424E+02 -0.23927E+01 -0.23927E+01 -0.36594E+02 -0.36594E+02 + 0.21600 -0.34476E+02 -0.23481E+01 -0.23481E+01 -0.35626E+02 -0.35626E+02 + 0.22000 -0.33567E+02 -0.23066E+01 -0.23066E+01 -0.34697E+02 -0.34697E+02 + 0.22400 -0.32693E+02 -0.22684E+01 -0.22684E+01 -0.33807E+02 -0.33807E+02 + 0.22800 -0.31853E+02 -0.22336E+01 -0.22336E+01 -0.32952E+02 -0.32952E+02 + 0.23200 -0.31044E+02 -0.22023E+01 -0.22023E+01 -0.32130E+02 -0.32130E+02 + 0.23600 -0.30267E+02 -0.21745E+01 -0.21745E+01 -0.31341E+02 -0.31341E+02 + 0.24000 -0.29517E+02 -0.21503E+01 -0.21503E+01 -0.30583E+02 -0.30583E+02 + 0.24400 -0.28795E+02 -0.21295E+01 -0.21295E+01 -0.29853E+02 -0.29853E+02 + 0.24800 -0.28099E+02 -0.21120E+01 -0.21120E+01 -0.29151E+02 -0.29151E+02 + 0.25200 -0.27427E+02 -0.20977E+01 -0.20977E+01 -0.28476E+02 -0.28476E+02 + 0.25600 -0.26779E+02 -0.20862E+01 -0.20862E+01 -0.27825E+02 -0.27825E+02 + 0.26000 -0.26153E+02 -0.20772E+01 -0.20772E+01 -0.27199E+02 -0.27199E+02 + 0.26400 -0.25548E+02 -0.20703E+01 -0.20703E+01 -0.26594E+02 -0.26594E+02 + 0.26800 -0.24964E+02 -0.20653E+01 -0.20653E+01 -0.26011E+02 -0.26011E+02 + 0.27200 -0.24399E+02 -0.20618E+01 -0.20618E+01 -0.25448E+02 -0.25448E+02 + 0.27600 -0.23853E+02 -0.20594E+01 -0.20594E+01 -0.24904E+02 -0.24904E+02 + 0.28000 -0.23323E+02 -0.20578E+01 -0.20578E+01 -0.24377E+02 -0.24377E+02 + 0.28400 -0.22812E+02 -0.20568E+01 -0.20568E+01 -0.23869E+02 -0.23869E+02 + 0.28800 -0.22316E+02 -0.20560E+01 -0.20560E+01 -0.23376E+02 -0.23376E+02 + 0.29200 -0.21835E+02 -0.20553E+01 -0.20553E+01 -0.22899E+02 -0.22899E+02 + 0.29600 -0.21369E+02 -0.20546E+01 -0.20546E+01 -0.22437E+02 -0.22437E+02 + 0.30000 -0.20918E+02 -0.20540E+01 -0.20540E+01 -0.21989E+02 -0.21989E+02 + 0.30800 -0.20055E+02 -0.20510E+01 -0.20510E+01 -0.21132E+02 -0.21132E+02 + 0.31600 -0.19244E+02 -0.20458E+01 -0.20458E+01 -0.20324E+02 -0.20324E+02 + 0.32400 -0.18477E+02 -0.20397E+01 -0.20397E+01 -0.19562E+02 -0.19562E+02 + 0.33200 -0.17755E+02 -0.20319E+01 -0.20319E+01 -0.18842E+02 -0.18842E+02 + 0.34000 -0.17071E+02 -0.20226E+01 -0.20226E+01 -0.18161E+02 -0.18161E+02 + 0.34800 -0.16426E+02 -0.20120E+01 -0.20120E+01 -0.17515E+02 -0.17515E+02 + 0.35600 -0.15813E+02 -0.20003E+01 -0.20003E+01 -0.16903E+02 -0.16903E+02 + 0.36400 -0.15234E+02 -0.19875E+01 -0.19875E+01 -0.16323E+02 -0.16323E+02 + 0.37200 -0.14684E+02 -0.19737E+01 -0.19737E+01 -0.15771E+02 -0.15771E+02 + 0.38000 -0.14162E+02 -0.19590E+01 -0.19590E+01 -0.15246E+02 -0.15246E+02 + 0.38800 -0.13666E+02 -0.19435E+01 -0.19435E+01 -0.14747E+02 -0.14747E+02 + 0.39600 -0.13194E+02 -0.19273E+01 -0.19273E+01 -0.14271E+02 -0.14271E+02 + 0.40400 -0.12745E+02 -0.19104E+01 -0.19104E+01 -0.13817E+02 -0.13817E+02 + 0.41200 -0.12318E+02 -0.18930E+01 -0.18930E+01 -0.13385E+02 -0.13385E+02 + 0.42000 -0.11911E+02 -0.18750E+01 -0.18750E+01 -0.12971E+02 -0.12971E+02 + 0.42800 -0.11523E+02 -0.18567E+01 -0.18567E+01 -0.12576E+02 -0.12576E+02 + 0.43600 -0.11152E+02 -0.18379E+01 -0.18379E+01 -0.12199E+02 -0.12199E+02 + 0.44400 -0.10799E+02 -0.18189E+01 -0.18189E+01 -0.11838E+02 -0.11838E+02 + 0.45200 -0.10460E+02 -0.17996E+01 -0.17996E+01 -0.11492E+02 -0.11492E+02 + 0.46000 -0.10138E+02 -0.17800E+01 -0.17800E+01 -0.11161E+02 -0.11161E+02 + 0.46800 -0.98287E+01 -0.17604E+01 -0.17604E+01 -0.10843E+02 -0.10843E+02 + 0.47600 -0.95335E+01 -0.17406E+01 -0.17406E+01 -0.10538E+02 -0.10538E+02 + 0.48400 -0.92504E+01 -0.17207E+01 -0.17207E+01 -0.10246E+02 -0.10246E+02 + 0.49200 -0.89798E+01 -0.17007E+01 -0.17007E+01 -0.99654E+01 -0.99654E+01 + 0.50000 -0.87199E+01 -0.16807E+01 -0.16807E+01 -0.96956E+01 -0.96956E+01 + 0.50800 -0.84713E+01 -0.16607E+01 -0.16607E+01 -0.94366E+01 -0.94366E+01 + 0.51600 -0.82323E+01 -0.16407E+01 -0.16407E+01 -0.91873E+01 -0.91873E+01 + 0.52400 -0.80034E+01 -0.16207E+01 -0.16207E+01 -0.89476E+01 -0.89476E+01 + 0.53200 -0.77833E+01 -0.16008E+01 -0.16008E+01 -0.87167E+01 -0.87167E+01 + 0.54000 -0.75722E+01 -0.15809E+01 -0.15809E+01 -0.84945E+01 -0.84945E+01 + 0.54800 -0.73690E+01 -0.15611E+01 -0.15611E+01 -0.82803E+01 -0.82803E+01 + 0.55600 -0.71741E+01 -0.15414E+01 -0.15414E+01 -0.80739E+01 -0.80739E+01 + 0.56400 -0.69862E+01 -0.15218E+01 -0.15218E+01 -0.78748E+01 -0.78748E+01 + 0.57200 -0.68059E+01 -0.15023E+01 -0.15023E+01 -0.76828E+01 -0.76828E+01 + 0.58000 -0.66319E+01 -0.14829E+01 -0.14829E+01 -0.74974E+01 -0.74974E+01 + 0.58800 -0.64648E+01 -0.14637E+01 -0.14637E+01 -0.73186E+01 -0.73186E+01 + 0.59600 -0.63034E+01 -0.14445E+01 -0.14445E+01 -0.71457E+01 -0.71457E+01 + 0.60400 -0.61483E+01 -0.14256E+01 -0.14256E+01 -0.69788E+01 -0.69788E+01 + 0.61200 -0.59985E+01 -0.14067E+01 -0.14067E+01 -0.68172E+01 -0.68172E+01 + 0.62000 -0.58543E+01 -0.13881E+01 -0.13881E+01 -0.66613E+01 -0.66613E+01 + 0.63600 -0.55801E+01 -0.13513E+01 -0.13513E+01 -0.63639E+01 -0.63639E+01 + 0.65200 -0.53257E+01 -0.13151E+01 -0.13151E+01 -0.60858E+01 -0.60858E+01 + 0.66800 -0.50874E+01 -0.12797E+01 -0.12797E+01 -0.58244E+01 -0.58244E+01 + 0.68400 -0.48655E+01 -0.12449E+01 -0.12449E+01 -0.55793E+01 -0.55793E+01 + 0.70000 -0.46572E+01 -0.12109E+01 -0.12109E+01 -0.53483E+01 -0.53483E+01 + 0.71600 -0.44628E+01 -0.11777E+01 -0.11777E+01 -0.51311E+01 -0.51311E+01 + 0.73200 -0.42798E+01 -0.11452E+01 -0.11452E+01 -0.49260E+01 -0.49260E+01 + 0.74800 -0.41085E+01 -0.11134E+01 -0.11134E+01 -0.47328E+01 -0.47328E+01 + 0.76400 -0.39469E+01 -0.10825E+01 -0.10825E+01 -0.45499E+01 -0.45499E+01 + 0.78000 -0.37954E+01 -0.10523E+01 -0.10523E+01 -0.43772E+01 -0.43772E+01 + 0.79600 -0.36521E+01 -0.10229E+01 -0.10229E+01 -0.42135E+01 -0.42135E+01 + 0.81200 -0.35174E+01 -0.99421E+00 -0.99421E+00 -0.40585E+01 -0.40585E+01 + 0.82800 -0.33897E+01 -0.96629E+00 -0.96629E+00 -0.39114E+01 -0.39114E+01 + 0.84400 -0.32694E+01 -0.93913E+00 -0.93913E+00 -0.37718E+01 -0.37718E+01 + 0.86000 -0.31553E+01 -0.91271E+00 -0.91271E+00 -0.36391E+01 -0.36391E+01 + 0.87600 -0.30474E+01 -0.88702E+00 -0.88702E+00 -0.35130E+01 -0.35130E+01 + 0.89200 -0.29449E+01 -0.86206E+00 -0.86206E+00 -0.33929E+01 -0.33929E+01 + 0.90800 -0.28478E+01 -0.83782E+00 -0.83782E+00 -0.32786E+01 -0.32786E+01 + 0.92400 -0.27554E+01 -0.81428E+00 -0.81428E+00 -0.31696E+01 -0.31696E+01 + 0.94000 -0.26677E+01 -0.79146E+00 -0.79146E+00 -0.30658E+01 -0.30658E+01 + 0.95600 -0.25840E+01 -0.76932E+00 -0.76932E+00 -0.29666E+01 -0.29666E+01 + 0.97200 -0.25045E+01 -0.74788E+00 -0.74788E+00 -0.28719E+01 -0.28719E+01 + 0.98800 -0.24286E+01 -0.72712E+00 -0.72712E+00 -0.27814E+01 -0.27814E+01 + 1.00400 -0.23563E+01 -0.70703E+00 -0.70703E+00 -0.26949E+01 -0.26949E+01 + 1.02000 -0.22870E+01 -0.68762E+00 -0.68762E+00 -0.26122E+01 -0.26122E+01 + 1.03600 -0.22211E+01 -0.66888E+00 -0.66888E+00 -0.25330E+01 -0.25330E+01 + 1.05200 -0.21578E+01 -0.65080E+00 -0.65080E+00 -0.24572E+01 -0.24572E+01 + 1.06800 -0.20974E+01 -0.63338E+00 -0.63338E+00 -0.23846E+01 -0.23846E+01 + 1.08400 -0.20394E+01 -0.61661E+00 -0.61661E+00 -0.23150E+01 -0.23150E+01 + 1.10000 -0.19840E+01 -0.60048E+00 -0.60048E+00 -0.22483E+01 -0.22483E+01 + 1.11600 -0.19307E+01 -0.58499E+00 -0.58499E+00 -0.21843E+01 -0.21843E+01 + 1.13200 -0.18797E+01 -0.57014E+00 -0.57014E+00 -0.21230E+01 -0.21230E+01 + 1.14800 -0.18306E+01 -0.55590E+00 -0.55590E+00 -0.20641E+01 -0.20641E+01 + 1.16400 -0.17835E+01 -0.54226E+00 -0.54226E+00 -0.20076E+01 -0.20076E+01 + 1.18000 -0.17381E+01 -0.52922E+00 -0.52922E+00 -0.19532E+01 -0.19532E+01 + 1.19600 -0.16946E+01 -0.51674E+00 -0.51674E+00 -0.19011E+01 -0.19011E+01 + 1.21200 -0.16526E+01 -0.50481E+00 -0.50481E+00 -0.18509E+01 -0.18509E+01 + 1.22800 -0.16122E+01 -0.49341E+00 -0.49341E+00 -0.18027E+01 -0.18027E+01 + 1.24400 -0.15732E+01 -0.48250E+00 -0.48250E+00 -0.17564E+01 -0.17564E+01 + 1.26000 -0.15356E+01 -0.47209E+00 -0.47209E+00 -0.17117E+01 -0.17117E+01 + 1.29200 -0.14644E+01 -0.45255E+00 -0.45255E+00 -0.16273E+01 -0.16273E+01 + 1.32400 -0.13981E+01 -0.43437E+00 -0.43437E+00 -0.15489E+01 -0.15489E+01 + 1.35600 -0.13360E+01 -0.41732E+00 -0.41732E+00 -0.14757E+01 -0.14757E+01 + 1.38800 -0.12781E+01 -0.40112E+00 -0.40112E+00 -0.14073E+01 -0.14073E+01 + 1.42000 -0.12237E+01 -0.38551E+00 -0.38551E+00 -0.13431E+01 -0.13431E+01 + 1.45200 -0.11728E+01 -0.37036E+00 -0.37036E+00 -0.12828E+01 -0.12828E+01 + 1.48400 -0.11248E+01 -0.35566E+00 -0.35566E+00 -0.12260E+01 -0.12260E+01 + 1.51600 -0.10797E+01 -0.34154E+00 -0.34154E+00 -0.11726E+01 -0.11726E+01 + 1.54800 -0.10372E+01 -0.32826E+00 -0.32826E+00 -0.11224E+01 -0.11224E+01 + 1.58000 -0.99714E+00 -0.31620E+00 -0.31620E+00 -0.10754E+01 -0.10754E+01 + 1.61200 -0.95925E+00 -0.30571E+00 -0.30571E+00 -0.10316E+01 -0.10316E+01 + 1.64400 -0.92348E+00 -0.29709E+00 -0.29709E+00 -0.99096E+00 -0.99096E+00 + 1.67600 -0.88958E+00 -0.29045E+00 -0.29045E+00 -0.95336E+00 -0.95336E+00 + 1.70800 -0.85751E+00 -0.28573E+00 -0.28573E+00 -0.91865E+00 -0.91865E+00 + 1.74000 -0.82706E+00 -0.28270E+00 -0.28270E+00 -0.88654E+00 -0.88654E+00 + 1.77200 -0.79820E+00 -0.28100E+00 -0.28100E+00 -0.85677E+00 -0.85677E+00 + 1.80400 -0.77075E+00 -0.28024E+00 -0.28024E+00 -0.82900E+00 -0.82900E+00 + 1.83600 -0.74470E+00 -0.28005E+00 -0.28005E+00 -0.80296E+00 -0.80296E+00 + 1.86800 -0.71989E+00 -0.28012E+00 -0.28012E+00 -0.77839E+00 -0.77839E+00 + 1.90000 -0.69630E+00 -0.28023E+00 -0.28023E+00 -0.75510E+00 -0.75510E+00 + 1.93200 -0.67380E+00 -0.28023E+00 -0.28023E+00 -0.73292E+00 -0.73292E+00 + 1.96400 -0.65238E+00 -0.28002E+00 -0.28002E+00 -0.71175E+00 -0.71175E+00 + 1.99600 -0.63192E+00 -0.27957E+00 -0.27957E+00 -0.69148E+00 -0.69148E+00 + 2.02800 -0.61243E+00 -0.27888E+00 -0.27888E+00 -0.67208E+00 -0.67208E+00 + 2.06000 -0.59378E+00 -0.27795E+00 -0.27795E+00 -0.65345E+00 -0.65345E+00 + 2.09200 -0.57600E+00 -0.27681E+00 -0.27681E+00 -0.63559E+00 -0.63559E+00 + 2.12400 -0.55897E+00 -0.27548E+00 -0.27548E+00 -0.61843E+00 -0.61843E+00 + 2.15600 -0.54270E+00 -0.27398E+00 -0.27398E+00 -0.60196E+00 -0.60196E+00 + 2.18800 -0.52711E+00 -0.27234E+00 -0.27234E+00 -0.58612E+00 -0.58612E+00 + 2.22000 -0.51221E+00 -0.27058E+00 -0.27058E+00 -0.57092E+00 -0.57092E+00 + 2.25200 -0.49791E+00 -0.26871E+00 -0.26871E+00 -0.55628E+00 -0.55628E+00 + 2.28400 -0.48423E+00 -0.26675E+00 -0.26675E+00 -0.54222E+00 -0.54222E+00 + 2.31600 -0.47109E+00 -0.26472E+00 -0.26472E+00 -0.52867E+00 -0.52867E+00 + 2.34800 -0.45851E+00 -0.26261E+00 -0.26261E+00 -0.51565E+00 -0.51565E+00 + 2.38000 -0.44641E+00 -0.26046E+00 -0.26046E+00 -0.50309E+00 -0.50309E+00 + 2.41200 -0.43482E+00 -0.25825E+00 -0.25825E+00 -0.49101E+00 -0.49101E+00 + 2.44400 -0.42366E+00 -0.25601E+00 -0.25601E+00 -0.47936E+00 -0.47936E+00 + 2.47600 -0.41296E+00 -0.25372E+00 -0.25372E+00 -0.46813E+00 -0.46813E+00 + 2.50800 -0.40266E+00 -0.25142E+00 -0.25142E+00 -0.45729E+00 -0.45729E+00 + 2.54000 -0.39277E+00 -0.24909E+00 -0.24909E+00 -0.44685E+00 -0.44685E+00 + 2.60400 -0.37405E+00 -0.24437E+00 -0.24437E+00 -0.42701E+00 -0.42701E+00 + 2.66800 -0.35677E+00 -0.23959E+00 -0.23959E+00 -0.40851E+00 -0.40851E+00 + 2.73200 -0.34067E+00 -0.23480E+00 -0.23480E+00 -0.39120E+00 -0.39120E+00 + 2.79600 -0.32577E+00 -0.23000E+00 -0.23000E+00 -0.37502E+00 -0.37502E+00 + 2.86000 -0.31184E+00 -0.22521E+00 -0.22521E+00 -0.35983E+00 -0.35983E+00 + 2.92400 -0.29892E+00 -0.22044E+00 -0.22044E+00 -0.34559E+00 -0.34559E+00 + 2.98800 -0.28681E+00 -0.21570E+00 -0.21570E+00 -0.33218E+00 -0.33218E+00 + 3.05200 -0.27555E+00 -0.21100E+00 -0.21100E+00 -0.31958E+00 -0.31958E+00 + 3.11600 -0.26497E+00 -0.20634E+00 -0.20634E+00 -0.30767E+00 -0.30767E+00 + 3.18000 -0.25511E+00 -0.20173E+00 -0.20173E+00 -0.29645E+00 -0.29645E+00 + 3.24400 -0.24582E+00 -0.19717E+00 -0.19717E+00 -0.28582E+00 -0.28582E+00 + 3.30800 -0.23714E+00 -0.19267E+00 -0.19267E+00 -0.27578E+00 -0.27578E+00 + 3.37200 -0.22896E+00 -0.18822E+00 -0.18822E+00 -0.26625E+00 -0.26625E+00 + 3.43600 -0.22128E+00 -0.18383E+00 -0.18383E+00 -0.25721E+00 -0.25721E+00 + 3.50000 -0.21403E+00 -0.17950E+00 -0.17950E+00 -0.24862E+00 -0.24862E+00 + 3.56400 -0.20723E+00 -0.17522E+00 -0.17522E+00 -0.24045E+00 -0.24045E+00 + 3.62800 -0.20078E+00 -0.17101E+00 -0.17101E+00 -0.23266E+00 -0.23266E+00 + 3.69200 -0.19471E+00 -0.16685E+00 -0.16685E+00 -0.22525E+00 -0.22525E+00 + 3.75600 -0.18895E+00 -0.16275E+00 -0.16275E+00 -0.21816E+00 -0.21816E+00 + 3.82000 -0.18352E+00 -0.15871E+00 -0.15871E+00 -0.21140E+00 -0.21140E+00 + 3.88400 -0.17836E+00 -0.15473E+00 -0.15473E+00 -0.20493E+00 -0.20493E+00 + 3.94800 -0.17348E+00 -0.15082E+00 -0.15082E+00 -0.19874E+00 -0.19874E+00 + 4.01200 -0.16884E+00 -0.14696E+00 -0.14696E+00 -0.19281E+00 -0.19281E+00 + 4.07600 -0.16444E+00 -0.14317E+00 -0.14317E+00 -0.18713E+00 -0.18713E+00 + 4.14000 -0.16024E+00 -0.13944E+00 -0.13944E+00 -0.18167E+00 -0.18167E+00 + 4.20400 -0.15626E+00 -0.13577E+00 -0.13577E+00 -0.17644E+00 -0.17644E+00 + 4.26800 -0.15246E+00 -0.13218E+00 -0.13218E+00 -0.17141E+00 -0.17141E+00 + 4.33200 -0.14885E+00 -0.12865E+00 -0.12865E+00 -0.16658E+00 -0.16658E+00 + 4.39600 -0.14539E+00 -0.12519E+00 -0.12519E+00 -0.16193E+00 -0.16193E+00 + 4.46000 -0.14210E+00 -0.12180E+00 -0.12180E+00 -0.15746E+00 -0.15746E+00 + 4.52400 -0.13894E+00 -0.11848E+00 -0.11848E+00 -0.15316E+00 -0.15316E+00 + 4.58800 -0.13593E+00 -0.11524E+00 -0.11524E+00 -0.14903E+00 -0.14903E+00 + 4.65200 -0.13305E+00 -0.11208E+00 -0.11208E+00 -0.14504E+00 -0.14504E+00 + 4.71600 -0.13029E+00 -0.10899E+00 -0.10899E+00 -0.14122E+00 -0.14122E+00 + 4.78000 -0.12764E+00 -0.10599E+00 -0.10599E+00 -0.13753E+00 -0.13753E+00 + 4.84400 -0.12510E+00 -0.10306E+00 -0.10306E+00 -0.13398E+00 -0.13398E+00 + 4.90800 -0.12266E+00 -0.10022E+00 -0.10022E+00 -0.13056E+00 -0.13056E+00 + 4.97200 -0.12032E+00 -0.97466E-01 -0.97466E-01 -0.12727E+00 -0.12727E+00 + 5.03600 -0.11807E+00 -0.94796E-01 -0.94796E-01 -0.12411E+00 -0.12411E+00 + 5.10000 -0.11590E+00 -0.92179E-01 -0.92179E-01 -0.12105E+00 -0.12105E+00 + 5.22800 -0.11180E+00 -0.87227E-01 -0.87227E-01 -0.11528E+00 -0.11528E+00 + 5.35600 -0.10801E+00 -0.82769E-01 -0.82769E-01 -0.11002E+00 -0.11002E+00 + 5.48400 -0.10446E+00 -0.78553E-01 -0.78553E-01 -0.10511E+00 -0.10511E+00 + 5.61200 -0.10116E+00 -0.74745E-01 -0.74745E-01 -0.10062E+00 -0.10062E+00 + 5.74000 -0.98065E-01 -0.71291E-01 -0.71291E-01 -0.96482E-01 -0.96482E-01 + 5.86800 -0.95170E-01 -0.68216E-01 -0.68216E-01 -0.92711E-01 -0.92711E-01 + 5.99600 -0.92443E-01 -0.65512E-01 -0.65512E-01 -0.89276E-01 -0.89276E-01 + 6.12400 -0.89883E-01 -0.63184E-01 -0.63184E-01 -0.86170E-01 -0.86170E-01 + 6.25200 -0.87463E-01 -0.61228E-01 -0.61228E-01 -0.83374E-01 -0.83374E-01 + 6.38000 -0.85182E-01 -0.59642E-01 -0.59642E-01 -0.80880E-01 -0.80880E-01 + 6.50800 -0.83019E-01 -0.58416E-01 -0.58416E-01 -0.78668E-01 -0.78668E-01 + 6.63600 -0.80972E-01 -0.57536E-01 -0.57536E-01 -0.76728E-01 -0.76728E-01 + 6.76400 -0.79026E-01 -0.56982E-01 -0.56982E-01 -0.75036E-01 -0.75036E-01 + 6.89200 -0.77178E-01 -0.56723E-01 -0.56723E-01 -0.73573E-01 -0.73573E-01 + 7.02000 -0.75417E-01 -0.56719E-01 -0.56719E-01 -0.72311E-01 -0.72311E-01 + 7.14800 -0.73740E-01 -0.56920E-01 -0.56920E-01 -0.71221E-01 -0.71221E-01 + 7.27600 -0.72138E-01 -0.57265E-01 -0.57265E-01 -0.70266E-01 -0.70266E-01 + 7.40400 -0.70608E-01 -0.57687E-01 -0.57687E-01 -0.69407E-01 -0.69407E-01 + 7.53200 -0.69144E-01 -0.58111E-01 -0.58111E-01 -0.68603E-01 -0.68603E-01 + 7.66000 -0.67742E-01 -0.58459E-01 -0.58459E-01 -0.67811E-01 -0.67811E-01 + 7.78800 -0.66397E-01 -0.58657E-01 -0.58657E-01 -0.66990E-01 -0.66990E-01 + 7.91600 -0.65107E-01 -0.58635E-01 -0.58635E-01 -0.66104E-01 -0.66104E-01 + 8.04400 -0.63867E-01 -0.58337E-01 -0.58337E-01 -0.65119E-01 -0.65119E-01 + 8.17200 -0.62676E-01 -0.57718E-01 -0.57718E-01 -0.64012E-01 -0.64012E-01 + 8.30000 -0.61529E-01 -0.56754E-01 -0.56754E-01 -0.62766E-01 -0.62766E-01 + 8.42800 -0.60424E-01 -0.55435E-01 -0.55435E-01 -0.61377E-01 -0.61377E-01 + 8.55600 -0.59359E-01 -0.53772E-01 -0.53772E-01 -0.59846E-01 -0.59846E-01 + 8.68400 -0.58332E-01 -0.51790E-01 -0.51790E-01 -0.58185E-01 -0.58185E-01 + 8.81200 -0.57341E-01 -0.49529E-01 -0.49529E-01 -0.56411E-01 -0.56411E-01 + 8.94000 -0.56383E-01 -0.47038E-01 -0.47038E-01 -0.54548E-01 -0.54548E-01 + 9.06800 -0.55457E-01 -0.44369E-01 -0.44369E-01 -0.52620E-01 -0.52620E-01 + 9.19600 -0.54562E-01 -0.41581E-01 -0.41581E-01 -0.50655E-01 -0.50655E-01 + 9.32400 -0.53695E-01 -0.38728E-01 -0.38728E-01 -0.48679E-01 -0.48679E-01 + 9.45200 -0.52856E-01 -0.35862E-01 -0.35862E-01 -0.46717E-01 -0.46717E-01 + 9.58000 -0.52042E-01 -0.33028E-01 -0.33028E-01 -0.44790E-01 -0.44790E-01 + 9.70800 -0.51254E-01 -0.30266E-01 -0.30266E-01 -0.42917E-01 -0.42917E-01 + 9.83600 -0.50489E-01 -0.27608E-01 -0.27608E-01 -0.41113E-01 -0.41113E-01 + 9.96400 -0.49746E-01 -0.25075E-01 -0.25075E-01 -0.39388E-01 -0.39388E-01 + 10.09200 -0.49025E-01 -0.22687E-01 -0.22687E-01 -0.37750E-01 -0.37750E-01 + 10.22000 -0.48325E-01 -0.20526E-01 -0.20526E-01 -0.36241E-01 -0.36241E-01 + 10.47600 -0.46982E-01 -0.16523E-01 -0.16523E-01 -0.33423E-01 -0.33423E-01 + 10.73200 -0.45712E-01 -0.13072E-01 -0.13072E-01 -0.30931E-01 -0.30931E-01 + 10.98800 -0.44508E-01 -0.10367E-01 -0.10367E-01 -0.28859E-01 -0.28859E-01 + 11.24400 -0.43365E-01 -0.81480E-02 -0.81480E-02 -0.27071E-01 -0.27071E-01 + 11.50000 -0.42278E-01 -0.63810E-02 -0.63810E-02 -0.25547E-01 -0.25547E-01 + 11.75600 -0.41244E-01 -0.49785E-02 -0.49785E-02 -0.24241E-01 -0.24241E-01 + 12.01200 -0.40258E-01 -0.38752E-02 -0.38752E-02 -0.23116E-01 -0.23116E-01 + 12.26800 -0.39317E-01 -0.30111E-02 -0.30111E-02 -0.22140E-01 -0.22140E-01 + 12.52400 -0.38418E-01 -0.23370E-02 -0.23370E-02 -0.21287E-01 -0.21287E-01 + 12.78000 -0.37559E-01 -0.18126E-02 -0.18126E-02 -0.20534E-01 -0.20534E-01 + 13.03600 -0.36735E-01 -0.14055E-02 -0.14055E-02 -0.19863E-01 -0.19863E-01 + 13.29200 -0.35947E-01 -0.10897E-02 -0.10897E-02 -0.19259E-01 -0.19259E-01 + 13.54800 -0.35190E-01 -0.84505E-03 -0.84505E-03 -0.18711E-01 -0.18711E-01 + 13.80400 -0.34463E-01 -0.65552E-03 -0.65552E-03 -0.18209E-01 -0.18209E-01 + 14.06000 -0.33765E-01 -0.50871E-03 -0.50871E-03 -0.17746E-01 -0.17746E-01 + 14.31600 -0.33093E-01 -0.39498E-03 -0.39498E-03 -0.17316E-01 -0.17316E-01 + 14.57200 -0.32446E-01 -0.30685E-03 -0.30685E-03 -0.16915E-01 -0.16915E-01 + 14.82800 -0.31824E-01 -0.23853E-03 -0.23853E-03 -0.16538E-01 -0.16538E-01 + 15.08400 -0.31223E-01 -0.18554E-03 -0.18554E-03 -0.16181E-01 -0.16181E-01 + 15.34000 -0.30644E-01 -0.14441E-03 -0.14441E-03 -0.15844E-01 -0.15844E-01 + 15.59600 -0.30085E-01 -0.11247E-03 -0.11247E-03 -0.15523E-01 -0.15523E-01 + 15.85200 -0.29545E-01 -0.87651E-04 -0.87651E-04 -0.15217E-01 -0.15217E-01 + 16.10800 -0.29024E-01 -0.68351E-04 -0.68351E-04 -0.14925E-01 -0.14925E-01 + 16.36400 -0.28519E-01 -0.53333E-04 -0.53333E-04 -0.14645E-01 -0.14645E-01 + 16.62000 -0.28031E-01 -0.41639E-04 -0.41639E-04 -0.14375E-01 -0.14375E-01 + 16.87600 -0.27558E-01 -0.32528E-04 -0.32528E-04 -0.14117E-01 -0.14117E-01 + 17.13200 -0.27100E-01 -0.25424E-04 -0.25424E-04 -0.13867E-01 -0.13867E-01 + 17.38800 -0.26656E-01 -0.19882E-04 -0.19882E-04 -0.13627E-01 -0.13627E-01 + 17.64400 -0.26226E-01 -0.15556E-04 -0.15556E-04 -0.13395E-01 -0.13395E-01 + 17.90000 -0.25808E-01 -0.12176E-04 -0.12176E-04 -0.13171E-01 -0.13171E-01 + 18.15600 -0.25403E-01 -0.95354E-05 -0.95354E-05 -0.12954E-01 -0.12954E-01 + 18.41200 -0.25009E-01 -0.74700E-05 -0.74700E-05 -0.12744E-01 -0.12744E-01 + 18.66800 -0.24627E-01 -0.58546E-05 -0.58546E-05 -0.12541E-01 -0.12541E-01 + 18.92400 -0.24255E-01 -0.45881E-05 -0.45881E-05 -0.12344E-01 -0.12344E-01 + 19.18000 -0.23894E-01 -0.36023E-05 -0.36023E-05 -0.12153E-01 -0.12153E-01 + 19.43600 -0.23543E-01 -0.28114E-05 -0.28114E-05 -0.11967E-01 -0.11967E-01 + 19.69200 -0.23201E-01 -0.22450E-05 -0.22450E-05 -0.11787E-01 -0.11787E-01 + 19.94800 -0.22868E-01 -0.16590E-05 -0.16590E-05 -0.11612E-01 -0.11612E-01 + 20.20400 -0.22544E-01 -0.15366E-05 -0.15366E-05 -0.11442E-01 -0.11442E-01 + 20.46000 -0.22228E-01 -0.13842E-05 -0.13842E-05 -0.11277E-01 -0.11277E-01 + + + + ********************* iteration: 2 *********************** + + l = 0, 5 bound states + l = 1, 3 bound states + l = 2, 1 bound states + l = 0, 5 bound states + l = 1, 3 bound states + l = 2, 1 bound states + + + bound states + + 100 energy: -54.47671 iteration loops: 6 + 200 energy: -4.17535 iteration loops: 11 + 300 energy: -0.29422 iteration loops: 12 + 210 energy: -2.79007 iteration loops: 8 + 310 energy: -0.11055 iteration loops: 9 + 100 energy: -54.47671 iteration loops: 6 + 200 energy: -4.17535 iteration loops: 11 + 300 energy: -0.29422 iteration loops: 12 + 210 energy: -2.79007 iteration loops: 8 + + integr charges: total 13.0000001 valence: 13.0000001 0.0000000 + induced moment: 1.00000 + + energy terms + energy eigenvalue sum: -0.134744E+03 + kin: 0.187132E+03 0.186409E+03 coul: -0.468433E+03 exc: -0.184789E+02 + + total energy: -0.2481140E+03 + valence energy: -0.2422917E+03 + + + + ********************* iteration: 3 *********************** + + l = 0, 5 bound states + l = 1, 3 bound states + l = 2, 1 bound states + l = 0, 5 bound states + l = 1, 3 bound states + l = 2, 1 bound states + + + bound states + + 100 energy: -55.36892 iteration loops: 5 + 200 energy: -4.29777 iteration loops: 5 + 300 energy: -0.36089 iteration loops: 7 + 210 energy: -2.91215 iteration loops: 6 + 310 energy: -0.16411 iteration loops: 8 + 100 energy: -55.36808 iteration loops: 5 + 200 energy: -4.29667 iteration loops: 5 + 300 energy: -0.34758 iteration loops: 7 + 210 energy: -2.91076 iteration loops: 6 + + integr charges: total 13.0000001 valence: 13.0000001 0.0000000 + induced moment: 1.00000 + + energy terms + energy eigenvalue sum: -0.137673E+03 + kin: 0.190704E+03 0.189800E+03 coul: -0.470290E+03 exc: -0.186975E+02 + + total energy: -0.2461560E+03 + valence energy: -0.2469787E+03 + + + + ********************* iteration: 4 *********************** + + l = 0, 5 bound states + l = 1, 3 bound states + l = 2, 1 bound states + l = 0, 4 bound states + l = 1, 3 bound states + + + bound states + + 100 energy: -55.55097 iteration loops: 4 + 200 energy: -4.20776 iteration loops: 4 + 300 energy: -0.35526 iteration loops: 7 + 210 energy: -2.81804 iteration loops: 5 + 310 energy: -0.15966 iteration loops: 6 + 100 energy: -55.54955 iteration loops: 4 + 200 energy: -4.20596 iteration loops: 4 + 300 energy: -0.33342 iteration loops: 6 + 210 energy: -2.81575 iteration loops: 5 + + integr charges: total 13.0000001 valence: 13.0000001 0.0000000 + induced moment: 1.00000 + + energy terms + energy eigenvalue sum: -0.137264E+03 + kin: 0.190734E+03 0.189832E+03 coul: -0.468741E+03 exc: -0.186828E+02 + + total energy: -0.2441225E+03 + valence energy: -0.2463262E+03 + + + + ********************* iteration: 5 *********************** + + l = 0, 4 bound states + l = 1, 3 bound states + l = 0, 4 bound states + l = 1, 2 bound states + + + bound states + + 100 energy: -55.51177 iteration loops: 4 + 200 energy: -4.09189 iteration loops: 5 + 300 energy: -0.33274 iteration loops: 6 + 210 energy: -2.69809 iteration loops: 6 + 310 energy: -0.14172 iteration loops: 8 + 100 energy: -55.51008 iteration loops: 4 + 200 energy: -4.08978 iteration loops: 5 + 300 energy: -0.30655 iteration loops: 5 + 210 energy: -2.69538 iteration loops: 6 + + integr charges: total 13.0000001 valence: 13.0000001 0.0000000 + induced moment: 1.00000 + + energy terms + energy eigenvalue sum: -0.136165E+03 + kin: 0.189870E+03 0.189016E+03 coul: -0.466985E+03 exc: -0.186108E+02 + + total energy: -0.2428752E+03 + valence energy: -0.2445257E+03 + + + + ********************* iteration: 6 *********************** + + l = 0, 4 bound states + l = 1, 3 bound states + l = 0, 4 bound states + l = 1, 2 bound states + + + bound states + + 100 energy: -55.45132 iteration loops: 4 + 200 energy: -4.01239 iteration loops: 4 + 300 energy: -0.31424 iteration loops: 5 + 210 energy: -2.61641 iteration loops: 5 + 310 energy: -0.12716 iteration loops: 9 + 100 energy: -55.44954 iteration loops: 4 + 200 energy: -4.01021 iteration loops: 4 + 300 energy: -0.28628 iteration loops: 5 + 210 energy: -2.61358 iteration loops: 5 + + integr charges: total 13.0000001 valence: 13.0000001 0.0000000 + induced moment: 1.00000 + + energy terms + energy eigenvalue sum: -0.135341E+03 + kin: 0.189155E+03 0.188346E+03 coul: -0.465936E+03 exc: -0.185527E+02 + + total energy: -0.2423289E+03 + valence energy: -0.2431501E+03 + + + + ********************* iteration: 7 *********************** + + l = 0, 4 bound states + l = 1, 3 bound states + l = 0, 4 bound states + l = 1, 2 bound states + + + bound states + + 100 energy: -55.42092 iteration loops: 3 + 200 energy: -3.97283 iteration loops: 5 + 300 energy: -0.30360 iteration loops: 5 + 210 energy: -2.57639 iteration loops: 5 + 310 energy: -0.11875 iteration loops: 5 + 100 energy: -55.41915 iteration loops: 3 + 200 energy: -3.97066 iteration loops: 5 + 300 energy: -0.27518 iteration loops: 5 + 210 energy: -2.57357 iteration loops: 5 + + integr charges: total 13.0000001 valence: 13.0000001 0.0000000 + induced moment: 1.00000 + + energy terms + energy eigenvalue sum: -0.134931E+03 + kin: 0.188797E+03 0.188014E+03 coul: -0.465552E+03 exc: -0.185233E+02 + + total energy: -0.2421949E+03 + valence energy: -0.2424598E+03 + + + + ********************* iteration: 8 *********************** + + l = 0, 4 bound states + l = 1, 2 bound states + l = 0, 4 bound states + l = 1, 2 bound states + + + bound states + + 100 energy: -55.41596 iteration loops: 3 + 200 energy: -3.95882 iteration loops: 5 + 300 energy: -0.29885 iteration loops: 5 + 210 energy: -2.56284 iteration loops: 4 + 310 energy: -0.11484 iteration loops: 5 + 100 energy: -55.41421 iteration loops: 3 + 200 energy: -3.95669 iteration loops: 5 + 300 energy: -0.27046 iteration loops: 5 + 210 energy: -2.56007 iteration loops: 4 + + integr charges: total 13.0000001 valence: 13.0000001 0.0000000 + induced moment: 1.00000 + + energy terms + energy eigenvalue sum: -0.134799E+03 + kin: 0.188694E+03 0.187922E+03 coul: -0.465531E+03 exc: -0.185148E+02 + + total energy: -0.2422287E+03 + valence energy: -0.2422434E+03 + + + + ********************* iteration: 9 *********************** + + l = 0, 4 bound states + l = 1, 2 bound states + l = 0, 4 bound states + l = 1, 2 bound states + + + bound states + + 100 energy: -55.42156 iteration loops: 4 + 200 energy: -3.95653 iteration loops: 4 + 300 energy: -0.29725 iteration loops: 5 + 210 energy: -2.56125 iteration loops: 4 + 310 energy: -0.11332 iteration loops: 5 + 100 energy: -55.41983 iteration loops: 4 + 200 energy: -3.95443 iteration loops: 4 + 300 energy: -0.26899 iteration loops: 5 + 210 energy: -2.55852 iteration loops: 4 + + integr charges: total 13.0000001 valence: 13.0000001 0.0000000 + induced moment: 1.00000 + + energy terms + energy eigenvalue sum: -0.134791E+03 + kin: 0.188705E+03 0.187936E+03 coul: -0.465626E+03 exc: -0.185158E+02 + + total energy: -0.2422928E+03 + valence energy: -0.2422437E+03 + + + + ********************* iteration: 10 *********************** + + l = 0, 4 bound states + l = 1, 2 bound states + l = 0, 4 bound states + l = 1, 2 bound states + + + bound states + + 100 energy: -55.42793 iteration loops: 4 + 200 energy: -3.95770 iteration loops: 4 + 300 energy: -0.29690 iteration loops: 4 + 210 energy: -2.56301 iteration loops: 4 + 310 energy: -0.11279 iteration loops: 5 + 100 energy: -55.42622 iteration loops: 4 + 200 energy: -3.95562 iteration loops: 4 + 300 energy: -0.26872 iteration loops: 4 + 210 energy: -2.56031 iteration loops: 4 + + integr charges: total 13.0000001 valence: 13.0000001 0.0000000 + induced moment: 1.00000 + + energy terms + energy eigenvalue sum: -0.134816E+03 + kin: 0.188741E+03 0.187972E+03 coul: -0.465715E+03 exc: -0.185191E+02 + + total energy: -0.2423368E+03 + valence energy: -0.2422989E+03 + + + + ********************* iteration: 11 *********************** + + l = 0, 4 bound states + l = 1, 2 bound states + l = 0, 4 bound states + l = 1, 2 bound states + + + bound states + + 100 energy: -55.43163 iteration loops: 3 + 200 energy: -3.95890 iteration loops: 4 + 300 energy: -0.29685 iteration loops: 4 + 210 energy: -2.56458 iteration loops: 3 + 310 energy: -0.11256 iteration loops: 5 + 100 energy: -55.42992 iteration loops: 3 + 200 energy: -3.95682 iteration loops: 4 + 300 energy: -0.26871 iteration loops: 4 + 210 energy: -2.56189 iteration loops: 3 + + integr charges: total 13.0000001 valence: 13.0000001 0.0000000 + induced moment: 1.00000 + + energy terms + energy eigenvalue sum: -0.134835E+03 + kin: 0.188768E+03 0.187998E+03 coul: -0.465764E+03 exc: -0.185217E+02 + + total energy: -0.2423554E+03 + valence energy: -0.2423421E+03 + + + + ********************* iteration: 12 *********************** + + l = 0, 4 bound states + l = 1, 2 bound states + l = 0, 4 bound states + l = 1, 2 bound states + + + bound states + + 100 energy: -55.43277 iteration loops: 3 + 200 energy: -3.95934 iteration loops: 4 + 300 energy: -0.29679 iteration loops: 4 + 210 energy: -2.56521 iteration loops: 3 + 310 energy: -0.11238 iteration loops: 5 + 100 energy: -55.43107 iteration loops: 3 + 200 energy: -3.95727 iteration loops: 4 + 300 energy: -0.26864 iteration loops: 4 + 210 energy: -2.56252 iteration loops: 3 + + integr charges: total 13.0000001 valence: 13.0000001 0.0000000 + induced moment: 1.00000 + + energy terms + energy eigenvalue sum: -0.134841E+03 + kin: 0.188779E+03 0.188008E+03 coul: -0.465781E+03 exc: -0.185229E+02 + + total energy: -0.2423586E+03 + valence energy: -0.2423610E+03 + + + + ********************* iteration: 13 *********************** + + l = 0, 4 bound states + l = 1, 2 bound states + l = 0, 4 bound states + l = 1, 2 bound states + + + bound states + + 100 energy: -55.43252 iteration loops: 3 + 200 energy: -3.95924 iteration loops: 3 + 300 energy: -0.29667 iteration loops: 4 + 210 energy: -2.56520 iteration loops: 3 + 310 energy: -0.11222 iteration loops: 4 + 100 energy: -55.43081 iteration loops: 3 + 200 energy: -3.95717 iteration loops: 3 + 300 energy: -0.26851 iteration loops: 4 + 210 energy: -2.56251 iteration loops: 3 + + integr charges: total 13.0000001 valence: 13.0000001 0.0000000 + induced moment: 1.00000 + + energy terms + energy eigenvalue sum: -0.134840E+03 + kin: 0.188780E+03 0.188009E+03 coul: -0.465781E+03 exc: -0.185232E+02 + + total energy: -0.2423557E+03 + valence energy: -0.2423635E+03 + + + + ********************* iteration: 14 *********************** + + l = 0, 4 bound states + l = 1, 2 bound states + l = 0, 4 bound states + l = 1, 2 bound states + + + bound states + + 100 energy: -55.43184 iteration loops: 4 + 200 energy: -3.95896 iteration loops: 4 + 300 energy: -0.29655 iteration loops: 4 + 210 energy: -2.56494 iteration loops: 3 + 310 energy: -0.11208 iteration loops: 4 + 100 energy: -55.43013 iteration loops: 4 + 200 energy: -3.95688 iteration loops: 4 + 300 energy: -0.26838 iteration loops: 4 + 210 energy: -2.56225 iteration loops: 3 + + integr charges: total 13.0000001 valence: 13.0000001 0.0000000 + induced moment: 1.00000 + + energy terms + energy eigenvalue sum: -0.134836E+03 + kin: 0.188777E+03 0.188007E+03 coul: -0.465777E+03 exc: -0.185231E+02 + + total energy: -0.2423522E+03 + valence energy: -0.2423593E+03 + + + + ********************* iteration: 15 *********************** + + l = 0, 4 bound states + l = 1, 2 bound states + l = 0, 4 bound states + l = 1, 2 bound states + + + bound states + + 100 energy: -55.43124 iteration loops: 3 + 200 energy: -3.95870 iteration loops: 4 + 300 energy: -0.29644 iteration loops: 4 + 210 energy: -2.56469 iteration loops: 3 + 310 energy: -0.11199 iteration loops: 4 + 100 energy: -55.42953 iteration loops: 3 + 200 energy: -3.95663 iteration loops: 4 + 300 energy: -0.26827 iteration loops: 4 + 210 energy: -2.56199 iteration loops: 3 + + integr charges: total 13.0000001 valence: 13.0000001 0.0000000 + induced moment: 1.00000 + + energy terms + energy eigenvalue sum: -0.134833E+03 + kin: 0.188774E+03 0.188004E+03 coul: -0.465772E+03 exc: -0.185230E+02 + + total energy: -0.2423499E+03 + valence energy: -0.2423544E+03 + + + + ********************* iteration: 16 *********************** + + l = 0, 4 bound states + l = 1, 2 bound states + l = 0, 4 bound states + l = 1, 2 bound states + + + bound states + + 100 energy: -55.43086 iteration loops: 3 + 200 energy: -3.95854 iteration loops: 3 + 300 energy: -0.29638 iteration loops: 4 + 210 energy: -2.56452 iteration loops: 3 + 310 energy: -0.11193 iteration loops: 4 + 100 energy: -55.42915 iteration loops: 3 + 200 energy: -3.95646 iteration loops: 3 + 300 energy: -0.26820 iteration loops: 4 + 210 energy: -2.56183 iteration loops: 3 + + integr charges: total 13.0000001 valence: 13.0000001 0.0000000 + induced moment: 1.00000 + + energy terms + energy eigenvalue sum: -0.134831E+03 + kin: 0.188772E+03 0.188002E+03 coul: -0.465769E+03 exc: -0.185228E+02 + + total energy: -0.2423489E+03 + valence energy: -0.2423511E+03 + + + + ********************* iteration: 17 *********************** + + l = 0, 4 bound states + l = 1, 2 bound states + l = 0, 4 bound states + l = 1, 2 bound states + + + bound states + + 100 energy: -55.43068 iteration loops: 2 + 200 energy: -3.95846 iteration loops: 3 + 300 energy: -0.29634 iteration loops: 4 + 210 energy: -2.56445 iteration loops: 3 + 310 energy: -0.11190 iteration loops: 4 + 100 energy: -55.42897 iteration loops: 2 + 200 energy: -3.95639 iteration loops: 3 + 300 energy: -0.26817 iteration loops: 4 + 210 energy: -2.56176 iteration loops: 3 + + integr charges: total 13.0000001 valence: 13.0000001 0.0000000 + induced moment: 1.00000 + + energy terms + energy eigenvalue sum: -0.134830E+03 + kin: 0.188771E+03 0.188001E+03 coul: -0.465769E+03 exc: -0.185228E+02 + + total energy: -0.2423487E+03 + valence energy: -0.2423495E+03 + + + + ********************* iteration: 18 *********************** + + l = 0, 4 bound states + l = 1, 2 bound states + l = 0, 4 bound states + l = 1, 2 bound states + + + bound states + + 100 energy: -55.43062 iteration loops: 2 + 200 energy: -3.95843 iteration loops: 3 + 300 energy: -0.29633 iteration loops: 4 + 210 energy: -2.56442 iteration loops: 3 + 310 energy: -0.11188 iteration loops: 4 + 100 energy: -55.42891 iteration loops: 2 + 200 energy: -3.95636 iteration loops: 3 + 300 energy: -0.26815 iteration loops: 4 + 210 energy: -2.56173 iteration loops: 3 + + integr charges: total 13.0000001 valence: 13.0000001 0.0000000 + induced moment: 1.00000 + + energy terms + energy eigenvalue sum: -0.134829E+03 + kin: 0.188771E+03 0.188001E+03 coul: -0.465769E+03 exc: -0.185228E+02 + + total energy: -0.2423488E+03 + valence energy: -0.2423489E+03 + + + + ********************* iteration: 19 *********************** + + l = 0, 4 bound states + l = 1, 2 bound states + l = 0, 4 bound states + l = 1, 2 bound states + + + bound states + + 100 energy: -55.43060 iteration loops: 2 + 200 energy: -3.95843 iteration loops: 3 + 300 energy: -0.29632 iteration loops: 3 + 210 energy: -2.56442 iteration loops: 3 + 310 energy: -0.11188 iteration loops: 4 + 100 energy: -55.42889 iteration loops: 2 + 200 energy: -3.95636 iteration loops: 3 + 300 energy: -0.26814 iteration loops: 3 + 210 energy: -2.56173 iteration loops: 3 + + integr charges: total 13.0000001 valence: 13.0000001 0.0000000 + induced moment: 1.00000 + + energy terms + energy eigenvalue sum: -0.134829E+03 + kin: 0.188771E+03 0.188001E+03 coul: -0.465769E+03 exc: -0.185228E+02 + + total energy: -0.2423489E+03 + valence energy: -0.2423488E+03 + + + + ********************* iteration: 20 *********************** + + l = 0, 4 bound states + l = 1, 2 bound states + l = 0, 4 bound states + l = 1, 2 bound states + + + bound states + + 100 energy: -55.43060 iteration loops: 2 + 200 energy: -3.95844 iteration loops: 3 + 300 energy: -0.29632 iteration loops: 3 + 210 energy: -2.56443 iteration loops: 3 + 310 energy: -0.11188 iteration loops: 3 + 100 energy: -55.42889 iteration loops: 2 + 200 energy: -3.95636 iteration loops: 3 + 300 energy: -0.26814 iteration loops: 3 + 210 energy: -2.56174 iteration loops: 3 + + integr charges: total 13.0000001 valence: 13.0000001 0.0000000 + induced moment: 1.00000 + + energy terms + energy eigenvalue sum: -0.134829E+03 + kin: 0.188771E+03 0.188000E+03 coul: -0.465768E+03 exc: -0.185228E+02 + + total energy: -0.2423490E+03 + valence energy: -0.2423489E+03 + + + + ********************* iteration: 21 *********************** + + l = 0, 4 bound states + l = 1, 2 bound states + l = 0, 4 bound states + l = 1, 2 bound states + + + bound states + + 100 energy: -55.43061 iteration loops: 7 + 200 energy: -3.95844 iteration loops: 3 + 300 energy: -0.29632 iteration loops: 3 + 210 energy: -2.56443 iteration loops: 3 + 310 energy: -0.11188 iteration loops: 3 + 100 energy: -55.42890 iteration loops: 2 + 200 energy: -3.95637 iteration loops: 3 + 300 energy: -0.26814 iteration loops: 3 + 210 energy: -2.56174 iteration loops: 3 + + integr charges: total 13.0000001 valence: 13.0000001 0.0000000 + induced moment: 1.00000 + + energy terms + energy eigenvalue sum: -0.134829E+03 + kin: 0.188771E+03 0.188000E+03 coul: -0.465769E+03 exc: -0.185228E+02 + + total energy: -0.2423491E+03 + valence energy: -0.2423490E+03 + + + + ********************* iteration: 22 *********************** + + l = 0, 4 bound states + l = 1, 2 bound states + l = 0, 4 bound states + l = 1, 2 bound states + + + bound states + + 100 energy: -55.43061 iteration loops: 2 + 200 energy: -3.95844 iteration loops: 3 + 300 energy: -0.29632 iteration loops: 3 + 210 energy: -2.56444 iteration loops: 3 + 310 energy: -0.11188 iteration loops: 3 + 100 energy: -55.42890 iteration loops: 2 + 200 energy: -3.95637 iteration loops: 3 + 300 energy: -0.26815 iteration loops: 3 + 210 energy: -2.56174 iteration loops: 3 + + integr charges: total 13.0000001 valence: 13.0000001 0.0000000 + induced moment: 1.00000 + + energy terms + energy eigenvalue sum: -0.134829E+03 + kin: 0.188771E+03 0.188000E+03 coul: -0.465769E+03 exc: -0.185228E+02 + + total energy: -0.2423491E+03 + valence energy: -0.2423491E+03 + + + + ********************* iteration: 23 *********************** + + l = 0, 4 bound states + l = 1, 2 bound states + l = 0, 4 bound states + l = 1, 2 bound states + + + bound states + + 100 energy: -55.43061 iteration loops: 2 + 200 energy: -3.95844 iteration loops: 3 + 300 energy: -0.29632 iteration loops: 3 + 210 energy: -2.56444 iteration loops: 3 + 310 energy: -0.11188 iteration loops: 3 + 100 energy: -55.42890 iteration loops: 2 + 200 energy: -3.95637 iteration loops: 3 + 300 energy: -0.26815 iteration loops: 3 + 210 energy: -2.56174 iteration loops: 3 + + integr charges: total 13.0000001 valence: 13.0000001 0.0000000 + induced moment: 1.00000 + + energy terms + energy eigenvalue sum: -0.134829E+03 + kin: 0.188771E+03 0.188000E+03 coul: -0.465769E+03 exc: -0.185228E+02 + + total energy: -0.2423491E+03 + 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 @@ +13 0 +10 40 0.2000 +0.5000 0.00001 0.005 +30 0 1 0 +5 2 2 +100 -84.5000 1 1 0 +200 -16.2450 1 1 0 +210 -5.3356 3 1 0 +300 -0.7812 1 1 0 +310 -0.2312 1 1 0 +100 -84.5000 1 1 0 +200 -16.2450 1 1 0 +210 -5.3356 3 1 0 +300 -0.7812 1 1 0 +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 @@ + 0.000000000000E+00 0.000000000000E+00 0.000000000000E+00 + 0.500000000000E-03 0.436175457142E-02 0.000000000000E+00 + 0.100000000000E-02 0.172211515283E-01 0.000000000000E+00 + 0.150000000000E-02 0.382459117112E-01 0.000000000000E+00 + 0.200000000000E-02 0.671124120455E-01 0.000000000000E+00 + 0.250000000000E-02 0.103505537733E+00 0.000000000000E+00 + 0.300000000000E-02 0.147118470048E+00 0.000000000000E+00 + 0.350000000000E-02 0.197652522367E+00 0.000000000000E+00 + 0.400000000000E-02 0.254816957219E+00 0.000000000000E+00 + 0.450000000000E-02 0.318328815746E+00 0.000000000000E+00 + 0.500000000000E-02 0.387912747299E+00 0.000000000000E+00 + 0.550000000000E-02 0.463300842732E+00 0.000000000000E+00 + 0.600000000000E-02 0.544232471462E+00 0.000000000000E+00 + 0.650000000000E-02 0.630454120441E+00 0.000000000000E+00 + 0.700000000000E-02 0.721719237721E+00 0.000000000000E+00 + 0.750000000000E-02 0.817788077185E+00 0.000000000000E+00 + 0.800000000000E-02 0.918427548340E+00 0.000000000000E+00 + 0.850000000000E-02 0.102341106664E+01 0.000000000000E+00 + 0.900000000000E-02 0.113251840931E+01 0.000000000000E+00 + 0.950000000000E-02 0.124553557108E+01 0.000000000000E+00 + 0.100000000000E-01 0.136225462590E+01 0.000000000000E+00 + 0.105000000000E-01 0.148247358782E+01 0.000000000000E+00 + 0.110000000000E-01 0.160599627846E+01 0.000000000000E+00 + 0.115000000000E-01 0.173263219287E+01 0.000000000000E+00 + 0.120000000000E-01 0.186219637254E+01 0.000000000000E+00 + 0.125000000000E-01 0.199450927612E+01 0.000000000000E+00 + 0.130000000000E-01 0.212939665777E+01 0.000000000000E+00 + 0.135000000000E-01 0.226668944255E+01 0.000000000000E+00 + 0.140000000000E-01 0.240622360993E+01 0.000000000000E+00 + 0.145000000000E-01 0.254784007371E+01 0.000000000000E+00 + 0.150000000000E-01 0.269138457059E+01 0.000000000000E+00 + 0.155000000000E-01 0.283670754435E+01 0.000000000000E+00 + 0.160000000000E-01 0.298366403931E+01 0.000000000000E+00 + 0.165000000000E-01 0.313211358875E+01 0.000000000000E+00 + 0.170000000000E-01 0.328192011295E+01 0.000000000000E+00 + 0.175000000000E-01 0.343295181175E+01 0.000000000000E+00 + 0.180000000000E-01 0.358508106710E+01 0.000000000000E+00 + 0.185000000000E-01 0.373818433947E+01 0.000000000000E+00 + 0.190000000000E-01 0.389214207482E+01 0.000000000000E+00 + 0.195000000000E-01 0.404683860473E+01 0.000000000000E+00 + 0.200000000000E-01 0.420216205770E+01 0.000000000000E+00 + 0.210000000000E-01 0.451426066096E+01 0.000000000000E+00 + 0.220000000000E-01 0.482761538713E+01 0.000000000000E+00 + 0.230000000000E-01 0.514145874839E+01 0.000000000000E+00 + 0.240000000000E-01 0.545507568127E+01 0.000000000000E+00 + 0.250000000000E-01 0.576780090940E+01 0.000000000000E+00 + 0.260000000000E-01 0.607901658509E+01 0.000000000000E+00 + 0.270000000000E-01 0.638814985059E+01 0.000000000000E+00 + 0.280000000000E-01 0.669467068676E+01 0.000000000000E+00 + 0.290000000000E-01 0.699808966255E+01 0.000000000000E+00 + 0.300000000000E-01 0.729795597458E+01 0.000000000000E+00 + 0.310000000000E-01 0.759385537159E+01 0.000000000000E+00 + 0.320000000000E-01 0.788540837030E+01 0.000000000000E+00 + 0.330000000000E-01 0.817226834232E+01 0.000000000000E+00 + 0.340000000000E-01 0.845411989252E+01 0.000000000000E+00 + 0.350000000000E-01 0.873067709677E+01 0.000000000000E+00 + 0.360000000000E-01 0.900168202993E+01 0.000000000000E+00 + 0.370000000000E-01 0.926690314354E+01 0.000000000000E+00 + 0.380000000000E-01 0.952613393144E+01 0.000000000000E+00 + 0.390000000000E-01 0.977919143729E+01 0.000000000000E+00 + 0.400000000000E-01 0.100259150466E+02 0.000000000000E+00 + 0.410000000000E-01 0.102661651144E+02 0.000000000000E+00 + 0.420000000000E-01 0.104998218739E+02 0.000000000000E+00 + 0.430000000000E-01 0.107267841749E+02 0.000000000000E+00 + 0.440000000000E-01 0.109469684991E+02 0.000000000000E+00 + 0.450000000000E-01 0.111603078023E+02 0.000000000000E+00 + 0.460000000000E-01 0.113667506265E+02 0.000000000000E+00 + 0.470000000000E-01 0.115662600379E+02 0.000000000000E+00 + 0.480000000000E-01 0.117588128282E+02 0.000000000000E+00 + 0.490000000000E-01 0.119443985413E+02 0.000000000000E+00 + 0.500000000000E-01 0.121230187558E+02 0.000000000000E+00 + 0.510000000000E-01 0.122946861934E+02 0.000000000000E+00 + 0.520000000000E-01 0.124594240762E+02 0.000000000000E+00 + 0.530000000000E-01 0.126172653109E+02 0.000000000000E+00 + 0.540000000000E-01 0.127682519135E+02 0.000000000000E+00 + 0.550000000000E-01 0.129124342637E+02 0.000000000000E+00 + 0.560000000000E-01 0.130498705915E+02 0.000000000000E+00 + 0.570000000000E-01 0.131806262959E+02 0.000000000000E+00 + 0.580000000000E-01 0.133047734887E+02 0.000000000000E+00 + 0.590000000000E-01 0.134223903716E+02 0.000000000000E+00 + 0.600000000000E-01 0.135335608332E+02 0.000000000000E+00 + 0.620000000000E-01 0.137369231858E+02 0.000000000000E+00 + 0.640000000000E-01 0.139156271828E+02 0.000000000000E+00 + 0.660000000000E-01 0.140705011276E+02 0.000000000000E+00 + 0.680000000000E-01 0.142024242737E+02 0.000000000000E+00 + 0.700000000000E-01 0.143123149024E+02 0.000000000000E+00 + 0.720000000000E-01 0.144011220159E+02 0.000000000000E+00 + 0.740000000000E-01 0.144698156068E+02 0.000000000000E+00 + 0.760000000000E-01 0.145193802486E+02 0.000000000000E+00 + 0.780000000000E-01 0.145508072765E+02 0.000000000000E+00 + 0.800000000000E-01 0.145650899292E+02 0.000000000000E+00 + 0.820000000000E-01 0.145632171303E+02 0.000000000000E+00 + 0.840000000000E-01 0.145461698998E+02 0.000000000000E+00 + 0.860000000000E-01 0.145149164697E+02 0.000000000000E+00 + 0.880000000000E-01 0.144704097293E+02 0.000000000000E+00 + 0.900000000000E-01 0.144135834483E+02 0.000000000000E+00 + 0.920000000000E-01 0.143453505597E+02 0.000000000000E+00 + 0.940000000000E-01 0.142666002980E+02 0.000000000000E+00 + 0.960000000000E-01 0.141781971550E+02 0.000000000000E+00 + 0.980000000000E-01 0.140809787718E+02 0.000000000000E+00 + 0.100000000000E+00 0.139757554301E+02 0.000000000000E+00 + 0.102000000000E+00 0.138633085605E+02 0.000000000000E+00 + 0.104000000000E+00 0.137443906570E+02 0.000000000000E+00 + 0.106000000000E+00 0.136197242856E+02 0.000000000000E+00 + 0.108000000000E+00 0.134900023280E+02 0.000000000000E+00 + 0.110000000000E+00 0.133558873940E+02 0.000000000000E+00 + 0.112000000000E+00 0.132180123169E+02 0.000000000000E+00 + 0.114000000000E+00 0.130769798879E+02 0.000000000000E+00 + 0.116000000000E+00 0.129333635406E+02 0.000000000000E+00 + 0.118000000000E+00 0.127877073393E+02 0.000000000000E+00 + 0.120000000000E+00 0.126405268000E+02 0.000000000000E+00 + 0.122000000000E+00 0.124923090764E+02 0.000000000000E+00 + 0.124000000000E+00 0.123435138760E+02 0.000000000000E+00 + 0.126000000000E+00 0.121945737962E+02 0.000000000000E+00 + 0.128000000000E+00 0.120458953010E+02 0.000000000000E+00 + 0.130000000000E+00 0.118978591688E+02 0.000000000000E+00 + 0.132000000000E+00 0.117508215028E+02 0.000000000000E+00 + 0.134000000000E+00 0.116051142588E+02 0.000000000000E+00 + 0.136000000000E+00 0.114610462665E+02 0.000000000000E+00 + 0.138000000000E+00 0.113189038105E+02 0.000000000000E+00 + 0.140000000000E+00 0.111789516517E+02 0.000000000000E+00 + 0.144000000000E+00 0.109065733402E+02 0.000000000000E+00 + 0.148000000000E+00 0.106456277689E+02 0.000000000000E+00 + 0.152000000000E+00 0.103975360123E+02 0.000000000000E+00 + 0.156000000000E+00 0.101634506611E+02 0.000000000000E+00 + 0.160000000000E+00 0.994427827634E+01 0.000000000000E+00 + 0.164000000000E+00 0.974070118733E+01 0.000000000000E+00 + 0.168000000000E+00 0.955320856633E+01 0.000000000000E+00 + 0.172000000000E+00 0.938210818041E+01 0.000000000000E+00 + 0.176000000000E+00 0.922754822873E+01 0.000000000000E+00 + 0.180000000000E+00 0.908953714697E+01 0.000000000000E+00 + 0.184000000000E+00 0.896795938169E+01 0.000000000000E+00 + 0.188000000000E+00 0.886259238863E+01 0.000000000000E+00 + 0.192000000000E+00 0.877312004143E+01 0.000000000000E+00 + 0.196000000000E+00 0.869914699278E+01 0.000000000000E+00 + 0.200000000000E+00 0.864020983888E+01 0.000000000000E+00 + 0.204000000000E+00 0.859578907906E+01 0.000000000000E+00 + 0.208000000000E+00 0.856531822751E+01 0.000000000000E+00 + 0.212000000000E+00 0.854819364215E+01 0.000000000000E+00 + 0.216000000000E+00 0.854378181368E+01 0.000000000000E+00 + 0.220000000000E+00 0.855142734840E+01 0.000000000000E+00 + 0.224000000000E+00 0.857045868213E+01 0.000000000000E+00 + 0.228000000000E+00 0.860019450042E+01 0.000000000000E+00 + 0.232000000000E+00 0.863994812524E+01 0.000000000000E+00 + 0.236000000000E+00 0.868903264105E+01 0.000000000000E+00 + 0.240000000000E+00 0.874676418673E+01 0.000000000000E+00 + 0.244000000000E+00 0.881246602644E+01 0.000000000000E+00 + 0.248000000000E+00 0.888547094821E+01 0.000000000000E+00 + 0.252000000000E+00 0.896512447677E+01 0.000000000000E+00 + 0.256000000000E+00 0.905078653868E+01 0.000000000000E+00 + 0.260000000000E+00 0.914183396801E+01 0.000000000000E+00 + 0.264000000000E+00 0.923766155756E+01 0.000000000000E+00 + 0.268000000000E+00 0.933768397142E+01 0.000000000000E+00 + 0.272000000000E+00 0.944133627734E+01 0.000000000000E+00 + 0.276000000000E+00 0.954807536204E+01 0.000000000000E+00 + 0.280000000000E+00 0.965738003028E+01 0.000000000000E+00 + 0.284000000000E+00 0.976875200893E+01 0.000000000000E+00 + 0.288000000000E+00 0.988171569009E+01 0.000000000000E+00 + 0.292000000000E+00 0.999581879582E+01 0.000000000000E+00 + 0.296000000000E+00 0.101106318394E+02 0.000000000000E+00 + 0.300000000000E+00 0.102257485032E+02 0.000000000000E+00 + 0.308000000000E+00 0.104553787146E+02 0.000000000000E+00 + 0.316000000000E+00 0.106819076813E+02 0.000000000000E+00 + 0.324000000000E+00 0.109028727525E+02 0.000000000000E+00 + 0.332000000000E+00 0.111161395682E+02 0.000000000000E+00 + 0.340000000000E+00 0.113198756191E+02 0.000000000000E+00 + 0.348000000000E+00 0.115125374106E+02 0.000000000000E+00 + 0.356000000000E+00 0.116928409854E+02 0.000000000000E+00 + 0.364000000000E+00 0.118597484360E+02 0.000000000000E+00 + 0.372000000000E+00 0.120124387908E+02 0.000000000000E+00 + 0.380000000000E+00 0.121502951670E+02 0.000000000000E+00 + 0.388000000000E+00 0.122728772544E+02 0.000000000000E+00 + 0.396000000000E+00 0.123799099143E+02 0.000000000000E+00 + 0.404000000000E+00 0.124712579462E+02 0.000000000000E+00 + 0.412000000000E+00 0.125469165365E+02 0.000000000000E+00 + 0.420000000000E+00 0.126069886327E+02 0.000000000000E+00 + 0.428000000000E+00 0.126516773497E+02 0.000000000000E+00 + 0.436000000000E+00 0.126812660217E+02 0.000000000000E+00 + 0.444000000000E+00 0.126961124851E+02 0.000000000000E+00 + 0.452000000000E+00 0.126966317145E+02 0.000000000000E+00 + 0.460000000000E+00 0.126832917988E+02 0.000000000000E+00 + 0.468000000000E+00 0.126565989792E+02 0.000000000000E+00 + 0.476000000000E+00 0.126170950873E+02 0.000000000000E+00 + 0.484000000000E+00 0.125653447612E+02 0.000000000000E+00 + 0.492000000000E+00 0.125019341037E+02 0.000000000000E+00 + 0.500000000000E+00 0.124274598383E+02 0.000000000000E+00 + 0.508000000000E+00 0.123425289558E+02 0.000000000000E+00 + 0.516000000000E+00 0.122477495743E+02 0.000000000000E+00 + 0.524000000000E+00 0.121437313636E+02 0.000000000000E+00 + 0.532000000000E+00 0.120310778864E+02 0.000000000000E+00 + 0.540000000000E+00 0.119103876158E+02 0.000000000000E+00 + 0.548000000000E+00 0.117822475537E+02 0.000000000000E+00 + 0.556000000000E+00 0.116472346836E+02 0.000000000000E+00 + 0.564000000000E+00 0.115059106819E+02 0.000000000000E+00 + 0.572000000000E+00 0.113588236758E+02 0.000000000000E+00 + 0.580000000000E+00 0.112065038847E+02 0.000000000000E+00 + 0.588000000000E+00 0.110494655756E+02 0.000000000000E+00 + 0.596000000000E+00 0.108882034917E+02 0.000000000000E+00 + 0.604000000000E+00 0.107231949218E+02 0.000000000000E+00 + 0.612000000000E+00 0.105548967853E+02 0.000000000000E+00 + 0.620000000000E+00 0.103837477718E+02 0.000000000000E+00 + 0.636000000000E+00 0.100345496045E+02 0.000000000000E+00 + 0.652000000000E+00 0.967872344891E+01 0.000000000000E+00 + 0.668000000000E+00 0.931907101425E+01 0.000000000000E+00 + 0.684000000000E+00 0.895810820401E+01 0.000000000000E+00 + 0.700000000000E+00 0.859805485680E+01 0.000000000000E+00 + 0.716000000000E+00 0.824087119330E+01 0.000000000000E+00 + 0.732000000000E+00 0.788825582818E+01 0.000000000000E+00 + 0.748000000000E+00 0.754167995457E+01 0.000000000000E+00 + 0.764000000000E+00 0.720239080394E+01 0.000000000000E+00 + 0.780000000000E+00 0.687144226797E+01 0.000000000000E+00 + 0.796000000000E+00 0.654970128574E+01 0.000000000000E+00 + 0.812000000000E+00 0.623787449324E+01 0.000000000000E+00 + 0.828000000000E+00 0.593651588253E+01 0.000000000000E+00 + 0.844000000000E+00 0.564604949937E+01 0.000000000000E+00 + 0.860000000000E+00 0.536677735057E+01 0.000000000000E+00 + 0.876000000000E+00 0.509889842178E+01 0.000000000000E+00 + 0.892000000000E+00 0.484251621275E+01 0.000000000000E+00 + 0.908000000000E+00 0.459765446156E+01 0.000000000000E+00 + 0.924000000000E+00 0.436426397342E+01 0.000000000000E+00 + 0.940000000000E+00 0.414223547405E+01 0.000000000000E+00 + 0.956000000000E+00 0.393140557927E+01 0.000000000000E+00 + 0.972000000000E+00 0.373156719441E+01 0.000000000000E+00 + 0.988000000000E+00 0.354247458632E+01 0.000000000000E+00 + 0.100400000000E+01 0.336385171559E+01 0.000000000000E+00 + 0.102000000000E+01 0.319539644101E+01 0.000000000000E+00 + 0.103600000000E+01 0.303678712977E+01 0.000000000000E+00 + 0.105200000000E+01 0.288768606201E+01 0.000000000000E+00 + 0.106800000000E+01 0.274774461904E+01 0.000000000000E+00 + 0.108400000000E+01 0.261660597359E+01 0.000000000000E+00 + 0.110000000000E+01 0.249390911171E+01 0.000000000000E+00 + 0.111600000000E+01 0.237929089981E+01 0.000000000000E+00 + 0.113200000000E+01 0.227238915565E+01 0.000000000000E+00 + 0.114800000000E+01 0.217284418122E+01 0.000000000000E+00 + 0.116400000000E+01 0.208030106234E+01 0.000000000000E+00 + 0.118000000000E+01 0.199441075044E+01 0.000000000000E+00 + 0.119600000000E+01 0.191483173901E+01 0.000000000000E+00 + 0.121200000000E+01 0.184123076936E+01 0.000000000000E+00 + 0.122800000000E+01 0.177328400445E+01 0.000000000000E+00 + 0.124400000000E+01 0.171067742461E+01 0.000000000000E+00 + 0.126000000000E+01 0.165310759694E+01 0.000000000000E+00 + 0.129200000000E+01 0.155191724116E+01 0.000000000000E+00 + 0.132400000000E+01 0.146750525512E+01 0.000000000000E+00 + 0.135600000000E+01 0.139784381401E+01 0.000000000000E+00 + 0.138800000000E+01 0.134107966092E+01 0.000000000000E+00 + 0.142000000000E+01 0.129552654599E+01 0.000000000000E+00 + 0.145200000000E+01 0.125965628032E+01 0.000000000000E+00 + 0.148400000000E+01 0.123208593666E+01 0.000000000000E+00 + 0.151600000000E+01 0.121156835897E+01 0.000000000000E+00 + 0.154800000000E+01 0.119698112083E+01 0.000000000000E+00 + 0.158000000000E+01 0.118731944043E+01 0.000000000000E+00 + 0.161200000000E+01 0.118168771367E+01 0.000000000000E+00 + 0.164400000000E+01 0.117929367566E+01 0.000000000000E+00 + 0.167600000000E+01 0.117944032275E+01 0.000000000000E+00 + 0.170800000000E+01 0.118151949160E+01 0.000000000000E+00 + 0.174000000000E+01 0.118500323242E+01 0.000000000000E+00 + 0.177200000000E+01 0.118943698637E+01 0.000000000000E+00 + 0.180400000000E+01 0.119443119513E+01 0.000000000000E+00 + 0.183600000000E+01 0.119965506433E+01 0.000000000000E+00 + 0.186800000000E+01 0.120482918576E+01 0.000000000000E+00 + 0.190000000000E+01 0.120972037857E+01 0.000000000000E+00 + 0.193200000000E+01 0.121413551639E+01 0.000000000000E+00 + 0.196400000000E+01 0.121791745169E+01 0.000000000000E+00 + 0.199600000000E+01 0.122093993025E+01 0.000000000000E+00 + 0.202800000000E+01 0.122310443309E+01 0.000000000000E+00 + 0.206000000000E+01 0.122433599445E+01 0.000000000000E+00 + 0.209200000000E+01 0.122458078315E+01 0.000000000000E+00 + 0.212400000000E+01 0.122380265919E+01 0.000000000000E+00 + 0.215600000000E+01 0.122198134504E+01 0.000000000000E+00 + 0.218800000000E+01 0.121910958787E+01 0.000000000000E+00 + 0.222000000000E+01 0.121519180101E+01 0.000000000000E+00 + 0.225200000000E+01 0.121024172586E+01 0.000000000000E+00 + 0.228400000000E+01 0.120428144770E+01 0.000000000000E+00 + 0.231600000000E+01 0.119733947184E+01 0.000000000000E+00 + 0.234800000000E+01 0.118945003633E+01 0.000000000000E+00 + 0.238000000000E+01 0.118065153236E+01 0.000000000000E+00 + 0.241200000000E+01 0.117098605097E+01 0.000000000000E+00 + 0.244400000000E+01 0.116049808940E+01 0.000000000000E+00 + 0.247600000000E+01 0.114923428069E+01 0.000000000000E+00 + 0.250800000000E+01 0.113724233640E+01 0.000000000000E+00 + 0.254000000000E+01 0.112457091994E+01 0.000000000000E+00 + 0.260400000000E+01 0.109738470182E+01 0.000000000000E+00 + 0.266800000000E+01 0.106806439154E+01 0.000000000000E+00 + 0.273200000000E+01 0.103698439917E+01 0.000000000000E+00 + 0.279600000000E+01 0.100450307329E+01 0.000000000000E+00 + 0.286000000000E+01 0.970953381730E+00 0.000000000000E+00 + 0.292400000000E+01 0.936644159167E+00 0.000000000000E+00 + 0.298800000000E+01 0.901855019638E+00 0.000000000000E+00 + 0.305200000000E+01 0.866839215964E+00 0.000000000000E+00 + 0.311600000000E+01 0.831821125455E+00 0.000000000000E+00 + 0.318000000000E+01 0.796999736132E+00 0.000000000000E+00 + 0.324400000000E+01 0.762547673700E+00 0.000000000000E+00 + 0.330800000000E+01 0.728614749752E+00 0.000000000000E+00 + 0.337200000000E+01 0.695327865933E+00 0.000000000000E+00 + 0.343600000000E+01 0.662794304433E+00 0.000000000000E+00 + 0.350000000000E+01 0.631102113379E+00 0.000000000000E+00 + 0.356400000000E+01 0.600323008499E+00 0.000000000000E+00 + 0.362800000000E+01 0.570512981599E+00 0.000000000000E+00 + 0.369200000000E+01 0.541714781818E+00 0.000000000000E+00 + 0.375600000000E+01 0.513958604532E+00 0.000000000000E+00 + 0.382000000000E+01 0.487264171106E+00 0.000000000000E+00 + 0.388400000000E+01 0.461641419373E+00 0.000000000000E+00 + 0.394800000000E+01 0.437092224312E+00 0.000000000000E+00 + 0.401200000000E+01 0.413611047722E+00 0.000000000000E+00 + 0.407600000000E+01 0.391186347874E+00 0.000000000000E+00 + 0.414000000000E+01 0.369801165599E+00 0.000000000000E+00 + 0.420400000000E+01 0.349434267039E+00 0.000000000000E+00 + 0.426800000000E+01 0.330060656641E+00 0.000000000000E+00 + 0.433200000000E+01 0.311652491038E+00 0.000000000000E+00 + 0.439600000000E+01 0.294179509305E+00 0.000000000000E+00 + 0.446000000000E+01 0.277609755909E+00 0.000000000000E+00 + 0.452400000000E+01 0.261909928620E+00 0.000000000000E+00 + 0.458800000000E+01 0.247045937393E+00 0.000000000000E+00 + 0.465200000000E+01 0.232983174510E+00 0.000000000000E+00 + 0.471600000000E+01 0.219686935923E+00 0.000000000000E+00 + 0.478000000000E+01 0.207122620601E+00 0.000000000000E+00 + 0.484400000000E+01 0.195256038533E+00 0.000000000000E+00 + 0.490800000000E+01 0.184053548124E+00 0.000000000000E+00 + 0.497200000000E+01 0.173482273608E+00 0.000000000000E+00 + 0.503600000000E+01 0.163510189161E+00 0.000000000000E+00 + 0.510000000000E+01 0.154106267371E+00 0.000000000000E+00 + 0.522800000000E+01 0.136884591654E+00 0.000000000000E+00 + 0.535600000000E+01 0.121591321367E+00 0.000000000000E+00 + 0.548400000000E+01 0.108017651918E+00 0.000000000000E+00 + 0.561200000000E+01 0.959753749055E-01 0.000000000000E+00 + 0.574000000000E+01 0.852944707494E-01 0.000000000000E+00 + 0.586800000000E+01 0.758227542149E-01 0.000000000000E+00 + 0.599600000000E+01 0.674244363565E-01 0.000000000000E+00 + 0.612400000000E+01 0.599788218697E-01 0.000000000000E+00 + 0.625200000000E+01 0.533786398769E-01 0.000000000000E+00 + 0.638000000000E+01 0.475284971489E-01 0.000000000000E+00 + 0.650800000000E+01 0.423433479881E-01 0.000000000000E+00 + 0.663600000000E+01 0.377472637261E-01 0.000000000000E+00 + 0.676400000000E+01 0.336723948963E-01 0.000000000000E+00 + 0.689200000000E+01 0.300581838419E-01 0.000000000000E+00 + 0.702000000000E+01 0.268506826101E-01 0.000000000000E+00 + 0.714800000000E+01 0.240019738064E-01 0.000000000000E+00 + 0.727600000000E+01 0.214696134695E-01 0.000000000000E+00 + 0.740400000000E+01 0.192161145818E-01 0.000000000000E+00 + 0.753200000000E+01 0.172084431025E-01 0.000000000000E+00 + 0.766000000000E+01 0.154175504525E-01 0.000000000000E+00 + 0.778800000000E+01 0.138179319918E-01 0.000000000000E+00 + 0.791600000000E+01 0.123872273736E-01 0.000000000000E+00 + 0.804400000000E+01 0.111058555610E-01 0.000000000000E+00 + 0.817200000000E+01 0.995669175697E-02 0.000000000000E+00 + 0.830000000000E+01 0.892477900357E-02 0.000000000000E+00 + 0.842800000000E+01 0.799707541516E-02 0.000000000000E+00 + 0.855600000000E+01 0.716222883183E-02 0.000000000000E+00 + 0.868400000000E+01 0.641037533463E-02 0.000000000000E+00 + 0.881200000000E+01 0.573295290543E-02 0.000000000000E+00 + 0.894000000000E+01 0.512252596993E-02 0.000000000000E+00 + 0.906800000000E+01 0.457261653329E-02 0.000000000000E+00 + 0.919600000000E+01 0.407754389913E-02 0.000000000000E+00 + 0.932400000000E+01 0.363227714481E-02 0.000000000000E+00 + 0.945200000000E+01 0.323230745826E-02 0.000000000000E+00 + 0.958000000000E+01 0.287354503590E-02 0.000000000000E+00 + 0.970800000000E+01 0.255224239652E-02 0.000000000000E+00 + 0.983600000000E+01 0.226494165840E-02 0.000000000000E+00 + 0.996400000000E+01 0.200844067852E-02 0.000000000000E+00 + 0.100920000000E+02 0.177977305756E-02 0.000000000000E+00 + 0.102200000000E+02 0.157619451435E-02 0.000000000000E+00 + 0.104760000000E+02 0.123436917698E-02 0.000000000000E+00 + 0.107320000000E+02 0.965186451268E-03 0.000000000000E+00 + 0.109880000000E+02 0.753908554242E-03 0.000000000000E+00 + 0.112440000000E+02 0.588465538491E-03 0.000000000000E+00 + 0.115000000000E+02 0.459129900109E-03 0.000000000000E+00 + 0.117560000000E+02 0.358136490652E-03 0.000000000000E+00 + 0.120120000000E+02 0.279333173696E-03 0.000000000000E+00 + 0.122680000000E+02 0.217872128786E-03 0.000000000000E+00 + 0.125240000000E+02 0.169948253475E-03 0.000000000000E+00 + 0.127800000000E+02 0.132583106199E-03 0.000000000000E+00 + 0.130360000000E+02 0.103449732933E-03 0.000000000000E+00 + 0.132920000000E+02 0.807324659074E-04 0.000000000000E+00 + 0.135480000000E+02 0.630157231199E-04 0.000000000000E+00 + 0.138040000000E+02 0.491963718127E-04 0.000000000000E+00 + 0.140600000000E+02 0.384149672470E-04 0.000000000000E+00 + 0.143160000000E+02 0.300019668906E-04 0.000000000000E+00 + 0.145720000000E+02 0.234357449754E-04 0.000000000000E+00 + 0.148280000000E+02 0.183098631066E-04 0.000000000000E+00 + 0.150840000000E+02 0.143075777290E-04 0.000000000000E+00 + 0.153400000000E+02 0.111819939178E-04 0.000000000000E+00 + 0.155960000000E+02 0.874061827897E-05 0.000000000000E+00 + 0.158520000000E+02 0.683333638838E-05 0.000000000000E+00 + 0.161080000000E+02 0.534305478230E-05 0.000000000000E+00 + 0.163640000000E+02 0.417841576076E-05 0.000000000000E+00 + 0.166200000000E+02 0.326812462090E-05 0.000000000000E+00 + 0.168760000000E+02 0.255653132983E-05 0.000000000000E+00 + 0.171320000000E+02 0.200018830515E-05 0.000000000000E+00 + 0.173880000000E+02 0.156516791554E-05 0.000000000000E+00 + 0.176440000000E+02 0.122497144447E-05 0.000000000000E+00 + 0.179000000000E+02 0.958898661647E-06 0.000000000000E+00 + 0.181560000000E+02 0.750776203914E-06 0.000000000000E+00 + 0.184120000000E+02 0.587965550136E-06 0.000000000000E+00 + 0.186680000000E+02 0.460588927040E-06 0.000000000000E+00 + 0.189240000000E+02 0.360925130814E-06 0.000000000000E+00 + 0.191800000000E+02 0.282937864443E-06 0.000000000000E+00 + 0.194360000000E+02 0.221907449552E-06 0.000000000000E+00 + 0.196920000000E+02 0.174143200666E-06 0.000000000000E+00 + 0.199480000000E+02 0.136758752860E-06 0.000000000000E+00 + 0.202040000000E+02 0.107496536977E-06 0.000000000000E+00 + 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include +using namespace std; + +const mstring LABAT=htchome()+sref("/bin/labat"); + +const int SLOTS=8; +const int RUNLIMIT=600; +static int SLOT; + +extern "C" { +static void FreeSlot(int dummy) +{ + static int ok=0; + static char buf[256]; + if(!ok) { + ok=1; + sprintf(buf,"rm -rf /tmp/labat%d/",SLOT); + system(buf); + } +} +} + +static int AllocSlot() +{ + struct stat FS; + char buf[256]; + for(SLOT=0;SLOT0||nr>0) { + ctl.left[ctl.basisn].n=i+1; + ctl.left[ctl.basisn].l=k; + ctl.left[ctl.basisn].occ=nl; + ctl.left[ctl.basisn].SetEnergy(ctl.atomz); + ctl.right[ctl.basisn].n=i+1; + ctl.right[ctl.basisn].l=k; + ctl.right[ctl.basisn].occ=nr; + ctl.right[ctl.basisn].SetEnergy(ctl.atomz); + ctl.basisn++; + } + elecs+=nl+nr; + } + } + ctl.atomz+=elecs; + char buf[1024]; + sprintf(buf,"/tmp/labat%d/atomctrl.dat",SLOT); + ofstream os(buf); + os<\n"; + cout<<"NOTE: if the program does >="<\n"; + cout<<"Also note that there is currently a maximum time limit of "<< + RUNLIMIT<<" seconds.
\n"; +} + +static void RunLabat() +{ + char buf[1024]; + sprintf(buf,"cd /tmp/labat%d/\nulimit -t %d\n%s",SLOT,RUNLIMIT,LABAT.c_str()); + system(buf); +} + +static void SaveLabat(const mstring& resfile) +{ + const char* docroot=getenv("DOCROOT"); + if(docroot&&resfile.size()) { + char buf[1024]; + sprintf(buf,"cp -rfp /tmp/labat%d/atomdens.dat %s/%s", + SLOT,docroot,resfile.c_str()); + system(buf); + cout<<"

\n" + <<"Here you may download the density profile.\n" + <<"Example: Save the file as 'dens.dat', and load it from\n" + <<"matlab with 'load dens.dat'.\n" + <<"Then you can look at it with 'plot(dens(:,1),dens(:,2))'.\n" + <<"

\n"<<"Get atomic density\n"; + } +} + +main(int argc,char* argv[]) +{ + if(argc<12) { + cerr<<"Usage: "< x6\n"; + exit(-1); + } + mstring resfile; + char buf[1024]; + if(AllocSlot()) { + cout<<"

Running

\n" + <<"
\n";
+    cout.flush();
+    SetupLabat(resfile,argc,argv);
+    RunLabat();
+    cout<<"
\n" + <<"

Done

\n"; + SaveLabat(resfile); + FreeSlot(0); + } + else { + cout<<"No vacant slots at the moment. Try again later.\n"; + } +} 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 @@ + function deriv(r,x,x2,spin,i,imin,imax) +c deriv calculates the derivative of x with respect to r, at +c position r(i). +c input r : radial coordinate (array) +c input x : function to be derivated (array) +c input x2 : second derivative of x (array) +c input spin : -1 if spin-down, 1 if spin-up, 0 otherwise +c input i : counter, i.e. current position = r(i) +c input imin : min value of i +c input imax : max value of i + implicit logical (a-z) + double precision deriv,r,x,x2 + double precision h,d,dforw,dback,dforup,dfordn,dbacup,dbacdn + integer spin,i,imin,imax + dimension r(561),x(2,561),x2(2,561) + if (i.eq.imin) then + h = (r(i+1)-r(i))/2.d0 + if (spin.eq.-1) then + d = x(2,i) + call splint(r,x,x2,-1,imin,imax,r(i)+h,dforw) + elseif (spin.eq.1) then + d = x(1,i) + call splint(r,x,x2,1,imin,imax,r(i)+h,dforw) + else + d = (x(1,i) + x(2,i)) + call splint(r,x,x2,1,imin,imax,r(i)+h,dforup) + call splint(r,x,x2,-1,imin,imax,r(i)+h,dfordn) + dforw = dforup + dfordn + endif + deriv = (dforw-d)/h + elseif (i.eq.imax) then + h = (r(i)-r(i-1))/2.d0 + if (spin.eq.-1) then + call splint(r,x,x2,-1,imin,imax,r(i)-h,dback) + d = x(2,i) + elseif (spin.eq.1) then + call splint(r,x,x2,1,imin,imax,r(i)-h,dback) + d = x(1,i) + else + call splint(r,x,x2,1,imin,imax,r(i)-h,dbacup) + call splint(r,x,x2,-1,imin,imax,r(i)-h,dbacdn) + dback = dbacup + dbacdn + d = x(1,i) + x(2,i) + endif + deriv = (d-dback)/h + else + h = (r(i)-r(i-1))/2.d0 + if (spin.eq.-1) then + call splint(r,x,x2,-1,imin,imax,r(i)+h,dforw) + call splint(r,x,x2,-1,imin,imax,r(i)-h,dback) + elseif (spin.eq.1) then + call splint(r,x,x2,1,imin,imax,r(i)+h,dforw) + call splint(r,x,x2,1,imin,imax,r(i)-h,dback) + else + call splint(r,x,x2,-1,imin,imax,r(i)+h,dfordn) + call splint(r,x,x2,-1,imin,imax,r(i)-h,dbacdn) + call splint(r,x,x2,1,imin,imax,r(i)+h,dforup) + call splint(r,x,x2,1,imin,imax,r(i)-h,dbacup) + dback = dbacup + dbacdn + dforw = dforup + dfordn + endif + deriv = (dforw-dback)/(2.d0*h) + endif + return + 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 @@ + subroutine exchen(d,s,ex) +c gga91 exchange energy for a spin-unpolarized electronic system +c input d : density +c input s : abs(grad d)/(2*kf*d) +c output ex : exchange energy per electron + implicit double precision (a-h,o-z) + data a1,a2,a3,a4/0.19645d0,0.27430d0,0.15084d0,100.d0/ + data ax,a,b1/-0.7385588d0,7.7956d0,0.004d0/ + data thrd/0.333333333333d0/ + fac = ax*d**thrd + s2 = s*s + s4 = s2*s2 + p0 = 1.d0/dsqrt(1.d0+a*a*s2) + p1 = dlog(a*s+1.d0/p0) + p2 = dexp(-a4*s2) + p3 = 1.d0/(1.d0+a1*s*p1+b1*s4) + p4 = 1.d0+a1*s*p1+(a2-a3*p2)*s2 + f = p3*p4 + ex = fac*f + return + 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 @@ + subroutine exchpt(d,s,u,v,vx) +c gga91 exchange potential for a spin-unpolarized electronic system +c input d : density +c input s : abs(grad d)/(2*kf*d) +c input u : (grad d)*grad(abs(grad d))/(d**2 * (2*kf)**3) +c input v : (laplacian d)/(d*(2*kf)**2) +c output vx : exchange potential per electron + implicit double precision (a-h,o-z) + data a1,a2,a3,a4/0.19645d0,0.27430d0,0.15084d0,100.d0/ + data ax,a,b1/-0.7385588d0,7.7956d0,0.004d0/ + data thrd,thrd4/0.333333333333d0,1.33333333333d0/ + fac = ax*d**thrd + s2 = s*s + s3 = s2*s + s4 = s2*s2 + p0 = 1.d0/dsqrt(1.d0+a*a*s2) + p1 = dlog(a*s+1.d0/p0) + p2 = dexp(-a4*s2) + p3 = 1.d0/(1.d0+a1*s*p1+b1*s4) + p4 = 1.d0+a1*s*p1+(a2-a3*p2)*s2 + f = p3*p4 + p5 = b1*s2-(a2-a3*p2) + p6 = a1*s*(p1+a*s*p0) + p7 = 2.d0*(a2-a3*p2)+2.d0*a3*a4*s2*p2-4.d0*b1*s2*f + fs = p3*(p3*p5*p6+p7) + p8 = 2.d0*s*(b1-a3*a4*p2) + p9 = a1*p1+a*a1*s*p0*(3.d0-a*a*s2*p0*p0) + p10 = 4.d0*a3*a4*s*p2*(2.d0-a4*s2)-8.d0*b1*s*f-4.d0*b1*s3*fs + p11 = -p3*p3*(a1*p1+a*a1*s*p0+4.d0*b1*s3) + fss = p3*p3*(p5*p9+p6*p8)+2.d0*p3*p5*p6*p11+p3*p10+p7*p11 + vx = fac*(thrd4*f-(u-thrd4*s3)*fss-v*fs) + return + 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 @@ + subroutine gcor(a,a1,b1,b2,b3,b4,p,rs,gg,ggrs) +c called by subroutines ldaec and ldauc + implicit double precision (a-h,o-z) + p1 = p + 1.d0 + q0 = -2.d0*a*(1.d0+a1*rs) + rs12 = dsqrt(rs) + rs32 = rs12**3 + rsp = rs**p + q1 = 2.d0*a*(b1*rs12+b2*rs+b3*rs32+b4*rs*rsp) + q2 = dlog(1.d0+1.d0/q1) + gg = q0*q2 + q3 = a*(b1/rs12+2.d0*b2+3.d0*b3*rs12+2.d0*b4*p1*rsp) + ggrs = -2.d0*a*a1*q2-q0*q3/(q1**2+q1) + return + 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 @@ +c***************************************************************** +c***************************************************************** +c***************************************************************** +c GGA +c The Generalized Gradient Approximation + +c GGA is a way to improve the local spin density approximation +c by adding nonlocal gradients in the evaluation of the exchange- +c correlation energy and potential. These functions and subroutines +c are based on programs made by John Perdew, Tulane University, +c New Orleans, Louisiana, USA. Email: PY03APF%music.tcs.tulane.edu +c The modifications necessary to fit them to the atom program was +c made by Tomas Holmquist 1993 (so now you know who to blame). +c Email: tomash@fy.chalmers.se +c A more thorough description of the GGA used may be found in +c J.P. Perdew et al, Phys. Rev. B (46) 1992 pp. 6671-6687. + +c The GGA package is: + +c function deriv +c subroutine grad +c subroutine grabgr +c subroutine laplac +c subroutine spline +c subroutine splint +c subroutine ggaexc +c subroutine exchen +c subroutine ldaec +c subroutine gcor +c subroutine ggaec +c subroutine ggauxc +c subroutine exchpt +c subroutine ldauc +c subroutine ggauc + +c The grad, grabgr, and laplace subroutines uses the function deriv +c to calculate different derivatives with respect to the radial +c coordinate r. Spline and splint calculates the cubic spline +c interpolation which is used in function deriv. +c The two main subprograms, ggaexc and ggauxc, calculates +c the exchange-correlation energy and potential respectively. +c The other subroutines are modified versions of Perdew's program. + +c***************************************************************** +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 @@ + subroutine ggaec(rs,zet,t,ec,h) +c called by subroutine ggaexc +c gga91 correlation +c input rs : seitz radius +c input zet : relative spin polarization +c input t : abs(grad d)/(d*2.*ks*g) +c input : correlation energy per electron (ec) +c output h : nonlocal part of correlation energy per electron + implicit double precision (a-h,o-z) + data xnu,cc0,cx,alf/15.75592d0,0.004235d0,-0.001667212d0,0.09d0/ + data c1,c2,c3,c4/0.002568d0,0.023266d0,7.389d-6,8.723d0/ + data c5,c6,a4/0.472d0,7.389d-2,100.d0/ + data thrd2/0.666666666667d0/ + pi = 4.d0*datan(1.d0) + fk = 1.91915829d0/rs + sk = dsqrt(4.d0*fk/pi) + g = ((1.d0+zet)**thrd2+(1.d0-zet)**thrd2)/2.d0 + bet = xnu*cc0 + delt = 2.d0*alf/bet + g3 = g**3 + g4 = g3*g + pon = -delt*ec/(g3*bet) + b = delt/(dexp(pon)-1.d0) + b2 = b*b + t2 = t*t + t4 = t2*t2 + rs2 = rs*rs + rs3 = rs2*rs + q4 = 1.d0+b*t2 + q5 = 1.d0+b*t2+b2*t4 + q6 = c1+c2*rs+c3*rs2 + q7 = 1.d0+c4*rs+c5*rs2+c6*rs3 + cc = -cx + q6/q7 + r0 = (sk/fk)**2 + r1 = a4*r0*g4 + coeff = cc-cc0-3.d0*cx/7.d0 + r2 = xnu*coeff*g3 + r3 = dexp(-r1*t2) + h0 = g3*(bet/delt)*dlog(1.d0+delt*q4*t2/q5) + h1 = r3*r2*t2 + h = h0 + h1 + return + 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 @@ + subroutine ggaexc(r,db,i,imin,imax,doned,exc) +c ggaexc calculates the exchange-correlation energy +c input r : position coordinate (array) +c input db : spin up and down density. (array) +c input i : counter, i.e. present position = r(i) +c input imin : min value of i +c input imax : max value of i +c in/output doned : true if density is splined +c output exc : exchange-correlation energy + implicit logical (a-z) + logical doned + double precision r,db,gradd,gradup,graddn,fk,fkup,fkdn,sk,g + double precision sup,sdn,t,exc,ec + double precision onethi,twothi,pi,conkf,d,zet,rs,exup,exdn + double precision ex,eclda,ecgga + integer i,imin,imax + dimension r(561),db(2,561) + dimension gradd(561),gradup(561),graddn(561),fk(561),fkup(561) + dimension fkdn(561),sk(561),g(561),sup(561),sdn(561),t(561) + common/gga/gradd,gradup,graddn,fkup,fkdn,sk,g,sup,sdn,t + onethi = 1.d0/3.d0 + twothi = 2.d0/3.d0 + pi = 4.d0*datan(1.d0) + conkf = (3.d0*pi**2)**onethi + d = db(1,i) + db(2,i) + call grad(r,db,i,imin,imax,doned,gradd(i),gradup(i),graddn(i)) + +c calculate the exchange energy, first spin up, then spin down + + if (db(1,i).gt.1.d-100) then + fkup(i) = conkf*(2.d0*db(1,i))**onethi + sup(i) = dabs(gradup(i))/(2.d0*fkup(i)*db(1,i)) + call exchen(2.d0*db(1,i),sup(i),exup) + else + fkup(i) = 0.d0 + sup(i) = 0.d0 + exup = 0.d0 + endif + if (db(2,i).gt.1.d-100) then + fkdn(i) = conkf*(2.d0*db(2,i))**onethi + sdn(i) = dabs(graddn(i))/(2.d0*fkdn(i)*db(2,i)) + call exchen(2.d0*db(2,i),sdn(i),exdn) + else + fkdn(i) = 0.d0 + sdn(i) = 0.d0 + exdn = 0.d0 + endif + if (d.gt.1d-100) then + ex = (exup*db(1,i) + exdn*db(2,i))/d + else + ex = 0.d0 + endif + +c exchange energy done, now calculate the correlation energy + + fk(i) = conkf*d**onethi + sk(i) = dsqrt(4.d0*fk(i)/pi) + if (d.gt.1.d-100) then + zet = (db(1,i) - db(2,i))/d + else + zet = 0.d0 + endif + g(i) = ((1.d0+zet)**twothi+(1.d0-zet)**twothi)/2.d0 + if (d.gt.1.d-18) then + rs = (3.d0/(4.d0*pi*d))**onethi + t(i) = dabs(gradd(i))/(d*2*sk(i)*g(i)) + call ldaec(rs,zet,eclda) + call ggaec(rs,zet,t(i),eclda,ecgga) + ec = eclda + ecgga + else + ec = 0.d0 + endif + exc = ex + ec + + return + 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 @@ + subroutine ggauc(rs,zet,t,uu,vv,ww,ec,ecrs,eczet,dvcup,dvcdn) +c gga91 correlation +c input rs : seitz radius +c input zet : relative spin polarization +c input t : abs(grad d)/(d*2.*ks*g) +c input uu : (grad d)*grad(abs(grad d))/(d**2 * (2*ks*g)**3) +c input vv : (laplacian d)/(d * (2*ks*g)**2) +c input ww : (grad d)*(grad zet)/(d * (2*ks*g)**2 +c input ec : correlation energy +c input ecrs : derivative of ec with respect to rs +c input eczet : derivative of ec with respect to zet +c output dvcup,dvcdn : nonlocal parts of correlation potentials + implicit double precision (a-h,o-z) + data xnu,cc0,cx,alf/15.75592d0,0.004235d0,-0.001667212d0,0.09d0/ + data c1,c2,c3,c4/0.002568d0,0.023266d0,7.389d-6,8.723d0/ + data c5,c6,a4/0.472d0,7.389d-2,100.d0/ + data thrdm,thrd2/-0.333333333333d0,0.666666666667d0/ + pi = 4.d0*datan(1.d0) + fk = 1.91915829d0/rs + sk = dsqrt(4.d0*fk/pi) + g = ((1.d0+zet)**thrd2+(1.d0-zet)**thrd2)/2.d0 + bet = xnu*cc0 + delt = 2.d0*alf/bet + g3 = g**3 + g4 = g3*g + pon = -delt*ec/(g3*bet) + b = delt/(dexp(pon)-1.d0) + b2 = b*b + t2 = t*t + t4 = t2*t2 + t6 = t4*t2 + rs2 = rs*rs + rs3 = rs2*rs + q4 = 1.d0+b*t2 + q5 = 1.d0+b*t2+b2*t4 + q6 = c1+c2*rs+c3*rs2 + q7 = 1.d0+c4*rs+c5*rs2+c6*rs3 + cc = -cx + q6/q7 + r0 = (sk/fk)**2 + r1 = a4*r0*g4 + coeff = cc-cc0-3.d0*cx/7.d0 + r2 = xnu*coeff*g3 + r3 = dexp(-r1*t2) + h0 = g3*(bet/delt)*dlog(1.d0+delt*q4*t2/q5) + h1 = r3*r2*t2 + h = h0+h1 +c energy done. now the potential: + ccrs = (c2+2.*c3*rs)/q7 - q6*(c4+2.*c5*rs+3.*c6*rs2)/q7**2 + rsthrd = rs/3.d0 + r4 = rsthrd*ccrs/coeff +c========================================================= +c fix made by Tomas Holmquist + if ((zet.eq.1.d0).or.(zet.eq.-1.d0)) then + gz = 0.d0 + else + gz = ((1.d0+zet)**thrdm - (1.d0-zet)**thrdm)/3.d0 + endif +c========================================================= + fac = delt/b+1.d0 + bg = -3.d0*b2*ec*fac/(bet*g4) + bec = b2*fac/(bet*g3) + q8 = q5*q5+delt*q4*q5*t2 + q9 = 1.d0+2.d0*b*t2 + h0b = -bet*g3*b*t6*(2.d0+b*t2)/q8 + h0rs = -rsthrd*h0b*bec*ecrs + fact0 = 2.d0*delt-6.d0*b + fact1 = q5*q9+q4*q9*q9 + h0bt = 2.d0*bet*g3*t4*((q4*q5*fact0-delt*fact1)/q8)/q8 + h0rst = rsthrd*t2*h0bt*bec*ecrs + h0z = 3.d0*gz*h0/g + h0b*(bg*gz+bec*eczet) + h0t = 2.*bet*g3*q9/q8 + h0zt = 3.d0*gz*h0t/g+h0bt*(bg*gz+bec*eczet) + fact2 = q4*q5+b*t2*(q4*q9+q5) + fact3 = 2.d0*b*q5*q9+delt*fact2 + h0tt = 4.d0*bet*g3*t*(2.d0*b/q8-(q9*fact3/q8)/q8) + h1rs = r3*r2*t2*(-r4+r1*t2/3.d0) + fact4 = 2.d0-r1*t2 + h1rst = r3*r2*t2*(2.d0*r4*(1.d0-r1*t2)-thrd2*r1*t2*fact4) + h1z = gz*r3*r2*t2*(3.d0-4.d0*r1*t2)/g + h1t = 2.d0*r3*r2*(1.d0-r1*t2) + h1zt = 2.d0*gz*r3*r2*(3.d0-11.d0*r1*t2+4.d0*r1*r1*t4)/g + h1tt = 4.d0*r3*r2*r1*t*(-2.d0+r1*t2) + hrs = h0rs+h1rs + hrst = h0rst+h1rst + ht = h0t+h1t + htt = h0tt+h1tt + hz = h0z+h1z + hzt = h0zt+h1zt + comm = h+hrs+hrst+t2*ht/6.d0+7.d0*t2*t*htt/6.d0 + pref = hz-gz*t2*ht/g + fact5 = gz*(2.d0*ht+t*htt)/g + comm = comm-pref*zet-uu*htt-vv*ht-ww*(hzt-fact5) + dvcup = comm + pref + dvcdn = comm - pref + return + 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 @@ + subroutine ggauxc(r,db,zet,i,imin,imax,donela,donegr,donez, + j uxcup,uxcdn) +c ggauxc calculates the exchange-correlation potential by taking +c the functional derivative of the energy with respect to the density +c input r : position coordinate (array) +c input db : spin up and down density. (array) +c input zet : relative spin polarization (array) +c input i : counter, i.e. present position = r(i) +c input imin : min value of i +c input imax : max value of i +c in/output donela : true if r^2*grad(density) is splined +c in/output donegr : true if abs(grad(density)) is splined +c in/output donez : true if zet is splined +c output uxcup : spin-up exchange-correlation potential +c output uxcdn : spin-down exchange-correlation potential + implicit logical (a-z) + double precision r,db,zet,uxcup,uxcdn,gradd,gradup,graddn + double precision fkup,fkdn,sk,g,sup,sdn,t,tempz,z2,gradz + double precision onethi,pi,d,rs,lapld,laplup,lapldn,deriv + double precision gagd,gagup,gagdn,uu,vv,ww,uup,vup,udn,vdn + double precision uclcup,uclcdn,ucgaup,ucgadn,uxup,uxdn + double precision ucup,ucdn,ec,ecrs,eczet + integer i,imin,imax,j + logical donela,donegr,donez + common/gga/gradd,gradup,graddn,fkup,fkdn,sk,g,sup,sdn,t + common/ggaz/tempz,z2 + dimension r(561),db(2,561),zet(561),tempz(2,561),z2(2,561) + dimension gradd(561),gradup(561),graddn(561),fkup(561) + dimension fkdn(561),sk(561),g(561),sup(561),sdn(561),t(561) + onethi = 1.d0/3.d0 + pi = 4.d0*datan(1.d0) + call laplac(r,gradup,graddn,i,imin,imax,donela,lapld,laplup, + j lapldn) + call grabgr(r,gradup,graddn,i,imin,imax,donegr,gagd,gagup,gagdn) + +c calculate the exchange potential + if (db(1,i).gt.1.d-100) then + uup = gradup(i)*gagup/(db(1,i)**2*(2.d0*fkup(i))**3) + vup = laplup/(db(1,i)*(2.d0*fkup(i))**2) + call exchpt(2.d0*db(1,i),sup(i),uup,vup,uxup) + else + uxup = 0.d0 + endif + if (db(2,i).gt.1.d-100) then + udn = graddn(i)*gagdn/(db(2,i)**2*(2.d0*fkdn(i))**3) + vdn = lapldn/(db(2,i)*(2.d0*fkdn(i))**2) + call exchpt(2.d0*db(2,i),sdn(i),udn,vdn,uxdn) + else + uxdn = 0.d0 + endif + +c exchange potential done, now calculate the correlation potential + + if (.not.donez) then + do 10 j = imin,imax + tempz(1,j) = zet(j) + 10 continue + call spline(r,imin+1,imax,tempz,z2) + donez = .true. + endif + gradz = deriv(r,tempz,z2,1,i,imin,imax) + d = db(1,i) + db(2,i) + if (d.gt.1.d-18) then + rs = (3.d0/(4.d0*pi*d))**onethi + uu = gradd(i)*gagd/(d**2*(2.d0*sk(i)*g(i))**3) + vv = lapld/(d*(2.d0*sk(i)*g(i))**2) + ww = gradd(i)*gradz/(d*(2.d0*sk(i)*g(i))**2) + call ldauc(rs,zet(i),ec,ecrs,eczet,uclcup,uclcdn) + call ggauc(rs,zet(i),t(i),uu,vv,ww,ec,ecrs,eczet,ucgaup, + j ucgadn) + ucup = uclcup + ucgaup + ucdn = uclcdn + ucgadn + else + ucdn = 0.d0 + ucup = 0.d0 + endif + uxcup = uxup + ucup + uxcdn = uxdn + ucdn + + return + end + 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 @@ + subroutine grabgr(r,gradup,graddn,i,imin,imax,done,gagd,gagup, + j gagdn) +c calculates grad(abs(grad(density))) +c input r : radial coordinate (array) +c input gradup : grad(density), spin up (array) +c input graddn : grad(density), spin down (array) +c input i : counter, i.e. current position = r(i) +c input imin : min value of i +c input imax : max value of i +c in/output done : true if abs(grad(density)) is splined +c output gagd : grad(abs(grad(density))) +c output gagup,gagdn : grad(abs(grad(density))), spin up and down + implicit logical (a-z) + logical done + double precision r,gradup,graddn,gagd,gagup,gagdn,temp,gag2,deriv + integer i,imin,imax,j + common/ggagag/temp,gag2 + dimension r(561),gradup(561),graddn(561) + dimension temp(2,561),gag2(2,561) + if (.not.done) then + do 10 j = imin,imax + temp(1,j) = dabs(gradup(j)) + temp(2,j) = dabs(graddn(j)) + 10 continue + call spline(r,imin+1,imax,temp,gag2) + done = .true. + endif + gagup = deriv(r,temp,gag2,1,i,imin,imax) + gagdn = deriv(r,temp,gag2,-1,i,imin,imax) + gagd = gagup + gagdn + return + 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 @@ + subroutine grad(r,db,i,imin,imax,done,gradd,gradup,graddn) +c grad calculates the derivative of db with respect to r, at +c position r(i). +c input r : radial coordinate (array) +c input db : spin-up and down densities (array) +c input i : counter, i.e. current position = r(i) +c input imin : min value of i +c input imax : max value of i +c in/output done : true if density is splined +c output gradd : grad(density) +c output gradup,graddn : grad(density), spin up and down + implicit logical (a-z) + logical done + double precision r,db,gradd,gradup,graddn,db2,deriv + integer i,imin,imax + dimension r(561),db(2,561),db2(2,561) + common/ggagra/db2 + if (.not.done) then + call spline(r,imin+1,imax,db,db2) + done = .true. + endif + gradup = deriv(r,db,db2,1,i,imin,imax) + graddn = deriv(r,db,db2,-1,i,imin,imax) + gradd = gradup + graddn + return + 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 @@ + program atom + implicit double precision (a-h,o-z) + dimension dval(2,561),nval(2,7,10),ddval(2,561),ndval(2,7,10) + dimension dcore(2,561),vhv(561),fpu(561) +c +c free atom program by m.p. summer 1985 (valence energy and core +c density are calculated) +c +c GGA implemented by T. Holmquist and U. Yxklinten. +c +c files used: +c 6: terminal output +c 22: density and potential output +c 33: density and potential input +c 44: potential and density double prec. output +c 46: potential and density double prec. input +c 55: control input +c 66: printer output +c 77: density (total and core) output (J.H.) +c + dimension r(561),veff(2,561),vc(561),vcold(561),vv(561) + dimension gr(561),lm(2),rnocc(2,7,10),ux1(561),ux2(561) + dimension u(561),roo(561),spl(561),nb(7) + dimension db(2,561),v(561),vold(2,561) + dimension snlo(561),wj(301),ekin(2) + dimension ebound(2,7,10),nbound(2,7),de(2,7,10) + dimension apu(561),bpu(561),cpu(561),dpu(561),nlp(2,7,10) + dimension epu(561) +c=================================================================== +c gga + dimension excgga(561),uxcup(561),uxcdn(561) + logical doned,donela,donegr,donez,donec +c gga +c=================================================================== + common/sc/gr,r,snlo,nbl + common/mess/wj,dx,nblock,jblock + common/pot/v + frs(x)=(3.d0/(4.d0*pi*x))**(1.d0/3.d0) + pi=4.d0*datan(1.d0) + pi2=pi/2.d0 + a=(4.d0/9.d0/pi)**(1.d0/3.d0) +c + open(22,file='adensout.dat',status='unknown') + open(33,file='adensin.dat',status='unknown') + open(44,file='apotout.dat',status='unknown') + open(46,file='apotin.dat',status='unknown') + open(55,file='atomctrl.dat',status='old') + open(66,file='aprtout.dat',status='unknown') + open(77,file='atomdens.dat',status='unknown') + write(6,*) '=== Its ===== Energy (Ha) ======' + call flush(6) + read(55,*)z,zion +c z : atomic number +c zion : ionicity +c + write(66,2) z,zion +2 format(/' atom number:',f5.0,' ionicity:',f5.0) + sf=4.d0*pi + read(55,*)jblock,nbl,c +c parameters of the hermann-skillmann mesh + read(55,*)fback,thresh,qsc +C fback : feedback +c thresh : error allowed for the bound state eigenenergy +c e.g. 0.00001 +c qsc : parameter for the screened green's function (0.005) + read(55,*)itmax,inopt,ipr,iout +c itmax : max. no. of iterations +c iopt : =0 starting potential generated; =1 starting potential +c read in; =2 starting potential read in from unit 46. +c (double precision format) +c ipr, iout : print out parameters +c +c set up the herman-skillman mesh +c + nblock=jblock + mesh=nblock*nbl+1 + n=mesh + mest=mesh + dx=c*0.0025d0 + en0=-0.01d0 + i=1 + r(i)=0.d0 + deltax=dx + do 251 j=1,nblock + do 241 jk=1,nbl + i=i+1 + 241 r(i)=r(i-1)+deltax + deltax=2.d0*deltax + 251 continue +c + read(55,*)ne,iys,ixc +c ne: no. bound states +c iys: =1 for spin compensated; =2 spin polarized +c ixc: = 1 b-h xc; =0 c-a xc + if(ixc.eq.1)write(66,2149) + if(ixc.eq.0)write(66,2148) + if(ixc.eq.2)write(66,2147) +2149 format(/' von barth - hedin xc') +2148 format(/' ceperley - alder xc') +2147 format(/' perdew - wang xc') + dxx=r(n)-r(n-1) + write(66,5)jblock,nbl,c + write(66,5849)dx,dxx,r(n) + 5 format(/' hermann-skillmann mesh',/,' blocks, nbl, c:',2(i5,','), + j f10.7) +5849 format(' first interval, last interval, final r:',2(f10.6,','), + j f10.6) + write(66,2312) thresh,qsc,fback +2312 format(/' energy eigenvalue threshold, screening parameter, ', + j 'feedback:',2(f12.6,','),f6.3) + write(66,9) + do 5273 i=1,7 +5273 nb(i)=0 + lmax=0 +9 format(//' initial bound state configuration',/, + j ' nlm energy occup. val.el. d-band el.') + zv=0.d0 + do 5595 ispin=1,iys + do 5595 ii=1,ne + read(55,*)nnlz,eb0,rnoc,nv,ndv +c +c nnlz : e.g. 100 +c eb0 : energy eigenvalue guess +c rnoc : occupation number +c nv : =1 when orbital is a valence orbital; =0 for core orbitals +c ndv : =1 when orbital is a d-valence orbital; =0 for other orbitals +c + nnn=nnlz/100 + lll=(nnlz-nnn*100)/10 + nnn=nnn-lll + if(nnn.gt.nb(lll+1))nb(lll+1)=nnn + if(lll.gt.lmax)lmax=lll + rnocc(ispin,lll+1,nnn)=rnoc + nval(ispin,lll+1,nnn)=nv + ndval(ispin,lll+1,nnn)=ndv + if(iys.eq.1)nval(2,lll+1,nnn)=nv + if(iys.eq.1)ndval(2,lll+1,nnn)=ndv + if(iys.eq.1)rnocc(2,lll+1,nnn)=rnoc + if(iys.eq.1)rnoc=rnoc*2 + write(66,19)nnlz,eb0,rnoc,nv,ndv + zv=zv+rnoc*(nv+ndv) +5595 ebound(ispin,lll+1,nnn)=eb0 + write(66,5120)zv +5120 format(/' number of valence electrons: ',f5.1) + 19 format(i6,e12.4,f7.2,i7,i10) + nb1=nbl+1 + iter=0 + itr=itmax-iout +c + 16 format(7(f12.5,1x)) + 17 format(/' charge and spin density profiles '/) + 18 format(1h0/' potentials vs. distance after ',i3,' iterations'/) +c +c tabulate screened green's function + do 10 i=1,n + 10 gr(i)=exp(-qsc*r(i)) +c +c integration weigths + do 121 i=1,nb1 + 121 wj(i)=(3.d0+(-1.d0)**i)/3.d0 + wj(1)=1.d0/3.d0 + wj(nb1)=1.d0/3.d0 +c +c initial values of the potentials + if(inopt.eq.1) goto 302 + if(inopt.eq.2) goto 306 +c + itt=0 +c thomas-fermi potential + do 30 i=2,n + x=r(i)/0.88534135d0*z**(1.d0/3.d0) + xx=sqrt(x) + vc(i)=-z/r(i)/(1.+0.02747d0*xx+1.243d0*x-0.1486d0*x*xx + j+0.2302d0*x*x+0.007298d0*x*x*xx+0.006944d0*x*x*x) + do 30 ispin=1,2 + 30 veff(ispin,i)=vc(i) + goto 311 +c read in an old potential for the input +302 read(33,2645)itt +2645 format(i3) +1645 format(i3,' z,ion:',2f4.0,' jblock,nbl,c:',2i5,f10.7) + do 303 i=1,n + 303 read(33,907) vc(i),veff(1,i),veff(2,i),du1,du2 + goto 311 + 306 read(46,2645) itt + do 304 i = 1, n + read(46,*) du1, vc(i), vve, du2 + veff(1,i) = vve + veff(2,i) = vve + 304 continue + 311 do 312 i=1,n + vcold(i)=vc(i) + do 312 ispin=1,2 + 312 vold(ispin,i)=veff(ispin,i) + 5555 format(e15.8) + 7771 format(/' initial potentials'/) + 7773 format(5f13.5) + if(iout.lt.-1)go to 1437 + write(66,7771) + do 7772 i=2,n,ipr + 7772 write(66,7773) r(i),vc(i),veff(1,i),veff(2,i) +1437 eold=0.d0 + etot=-1.d0 + itec=0 +c +c iteration +c + 100 iter=iter+1 +c write(6,*) 'NEW ITERATION' +c call flush(6) +c convergency check + if(abs(etot-eold).lt.5.d-5)itec=itec+1 + if(abs(etot-eold).lt.5.d-5.and.itec.eq.1)itmax=iter + eold=etot + if(iter-itmax)999,999,400 +999 itt=itt+1 + write(66,6147)itt + do 117 i=1,n + dval(2,i)=0.d0 + ddval(2,i)=0.d0 + dcore(1,i)=0.d0 + dcore(2,i)=0.d0 + dval(1,i)=0.d0 + 117 ddval(1,i)=0.d0 + 6147 format(///' ********************* iteration:', + 1 i4,' ***********************'/) + do 917 ispin=1,iys + do 116 i=1,n + vv(i)=veff(ispin,i) + v(i)=2*vv(i) + 116 db(ispin,i)=0.d0 + lm(ispin)=-1 + do 807 i=0,4 + ik=i + if(i)817,817,818 +817 do 819 jj=1,4 +819 u(jj)=r(jj)-z*r(jj)**2 + go to 822 +818 do 821 jj=1,4 +821 u(jj)=r(jj)**(i+1) +822 call schrhs(vv,0.d0,ik,u) + merkki=1 +c determine the number of bound states + ncross=0 + do 826 ii=2,n + if(merkki)823,823,824 +823 if(u(ii))826,826,825 +824 if(u(ii))825,826,826 +825 merkki=-merkki + ncross=ncross+1 +826 continue + dlo=(u(n)-u(n-1))*u(n) + if(dlo.ge.0)nbound(ispin,i+1)=ncross + if(dlo.lt.0)nbound(ispin,i+1)=ncross+1 + if(nbound(ispin,i+1).eq.0)go to 827 + lm(ispin)=i + write(66,678)i,nbound(ispin,i+1) + nbound(ispin,i+1)=min0(nbound(ispin,i+1),nb(i+1)) +678 format(' l = ',i4,',',i4,' bound states ') +807 continue +827 if(lm(ispin).lt.0.and.ispin.eq.2)go to 674 + if(lm(ispin).lt.0.and.ispin.eq.1)go to 917 + lm(ispin)=min0(lm(ispin),lmax) + lmm=lm(ispin) + do 918 i=0,lmm + nii=min0(nbound(ispin,i+1),8) + ik=i + do 918 ii=1,nii + if(rnocc(ispin,i+1,ii).lt.0.1d0)go to 918 + nn=i+ii + en=2.d0*ebound(ispin,i+1,ii) + if(en.ge.0.d0)en=en0 + en1=en + dde=de(ispin,i+1,ii) + if(iter.le.2)dde=0.d0 +c determine the bound state energy and eigenfunction + call scheq(z,en,ik,nn,mest,mesh,c,thresh,iflag,npr,dde) +c scheq operates in rydberg units + if(iter.ge.2)de(ispin,i+1,ii)=abs(en-en1) + if(iflag.eq.1) goto 400 + 163 ebound(ispin,i+1,ii)=en/2.d0 + nlp(ispin,i+1,ii)=npr + do 9188 ji=1,n + dval(ispin,ji)=dval(ispin,ji)+rnocc(ispin,i+1,ii)*snlo(ji)**2/sf + j*nval(ispin,i+1,ii) + ddval(ispin,ji)=ddval(ispin,ji)+rnocc(ispin,i+1,ii)*snlo(ji)**2/ + j sf*ndval(ispin,i+1,ii) + dcore(ispin,ji)=dcore(ispin,ji)+rnocc(ispin,i+1,ii)*snlo(ji)**2/ + j sf*(1-ndval(ispin,i+1,ii))*(1-nval(ispin,i+1,ii)) + 9188 db(ispin,ji)=db(ispin,ji)+rnocc(ispin,i+1,ii)*snlo(ji)**2/sf + 918 continue + do 919 ji=2,n + dcore(ispin,ji)=dcore(ispin,ji)/r(ji)**2 + 919 db(ispin,ji)=db(ispin,ji)/r(ji)**2 + db(ispin,1)=db(ispin,2) + dcore(ispin,1)=dcore(ispin,2) + do 5739 ji=2,n + ddval(ispin,ji)=ddval(ispin,ji)/r(ji)**2 +5739 dval(ispin,ji)=dval(ispin,ji)/r(ji)**2 + dval(ispin,1)=dval(ispin,2) + ddval(ispin,1)=ddval(ispin,2) + 917 continue + if(iys.eq.2)go to 923 + do 921 i=1,n + dval(2,i)=dval(1,i) + ddval(2,i)=ddval(1,i) + dcore(2,i)=dcore(1,i) +921 db(2,i)=db(1,i) + lmm=lm(1) + lm(2)=lm(1) + do 922 i=0,lmm + nii=nbound(1,i+1) + nbound(2,i+1)=nii + do 922 ii=1,nii +922 ebound(2,i+1,ii)=ebound(1,i+1,ii) +923 continue + 8 format(' ',i6,' energy: ',f12.5,' iteration loops: ',i4) +c +c total bound state energy +c +c write(6,*) 'Total energy starts' +c call flush(6) + 661 eb=0.d0 + ebv=0.d0 + write(66,7496) +7496 format(//' bound states'/) + do 673 ispin=1,2 + lmm=lm(ispin) + do 673 i=0,lmm + nii=nbound(ispin,i+1) + do 673 j=1,nii + nn=i+j + nnlz=100*nn+10*i + eb=eb+ebound(ispin,i+1,j)*rnocc(ispin,i+1,j) + ebv=ebv+ebound(ispin,i+1,j)*rnocc(ispin,i+1,j)* + j (nval(ispin,i+1,j)+ndval(ispin,i+1,j)) + if(rnocc(ispin,i+1,j).lt.0.1d0) go to 673 + write(66,8) nnlz,ebound(ispin,i+1,j),nlp(ispin,i+1,j) + 673 continue + go to 679 +674 write(66,676) +676 format('0no bound states') +679 continue +c +c total charge and spin densities +c computing energy integrals +c +506 continue +c========================================= +c gga +c set the "done" controle variables to false in the beginning of +c each iteration + + if (ixc.eq.2) then + doned = .false. + donela = .false. + donegr = .false. + donez = .false. + donec = .false. + endif +c gga +c======================================== + do 660 i=2,n + roo(i)=db(1,i)+db(2,i) + rr=roo(i) +c When db = (0,0) then the spin-polarization, spl = 0, and not 0/0. + if (rr.gt.0.0000000001) then + spl(i)=(db(1,i)-db(2,i))/rr + else + spl(i)=0.0 + endif + x1=r(i)**2 + apu(i)=x1*veff(1,i)*db(1,i)*sf + bpu(i)=x1*veff(2,i)*db(2,i)*sf + if (ixc.eq.2) then +c================================================================ +c gga +c calculate the gga exchange-correlation energy + + call ggaexc(r,db,i,1,n,doned,excgga(i)) + cpu(i) = x1*rr*excgga(i)*sf +c gga +c================================================================ + else + cpu(i)=x1*rr*exc(rr,spl(i),ixc)*sf + endif + dpu(i)=x1*spl(i)*rr*sf + 660 continue + 26 format(' induced moment: ',f10.5) + call simpsh(apu,v1) + call simpsh(bpu,v2) + call simpsh(cpu,eexc) + call simpsh(dpu,smom) +c +c compute coulomb energy +c + cz=z + do 683 i=1,n + bpu(i)=roo(i)*r(i)**2*sf + dpu(i)=(dval(1,i)+dval(2,i))*r(i)**2*sf + apu(i)=(ddval(1,i)+ddval(2,i))*r(i)**2*sf + cpu(i)=roo(i)*(r(i)**2*vc(i)-z*r(i))*sf/2.d0 +683 continue + call simpsh(dpu,sum1) + call simpsh(apu,sum3) + call simpsh(bpu,sum2) + call simpsh(cpu,ec) + 24 format(' kin: ',2(e14.6,1x),' coul: ',e14.6,' exc: ',e14.6) + 25 format(/' total energy: ',e15.7) + write(66,192) sum2,sum1,sum3 + write(66,26) smom + ekin(1)=-v1 + ekin(2)=-v2 + etot=ekin(1)+ekin(2)+eb+ec+eexc + write(66,7453) +7453 format(/' energy terms') + write(66,622)eb + 622 format(' energy eigenvalue sum: ',e14.6) + write(66,24) ekin(1),ekin(2),ec,eexc + write(66,25) etot +c write(6,2573) itt,sum2,etot +c call flush(6) +c2573 format(' iter:',i4,' total ch:',f6.2,' total en:',f15.7) + write(6,2573) itt,etot + call flush(6) +2573 format(' ',i4,' ',f15.5) + + if(iter.ne.1 .and. iter.lt.itr) goto 167 + if(iout.lt.0)go to 167 + write(66,17) + 192 format(/' integr charges: total ',f10.7,' valence: ',2f10.7) + do 166 i=1,n,ipr + r22=r(i)*r(i) + db1=db(1,i) + db2=db(2,i) + dr=db1+db2 + dcc=dcore(1,i)+dcore(2,i) + dvv=dval(1,i)+dval(2,i)+ddval(1,i)+ddval(2,i) + ddb=db1-db2 +c166 write(66,1624) r(i),db1,db2,dval(i),ddval(i),dr,ddb + 166 write(66,1624) r(i),db1,db2,dr,dcc,dvv +c +c +c compute coulomb potential +c + 167 do 55 i=2,n + 55 vc(i)=r(i)*vc(i)+zion +c write(6,*) 'Coulomb potential' +c call flush(6) + zi=z-zion + vc(1)=-zi + call scrhs(roo,vc,zi,qsc,n) + do 50 i=2,n + 50 vc(i)=(vc(i)-zion)/r(i) +c +c set up the total potential +c + do 60 i=2,n + dr=roo(i) + vc(i)=(1.d0-fback)*vcold(i)+fback*vc(i) + vcold(i)=vc(i) + if (ixc.eq.2) then +c================================================================ +c gga +c calculate the gga exchange-correlation potential + + call ggauxc(r,db,spl,i,1,n,donela,donegr,donez, + j uxcup(i),uxcdn(i)) + ux1(i) = uxcup(i) + ux2(i) = uxcdn(i) +c gga +c================================================================ + else + ux1(i)=uxc(dr,spl(i),1,ixc) + ux2(i)=uxc(dr,spl(i),2,ixc) + endif + 6848 veff(1,i)=vc(i)+ux1(i) + veff(2,i)=vc(i)+ux2(i) + do 60 ispin=1,2 + veff(ispin,i)=(1.d0-fback)*vold(ispin,i)+fback*veff(ispin,i) + 60 vold(ispin,i)=veff(ispin,i) +c calculate the valence energy + do 5100 i=2,mesh + do 5110 j=1,mesh + apu(j)=0.d0 + if(i.le.j)apu(j)=(dval(1,j)+dval(2,j)+ddval(1,j)+ddval(2,j))* + j (r(j)**2/r(i)-r(j)) +5110 continue + call simpsh(apu,vp) +5100 vhv(i)=-vp*4.d0*pi+zv/r(i) + do 5130 i=1,mesh + x1=r(i)**2 + rr=db(1,i)+db(2,i) + spt=0.d0 + if(rr.gt.1.d-10)spt=(db(1,i)-db(2,i))/rr + rrv=dval(1,i)+dval(2,i)+ddval(1,i)+ddval(2,i) + spv=0.d0 + if(rrv.gt.1.d-10)spv=(dval(1,i)-dval(2,i)+ddval(1,i)-ddval(2,i)) + j /rrv + rrc=dcore(1,i)+dcore(2,i) + spc=0.d0 + if(rrc.gt.1.d-10)spc=(dcore(1,i)-dcore(2,i))/rrc + apu(i)=-0.5d0*x1*sf*rrv*vhv(i) + if (ixc.eq.2) then +c============================================================= +c gga +c calculate the gga exchange-correlation energy for core electrons + + if (rrc.lt.1.d-100) then + excgac = 0.d0 + else + call ggaexc(r,dcore,i,1,n,donec,excgac) + endif + bpu(i)=x1*rr*excgga(i)*sf + cpu(i)=-x1*rrc*excgac*sf + fpu(i)=(dcore(1,i)+dcore(2,i))*excgga(i)*x1*sf + dpu(i)=(-(dval(1,i)+ddval(1,i))*uxcup(i) + j -(dval(2,i)+ddval(2,i))*uxcdn(i))*sf*x1 +c gga +c================================================================== + else + bpu(i)=x1*rr*exc(rr,spt,ixc)*sf + cpu(i)=-x1*rrc*exc(rrc,spc,ixc)*sf + fpu(i)=(dcore(1,i)+dcore(2,i))*exc(rr,spt,ixc)*x1*sf + dpu(i)=(-(dval(1,i)+ddval(1,i))*uxc(rr,spt,1,ixc) + j -(dval(2,i)+ddval(2,i))*uxc(rr,spt,2,ixc))*sf*x1 + endif + epu(i)=apu(i)+bpu(i)+cpu(i)+dpu(i)+fpu(i) +5130 continue +c call simpsh(apu,ec) +c call simpsh(bpu,eext) +c call simpsh(fpu,eexx) +c call simpsh(cpu,eexc) +c call simpsh(dpu,eexv) +c etv=ebv+ec+eext+eexc+eexv + call simpsh(epu,etv) + etv = etv + ebv + write(66,5140)etv +5140 format(' valence energy:',e15.7) + if(iter.ne.1 .and. iter.lt.itr) go to 100 + if(iout.lt.0)go to 100 + write(66,18) itt + do 75 i=2,n,ipr + dr=roo(i) + 75 write(66,1624) r(i),vc(i),ux1(i),ux2(i),veff(1,i),veff(2,i) +1624 format(1x,f12.5,6e14.5) + goto 100 + 400 continue +c +c +c + do 1140 i=2,mesh + do 1130 j=1,mesh + apu(j)=0.d0 + if(i.le.j)apu(j)=(db(1,j)+db(2,j))*(r(j)**2/r(i)-r(j)) +1130 continue + call simpsh(apu,vp) +1140 vc(i)=-vp*sf + write(22,1645)itt,z,zion,jblock,nbl,c + write(44,1645)itt,z,zion,jblock,nbl,c + do 900 i=1,n + dd=db(1,i)+db(2,i) + dc=dcore(1,i)+dcore(2,i) + dddc = dd + dc + dv1=dval(1,i)+dval(2,i) + ddv1=ddval(1,i)+ddval(2,i) + vve = 0.5d00*(veff(1,i) + veff(2,i)) + write(44,*) r(i), vc(i), vve, dddc +c The line below writes total and core densities to atomdens.dat (J.H.) + write(77,906) r(i), 4*pi*dd*r(i)*r(i), 4*pi*dc*r(i)*r(i) + write(22,907)vc(i),veff(1,i),veff(2,i),dddc,r(i) + 900 continue + 907 format(6e15.7) +c900 write(22,906)vc(i),veff(1,i),veff(2,i),dd,dc +c900 write(22,906)vc(i),veff(1,i),veff(2,i),dd,dv1,ddv1 + 906 format(6e20.12) + write(6,*) '================================' + call flush(6) +c ieeer=ieee_flags('clear','exception','all',ieeeout) + close(6) + close(22) + close(33) + close(55) + close(66) + close(77) + stop + 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 @@ + subroutine laplac(r,gradup,graddn,i,imin,imax,done, + j lapl,laplup,lapldn) +c calculates laplace(density), i.e. (del^2)(density) +c spherical coordinates => (del^2)phi = 1/r^2*d/dr[r^2*d(phi)/dr] +c input r : radial coordinate (array) +c input gradup : grad(density), spin up (array) +c input graddn : grad(density), spin down (array) +c input i : counter, i.e. current position = r(i) +c input imin : min value of i +c input imax : max value of i +c in/output done : true if r^2*grad(density) is splined +c output lapl : laplace(density) +c output laplup,lapldn : laplace(density), spin up and down + implicit logical (a-z) + logical done + double precision r,gradup,graddn,lapl,laplup,lapldn,lapl2,temp + double precision rj2,r2,deriv + integer i,imin,imax,j + common/ggalap/temp,lapl2 + dimension r(561),gradup(561),graddn(561) + dimension lapl2(2,561),temp(2,561) + if (.not.done) then + do 10 j = imin,imax + rj2 = r(j)**2 + temp(1,j) = rj2*gradup(j) + temp(2,j) = rj2*graddn(j) + 10 continue + call spline(r,imin+1,imax,temp,lapl2) + done = .true. + endif + if (i.eq.imin) then + call laplac2(r,gradup,graddn,i+1,imin,imax,done,lapl,laplup, + j lapldn) + else + r2 = r(i)**2 + laplup = (deriv(r,temp,lapl2,1,i,imin,imax))/r2 + lapldn = (deriv(r,temp,lapl2,-1,i,imin,imax))/r2 + lapl = laplup + lapldn + endif + return + 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 @@ + subroutine laplac2(r,gradup,graddn,i,imin,imax,done, + j lapl,laplup,lapldn) + implicit logical (a-z) + logical done + double precision r,gradup,graddn,lapl,laplup,lapldn + integer i,imin,imax + dimension r(561),gradup(561),graddn(561) + call laplac(r,gradup,graddn,i+1,imin,imax,done,lapl,laplup, + j lapldn) + return + 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 @@ + subroutine ldaec(rs,zet,ec) +c uniform-gas correlation of perdew and wang 1991 +c calculates the local correlation energy within the lda approx. +c input rs : seitz radius +c input zet : relative spin polarization +c output ec : correlation energy per electron + implicit double precision (a-h,o-z) + data gam,fzz/0.5198421d0,1.709921d0/ + data thrd4/1.333333333333d0/ + f = ((1.d0+zet)**thrd4+(1.d0-zet)**thrd4-2.d0)/gam + call gcor(0.0310907d0,0.21370d0,7.5957d0,3.5876d0,1.6382d0, + 1 0.49294d0,1.00d0,rs,eu,eurs) + call gcor(0.01554535d0,0.20548d0,14.1189d0,6.1977d0,3.3662d0, + 1 0.62517d0,1.00d0,rs,ep,eprs) + call gcor(0.0168869d0,0.11125d0,10.357d0,3.6231d0,0.88026d0, + 1 0.49671d0,1.00d0,rs,alfm,alfrsm) +c alfm is minus the spin stiffness alfc + z4 = zet**4 + ec = eu*(1.d0-f*z4)+ep*f*z4-alfm*f*(1.d0-z4)/fzz + return + 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 @@ + subroutine ldauc(rs,zet,ec,ecrs,eczet,vcup,vcdn) +c uniform-gas correlation of perdew and wang 1991 +c calculates the local correlation potential within the lda approx. +c input rs : seitz radius +c input zet : relative spin polarization +c output ec : correlation energy +c output ecrs : derivative of ec with respect to rs +c output eczet : derivative of ec with respect to zet +c output vcup, vcdn : up- and down-spin potentials + implicit double precision (a-h,o-z) + data gam,fzz/0.5198421d0,1.709921d0/ + data thrd,thrd4/0.333333333333d0,1.333333333333d0/ + f = ((1.d0+zet)**thrd4+(1.d0-zet)**thrd4-2.d0)/gam + call gcor(0.0310907d0,0.21370d0,7.5957d0,3.5876d0,1.6382d0, + 1 0.49294d0,1.00d0,rs,eu,eurs) + call gcor(0.01554535d0,0.20548d0,14.1189d0,6.1977d0,3.3662d0, + 1 0.62517d0,1.00d0,rs,ep,eprs) + call gcor(0.0168869d0,0.11125d0,10.357d0,3.6231d0,0.88026d0, + 1 0.49671d0,1.00d0,rs,alfm,alfrsm) +c alfm is minus the spin stiffness alfc + z4 = zet**4 + ec = eu*(1.d0-f*z4)+ep*f*z4-alfm*f*(1.d0-z4)/fzz +c energy done. now the potential: + ecrs = eurs*(1.d0-f*z4)+eprs*f*z4-alfrsm*f*(1.d0-z4)/fzz + fz = thrd4*((1.d0+zet)**thrd-(1.d0-zet)**thrd)/gam + eczet = 4.d0*(zet**3)*f*(ep-eu+alfm/fzz)+fz*(z4*ep-z4*eu + 1 -(1.d0-z4)*alfm/fzz) + comm = ec -rs*ecrs/3.d0-zet*eczet + vcup = comm + eczet + vcdn = comm - eczet + return + 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 @@ +c ********************************************************************* + subroutine scheq(zz,en,lambda,nofl,kkk,mess,scf,thresh,iflag,npr + 1,de) + implicit double precision (a-h,o-z) +c subroutine scheq +c compute energy eigenvalue and wave function +c originally written by sherwood skillman +c rca laboratories, princeton, new jersey, spring 1961 +c modified by frank herman, summer 1961 +c further modified by richard kortum and paul kelly, lockheed +c research laboratories, palo alto, california, summer 1962 +c further modified by r.m. nieminen, otaniemi,spring 1978 +c and last but not least modified by m.p. winter 1979 + dimension qq(561),p(5),q(5),t(5),d(5) + common/sc/gr(561),r(561),snlo(561),nbl + common/pot/v(561) + imp=1 + nb1=nbl+1 + nmb=nb1/5 + if (de.lt.1.d-10)imp=0 + if(imp.eq.1)de=dmax1(de,-e/500.d0) + eg=0.d0 + z=zz + lam=lambda + nn=nofl + mesh=mess + c=scf + i0=0 + many = 150 + iflag=0 + 73 e=en + morev=0 + lessv=0 + emore=0.0d0 + eless=0.0d0 + more=0 + less=0 + mp=0 + nprint=0 + lamm=lam-1 + lamp=lam+1 + xlp=lamp + ndcr=nn-lamp + b=lam*lamp + oc=r(2) + h=oc + hsq=h*h + b3=(v(3)-v(2))/h-z/hsq + y=h+h + flps=4*lam+6 + slpt=6*lam+12 + elpt=8*lam+20 + a1=-z/xlp + ysq=y*y + b1=-z-z + ab1=a1*b1 + ab3=a1*b3 +c raise h and y to lam+1 + htl=h + ytl=y + if(lam)77,1102,1100 + 1100 do 1101 i=1,lam + htl=htl*h + 1101 ytl=ytl*y + 1102 h1=hsq + bohs=b/hsq + boh=b1/h + bth=b3*h + bq3=bohs+boh+bth + bq4=bohs/4.d0+boh/2.d0+bth+bth + epl=8+lam + fpl=5+lam + xifc=c*.21701389d-4 +c start outward integration + 10 nprint=nprint+1 + eps =e-eg + eg =e + if(many-nprint) 900,75,75 +900 if(mp.eq.2)go to 300 + write (6,901)nn,lam ,z + call flush(6) + 901 format (21h no convergence on,i4,i1,f4.0) + iflag=1 + en=0.d0 + npr=nprint + return + 77 nstop=7 + 777 write(66,770) nstop + 770 format(' error in scheq',i6) + en=0.d0 + iflag=1 + npr=nprint + return + 75 do 11 i=1,mesh + 11 snlo(i)=0.0d0 + if(nprint-1) 77,500,529 + 500 continue + do 502 i= 4,mesh + qq(i) = v(i)+b/(r(i)*r(i))-e + 502 continue + 516 m= mesh + do 520 i=4,mesh + if(qq(m)) 519,520,520 + 519 ik=m+1 + go to 525 + 520 m=m-1 + write(66,562)lam,qq(m+1),e +562 format(/' l: ',i5,' q: ',g15.6,' e: ',g15.6/) + 521 nstop =521 +c q is everywhere positive + go to 777 + 525 if(mesh-ik) 526,526,535 + 526 eps = qq(mesh-nbl) + e = e+eps + 529 continue + do 530 i=4,mesh + 530 qq(i) = qq(i)-eps + go to 516 + 535 continue + 14 ncross=0 + sig=1.0d0 + h=oc + y=h+h +c b= lam*(lam+1) +c b1= -2.d0*z + b2=3.0d0*z/h-e+2.0d0*v(2)-v(3) +c b3=(v(3)-v(2))/h -z/hsq +c a1= -z/(lam+1) + a2=(ab1+b2)/flps +c a2=(a1*b1+b2)/(4*lam+6) + a3=(a2*b1+a1*b2+b3)/slpt +c a3=(a2*b1+a1*b2+b3)/(6*lam+12) + a4=(a3*b1+a2*b2+ab3)/elpt +c a4=(a3*b1+a2*b2+a1*b3)/(8*lam+20) + p(3)=(1.0d0+h*(a1+h*(a2+h*(a3+h*a4))))*htl +c p(3)=(1.0d0+a1*h+a2*h**2+a3*h**3+a4*h**4)*h**(xl+1.0d0) + p(4)=(1.0d0+y*(a1+y*(a2+y*(a3+y*a4))))*ytl +c p(4)=(1.0d0+a1*y+a2*y**2+a3*y**3+a4*y**4)*y**(xl+1.0d0) + q(3)=bq3+b2 +c q(3)=(b+b1*h+b2*h**2+b3*h**3)/h**2 + q(4)=bq4+b2 +c q(4)=(b+b1*y+b2*y**2+b3*y**3)/y**2 + snlo(2)=p(3) + snlo(3)=p(4) + i=3 + dx=oc + h1=h**2 + h2=h1/12.0d0 + t(3)=p(3)*(1.0d0-h2*q(3)) + t(4)=p(4)*(1.0d0-h2*q(4)) + d(4)=t(4)-t(3) + ncount=3 + nint=2 + 15 i=i+1 +c if end of mesh is reached, modify trial eigenvalue + if(i-mesh) 16,3,3 + 3 if(ndcr-ncross) 32,33,33 +c return to begininning of outward integration if necessary + 16 q(5) =qq(i) + if(ik-i) 29,29,21 + 21 d(5)=d(4)+h1*q(4)*p(4) + t(5)=d(5)+t(4) + if(1.0d0-abs (h2*q(5))) 3,3,501 + 501 p(5)=t(5)/(1.0d0-h2*q(5)) + snlo(i) = p(5) + if(sig) 211,77,212 + 211 if(p(5)) 23,23,22 + 212 if(p(5)) 22,23,23 + 22 ncross=ncross+1 +c count changes in sign + sig=-sig + 23 ncount=ncount+1 + if(7-ncount)77,24,25 + 24 ncount=2 + 25 nint=nint+1 + if(nbl-nint)77,26,27 + 26 dx=dx+dx + h=dx + h1=h**2 + h2=h1/12.0d0 + nint=0 + t(5)=p(5)*(1.0d0-h2*q(5)) + t(3)=p(3)*(1.0d0-h2*q(3)) + d(5)=t(5)-t(3) + 27 do 28 k=1,4 + p(k)=p(k+1) + t(k)=t(k+1) + d(k)=d(k+1) + 28 q(k)=q(k+1) + go to 15 + 29 if(ncount-2)77,30,21 + 30 if(nint-4)21,21,31 +c matching radius has been reached going out +c if ndcr not equal to ncross,modify trial eigenvalue + 31 eigen=e + if(ndcr-ncross) 32,35,33 + 32 more=1 + mp=0 +c too many crossings, increase absf(e) + morev=morev+1 + if(morev-1) 50,53,52 + 50 nstop=50 + go to 777 + 52 if(e -emore) 53,54,54 + 53 emore=e + 54 if (less) 55,56,64 + 55 nstop=55 + go to 777 + 56 e=1.25d0*eg + go to 10 + 33 less=1 + mp=0 +c too few crossings, decrease abs (e) + lessv=lessv+1 + if(lessv-1) 57,60,59 + 57 nstop=57 + go to 777 + 59 if(eless- e) 60,61,61 + 60 eless=e + 61 if(more) 62,63,64 + 62 nstop=62 + go to 777 + 63 e=0.75d0*eg + go to 10 + 64 e=0.5d0*(emore+eless) + go to 10 + 35 if(abs (snlo(i-1))-abs (snlo(i-2))) 351,354,354 +c check to see that wave is in the damped region (absolute value +c decreasing and signs alike) + 351 if (p(5)) 352,21 ,353 + 352 if(snlo(i-2)) 401,21,21 + 353 if(snlo(i-2)) 21,21,401 + 354 if(1.0d+25 -abs (p(5)))33,33,21 +c large absolute value of p in what should be the damped region +c indicates too few peaks, decrease absf(e) +c now ndcr = ncross and matching radius lies in damped region + 401 imatch=i-2 + xmatch=r(i-2) + ppout=(t(4)-t(2)-0.5d0*(p(4)-p(2)))/h + s2=ppout/p(3) +c integration is by 8 applications of newton-cotes closed +c quadrature for five intervals on each block +c xifc =(5*h(block 1)/288)/2 ,h(1) =0.0025*scale factor + sum1=0.0d0 + xif=xifc + i=1 + value=0.0d0 + 36 mm=nmb + sum2=0.0d0 + xif=xif+xif + 37 y=value + value=snlo(i+5)**2 + sum2=sum2+19.d0*(value+y)+75.d0*(snlo(i+4)**2+snlo(i+1)**2) + 1 +50.0d0*(snlo(i+2)**2+snlo(i+3)**2) + i=i+5 + if (imatch-i) 77,39,371 + 371 mm=mm-1 + if(mm)77,38,37 + 38 sum1=sum2*xif+sum1 + go to 36 + 39 sum1= sum1+sum2*xif + 40 s1=sum1/p(3)**2 + pmatch=p(3) + if(nn-1)77,41,42 + 41 xinw=epl* xmatch +c for n =1, start inward integration at(8+lam)*xmatch or x max + go to 421 + 42 xinw=fpl*xmatch +c for n not=1, start at (5+lam)*xmatch or x max (end of mesh) + 421 do 44 i= nb1,mesh,nbl + if(xinw-r(i)) 43,43,44 + 43 kkk =i + go to 45 + 44 continue + kkk =mesh + 45 i =kkk + dx =r(i-1)-r(i) + h =dx + xif=0.17361111d-1*dx + hsq=h*h + hsq12=hsq/12.0d0 + q(3)= qq(i) + p(3)= exp (-r(i)*sqrt (q(3))) + 402 sum3=p(3)/q(3) + i=i-1 + q(4) =qq(i) + 404 p(4)=exp (-r(i)*sqrt (q(4))) + if (abs (p(4))-1.0d-35) 4041,4041,405 + 4041 kkk=kkk -nbl + if(kkk -imatch) 4042,4042,45 + 4042 write (5,4043)z ,nn,lam,kkk + 4043 format (6hoat z=,f6.0,6h nl =,i3,i1,7h kkk =,i5,22h is less tha + 1n imatch =,i5,44h inward integration will be tried at kkk+nbl) + kkk =kkk +nbl + p(4) = 1.5d-35 + p(3) = 1.0d-35 + 405 if(pmatch)102,77,103 + 102 p(3)=-p(3) + p(4)=-p(4) + 103 snlo(i+1)=p(3) + snlo(i)=p(4) + t(3)=p(3)*(1.0d0-hsq12 *q(3)) + t(4)=p(4)*(1.0d0-hsq12*q(4)) + d(4)=t(4)-t(3) + 104 do 106 m=2,nbl + i=i-1 + q(5) =qq(i) + d(5)=hsq*q(4)*p(4)+d(4) + t(5)=d(5)+t(4) + p(5)=t(5)/(1.0d0-hsq12*q(5)) + if(i-imatch+1)77,200,105 + 105 snlo(i)=p(5) + do 106 k=1,4 + p(k)=p(k+1) + t(k)=t(k+1) + d(k)=d(k+1) + 106 q(k)=q(k+1) + q(5) =qq(i-2) + d(5)=hsq*q(4)*p(4)+d(4) + t(5)=d(5)+t(4) + p(5)=t(5)/(1.0d0-hsq12*q(5)) + p(5)=1.09375d0*p(4)+0.2734375d0*p(5)-0.546875d0*p(3)+0.21875d0* + 1 p(2)-0.0390625d0*p(1) + i=i-1 + dx=dx/2.0d0 + q(5) =qq(i) + h=dx + hsq=h*h + hsq12=hsq/12.0d0 + t(5)=p(5)*(1.0d0-hsq12*q(5)) + t(4)=p(4)*(1.0d0-hsq12*q(4)) + d(5)=t(5)-t(4) + snlo(i)=p(5) + do 107 l=1,4 + p(l)=p(l+1) + t(l)=t(l+1) + d(l)=d(l+1) + 107 q(l)=q(l+1) + go to 104 +c matching radius has been reached coming in + 200 k=kkk + value=snlo(k)**2 + go to 202 + 2001 continue + 201 sum3=sum3+xif*sum4 + xif =xif*0.5d0 + 202 mm=nmb + sum4 =0.0d0 + 203 y=value + value=snlo(k-5)**2 + sum4=sum4+19.d0*(value+y)+75.d0*(snlo(k-1)**2+snlo(k-4)**2) + 1+50.0d0*(snlo(k-2)**2+snlo(k-3)**2) + k=k-5 + if(k-imatch) 77,2031,2030 + 2030 mm=mm-1 + if(mm) 77,2001,203 + 2031 sum3=sum3+xif*sum4 + 204 s3=sum3/p(4)**2 + ppin=(t(5)-t(3)-0.5d0*(p(5)-p(3)))/h + s4=ppin/p(4) + fe=s4-s2 + if(abs(fe).lt.1.d-08)go to 300 +c write(66,4711)mp,nprint,e,fe + ml=more*less +4711 format(' mp',i2,' iter: ',i4,' e: ',e12.6,' fe: ',e12.6) + if(mp.eq.2)go to 9120 + if(mp.eq.1)go to 9100 + mp=1 + if(imp.eq.0)de=-e/10.d0 + de=dmin1(de,-e/10.d0) + if(i0.gt.0)de=de/5**i0 + i0=i0+1 + if(ml.gt.0)de=abs(emore-eless)/10.d0 + if(e.gt.-1.d-35)de=1.d-7 + eold=e + feold=fe + if(fe.gt.0)e=e-de + if(fe.lt.0)e=e+de + go to 10 +9100 if(fe*feold.lt.0)go to 9110 + if(fe.gt.0.d0.and.imp.eq.0) de=-e/10.d0 + if(i0.gt.1.and.ml.gt.0)de=abs(emore-eless)/10.d0 + eold=e + feold=fe +9101 if(fe.lt.0d0)e=e+de + if(fe.gt.0d0)e=e-de + go to 10 +9110 continue +9111 mp=2 + fe1=feold + fe2=fe + e1=eold + e2=e + eold=e + go to 9130 +9120 if(fe1*fe.lt.0d0)e2=e + if(fe1*fe.lt.0d0)fe2=fe + if(fe2*fe.lt.0d0)e1=e + if(fe2*fe.lt.0d0)fe1=fe + eold=e +6174 format(' e1: ',e12.6,' fe1: ',e12.6,' e2: ',e12.6, + j' fe2: ',e12.6) +9130 e=(e1*fe2-e2*fe1)/(fe2-fe1) + if(abs((e2-e1)/e).lt.thresh)go to 300 + if(abs((e-eold)/e).lt.1d-06)go to 300 + go to 10 + 300 pop=pmatch/p(4) + do 302 j=imatch,kkk + 302 snlo(j)=snlo(j)*pop + sum1=0.0d0 + j=1 + xif=xifc + value=0.0d0 + 303 mm=nmb + xif=xif+xif + sum2=0.0d0 + 304 y=value + value=snlo(j+5)**2 + sum2=sum2+19.d0*(value+y)+75.d0*(snlo(j+4)**2+snlo(j+1)**2) + 1+50.d0*(snlo(j+2)**2+snlo(j+3)**2) + j=j+5 + mm=mm-1 + if(mm)77,305,304 + 305 sum1=sum1+xif*sum2 + if(kkk-j)77,307,303 + 307 c1=sqrt (sum1) + if(snlo(3))308,77,310 + 308 c1=-c1 +c +c include tail +c + 310 tail=snlo(mesh)**2/(2.d0*sqrt(abs(e))) + c1=c1+tail + do 311 i=1,kkk + 311 snlo(i)=snlo(i)/c1 + en=e + if(abs(en).lt.1.d-6) iflag=1 + npr=nprint + return + end +c ********************************************************************** + subroutine simpsh(ff,s) + implicit double precision (a-h,o-z) +c integrates the matrix ff on the herman-skillman mesh + common/mess/wj(301),dx,nblock,jblock + common/sc/gr(561),r(561),snlo(561),nbl + dimension ff(561) + nb1=nbl+1 + s=0.d0 + deltax=dx + do 10 j=1,jblock + do 11 jk=1,nb1 + i=(j-1)*nbl+jk + 11 s=s+ff(i)*wj(jk)*deltax + 10 deltax=2.d0*deltax + return + end +c ********************************************************************** + subroutine scrhs(roo,u,z,q,n) + implicit double precision (a-h,o-z) +c evaluates the screened poisson integral +c in the herman-skillman mesh + dimension roo(561),u(561),ss(561),apu(561) + common/sc/gr(561),r(561),snlo(561),nbl + pi=4.d0*atan(1.d0) + c=4.d0*pi + do 11 i=1,n + 11 ss(i)=-c*roo(i)*r(i)-q**2*u(i) + do 20 i=1,n + do 30 j=1,n + aa=gr(i)/gr(j) + if(j.gt.i) aa=1.d0/aa + ab=gr(i)*gr(j) + 30 apu(j)=(aa-ab)*ss(j) + call simpsh(apu,s) + 20 u(i)=-s/(2.d0*q)-z*gr(i) + return + end +c ********************************************************************** + function exc(r,s,ixc) + implicit double precision (a-h,o-z) +c ceperley alder perdew zunger +c or von barth hedin + data gp,bp1,bp2,gf,bf1,bf2/-.1423d0,1.0529d0,.3334d0,-.0843d0, + j1.3981d0,.2611d0/ + data ap,bp,cp,dp,af,bf,cf,df/.0311d0,-.048d0,.002d0,-.0116d0, + j.01555d0,-.0269d0,.0007d0,-.0048d0/ + if(r.lt.1.d-25)go to 100 + pi=4.d0*atan(1.d0) + if(s.gt.0.99999999d0)s=0.99999999d0 + if(s.lt.-0.99999999d0)s=-0.99999999d0 + sinv=(4.d0*pi*r/3.d0)**(1.d0/3.d0) + rs=1.d0/sinv + if(ixc.eq.1)go to 200 + if(rs.lt.1.d0)go to 10 + srs=sqrt(rs) + excp=gp/(1.d0+bp1*srs+bp2*rs) + excf=gf/(1.d0+bf1*srs+bf2*rs) + go to 20 +10 aa=log(rs) + excp=ap*aa+bp+cp*rs*aa+dp*rs + excf=af*aa+bf+cf*rs*aa+df*rs +20 f=((1.d0+s)**(4.d0/3.d0)+(1.d0-s)**(4.d0/3.d0)-2.d0)/ + 1 (2.d0**(4.d0/3.d0)-2.d0) + excf=excf-.5772521d0/rs + excp=excp-.4581653d0/rs + exc=excp+f*(excf-excp) + return +100 exc=0.d0 + return +200 x=s/2.d0+0.5d0 + d43=4.d0/3.d0 + rsf=rs/75.d0 + rsf2=rsf*rsf + rsf3=rsf2*rsf + rsp=rs/30.d0 + rsp2=rsp*rsp + rsp3=rsp2*rsp + fcf=(1.d0+rsf3)*log(1.d0+1.d0/rsf)+0.5d0*rsf-rsf2-1.d0/3.d0 + fcp=(1.d0+rsp3)*log(1.d0+1.d0/rsp)+0.5d0*rsp-rsp2-1.d0/3.d0 + epscp=-.0504d0*fcp + epscf=-.0254d0*fcf + epsxp=-.91633059d0/rs + cny=5.1297628d0*(epscf-epscp) + aa=.5d0**(1.d0/3.d0) + if(x.lt..000001d0) x=.000001d0 + if(x.gt..999999d0) x=.999999d0 + fx=(x**d43+(1.d0-x)**d43-aa)/(1.d0-aa) + exc=epsxp+epscp+fx*(cny+4.d0/3.d0*epsxp)/5.1297628d0 + exc=exc/2.d0 + return + end +c ********************************************************************** + function uxc(r,s,ispin,ixc) + implicit double precision (a-h,o-z) +c ceperley alder perdew zunger + data gp,bp1,bp2,gf,bf1,bf2/-.1423d0,1.0529d0,.3334d0,-.0843d0, + j1.3981d0,.2611d0/ + data ap,bp,cp,dp,af,bf,cf,df/.0311d0,-.048d0,.002d0,-.0116d0, + j.01555d0,-.0269d0,.0007d0,-.0048d0/ + if(r.lt.1.d-35)go to 100 + pi=4.d0*atan(1.d0) + sinv=(4.d0*pi*r/3.d0)**(1.d0/3.d0) + rs=1.d0/sinv + if(ixc.eq.1)go to 200 + if(rs.lt.1.d0)go to 10 + srs=sqrt(rs) + excp=gp/(1.d0+bp1*srs+bp2*rs) + excf=gf/(1.d0+bf1*srs+bf2*rs) + uxcp=excp*(1.d0+7.d0/6.d0*bp1*srs+4.d0/3.d0*bp2*rs) + j/(1.d0+bp1*srs+bp2*rs) + uxcf=excf*(1.d0+7.d0/6.d0*bf1*srs+4.d0/3.d0*bf2*rs) + j/(1.d0+bf1*srs+bf2*rs) + go to 20 +10 aa=log(rs) + excp=ap*aa+bp+cp*rs*aa+dp*rs + excf=af*aa+bf+cf*rs*aa+df*rs + uxcp=ap*aa+(bp-ap/3.d0)+2.d0/3.d0*cp*rs*aa+(2.d0*dp-cp)*rs/3.d0 + uxcf=af*aa+(bf-af/3.d0)+2.d0/3.d0*cf*rs*aa+(2.d0*df-cf)*rs/3.d0 +20 f=((1.d0+s)**(4.d0/3.d0)+(1.d0-s)**(4.d0/3.d0)-2.d0)/ + j (2.d0**(4.d0/3.d0)-2.d0) + ddf=4.d0/3.d0*((1.d0+s)**(1.d0/3.d0)-(1.d0-s)**(1.d0/3.d0)) + j /(2.d0**(4.d0/3.d0)-2.d0) + uxc=uxcp+f*(uxcf-uxcp)+(excf-excp)*(3.d0-2.d0*ispin-s)*ddf + j -.6108871d0/rs*(1.d0+(3.d0-2.d0*ispin)*s)**(1.d0/3.d0) + return +100 uxc=0.d0 + return +200 x=s/2.d0+0.5d0 + d43=4.d0/3.d0 + xx=0.5d0-s/2.d0 + rsf=rs/75.d0 + rsf2=rsf*rsf + rsf3=rsf2*rsf + rsp=rs/30.d0 + rsp2=rsp*rsp + rsp3=rsp2*rsp + fcf=(1.d0+rsf3)*log(1.d0+1.d0/rsf)+0.5d0*rsf-rsf2-1.d0/3.d0 + fcp=(1.d0+rsp3)*log(1.d0+1.d0/rsp)+0.5d0*rsp-rsp2-1.d0/3.d0 + epscp=-.0504d0*fcp + epscf=-.0254d0*fcf + epsxp=-.91633059d0/rs + cny=5.1297628d0*(epscf-epscp) + aa=.5d0**(1.d0/3.d0) + if(x.lt..000001d0) x=.000001d0 + if(xx.lt..000001d0) xx=.000001d0 + if(x.gt..999999d0) x=.999999d0 + if(xx.gt..999999d0) xx=.999999d0 + ars=-1.22177412d0/rs+cny + brs=-0.0504d0*log(1.d0+30.d0/rs)-cny + trx1=(2.d0*x)**(1.d0/3.d0) + trx2=(2.d0*xx)**(1.d0/3.d0) + if(ispin.eq.1)vxc=ars*trx1+brs + if(ispin.eq.2)vxc=ars*trx2+brs + uxc=vxc/2.d0 + return + end +c ************************************************************ + subroutine schrhs(v,k,l,ukl) + implicit double precision (a-h,o-z) +c integrates the radial schrodinger equation +c on the herman-skillman mesh + double precision k + dimension v(561),ukl(561),y(561) + common/mess/wj(301),dx,nblock,jblock + common/sc/gr(561),r(561),snlo(561),nbl + sd(i)=(2.d0*v(i)-k**2+l*(l+1)/r(i)**2)*ukl(i) + sdd(i)=(2.d0*v(i)-k**2+l*(l+1)/r(i)**2)*y(i) +c initial values have been stored at ukl(1)...ukl(4) + nb1=nbl+1 + hh=dx + do 10 i=5,nb1 + ukl(i)=ukl(i-1)+ukl(i-3)-ukl(i-4) + 1+hh**2/4.d0*(5.d0*sd(i-1)+2.d0*sd(i-2)+5.d0*sd(i-3)) + 10 ukl(i)=2.d0*ukl(i-1)-ukl(i-2)+ + 1hh**2/12.d0*(sd(i)+10.d0*sd(i-1)+sd(i-2)) +c set initial values for the next block + do 20 j=2,jblock + hh=2.d0*hh + jj=(j-1)*nbl + y(jj+1)=ukl(jj+1) + y(jj)=ukl(jj-1) + y(jj-1)=ukl(jj-3) + y(jj-2)=ukl(jj-5) + do 30 jk=2,nb1 + i=jj+jk + y(i)=y(i-1)+y(i-3)-y(i-4)+ + 1hh**2/4.d0*(5.d0*sdd(i-1)+2.d0*sdd(i-2)+5.d0*sdd(i-3)) + y(i)=2.d0*y(i-1)-y(i-2)+ + 1hh**2/12.d0*(sdd(i)+10.d0*sdd(i-1)+sdd(i-2)) + 30 ukl(i)=y(i) + 20 continue + return + 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 @@ + subroutine spline(r,start,n,db,db2) +c spline calculates the cubic spline interpolation of the density +c together with subroutine splint. +c the main ideas are "stolen" from "numerical recipes", cambridge +c university press (1992). +c input r : position coordinate (array) +c input start : index, r(start) = starting point of the spline +c input n : index, r(n) = r_max +c input db : spin up and down density. (array) +c output db2 : second derivative of db (array) + implicit logical (a-z) + double precision r,db,db2,u,sig,p,qn,un + integer spin,start,n,i + dimension r(561),db(2,561),db2(2,561),u(561) + do 100 spin = 1,2 + db2(spin,start) = 0.d0 + u(start) = 0.d0 + do 10 i = start+1,n-1 + sig = (r(i)-r(i-1))/(r(i+1)-r(i-1)) + p = sig*db2(spin,i-1)+2.d0 + db2(spin,i) = (sig-1.d0)/p + u(i) = (6.d0*((db(spin,i+1)-db(spin,i))/(r(i+1)-r(i))- + j (db(spin,i)-db(spin,i-1))/(r(i)-r(i-1)))/ + j (r(i+1)-r(i-1))-sig*u(i-1))/p + 10 continue + qn = 0.d0 + un = 0.d0 + db2(spin,n) = (un-qn*u(n-1))/(qn*db2(spin,n-1)+1.d0) + do 20 i = n-1,start,-1 + db2(spin,i) = db2(spin,i)*db2(spin,i+1)+u(i) + 20 continue + 100 continue + return + 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 @@ + subroutine splint(r,db,db2,spin,start,n,ri,dbi) +c splint calculates the cubic spline interpolation of the density +c together with subroutine spline. +c the main ideas are "stolen" from "numerical recipes", cambridge +c university press (1992). +c input r : position coordinate (array) +c input db : spin up and down density. (array) +c input db2 : second derivative of db (array) +c input spin : 1 if spin up, -1 if spin down +c input start : starting point of spline = r(start) +c input n : index, r(n) = r_max +c input ri : position of interpolation +c output dbi : interpolated value of db + implicit logical (a-z) + integer spin,spinn,n,klo,khi,k,start + double precision r,db,db2,ri,dbi,h,a,b + dimension r(561),db(2,561),db2(2,561) + spinn = spin + if (spinn.eq.-1) spinn = 2 + klo = start + khi = n + 10 if (khi-klo.gt.1) then + k = (khi+klo)/2 + if (r(k).gt.ri) then + khi = k + else + klo = k + endif + goto 10 + endif + h = r(khi)-r(klo) + a = (r(khi)-ri)/h + b = (ri-r(klo))/h + dbi = a*db(spinn,klo)+b*db(spinn,khi)+((a**3-a)* + j db2(spinn,klo)+(b**3-b)*db2(spinn,khi))*(h**2)/6.d0 + return + 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +/////////////////////////////////////////////////// + +TOK_IMPL(asis) { out<expr; } +TOK_IMPL(mute) {} +TOK_IMPL(comment) {} + +/////////////////////////////////////////////////// + +TOK_IMPL(cond) { + Cond(*env.toks,env[0],env[1],tok_t::PUBLIC); +} +TOK_IMPL(global) { + Global(*env.toks,env[0],env[1],tok_t::PUBLIC); +} +TOK_IMPL(const) { + Const(*env.toks,env[0],env[1],tok_t::PUBLIC); +} +TOK_IMPL(reconst) { + Const(*env.toks,env[0],env[1],tok_t::PUBLIC,1); +} + +/////////////////////////////////////////////////// + +TOK_IMPL(type) { + tok_t* p=env.toks->get(env[0]); + if(env.is_clear(p)) out<mod; +} +TOK_IMPL(desc) { + tok_t* p=env.toks->get(env[0]); + if(env.is_clear(p)) out<get(env[0]); + if(env.is_clear(p)&&p->is_func()) ((func_t*)p)->x.trav(out,12); +} +TOK_IMPL(clear) { + ClearToken(*env.toks,env[0]); +} + +////////////////////////////////////////////////////// + +TOK_IMPL(exist) { out<parg(out,atoi(env[0])-1); } +TOK_IMPL(args) { if(env.up) out<args; else out<<0; } + +/////////////////////////////////////////////////// + +TOK_IMPL(random) { + out<\n" + "%\n" + "%Generates a list of names, beginning with the partial name,\n" + "%from the same - not nescessarily the current - local stack.\n" + "%\n" + "%Generates all local variables in the current stack if no\n" + "%partial name is given.\n" + "%\n" + "%Generates a list of tables if @ is given.\n" + ); + TOK_ADD(globlist,"?",tok_t::PUBLIC, + "%List global variables\n" + "%Syntax: \\globlist\n" + "%\n" + "%Generates a list of names, beginning with the partial name,\n" + "%from the same - not nescessarily the current - global level.\n" + "%\n" + "%Generates all global variables on the current level if no\n" + "%partial name is given.\n" + ); + TOK_ADD(lrec,"xx?",tok_t::PUBLIC, + "%Create a local record\n" + "%Syntax: \\lrec{partial name}{name list}\n" + "%\n" + "%Creates a set of local variables, all beginning with the\n" + "%partial name, and initializes each variable to init.\n" + ); + + ////////////////////////////////////////////////////// + + TOK_ADD(arg,"x",tok_t::PUBLIC, + "%Show/Evaluate argument #n.\n" + "%Syntax: \\arg{n}\n" + "%\n" + "%Same as the command \\1, \\2 etc, except this\n" + "%may be used to index the arguments e.g. using local variables.\n" + ); + TOK_ADD(args,"",tok_t::PUBLIC, + "%Number of arguments in the current function\n" + "%Syntax: \\args\n" + "%\n" + "%Note that the optional argument will count as one variable,\n" + "%and may be accesed using either \\0 or \\arg{\\args}.\n" + ); + + ////////////////////////////////////////////////////// + + TOK_ADD(random,"x",tok_t::PRIVATE, + "%Get n random digits between 0 and 9 inclusive\n" + "%Syntax: \\random{n}\n" + ); + +} 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +static dbmap* GetDB(Env& env) throw(merror_t) { + if(!env.db) THROW("htc: no open database"); + return env.db; +} + +static int eval(Env& env,expr_t* x,int mod=OP_ALL) { + mswrite out; + if(x->status&OP_PARSE) env.parse(out,x->expr); else x->eval(out,env,mod); + return atob(out.str()); +} + +//////////////////////////////////////////////////////////////////////////// + +TOK_IMPL(create) { + dbref_t* ref=DBRef(*env.toks,env[0],ms_empty,tok_t::PUBLIC,1); + ref->db.Open("/dev/zero",1); + sref first,rest=env[1]; int n=0; + while(Split(first,rest)) ref->db.InsertTable(n++,first); + ref->db.Order(env[2],env[3]); +} + +TOK_IMPL(sort) { + dbref_t* ref=(dbref_t*)env.toks->get_this(env[0]); + if(env.is_clear(ref)&&ref->is_dbref()) { + ref->db.remap(); + ref->db.Sort(env[1],env[2]); + } + else THROW("htc: "<get(env[0]); + if(env.is_clear(ref)&&ref->is_dbref()) { + ref->db.remap(); + Env(env,ref->db).parse(out,env.arg(1)); + } + else THROW("htc: "<=0&&env.req->is_running()&&nenv.dbatsize()) { + int size=db->size(); + if(eval(nenv,x[0],OP_LOCAL)) nenv.parse(out,x[1]); + if(db->size()==size) nenv.dbat++; + } +} + +TOK_IMPL(find_rec) { + dbmap* db=GetDB(env); + Env nenv(env,*db); + nenv.dbat=db->Find(env[0]); + if(nenv.dbat>=0&&nenv.dbatsize()) nenv.parse(out,env.arg(1)); + else env.parg(out,2); +} + +//////////////////////////////////////////////////////////////////// + +TOK_IMPL(first_rec) { env.dbat=0; } +TOK_IMPL(prev_rec) { if(env.dbat>0) env.dbat--; } +TOK_IMPL(next_rec) { if(env.dbatsize()) env.dbat++; } +TOK_IMPL(exist_rec) { out<=0&&env.dbatsize()); } + +TOK_IMPL(rem_rec) { + dbmap* db=GetDB(env); + if(env.dbat>=0&&env.dbatsize()) db->Rem(env.dbat); +} + +//////////////////////////////////////////////////////////////////// + +TOK_IMPL(lastkey) { + dbmap* db=GetDB(env); + if(!db->empty()) out<at(db->size()-1,db->Index()); +} + +TOK_IMPL(prevkey) { + dbmap* db=GetDB(env); + if(env.dbat>0&&env.dbat<=db->size()) out<at(env.dbat-1,db->Index()); +} + +TOK_IMPL(nextkey) { + dbmap* db=GetDB(env); + if(env.dbat>=0&&env.dbat+1size()) out<at(env.dbat+1,db->Index()); +} + +TOK_IMPL(qprevkey) { + dbmap* db=GetDB(env); + expr_t* x=env.arg(0); + Env nenv(env,*db); + nenv.dbat=env.dbat-1; + while(nenv.dbat>=0&&env.req->is_running()&&nenv.dbatsize()) { + if(eval(nenv,x,OP_LOCAL)) { out<at(nenv.dbat,db->Index()); break; } + else nenv.dbat--; + } +} + +TOK_IMPL(qnextkey) { + dbmap* db=GetDB(env); + expr_t* x=env.arg(0); + Env nenv(env,*db); + nenv.dbat=env.dbat+1; + while(nenv.dbat>=0&&env.req->is_running()&&nenv.dbatsize()) { + if(eval(nenv,x,OP_LOCAL)) { out<at(nenv.dbat,db->Index()); break; } + else nenv.dbat++; + } +} + +//////////////////////////////////////////////////////////////////// + +void envAddDB(tokmap& T) +{ + TOK_ADD(create,"xxxx",tok_t::SYSONLY, + "%Create a new database\n" + "%Syntax: \\create{varname}{tables}{index}{comp}\n" + "%\n" + "%Index is the unique, ordered table.\n" + "%Comp is the compare function.\n" + "%A maxmimum of 32 tables are allowed in HDB/1.2\n" + ); + TOK_ADD(sort,"xxx",tok_t::PRIVATE, + "%Sort a database\n" + "%Syntax: \\sort{varname}{index}{comp}\n" + "%\n" + "%Note that only globals on the current level are sortable.\n" + ); + + //////////////////////////////////////////////////////// + + TOK_ADD(db,"xr",tok_t::PRIVATE, + "%Set current database\n" + "%Syntax: \\db{varname}{body}\n" + "%\n" + "%Within body, all database functions apply.\n" + ); + TOK_ADD(query,"xr",tok_t::PRIVATE, + "%Query current database\n" + "%Syntax: \\query{test}{body}\n" + "%\n" + "%Evaluates body for all record where test is true.\n" + "%\n" + "%optimizes globals; it is ok to use full function\n" + "%expressions in the query. Turned out to be better after all.\n" + ); + TOK_ADD(find_rec,"xr?",tok_t::PRIVATE, + "%Find record by key, in current database\n" + "%Syntax: \\find.rec{key}{body}\n" + "%\n" + "%Evaluates body if key is found in the current ordering.\n" + "%Otherwise, evaluates , if exist.\n" + ); + + //////////////////////////////////////////////////////// + + TOK_ADD(first_rec,"",tok_t::PRIVATE, + "%Go to first record\n" + "%Syntax: \\first.rec\n" + ); + TOK_ADD(exist_rec,"",tok_t::PRIVATE, + "%True if current record exist\n" + "%Syntax: \\exist.rec\n" + ); + TOK_ADD(next_rec,"",tok_t::PRIVATE, + "%Go to next record\n" + "%Syntax: \\next.rec\n" + ); + TOK_ADD(prev_rec,"",tok_t::PRIVATE, + "%Go to previous record\n" + "%Syntax: \\prev.rec\n" + ); + TOK_ADD(rem_rec,"",tok_t::SYSONLY, + "%Remove current record\n" + "%Syntax: \\rem.rec\n" + ); + + //////////////////////////////////////////////////////// + + TOK_ADD(lastkey,"",tok_t::PRIVATE, + "%Last key of current order\n" + "%Syntax: \\lastkey\n" + "%\n" + "%Silently ignored if not found.\n" + ); + TOK_ADD(prevkey,"",tok_t::PRIVATE, + "%Previous key of current order\n" + "%Syntax: \\prevkey\n" + "%\n" + "%Silently ignored if not found.\n" + ); + TOK_ADD(nextkey,"",tok_t::PRIVATE, + "%Next key of current order\n" + "%Syntax: \\nextkey\n" + "%\n" + "%Silently ignored if not found.\n" + ); + + //////////////////////////////////////////////////////// + + TOK_ADD(qprevkey,"r",tok_t::PRIVATE, + "%Previous key of current order, satisfying query\n" + "%Syntax: \\qprevkey\n" + "%\n" + "%Silently ignored if not found.\n" + ); + TOK_ADD(qnextkey,"r",tok_t::PRIVATE, + "%Next key of current order, satisfying query\n" + "%Syntax: \\qnextkey\n" + "%\n" + "%Silently ignored if not found.\n" + ); + +} 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +static unsigned long seed=RandomInit(time(0)); + +mstring Random(int n) +{ + mstring s; + for(int i=0;i9) THROW("env: assertion on lib failed"); + s+=char(48+digit); + } + return s; +} + +/////////////////////////////////////////////////// + +void Env::clear_args() +{ + for(int i=0;i=0&&nresult; + else eval(out,rarg[n-xsize()],0); + } + } + else if(up) up->parg(out,n); +} + +void Env::parg(mstring& tmp,int n) throw(merror_t) +{ + swrite sw(tmp); + parg(sw,n); +} + +mstring Env::parg(int n) throw(merror_t) +{ + mswrite tmp; parg(tmp,n); return tmp.str(); +} + +////////////////////////////////////////////////////// + +int Env::onarg(int n) const +{ + if(args) { + if(n<0) n+=args; + if(n>=0&&nresult.nempty(); + else return rarg[n-xsize()]->expr.nempty(); + } + } + else if(up) return up->onarg(n); + return 0; +} + +expr_t* Env::arg(int n) throw(merror_t) { + if(args) { + if(n<0) n+=args; + if(n>=0&&narg(n); + THROW("env: bad arg number "<=0&&nresult; + else THROW("env: post-eval expression not readable here"); + } + } + else if(up) return up->operator[](n); + THROW("env: bad arg number "<get(t); + if(is_clear(p)&&!p->is_runnable()) return p->body; + THROW("env: could not find global variable "<get(t); + return is_clear(p)&&!p->is_runnable(); +} + +int Env::onglob(const sref& t) const +{ + const tok_t* p=toks->get(t); + return is_clear(p)&&!p->is_runnable()&&p->body.nempty(); +} + +void Env::glob_list(rpile& list,const sref& t) const +{ + list.clear(); + if(t.empty()) { + for(const_iterator p=toks->begin();p!=toks->end();++p) { + if(is_clear(*p)&&!(*p)->is_runnable()) list.push_back((*p)->name); + } + } + else { + int cont=1; + for(const tokmap* tok=toks;tok&&cont;tok=tok->up) { + for(const_iterator p=tok->begin();p!=tok->end();++p) { + if((*p)->name.left(t.size())==t&&is_clear(*p)&&!(*p)->is_runnable()) { + list.push_back((*p)->name); + cont=0; + } + } + } + } +} + +void Env::glob_adb(const sref& fx,const sref& t) throw(merror_t) +{ + if(!db) THROW("htc: no active database"); + rpile list; glob_list(list,t); + mrvec col(list.size()); + int index=-1; + for(int i=0;iIndex(fx+list[i].right(t.size())); + if(col[i]==db->Index()) index=i; + } + if(index<0) THROW("env: index required when adding a db record"); + int row=db->Find(glob(list[index])); + if(row>=0) { + for(int i=0;iSet(row,col[i],glob(list[i])); + } + else { + spile nlist(db->Tables()); + for(int i=0;iInsert(nlist,1); + } + if(row<0) THROW("htc: could not add record - denied"); + dbat=row; +} + +////////////////////////////////////////////////////// + +const sref Env::aloc(const sref& t,const sref& v) throw(merror_t) +{ + if(!is_tokname(t)) THROW("env: bad token name "<body; +} + +const sref Env::sloc(const sref& t,const sref& v) throw(merror_t) +{ + if(db) { + int p=db->FindIndex(*t=='@'?t.popf():t); + if(p>=0) { + if(p==db->Index()) THROW("env: cannot assign to db index"); + if(dbat<0||dbat>=db->size()) THROW("env: not a valid db record"); + db->Set(dbat,p,v); + return db->at(dbat,p); + } + } + return loc.set(new tok_t(t,v,tight()),1,1)->body; +} + +const sref Env::gloc(const sref& t) const throw(merror_t) +{ + if(db) { + int p=db->FindIndex(*t=='@'?t.popf():t); + if(p>=0) { + if(dbat>=0&&dbatsize()) return db->at(dbat,p); + else THROW("env: not a valid database record"); + } + } + const tok_t* p=loc.get(t); + if(is_clear(p)&&!p->is_runnable()) return p->body; + THROW("env: could not find local variable "<FindIndex(*t=='@'?t.popf():t); + if(p>=0) return dbat>=0&&dbatsize(); + } + const tok_t* p=loc.get(t); + return is_clear(p)&&!p->is_runnable(); +} + +int Env::onloc(const sref& t) const +{ + if(db) { + int p=db->FindIndex(*t=='@'?t.popf():t); + if(p>=0) return dbat>=0&&dbatsize()&&db->at(dbat,p).nempty(); + } + const tok_t* p=loc.get(t); + return is_clear(p)&&!p->is_runnable()&&p->body.nempty(); +} + +void Env::gloc_list(rpile& list,const sref& t) const +{ + list.clear(); + if(t.empty()) { + for(const_iterator p=loc.begin();p!=loc.end();++p) { + if(is_clear(*p)&&!(*p)->is_runnable()) list.push_back((*p)->name); + } + } + else if(*t=='@') { + if(db) { + sref tt=t.popf(); + for(int i=0;iTables();i++) { + if(tt.empty()||db->Table(i).left(tt.size())==tt) list.push_back(db->Table(i)); + } + } + else THROW("env: cannot use '@' - no active database"); + } + else { + int cont=1; + for(const tokmap* tok=&loc;tok&&cont;tok=tok->up) { + for(const_iterator p=tok->begin();p!=tok->end();++p) { + if((*p)->name.left(t.size())==t&&is_clear(*p)&&!(*p)->is_runnable()) { + list.push_back((*p)->name); + cont=0; + } + } + } + } +} + +void Env::gloc_adb(const sref& fx,const sref& t) throw(merror_t) +{ + if(!db) THROW("htc: no active database"); + rpile list; gloc_list(list,t); + mrvec col(list.size()); + int index=-1; + for(int i=0;iIndex(fx+list[i].right(t.size())); + if(col[i]==db->Index()) index=i; + } + if(index<0) THROW("env: index required when adding a db record"); + int row=db->Find(gloc(list[index])); + if(row>=0) { + for(int i=0;iSet(row,col[i],gloc(list[i])); + } + else { + spile nlist(db->Tables()); + for(int i=0;iInsert(nlist,1); + } + if(row<0) THROW("htc: could not add record - denied"); + dbat=row; +} + +////////////////////////////////////////////////////// + +const mstring sback="../",sident="./",sdots="..",sslash="//"; + +mstring Env::URI(const sref& raw) +{ + int s; mstring cwd=pwd.left_last('/'),uri=raw; + while(uri.left(sback.size())==sback) { + uri.erase(0,sback.size()); + cwd=cwd.left_last('/'); + } + while((s=uri.find(sback))>=0) { + mstring tmp=uri.left(s).left_last('/').leftand_last('/'); + tmp+=uri.right(s+sback.size()); + uri=tmp; + } + while((s=uri.find(sdots))>=0) uri.erase(s,sdots.size()); + while((s=uri.find(sident))>=0) uri.erase(s,sident.size()); + while((s=uri.find(sslash))>=0) uri.erase(s,sslash.size()); + if(*uri=='/') return uri; + else { cwd+='/'; cwd+=uri; return cwd; } +} 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef ENVH +#define ENVH + +#include + +mstring Random(int n); + +const int OP_PARSE=8; +const mstring para_def="\n"; + +//////////////////////////////////////////////////////////////////// + +struct Lang { + volatile int running; + opmap ops; + tokmap toks; + Lang(); + virtual ~Lang() {} +}; + +struct req_env { + Lang* glob; + tokmap toks; + mstring uri; + int lang; + volatile int* running; + + int is_running() const { return glob->running&&(!running||*running); } + + req_env(Lang& g,tokmap& p) : glob(&g),toks(p),uri(),lang(0),running(0) {} + virtual ~req_env() {} +}; + +//////////////////////////////////////////////////////////////////// + +struct Env : public op_env { + typedef mrvec xpile; + typedef tokmap::iterator iterator; + typedef tokmap::const_iterator const_iterator; + + Env(opmap& op,req_env& r,unsigned m): + op_env(op),req(&r),toks(&r.toks),up(0),mod(m), + loc(),db(0),dbat(0),pwd(r.uri),para(para_def),args(0) {} + + Env(Env& p,tokmap& tok,const sref& cwd): + op_env(p),req(p.req),toks(&tok),up(p.up),mod(p.mod), + loc(p.loc),db(0),dbat(0),pwd(cwd),para(p.para),args(0) {} + Env(Env& p,unsigned m,const sref& cwd): + op_env(p),req(p.req),toks(p.toks),up(p.up),mod(m), + loc(p.loc),db(0),dbat(0),pwd(cwd),para(p.para),args(0) {} + + Env(Env& p): + op_env(p),req(p.req),toks(p.toks),up(p.up),mod(p.mod), + loc(p.loc),db(p.db),dbat(p.dbat),pwd(p.pwd),para(p.para),args(0) {} + Env(Env& p,dbmap& dbm): + op_env(p),req(p.req),toks(p.toks),up(p.up),mod(p.mod), + loc(p.loc),db(&dbm),dbat(0),pwd(p.pwd),para(p.para),args(0) {} + Env(Env& p,opmap& op): + op_env(op),req(p.req),toks(p.toks),up(p.up),mod(p.mod), + loc(p.loc),db(p.db),dbat(p.dbat),pwd(p.pwd),para(p.para),args(0) {} + + ~Env() { clear_args(); } + + int is_clear(const tok_t* tok) const { return tok&&tok->is_clear(mod); } + unsigned tight() const { return tok_t::tight(mod); } + + int check_arg(const runnable_t& ftok) const; + int is_arg(const sref& t) const { return cset_digit.test(t.front()); } + + int xsize() const { return xarg.size(); } + int rsize() const { return rarg.size(); } + + void xpush(const sref& in) throw(merror_t); + void rpush(const sref& in) throw(merror_t); + void clear_args(); + + void parg(mstream& out,int n) throw(merror_t); + void parg(mstring& buf,int n) throw(merror_t); + mstring parg(int n) throw(merror_t); + + const sref& operator[](int m) const throw(merror_t); + expr_t* arg(int m) throw(merror_t); + + const sref glob(const sref& t) const throw(merror_t); + + int glob_find(const sref& t) const; + void glob_list(rpile& list,const sref& t) const; + void glob_adb(const sref& fx,const sref& t) throw(merror_t); + + const sref aloc(const sref& t,const sref& v) throw(merror_t); + const sref sloc(const sref& t,const sref& v) throw(merror_t); + const sref gloc(const sref& t) const throw(merror_t); + + int gloc_find(const sref& t) const; + void gloc_list(rpile& list,const sref& t) const; + void gloc_adb(const sref& fx,const sref& t) throw(merror_t); + + int onarg(int m) const; + int onglob(const sref& s) const; + int onloc(const sref& s) const; + + void parse(mstream& out,const sref& in) throw(merror_t); + void expr(mstream& out,const sref& in) throw(merror_t); + void parse(mstream& out,expr_t* x) throw(merror_t); + + void eval(mstream& out,const sref& in,int child) throw(merror_t); + void eval(mstream& out,expr_t* x,int child) throw(merror_t); + void eval(mstream& out,runnable_t* ftok,int child) throw(merror_t); + + int split(sref& first,sref& rest) throw(merror_t); + void term(mstream& out,expr_t* x) throw(merror_t); + + mstring URI(const sref& raw); + + Env *up; + req_env* req; + tokmap* toks; + int mod,dbat; + tokmap loc; + dbmap* db; + mstring pwd,para,epilog; + int args; + xpile xarg,rarg; +}; + +///////////////////////////////////////////////////////////////////// + +struct latex_env : public Env { + latex_env(Env& p); + + int split(sref& first,sref& rest) throw(merror_t); + void term(mstream& out,expr_t* x) throw(merror_t); +}; + +///////////////////////////////////////////////////////////////////// + +#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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +using namespace std; + +TOK_IMPL(branch) { + int index=atoi(env[0]); + if(index<0) index+=env.args; + if(index>0&&index=env.args) THROW("htc: bad branching index "<status&OP_PARSE) env.parse(out,x->expr); else x->eval(out,env,mod); + return atob(out.str()); +} + +TOK_IMPL(for) { + expr_t* x[4]={env.arg(0),env.arg(1),env.arg(2),env.arg(3)}; + Env nenv(env); + for(eval(nenv,x[0],OP_ALL); + env.req->is_running()&&eval(nenv,x[1],OP_LOCAL); + eval(nenv,x[2],OP_LOCAL)) + nenv.parse(out,x[3]); +} + +TOK_IMPL(while) { + expr_t* x[2]={env.arg(0),env.arg(1)}; + Env nenv(env); + while(env.req->is_running()&&eval(nenv,x[0],OP_ALL)) nenv.parse(out,x[1]); +} + +///////////////////////////////////////////////////////////////////// + +TOK_IMPL(forall) { + mstring sep; env.parg(sep,-1); + sref s=env[0]; + sref p,e=env[1]; + expr_t* x=env.arg(2); + Env nenv(env); + if(sep.nempty()) { + charset seps(sep.c_str()); + while(Split(p,e,seps)) { + nenv.aloc(s,p); + nenv.parse(out,x); + } + } + else { + while(Split(p,e)) { + nenv.aloc(s,p); + nenv.parse(out,x); + } + } +} + +///////////////////////////////////////////////////////////////////// + +TOK_IMPL(on_arg) { + if(env.up&&env.up->onarg(atoi(env[0])-1)) env.parg(out,1); else env.parg(out,2); +} +TOK_IMPL(on_glob) { if(env.onglob(env[0])) env.parg(out,1); else env.parg(out,2); } +TOK_IMPL(on_loc) { if(env.onloc(env[0])) env.parg(out,1); else env.parg(out,2); } + +///////////////////////////////////////////////////////////////////// + +TOK_IMPL(setlang) { + env.req->lang=Language(env[0]); if(env.req->lang<0) env.req->lang=0; +} + +TOK_IMPL(lang) { + env.parg(out,env.req->lang); +} + +///////////////////////////////////////////////////////////////////// + +void envAddFlow(tokmap& T) +{ + TOK_ADD(branch,"x*",tok_t::PUBLIC, + "%Multiple branch\n" + "%Syntax: \\branch{x}..\n" + "%\n" + "%x==0 means nothing is executed, the first body for x==1, etc\n" + "%Negative values wrap to end\n" + ); + TOK_ADD(if,"xr?",tok_t::PUBLIC, + "%if - logical branch\n" + "%Syntax: \\if{x}{body}\n" + "%\n" + "%if x is non-zero, evaluates body, otherwise else if exist\n" + ); + TOK_ADD(nif,"xr?",tok_t::PUBLIC, + "%nif - logical branch\n" + "%Syntax: \\nif{x}{body}\n" + "%\n" + "%if x is zero, evaluates body, otherwise else if exist\n" + ); + TOK_ADD(switch,"x*",tok_t::PUBLIC, + "%Multiple switch\n" + "%Syntax: \\switch{x}....\n" + "%\n" + "%A sequence of pairs follows x\n" + "%x==val means body is executed\n" + "%\n" + "%An unpaired body at the end is treated as default\n" + ); + + ///////////////////////////////////////////////////////////////////// + + TOK_ADD(for,"rrrr",tok_t::PRIVATE, + "%C style\n" + "%Syntax: \\for{start}{test}{next}{body}\n" + "%\n" + "%Note that test and next are evaluated with optimization: only\n" + "%local variables are updated. Hence, you cannot use a function\n" + "%as the whole test, only as a part of the test, as in i<\\function.\n" + ); + TOK_ADD(while,"rr",tok_t::PRIVATE, + "%C style\n" + "%Syntax: \\while{test}{body}\n" + "%\n" + "%There is no optimization on test - globals are re-evaluated in each step\n" + ); + TOK_ADD(forall,"xx?r",tok_t::PUBLIC, + "%Loop through elements\n" + "%Syntax: \\forall{varname}{list}{body}\n" + "%\n" + "%Default whitespace are ( \\t\\r\\n). Optional whitespace characters\n" + "%may be given. This enables the design of special lists.\n" + ); + + ///////////////////////////////////////////////////////////////////// + + TOK_ADD(on_arg,"xr?",tok_t::PUBLIC, + "%Do if arg exist and is non-empty\n" + "%Syntax: \\on.arg{number}{body}\n" + ); + TOK_ADD(on_glob,"xr?",tok_t::PUBLIC, + "%Do if global variable exist and is non-empty\n" + "%Syntax: \\on.glob{varname}{body}\n" + ); + TOK_ADD(on_loc,"xr?",tok_t::PUBLIC, + "%Do if local variable exist and is non-empty\n" + "%Syntax: \\on.loc{varname}{body}\n" + ); + + ///////////////////////////////////////////////////////////////////// + + TOK_ADD(lang,"r*",tok_t::PUBLIC, + "%Branch on global language\n" + "%Syntax: \\lang{en}{sv}..\n" + "%\n" + "%Currently English (en) and Swedish (sv) are supported\n" + ); + TOK_ADD(setlang,"x",tok_t::PUBLIC, + "%Set global language\n" + "%Syntax: \\setlang{language code list}\n" + "%\n" + "%The language actually set is a negotitation -\n" + "%the first code in the list recognized is set.\n" + "%If not found, the default language English (en) is set.\n" + ); +} 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +const mstring cron_tag="cron."; +const int SSECS=4; + +TOK_IMPL(def) { + expr_t* x=env.arg(2); + func_t* tok=Func(*env.toks,env[0],x->expr,tok_t::PUBLIC,env[1]); + if(x->status&OP_PARSE) tok->x.status=OP_PARSE; else tok->x.expand(env); +} + +TOK_IMPL(redef) { + expr_t* x=env.arg(2); + func_t* tok=Func(*env.toks,env[0],x->expr,tok_t::PUBLIC,env[1],1); + if(x->status&OP_PARSE) tok->x.status=OP_PARSE; else tok->x.expand(env); +} + +TOK_IMPL(ldef) { + if(env.toks->get(env[0])) THROW("htc: local function would override global token"); + expr_t* x=env.arg(2); + func_t* tok=Func(env.loc,env[0],x->expr,tok_t::PUBLIC,env[1]); + if(x->status&OP_PARSE) tok->x.status=OP_PARSE; else tok->x.expand(env); +} + +TOK_IMPL(cron) { + mstring name=cron_tag+env[0]; + expr_t* x=env.arg(1); + cron_t* tok=Cron(*env.toks,name,x->expr,tok_t::PUBLIC,atoi(env[0])); + if(x->status&OP_PARSE) tok->x.status=OP_PARSE; else tok->x.expand(env); +} + +/////////////////////////////////////////////////// + +static void Run(tokmap& m,mstream& out,Env& env,const sref& s) throw(merror_t) { + tok_t* p=m.get(s); + if(!p) THROW("htc: cannot run "<is_reference()) env.parse(out,((reference_t*)p)->data); + else if(!p->is_runnable()) env.parse(out,p->body); + } + catch(const merror_t& e) { + out< cron; + int cont=1; for(tokmap* tok=env.toks;tok&&cont;tok=tok->up) { + for(Env::iterator p=tok->begin();p!=tok->end();++p) { + if((*p)->name.left(cron_tag.size())==cron_tag&&(*p)->is_cron()) { + cron.push_back((cron_t*)(*p)); + cont=0; + } + } + } + while(env.req->is_running()&&cron.size()) { + int cont=1; + for(int i=0;icron[i]->last+cron[i]->interval) { + mstream ms; + env.eval(ms,&cron[i]->x,0); + cron[i]->last=time(0); + cont=0; + } + } + if(cont) sleep(SSECS); + } +} + +////////////////////////////////////////////////////// + +void envAddFunc(tokmap& T) +{ + TOK_ADD(def,"xxr",tok_t::PUBLIC, + "%Define new global function\n" + "%Syntax: \\def{varname}{argument string [xr?*]}{body}\n" + "%\n" + "%The argument string is a sequence of characters describing\n" + "%the argument type, which is one of x (pre-evaluate), r (post-evaluate),\n" + "%? (optional post-evaluate) or * (optional at end, post-evaluate).\n" + "%The can be only one optional (?) argument.\n" + "%The body contains the function body. The arguments are retrieved\n" + "%as \\1, \\2 etc, except the optional argument which is retrieved as \\0,\n" + "%regardless of where it stands in the sequence.\n" + "%\n" + "%Generates an error if already defined.\n" + ); + TOK_ADD(redef,"xxr",tok_t::PRIVATE, + "%Redefine global function\n" + "%Syntax: \\def{varname}{argument string [xr?*]}{body}\n" + "%\n" + "%The argument string is a sequence of characters describing\n" + "%the argument type, which is one of x (pre-evaluate), r (post-evaluate),\n" + "%? (optional post-evaluate) or * (optional at end, post-evaluate).\n" + "%The can be only one optional (?) argument.\n" + "%The body contains the function body. The arguments are retrieved\n" + "%as \\1, \\2 etc, except the optional argument which is retrieved as \\0,\n" + "%regardless of where it stands in the sequence.\n" + "%\n" + "%Takes precedence over any existing function.\n" + ); + TOK_ADD(ldef,"xxr",tok_t::PUBLIC, + "%Define a local function\n" + "%Syntax: \\ldef{varname}{argument string [xr?*]}{body}\n" + "%\n" + "%The argument string is a sequence of characters describing\n" + "%the argument type, which is one of x (pre-evaluate), r (post-evaluate),\n" + "%? (optional post-evaluate) or * (optional at end, post-evaluate).\n" + "%The can be only one optional (?) argument.\n" + "%The body contains the function body. The arguments are retrieved\n" + "%as \\1, \\2 etc, except the optional argument which is retrieved as \\0,\n" + "%regardless of where it stands in the sequence.\n" + "%\n" + "%Local functions work just like global functions, but are only\n" + "%accessible from within the current stack frame.\n" + ); + TOK_ADD(cron,"xr",tok_t::SYSONLY, + "%Define a cron function\n" + "%Syntax: \\cron{interval}{body}\n" + "%\n" + "%A cron function is executed every interval seconds,\n" + "%when running in cron mode.\n" + "%\n" + "%See \\run.cron.\n" + ); + + ////////////////////////////////////////////////////// + + TOK_ADD(run,"x",tok_t::SYSONLY, + "%Evaluate the body of variable in current running mode\n" + "%Syntax: \\run{varname}\n" + "%\n" + "%The running modes are:\n" + "%\n" + "%XINIT Init mode is only used to collect meta information\n" + "%XSYSTEM The system mode - everything is accessible\n" + "%XPRIVATE Private mode - suitable for in-door custom programs\n" + "%XPUBLIC Public mode - quite restrictive, may be run by anyone\n" + "% via the web. This is the default mode for all derivative\n" + "% functions, as well as for globals and constants.\n" + "%\n" + "%IT IS A MAJOR SECURITY HAZARD TO EVALUATE UNKNOWN\n" + "%VARIABLES IN XSYSTEM MODE!!\n" + "%\n" + "%If at all, user-supplied information should only be run\n" + "%in public mode, for instance to allow the expansion of latex\n" + "%commands. NEVER use this mode outside the core.\n" + ); + TOK_ADD(run_private,"x",tok_t::SYSONLY, + "%Evaluate the body of variable in private mode\n" + "%Syntax: \\run.private{varname}\n" + "%\n" + "%The running modes are:\n" + "%\n" + "%XINIT Init mode is only used to collect meta information\n" + "%XSYSONLY The system mode - everything is accessible\n" + "%XPRIVATE Private mode - suitable for in-door custom htc code\n" + "%XPUBLIC Public mode - quite restrictive, may be run by anyone\n" + "% via the web. This is the default mode for all derivative\n" + "% functions, as well as for globals and constants.\n" + "%\n" + "%The execution of sysonly functions is silent, just as it wasn't there.\n" + ); + TOK_ADD(run_public,"x",tok_t::PRIVATE, + "%Evaluate the body of variable in public mode\n" + "%Syntax: \\run.public{varname}\n" + "%\n" + "%The running modes are:\n" + "%\n" + "%XINIT Init mode is only used to collect meta information\n" + "%XSYSONLY The system mode - everything is accessible\n" + "%XPRIVATE Private mode - suitable for in-door custom programs\n" + "%XPUBLIC Public mode - quite restrictive, may be run by anyone\n" + "% via the web. This is the default mode for all derivative\n" + "% functions, as well as for globals and constants.\n" + "%\n" + "%The execution of sysonly or private functions is silent,\n" + "%just as they weren't there.\n" + ); + TOK_ADD(run_local,"x",tok_t::PRIVATE, + "%Evaluate the body of the local variable in public mode\n" + "%Syntax: \\run.local{varname}\n" + "%\n" + "%The running modes are:\n" + "%\n" + "%XINIT Init mode is only used to collect meta information\n" + "%XSYSTEM The system mode - everything is accessible\n" + "%XPRIVATE Private mode - suitable for in-door custom programs\n" + "%XPUBLIC Public mode - quite restrictive, may be run by anyone\n" + "% via the web. This is the default mode for all derivative\n" + "% functions, as well as for globals and constants.\n" + "%\n" + "%The execution of sysonly or private functions is silent,\n" + "%just as they weren't there.\n" + ); + TOK_ADD(run_cron,"",tok_t::SYSONLY, + "%Go into an infinite loop and run the crontab command.\n" + "%Syntax: \\run.cron{}\n" + "%\n" + "%Note that only cron functions from the highest global level\n" + "%where a cron function is defined is run. Hence you may redefine\n" + "%earlier crontabs, but cannot mix between levels.\n" + "%\n" + "%You can only have one crontab of a certain interval.\n" + "%\n" + "%Produces no output.\n" + ); +} 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +TOK_IMPL(help) { + out<<"HTC/1.2 - HyperText Compiler (H. Rydberg (C) 1998,1999,2000,2001)\n"; + out<<"\n"; + out<<"Try these commands:\n"; + out<<"\\help - This message\n"; + out<<"\\ops - List all operators\n"; + out<<"\\ops{op} - Get info on operator\n"; + out<<"\\tok - List all tokens\n"; + out<<"\\tok{tok} - Get info on token\n"; + out<<"\\src{tok} - View token source\n"; +} + +TOK_IMPL(ops) { + mstring cmd; env.parg(cmd,-1); + if(cmd.nempty()) { + out<get(cmd); + if(p) { + if(p->pre1) out<<"Unary operator, precedence "<pre1<<"\n"; + if(p->pre2) out<<"Binary operator, precedence "<pre2<<"\n"; + out<<"\n"; + out<desc; + } + else { + out<<"(not found)\n"; + } + } + else { + mstring line; + line.convert("%-3s %-3s %s\n","P1","P2","NAME"); + out<begin();p!=env.ops->end();p++) { + line.convert("%-3d %-3d %s\n",(*p)->pre1,(*p)->pre2,(*p)->name.c_str()); + out<get(cmd); + if(p) { + out<<"Mode: "<mod&tok_t::RESTRICT) out<<"public "; + else if(p->mod&tok_t::NORMAL) out<<"normal "; + else if(p->mod&tok_t::SYSONLY) out<<"system "; + else if(p->mod&tok_t::INIT) out<<"init "; + if(p->is_runnable()) { + if(p->is_binary()) out<<"built-in "; + out<<"function\n"; + } + else { + if(p->is_const()) out<<"constant"; else out<<"variable"; + if(p->is_reference()) out<<" reference"; + if(p->is_dbref()) out<<" database reference"; + out<<"\n"; + } + out<<"Usage: "; + if(p->is_runnable()) out<<*(func_t*)p; else out<<"\\"<name; + out<<"\n"; + if(p->is_runnable()) { + mstring desc=Desc(*p); + if(desc.nempty()) { out<<"\n"; out<up) { + line.convert("%-12s %s %d\n","MODE","NAME LEVEL",n); + out<begin();p!=tok->end();p++) { + line.convert("%s %s\n",Mode(*(*p)).c_str(),(*p)->name.c_str()); + out<get(env[0]); + if(!p) out<is_runnable()) { + const func_t* ftok=(func_t*)p; + out<<"{"<name<<"}{"<arg<<"}"; + if(p->is_binary()) out<<" (built-in function)\n"; + else out<<"{"<x.expr<<"}\n"; + } + else out<\n" + ); + TOK_ADD(tok,"?",tok_t::PRIVATE, + "%Help on tokens\n" + "%Syntax: \\tok\n" + ); + TOK_ADD(src,"x",tok_t::SYSONLY, + "%Source of token\n" + "%Syntax: \\src{tokname}\n" + ); +} 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +void envAddOps(opmap& M,tokmap& T); +void envAddBasic(tokmap& T); +void envAddFunc(tokmap& T); +void envAddFlow(tokmap& T); +void envAddDB(tokmap& T); +void envAddLatex(tokmap& T); +void envAddHelp(tokmap& T); + +Lang::Lang() : running(1) +{ + envAddOps(ops,toks); + envAddBasic(toks); + envAddFunc(toks); + envAddFlow(toks); + envAddDB(toks); + envAddLatex(toks); + envAddHelp(toks); +} 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +using namespace std; + +static opmap op_latex; + +latex_env::latex_env(Env& p) : Env(p) { ops=&op_latex; } + +////////////////////////////////////////////////////// + +TOK_IMPL(it) { + mstring s; env.parg(s,-1); + if(s.nempty()) { out<<""; out<"; } + else { out<<""; env.epilog=sref("")+env.epilog; } +} + +TOK_IMPL(em) { + mstring s; env.parg(s,-1); + if(s.nempty()) { out<<""; out<"; } + else { out<<""; env.epilog=sref("")+env.epilog; } +} + +TOK_IMPL(bf) { + mstring s; env.parg(s,-1); + if(s.nempty()) { out<<""; out<"; } + else { out<<""; env.epilog=sref("")+env.epilog; } +} + +TOK_IMPL(mathbf) { + mstring s; env.parg(s,-1); + if(s.nempty()) { out<<""; out<"; } + else { out<<""; env.epilog=sref("")+env.epilog; } +} + +TOK_IMPL(rm) { + mstring s; env.parg(s,-1); + if(s.nempty()) { out<expr); + out<\n" + "%\n" + "%Note that the body is optional, just like in latex.\n" + ); + TOK_ADD(em,"?",tok_t::PUBLIC, + "%Set emph mode\n" + "%Syntax: \\em\n" + "%\n" + "%Note that the body is optional, just like in latex.\n" + ); + TOK_ADD(bf,"?",tok_t::PUBLIC, + "%Set Boldface mode\n" + "%Syntax: \\bf\n" + "%\n" + "%Note that the body is optional, just like in latex.\n" + ); + TOK_ADD(mathbf,"?",tok_t::PUBLIC, + "%Set Math boldface mode\n" + "%Syntax: \\mathbf\n" + "%\n" + "%Note that the body is optional, just like in latex.\n" + ); + TOK_ADD(rm,"?",tok_t::PUBLIC, + "%Set rm face mode\n" + "%Syntax: \\rm\n" + "%\n" + "%Note that the body is optional, just like in latex.\n" + ); + + ////////////////////////////////////////////////////////// + + TOK_ADD(setpara,"x",tok_t::PUBLIC, + "%Set paragraph string\n" + "%Syntax: \\setpara{string}\n" + "%\n" + "%Whenever a series of newlines is encountered, it is\n" + "%replaced by this string. The default is a newline.\n" + "%\n" + "%Operates on stack level (may be nested)\n" + ); + TOK_ADD(epilog,"x",tok_t::PUBLIC, + "%Add string to the epilog\n" + "%Syntax: \\epilog{string}\n" + "%\n" + "%The epilog string is output when the current stack frame\n" + "%goes out of scope. For functions like \\bf, which needs\n" + "%an end tag to be inserted at the right place.\n" + "%\n" + "%Operates on stack level (may be nested)\n" + ); + + ////////////////////////////////////////////////////////// + + TOK_ADD(equation,"r",tok_t::PUBLIC, + "%Evaluate equation (LaTeX)\n" + "%Syntax: \\equation{body}\n" + ); + + ////////////////////////////////////////////////////////// + + Const(T,sref("t"),sref("\t"),tok_t::PUBLIC); + Const(T,sref("n"),sref("\n"),tok_t::PUBLIC); + Const(T,sref("f"),sref("\f"),tok_t::PUBLIC); + + ////////////////////////////////////////////////////////// +} + 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +////////////////////////////////////////////////////// + +struct xop_t : public op_t { + typedef void (*xop1_t)(mstream&,Env&,const sref&); + typedef void (*xop2_t)(mstream&,Env&,const sref&,const sref&); + xop_t(const mstring& s,int p1,int p2,int l,int r, + xop1_t op1,xop2_t op2,const mstring& d): + op_t(s,p1,p2,l,r,(op1_t)op1,(op2_t)op2,d) {} +}; + +////////////////////////////////////////////////////// + +#define X1_IMPL(name) \ +static void impl_##name(mstream& out,Env& env,const sref& a) throw(merror_t) +#define X2_IMPL(name) \ +static void impl_##name(mstream& out,Env& env,const sref& L,const sref& R) throw(merror_t) + +#define X1_ADDN(p,l,r,f,n,d) M.add(new xop_t(#n,p,0,l,r,impl_##f,0,d)) +#define X2_ADDN(p,l,r,f,n,d) M.add(new xop_t(#n,0,p,l,r,0,impl_##f,d)) + +////////////////////////////////////////////////////// + +X1_IMPL(exist) { + mstring name; + swrite sw(name); + env.eval(sw,a,0); + out<, + "Copy local record\n" + "Syntax: (partial name) -> (partial name)\n" + "Returns: nothing\n" + "\n" + "The partial name @ for data base records works in both arguments.\n" + "\n" + "Generates an error if any of the expanded names of the right\n" + "partial argument does not exist.\n" + ); +} 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +static const charset escaped("%$[]{};"); +static const charset prename("\"'`^~*,_=!\\"); +static const charset spec("+-*/%<=>^_!~&|,?:;"); +static const charset spec_latex("+-*/<=>^_;"); +static const charset delim("\"{}()\\"); +static const charset delim_latex("{}()[]\\"); +static const charset specws=spec|delim|cset_ws; +static const charset specws_latex=spec_latex|delim_latex|cset_ws; +static const charset tokname=cset_alphareal; +static const charset pretok=tokname|prename; + +const mstring begin_tag="begin",end_left="\\end{",end_right="}"; + +int is_tokname(const sref& s) { + return s.back()!='.'&&pretok.test(s.front())&&s.right(1).find_not_of(tokname)<0; +} + +int is_arglist(const sref& s) +{ + const char* p=s.begin(); int opt=0; + if(*p=='?') { ++p; opt=1; } + while(*p=='x') ++p; + while(*p=='r') ++p; + if(!opt&&*p=='?') ++p; + if(*p=='*') ++p; + return !*p; +} + +/////////////////////////////////////////////////////////// + +static sref getlocal(const sref& in) { + int w=0,i=0; for(;i0&&in[i-1]=='.') return in.left(i-1); + else return in.left(i); +} + +static int skip_quotes(const sref& in) throw(merror_t) { + int s=in.skip(cset_quotes); + if(s<0) THROW("parse: unmatched '\"'"); + return s; +} + +static int skip_braces(const sref& in) throw(merror_t) { + int s=in.skip(cset_braces); + if(s<0) THROW("parse: unmatched '{'"); + return s; +} + +static int skip_para(const sref& in) throw(merror_t) { + int s=in.skip(cset_para); + if(s<0) THROW("parse: unmatched '('"); + return s; +} + +static int skip_indices(const sref& in) throw(merror_t) { + int s=in.skip(cset_indices); + if(s<0) THROW("parse: unmatched '['"); + return s; +} + +static int skip_dollars(const sref& in) throw(merror_t) { + int s=in.skip(cset_dollars); + //if(s<0) THROW("parse: unmatched '$'"); + return s; +} + +/////////////////////////////////////////////////////////// + +static int count_args(const sref& in) throw(merror_t) +{ + sref e=in.right_first_not_of(cset_ws); + int s,n=0; while((s=skip_braces(e))>0||(s=skip_para(e))>0) { + e=e.adv(s).right_first_not_of(cset_ws); n++; + } + return n; +} + +static int past_args(const sref& in) throw(merror_t) +{ + sref p=in,e=in.right_first_not_of(cset_ws); + int s; while((s=skip_braces(e))>0||(s=skip_para(e))>0) { + e=(p=e.adv(s)).right_first_not_of(cset_ws); + } + return p-in; +} + +static int parse_args(Env& env,runnable_t* ftok,const sref& in,int inbegend) throw(merror_t) +{ + env.clear_args(); + sref option,p=in,e=in.right_first_not_of(cset_ws); + int s,narg=0,carg=count_args(e); + while((s=e.skip(cset_braces))>0||(s==0&&(s=e.skip(cset_para))>0)) { + if(ftok->arg[narg]=='?'&&cargarg.size()) narg++; + switch(ftok->arg[narg]){ + case 'x': env.xpush(e.left(s)); break; + case 'r': case '*': env.rpush(e.left(s)); break; + case '?': option=e.left(s); break; + case 0: THROW("htc: too many args in "<name); + default: THROW("htc: bad argument descriptor in "<name); + } + e=(p=e.adv(s)).right_first_not_of(cset_ws); + if(ftok->arg[narg]!='*') narg++; + } + if(s<0) THROW("htc: unmatched parenthesis in function "<name); + if(inbegend) { + mstring tag=end_left+ftok->name+end_right; + s=p.find(tag); if(s<0) THROW("htc: unmatched begin/end in function "<name); + if(ftok->arg[narg]=='?'&&cargarg.size()) narg++; + switch(ftok->arg[narg]){ + case 'x': env.xpush(p.left(s)); break; + case 'r': case '*': env.rpush(p.left(s)); break; + case '?': option=p.left(s); break; + case 0: THROW("htc: too many args in begin/end "<name); + default: THROW("htc: bad argument descriptor in "<name); + } + p=p.adv(s+tag.size()); + } + if(ftok->arg.find('?')>=0&&env.argsarg.size()) env.rpush(option); + return p-in; +} + +int Env::check_arg(const runnable_t& ftok) const +{ + static const charset tag("xr?"); + const char* p=ftok.arg.begin(); int x=0,r=0,o=0; + while(tag.test(*p)) { + switch(*p++) { + case 'x': x++; break; + case 'r': r++; break; + case '?': r++; o++; break; + } + } + if(*p=='*') { o++; ++p; } + if(*p||x!=xsize()||o>1||o==1&&rsize()expand(*this); else x->status=OP_PARSE; + swrite sw(x->result); + eval(sw,x,0); +} + +void Env::rpush(const sref& in) throw(merror_t) +{ + expr_t* x=new expr_t(in(1,-3)); + rarg.push_back(x); args++; + if(*in=='(') x->expand(*this); else x->status=OP_PARSE; +} + +/////////////////////////////////////////////////////////// + +static int indent(sref& p) { + if(cset_newl.test(p.front())) { p=p.right_first_not_of(cset_ws); return 1; } + else return 0; +} + +static int backindent(sref& p) { + if(cset_newl.test(p.leftand_last_not_of(cset_spaces).back())) { + p=p.leftand_last_not_of(cset_ws); return 1; + } + else return 0; +} + +static int pastsemi(sref& p) { + int s=p.find_not_of(cset_spaces); + if(s>=0&&p[s]==';') return indent(p=p.adv(s+1)); else return 0; +} + +static int past_func(const sref& in) throw(merror_t) +{ + sref e=getname(in.popf()),p=in.adv(e); + return p.adv(past_args(p))-in; +} + +static int parse_func(mstream& out,Env& env,const sref& in,int& run) throw(merror_t) +{ + run=0; sref e=getname(in),p=in.adv(e); + mstring name; + swrite sw(name); + env.eval(sw,e,0); + if(env.is_arg(name)) { + //if(count_args(p)) THROW("htc: expected no argument after "<parg(out,atoi(name)-1); + return p-in; + } + int inbegend=0; + if(name==begin_tag) { + sref next=p.right_first_not_of(cset_ws); + int s=skip_braces(next); + if(s>0) { name=next(1,s-2); p=next.adv(s); inbegend=1; } + } + tok_t* tok=env.toks->get(name); + if(!tok) { if(!(tok=env.loc.get(name))||!tok->is_func()) tok=0; } + if(!tok) return 0; + if(!tok->is_runnable()) { + //if(count_args(p)) THROW("htc: expected no argument after "<body; + return p-in; + } + runnable_t* ftok=(runnable_t*)tok; + if(env.is_clear(ftok)) { + p=p.adv(parse_args(env,ftok,p,inbegend)); + run=1; env.eval(out,ftok,1); + } + else p=p.adv(past_args(p)); + return p-in; +} + +void Env::parse(mstream& out,const sref& in) throw(merror_t) +{ + static const charset sensors=escaped|cset_newl|'\\'; + epilog.clear(); + int s,run; + sref p=in; + indent(p); + backindent(p); + sref e=p; + while(*p) { + switch(*p) { + case ';': + case '}': + case ']': + out.put(*p); + p=p.popf(); + break; + case '%': + if(p-e>0) { out.put(*p); p=p.popf(); } + else e=p=p.past_nl().right_first_not_of(cset_ws); + break; + case '\r': + p=p.popf(); + break; + case '\n': + out.put(*p); p=p.popf(); + if(cset_newl.test(*p.right_first_not_of(cset_spaces))) out<0) { + eval(out,p(1,s-2),0); + if(pastsemi(p=p.adv(s))) e=p; + } + } + else { out.put(*p); p=p.popf(); } + break; + case '[': + if(mod&tok_t::PUBLIC){ + if((s=skip_indices(p))>0) { + expr(out,p(1,s-2)); + if(pastsemi(p=p.adv(s))) e=p; + } + } + else { out.put(*p); p=p.popf(); } + break; + case '$': + if(mod&tok_t::PUBLIC){ + if((s=skip_dollars(p))>0) { + latex_env(*this).expr(out,p(1,s-2)); + if(pastsemi(p=p.adv(s))) e=p; + } + } + else { out.put(*p); p=p.popf(); } + break; + case '\\': + p=p.popf(); + if(p.empty()) out.put('\\'); + else if(escaped.test(*p)) { out.put(*p); p=p.popf(); } + else { + if((s=parse_func(out,*this,p,run))>0) { if(pastsemi(p=p.adv(s))) e=p; } + else out.put('\\'); + } + break; + default: + if((s=p.find_of(sensors))>=0) { out<status&OP_PARSE) parse(out,x->expr); + else x->eval(out,*this,OP_ALL); +} + +/////////////////////////////////////////////////////////// + +void Env::eval(mstream& out,const sref& in,int child) throw(merror_t) +{ + Env nenv(*this); if(child) nenv.up=this; + nenv.parse(out,in); +} + +void Env::eval(mstream& out,expr_t* x,int child) throw(merror_t) +{ + Env nenv(*this); if(child) nenv.up=this; + nenv.parse(out,x); +} + +void Env::eval(mstream& out,runnable_t* ftok,int child) throw(merror_t) +{ + if(child&&!check_arg(*ftok)) THROW("htc: bad number of args; expected "<<*ftok); + if(ftok->is_binary()) ((binary_t*)ftok)->func(out,*this); + else if(ftok->is_func()) eval(out,&((func_t*)ftok)->x,child); + else THROW("htc: unknown runnable"); +} + +////////////////////////////////////////////////////// + +int Env::split(sref& first,sref& rest) throw(merror_t) +{ + int s; + rest=rest.right_first_not_of(cset_ws); + if(*rest=='\\') { + first=rest.left(past_func(rest)); + rest=rest.adv(first); + } + else if(spec.test(*rest)) { + first=rest.left_first_not_of(spec); + rest=rest.adv(first); + } + else if((s=skip_quotes(rest))>0||(s=skip_braces(rest))>0) { + first=rest.left(s); + rest=rest.adv(first); + } + else if((s=skip_para(rest))>0) { + first=rest(1,s-2); + rest=rest.right(s); + } + else { + first=getlocal(rest); + rest=rest.adv(first); + } + return first.nempty(); +} + +void Env::term(mstream& out,expr_t* x) throw(merror_t) +{ + if(x->expr.empty()) x->status=0; + else if(*x->expr=='\"') { out<expr(1,-3); x->status=0; } + else if(*x->expr=='{') { eval(out,x->expr(1,-3),0); x->status=0; } + else if(x->expr.find_not_of(cset_real)<0) { out<expr; x->status=0; } + else if(*x->expr=='\\') { + sref p=x->expr.popf(); + if(p.empty()) { out.put('\\'); x->status=0; } + else if(escaped.test(*p)) { out.put(*p); x->status=0; } + else { + int run; + if(parse_func(out,*this,p,run)>0) x->status=run?OP_LOCAL:OP_GLOBAL; + else { out.put('\\')<expr; x->status=OP_NINIT; } + } + } + else { + mstring name; + swrite sw(name); + eval(sw,x->expr,0); + out<status=OP_LOCAL; + } +} + +/////////////////////////////////////////////////////////////////// + +int latex_env::split(sref& first,sref& rest) throw(merror_t) +{ + int s; + rest=rest.right_first_not_of(cset_ws); + if(*rest=='\\') { + first=rest.left(past_func(rest)); + rest=rest.adv(first); + } + else if(spec.test(*rest)) { + first=rest.left_first_not_of(spec); + rest=rest.adv(first); + } + else if((s=skip_braces(rest))>0||(s=skip_para(rest))>0||(s=skip_indices(rest))>0) { + first=rest.left(s); + rest=rest.adv(first); + } + else { + first=rest.left_first_of(specws); + rest=rest.adv(first); + } + return first.nempty(); +} + +void latex_env::term(mstream& out,expr_t* x) throw(merror_t) +{ + if(x->expr.empty()) x->status=0; + else if(*x->expr=='\\') { eval(out,x->expr,0); x->status=0; } + else if(*x->expr=='{') { eval(out,x->expr(1,-3),0); x->status=0; } + else if(*x->expr=='('||*x->expr=='[') { + out.put(x->expr.front()); + expr(out,x->expr(1,-3)); + out.put(x->expr.back()); + x->status=0; + } + else { out<expr; x->status=0; } +} 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +static fp_stream mout(stdout),merr(stderr); + +main(int argc,char* argv[]) try +{ + Lang lang; + req_env req(lang,lang.toks); + Env env(lang.ops,req,XSYSTEM); + mstring line; + while(!feof(stdin)) { + merr<<"lang>"; + getline(line,stdin); + try { + env.parse(mout,line); + mout<<"\n"; + } + catch(const merror_t& e) { + merr< +#include +using namespace std; + +/////////////////////////////////////////////////////////////////// + +const unsigned tok_t::CONSTANT=1; +const unsigned tok_t::RESTRICT=2; +const unsigned tok_t::NORMAL=4; +const unsigned tok_t::SYSONLY=8; +const unsigned tok_t::INIT=16; +const unsigned tok_t::RUNNABLE=32; +const unsigned tok_t::FUNCTION=64; +const unsigned tok_t::BINARY=128; +const unsigned tok_t::REFERENCE=256; +const unsigned tok_t::DBREF=512; +const unsigned tok_t::CRON=1024; +const unsigned tok_t::PRIVATE=NORMAL|SYSONLY; +const unsigned tok_t::PUBLIC=RESTRICT|PRIVATE; +const unsigned tok_t::XMODES=PUBLIC|INIT; + +/////////////////////////////////////////////////////////////////// + +uniheap tok_t::tree; +void* tok_t::operator new(size_t n) { return tree.push(); } +void tok_t::operator delete(void* p) { tree.pop(p); } + +uniheap reference_t::tree; +void* reference_t::operator new(size_t n) { return tree.push(); } +void reference_t::operator delete(void* p) { tree.pop(p); } + +uniheap dbref_t::tree; +void* dbref_t::operator new(size_t n) { return tree.push(); } +void dbref_t::operator delete(void* p) { tree.pop(p); } + +uniheap runnable_t::tree; +void* runnable_t::operator new(size_t n) { return tree.push(); } +void runnable_t::operator delete(void* p) { tree.pop(p); } + +uniheap func_t::tree; +void* func_t::operator new(size_t n) { return tree.push(); } +void func_t::operator delete(void* p) { tree.pop(p); } + +uniheap cron_t::tree; +void* cron_t::operator new(size_t n) { return tree.push(); } +void cron_t::operator delete(void* p) { tree.pop(p); } + +uniheap binary_t::tree; +void* binary_t::operator new(size_t n) { return tree.push(); } +void binary_t::operator delete(void* p) { tree.pop(p); } + +/////////////////////////////////////////////////////////////////// + +mstring uscore2dot(const char* s) { + mstring t=s; int p; while((p=t.find('_'))>=0) t[p]='.'; return t; +} + +/////////////////////////////////////////////////////////////////// + +tok_t::~tok_t() {} + +/////////////////////////////////////////////////////////////////// + +void tokmap::clear() +{ + for(iterator p=list.begin();p!=list.end();p++) delete *p; + list.clear(); +} + +tok_t* tokmap::get_this(const sref& t) +{ + pair p=equal_range(list.begin(),list.end(),(val_t)0,comp_t(t)); + return p.first!=p.second?*p.first:0; +} + +const tok_t* tokmap::get_this(const sref& t) const +{ + pair p= + equal_range(list.begin(),list.end(),(val_t)0,comp_t(t)); + return p.first!=p.second?*p.first:0; +} + +const tok_t* tokmap::get(const sref& t) const +{ + const tok_t* p=get_this(t); return p?p:up?up->get(t):0; +} + +tok_t* tokmap::get(const sref& t) +{ + tok_t* p=get_this(t); return p?p:up?up->get(t):0; +} + +tok_t* tokmap::set(tok_t* tok,int replace,int force) throw(merror_t) +{ + pair p= + equal_range(list.begin(),list.end(),(val_t)0,comp_t(tok->name)); + if(p.first!=p.second) { + if(!(*p.first)->is_replaceable(*tok)) { + delete tok; + THROW("token: Could not set "<<(*p.first)->name<<" - protected"); + return 0; + } + else if((*p.first)->is_const()&&!replace) { + delete tok; + if(force) THROW("token: Could not set "<<(*p.first)->name<<" - constant"); + return 0; + } + else { delete *p.first; return *p.first=tok; } + } + else if(up) return up->set(tok,replace,force); + else { + mstring name=tok->name; + delete tok; + if(force) THROW("token: Could not set "<name); + if(old) { + if(!old->is_replaceable(*tok)) { + delete tok; + THROW("token: Could not add "<name<<" - protected"); + return 0; + } + else if(old->is_const()&&!replace) { + delete tok; + if(force) THROW("token: Could not add "<name<<" - constant"); + return 0; + } + } + pair p= + equal_range(list.begin(),list.end(),(val_t)0,comp_t(tok->name)); + if(p.first!=p.second) { delete *p.first; return *p.first=tok; } + else return *list.insert(p.second,tok); +} + +/////////////////////////////////////////////////////////////////// + +static void Check(const sref& s) throw(merror_t) +{ + if(!is_tokname(s)) THROW("token: bad name ("<name.left(s.size())==s) p=map.erase(p); else p++; + } + } +} + +/////////////////////////////////////////////////////////////// + +mstream& operator<<(mstream& out,const runnable_t& ftok) +{ + out<<"\\"<=0;i--) { if(tok.mod&(1< +#include + +#define TOK_ARGS (mstream& out,Env& env) +#define TOK_IMPL(func) static void impl_##func TOK_ARGS throw(merror_t) +#define TOK_ADD(func,a,mod,help) \ +T.add(new binary_t(uscore2dot(#func),sref(help),mod,sref(a),impl_##func),0,1) + +mstring uscore2dot(const char* s); + +class Env; +typedef void (*s_func_t)TOK_ARGS; + +class tok_t { +public: + static const unsigned CONSTANT,RESTRICT,NORMAL,SYSONLY,INIT; + static const unsigned RUNNABLE,FUNCTION,BINARY; + static const unsigned REFERENCE,DBREF,CRON; + static const unsigned PRIVATE,PUBLIC,XMODES; + + static inline unsigned tight(unsigned xmod) { + // INIT is ignored here simply because no mode can + // read variables in INIT mode... defaults to public. + return (xmod&SYSONLY)?SYSONLY:(xmod&NORMAL)?PRIVATE:PUBLIC; + } + + mstring name,body; + unsigned mod; + + int is_clear(int xmod) const { return (mod&xmod)!=0; } + int is_replaceable(const tok_t& t) const { return (mod&t.mod)==t.mod; } + + int is_const() const { return (mod&CONSTANT)!=0; } + int is_runnable() const { return (mod&RUNNABLE)!=0; } + int is_func() const { return (mod&FUNCTION)!=0; } + int is_cron() const { return (mod&CRON)!=0; } + int is_binary() const { return (mod&BINARY)!=0; } + int is_reference() const { return (mod&REFERENCE)!=0; } + int is_dbref() const { return (mod&DBREF)!=0; } + + tok_t(const sref& s,const sref& b,unsigned m) : name(s),body(b),mod(m) {} + virtual ~tok_t(); + + static void* operator new(size_t n); + static void operator delete(void* p); +private: + static uniheap<32> tree; +}; + +/////////////////////////////////////////////////////////////////// + +class reference_t : public tok_t { +public: + mstring data; + reference_t(const sref& s,const sref& b,unsigned m): + tok_t(s,b,m|REFERENCE|CONSTANT) {} + + static void* operator new(size_t n); + static void operator delete(void* p); +private: + static uniheap<44> tree; +}; + +/////////////////////////////////////////////////////////////////// + +class dbref_t : public tok_t { +public: + dbmap db; + dbref_t(const sref& s,const sref& b,unsigned m): + tok_t(s,b,m|DBREF|CONSTANT) {} + + static void* operator new(size_t n); + static void operator delete(void* p); +private: + static uniheap<96> tree; +}; + +/////////////////////////////////////////////////////////////////// + +class runnable_t : public tok_t { +public: + mstring arg; + runnable_t(const sref& s,const sref& b,unsigned m,const sref& a): + tok_t(s,b,m|RUNNABLE|CONSTANT),arg(a) {} + + static void* operator new(size_t n); + static void operator delete(void* p); +private: + static uniheap<44> tree; +}; + +/////////////////////////////////////////////////////////////////// + +class func_t : public runnable_t { +public: + expr_t x; + func_t(const sref& s,const sref& b,unsigned m,const sref& a): + runnable_t(s,b,m|FUNCTION,a) { x=body; } + + static void* operator new(size_t n); + static void operator delete(void* p); +private: + static uniheap<80> tree; +}; + +/////////////////////////////////////////////////////////////////// + +class cron_t : public func_t { +public: + int last,interval; + cron_t(const sref& s,const sref& b,unsigned m,int i): + func_t(s,b,m|CRON,ms_empty),last(0),interval(i) {} + + static void* operator new(size_t n); + static void operator delete(void* p); +private: + static uniheap<88> tree; +}; + +/////////////////////////////////////////////////////////////////// + +class binary_t : public runnable_t { +public: + s_func_t func; + binary_t(const sref& s,const sref& b,unsigned m,const sref& a,s_func_t f): + runnable_t(s,b,m|BINARY,a),func(f) {} + + static void* operator new(size_t n); + static void operator delete(void* p); +private: + static uniheap<48> tree; +}; + +/////////////////////////////////////////////////////////////////// + +mstream& operator<<(mstream&,const runnable_t& ftok); +mstring Mode(const tok_t& tok); +mstring Desc(const tok_t& tok); + +/////////////////////////////////////////////////////////////////// + +struct tokmap { + typedef tok_t* val_t; + typedef mrvec map_t; + typedef map_t::iterator iterator; + typedef map_t::const_iterator const_iterator; + + struct comp_t { + sref key; + comp_t(const sref& skey) : key(skey) {} + bool operator()(val_t a,val_t b) const { + return (a?((const sref&)a->name):key)<(b?((const sref&)b->name):key); + } + }; + + tokmap* up; + map_t list; + + tokmap() : up(0),list() {} + tokmap(tokmap& p) : up(&p),list() {} + ~tokmap() { clear(); } + + iterator begin() { return list.begin(); } + const_iterator begin() const { return list.begin(); } + + iterator end() { return list.end(); } + const_iterator end() const { return list.end(); } + + void clear(); + iterator erase(iterator p) { delete *p; return list.erase(p); } + + tok_t* get_this(const sref& t); + const tok_t* get_this(const sref& t) const; + const tok_t* get(const sref& t) const; + tok_t* get(const sref& t); + + tok_t* set(tok_t* tok,int replace,int force) throw(merror_t); + tok_t* add(tok_t* tok,int replace,int force) throw(merror_t); +}; + +/////////////////////////////////////////////////////////////////// + +int is_tokname(const sref& s); +int is_arglist(const sref& s); + +tok_t* Cond(tokmap& map,const sref& s,const sref& b,unsigned m) throw(merror_t); +tok_t* Global(tokmap& map,const sref& s,const sref& b,unsigned m,int rpl=0) throw(merror_t); +tok_t* Const(tokmap& map,const sref& s,const sref& b,unsigned m,int rpl=0) throw(merror_t); +func_t* Func(tokmap& map,const sref& s,const sref& b, + unsigned m,const sref& a,int rpl=0) throw(merror_t); +cron_t* Cron(tokmap& map,const sref& s,const sref& b, + unsigned m,int i,int rpl=0) throw(merror_t); +binary_t* Binary(tokmap& map,const sref& s,const sref& b, + unsigned m,const sref& a,s_func_t f,int rpl=0) throw(merror_t); +reference_t* Reference(tokmap& map,const sref& s,const sref& b, + unsigned m,int rpl=0) throw(merror_t); +dbref_t* DBRef(tokmap& map,const sref& s, + const sref& b,unsigned m,int rpl=0) throw(merror_t); +void ClearToken(tokmap& map,const sref& s) throw(merror_t); + +/////////////////////////////////////////////////////////////////// + +const int XPUBLIC=tok_t::RESTRICT; +const int XPRIVATE=XPUBLIC|tok_t::NORMAL; +const int XSYSTEM=XPRIVATE|tok_t::SYSONLY; +const int XINIT=tok_t::INIT; + +#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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +main(int argc,char* argv[]) +{ + if(argc<3) return -1; + const char* infile=INBOX.c_str(); // argv[1] not used + const char* outfile=argv[2]; + LockFile(infile); + Mailbox box; + GetMessages(box,infile); + int ok=AppendMessages(box,outfile); + if(ok) truncate(infile,0); + UnlockFile(infile); + return !ok; +} 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +static fp_stream mout(stdout),merr(stderr); +const mstring multipart="multipart/"; + +main(int argc,char* argv[]) try +{ + if(argc<2) { + merr<<"Usage: "< [index]\n"; + return -1; + } + const char* infile=argv[1]; + Mailbox box; + GetMessages(box,infile); + if(argc>2) { + int m=atoi(argv[2])-1; + if(m>=0&&m=0; + mout<<"["<<(i+1)<<"]["< +#include + +static fp_stream mout(stdout),merr(stderr); + +main(int argc,char* argv[]) +{ + if(argc<3) { + merr<<"Usage: "< [indices]\n"; + return -1; + } + const char* infile=argv[1]; + const char* outfile=argv[2]; + Mailbox box,keep; + LockFile(infile); + LockFile(outfile); + FILE* outbox=fopen(outfile,"a+"); + if(outbox) { + GetMessages(box,infile); + for(int i=0;i3) { + for(int j=3;j +#include + +const mstring INBOX=htchome()+sref("/mail/INBOX"); +const mstring TODO=htchome()+sref("/mail/TODO"); +const mstring DONE=htchome()+sref("/mail/DONE"); + +#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 @@ + ######################################################################### + # + # HTCd - Copyright (C) 1998-2006 Henrik Rydberg + # + # This program is free software; you can redistribute it and/or modify + # it under the terms of the GNU General Public License as published by + # the Free Software Foundation; either version 2 of the License, or + # (at your option) any later version. + # + # This program is distributed in the hope that it will be useful, + # but WITHOUT ANY WARRANTY; without even the implied warranty of + # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + # GNU General Public License for more details. + # + # You should have received a copy of the GNU General Public License + # along with this program; if not, write to the Free Software + # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + # + +LIBRARY = libhtc.a +INSTALL = ../bin + +############################################################################ + +MODULE += mt +mt_c = test +mt_o = cfind crfind strip \ + sfind srfind sfindtab srfindtab scomptab sconvert \ + find_of rfind_of find_not_of rfind_not_of skip_parentesis \ + stringref mstream mread mstring mset msmap \ + random dates lock lookup issue config + + +MODULE += mime +mime_c = test +mime_o = mime def mailbox base64 qp pack + + +MODULE += mail +mail_c = inbox move list + + +MODULE += http +http_c = test +http_o = mime req resp + + +MODULE += ops +ops_c = test +ops_o = operator express basic comp string latex + + +MODULE += hdb +hdb_c = test hdbtest hdbcvt hdbfix +hdb_o = filemap sortable db comp cvt + + +MODULE += hed +hed_c = test hed +hed_o = input edit tables +hed_x = hed + + +MODULE += lang +lang_c = test +lang_o = token env parse ops basic func latex help flow db lang + + +MODULE += sh +sh_c = htc +sh_o = file convert dates user tree sys net main +sh_x = htc + +MODULE += serv +serv_c = htcs +serv_o = direct request const auth form tempmap main +serv_x = htcs + +MODULE += net +net_c = test htcd redirect route80 +net_o = isocket server thrserv +net_x = htcd redirect + +MODULE += labat +labat_c = atomlab +labat_f = labat +labat_o = resten deriv grad grabgr laplac laplac2 ggaexc \ + exchen ldaec gcor ggaec ggauxc exchpt ldauc \ + ggauc spline splint +labat_x = atomlab labat + +############################################################################ + +CTARGET = $(foreach mod,$(MODULE),\ + $(addprefix $(mod)/,$($(mod)_c))) + +FTARGET = $(foreach mod,$(MODULE),\ + $(addprefix $(mod)/,$($(mod)_f))) + +LTARGET = $(foreach mod,$(MODULE),\ + $(addprefix $(mod)/,$($(mod)_o))) + +XTARGET = $(foreach mod,$(MODULE),\ + $(addprefix $(mod)/,$($(mod)_x))) + +XLIST = $(foreach mod,$(MODULE),$($(mod)_x)) + +CTARG = $(addprefix tmp/bin/,$(CTARGET)) +FTARG = $(addprefix tmp/bin/,$(FTARGET)) +XTARG = $(addprefix tmp/bin/,$(XTARGET)) +COBJ = $(addprefix tmp/obj/c/,$(addsuffix .o,$(CTARGET))) +FOBJ = $(addprefix tmp/obj/f/,$(addsuffix .o,$(FTARGET))) +LOBJ = $(addprefix tmp/obj/l/,$(addsuffix .o,$(LTARGET))) +TLIB = $(addprefix tmp/obj/,$(LIBRARY)) + +############################################################################ + +INCLUDE = -I. +COPT = -O3 -pthread +FOPT = -O5 +CLIBS = -lncurses +FLIBS = + +.PHONY: all man html clean mkobj install +.PRECIOUS: tmp/obj/c/%.o tmp/obj/f/%.o tmp/obj/l/%.o + +############################################################################ + +all: $(LOBJ) $(TLIB) $(FOBJ) $(COBJ) $(FTARG) $(CTARG) + +tmp/bin/%: tmp/obj/c/%.o $(TLIB) + @mkdir -p $(@D) + g++ $(COPT) $< $(TLIB) $(CLIBS) -o $@ + +tmp/bin/%: tmp/obj/f/%.o $(TLIB) + @mkdir -p $(@D) + f77 $(FOPT) $< $(TLIB) $(FLIBS) -o $@ + +tmp/obj/c/%.o: %.cc + @mkdir -p $(@D) + gcc $(INCLUDE) $(COPT) -c $< -o $@ + +tmp/obj/f/%.o: %.f + @mkdir -p $(@D) + f77 $(FOPT) -c $< -o $@ + +$(TLIB): $(LOBJ) + @rm -f $(TLIB) + ar qc $(TLIB) $(LOBJ) + +tmp/obj/l/%.o: %.cc + @mkdir -p $(@D) + gcc $(INCLUDE) $(COPT) -c $< -o $@ + +tmp/obj/l/%.o: %.f + @mkdir -p $(@D) + f77 $(FOPT) -c $< -o $@ + +man: + @rm -rf tmp/man + doxygen etc/doxman + +html: + @rm -rf tmp/html + doxygen etc/doxhtml + +install: $(XTARG) + @mkdir -p $(INSTALL) + cp -rfp $(XTARG) $(INSTALL) + +clean: + rm -rf tmp + +distclean: + rm -rf tmp; cd $(INSTALL); rm -rf $(XLIST) + +############################################################################ 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +static unsigned char char2six[256]={ + 65,65,65,65,65,65,65,65, + 65,65,65,65,65,65,65,65, + 65,65,65,65,65,65,65,65, + 65,65,65,65,65,65,65,65, + 65,65,65,65,65,65,65,65, + 65,65,65,62,65,65,65,63, + 52,53,54,55,56,57,58,59, + 60,61,65,65,65,64,65,65, + 65, 0, 1, 2, 3, 4, 5, 6, + 7, 8, 9,10,11,12,13,14, + 15,16,17,18,19,20,21,22, + 23,24,25,65,65,65,65,65, + 65,26,27,28,29,30,31,32, + 33,34,35,36,37,38,39,40, + 41,42,43,44,45,46,47,48, + 49,50,51,65,65,65,65,65, + 65,65,65,65,65,65,65,65, + 65,65,65,65,65,65,65,65, + 65,65,65,65,65,65,65,65, + 65,65,65,65,65,65,65,65, + 65,65,65,65,65,65,65,65, + 65,65,65,65,65,65,65,65, + 65,65,65,65,65,65,65,65, + 65,65,65,65,65,65,65,65, + 65,65,65,65,65,65,65,65, + 65,65,65,65,65,65,65,65, + 65,65,65,65,65,65,65,65, + 65,65,65,65,65,65,65,65, + 65,65,65,65,65,65,65,65, + 65,65,65,65,65,65,65,65, + 65,65,65,65,65,65,65,65, + 65,65,65,65,65,65,65,65 +}; +static unsigned char six2char[64]={ + 'A','B','C','D','E','F','G','H', + 'I','J','K','L','M','N','O','P', + 'Q','R','S','T','U','V','W','X', + 'Y','Z','a','b','c','d','e','f', + 'g','h','i','j','k','l','m','n', + 'o','p','q','r','s','t','u','v', + 'w','x','y','z','0','1','2','3', + '4','5','6','7','8','9','+','/' +}; +inline void tri2quad(mstream& out,unsigned code,int m=4) +{ + char buf[4]; + buf[3]=six2char[code&63U]; code>>=6; + buf[2]=six2char[code&63U]; code>>=6; + buf[1]=six2char[code&63U]; code>>=6; + buf[0]=six2char[code&63U]; + out.write(buf,m); +} +inline void quad2tri(mstream& out,unsigned code,int m=3) +{ + char buf[3]; + buf[2]=code&255U; code>>=8; + buf[1]=code&255U; code>>=8; + buf[0]=code&255U; + out.write(buf,m); +} + +void encode64(mstream& out,const sref& in) +{ + unsigned m=0,code=0,wrap=0; + for(const char* p=in.begin();p!=in.end();p++) { + code<<=8; + code|=(unsigned char)*p; + if(++m==3) { + tri2quad(out,code); + m=0; + if(++wrap==15) { out< + +const mstring trans_base64="base64"; +const mstring trans_quote="quoted-printable"; +const mstring mime_default="iso-8859-1"; + +void decode64(mstream& out,const sref& in); +void encode64(mstream& out,const sref& in); +void decodeQP(mstream& out,const sref& in); +void encodeQP(mstream& out,const sref& in); +void decodeHeader(mstream& out,mstring& mime,const sref& in); +void encodeHeader(mstream& out,const sref& mime,const sref& in); + +#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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +static int FromHead(const sref& body) +{ + sref tag,from,rest=body; + Split(tag,rest); + Split(from,rest); + return tag==from_tag&&htcTime(0,rest)>=0; +} + +///////////////////////////////////////////////////////////////////// + +const mstring nextmsg_tag="\nFrom "; +const mstring sep_tag="--"; + +Message::Message() +{ +} + +int Message::Special(sref line) +{ + line=Rest(line); + from=from0=First(line); + date=Rest(line); + idate=htcTime(0,date); + return idate>=0; +} + +int Message::Handle(const sref& name, + const sref& rawval, + const sref& val, + const rrpile& opts) +{ + mstring mime; + if(Mime::Handle(name,rawval,val,opts)) return 1; + else if(eqn(name,from_tag)) { + swrite sw(from); + decodeHeader(sw,mime,rawval); + } + else if(eqn(name,subject_tag)) { + swrite sw(subject); + decodeHeader(sw,mime,rawval); + } + else if(eqn(name,to_tag)) { + swrite sw(to); + decodeHeader(sw,mime,rawval); + } + else if(eqn(name,msgid_tag)) msgid=rawval; + else if(eqn(name,received_tag)) received.push_back(rawval); + else return 0; + return 1; +} + +void Message::putHead(mstream& out) const +{ + if(from0.nempty()) { out<<"From "< +#include + +const mstring from_tag="From"; +const mstring to_tag="To"; +const mstring subject_tag="Subject"; +const mstring msgid_tag="Message-ID"; +const mstring received_tag="Received"; + +class Message : public Mime { +public: + Message(); + Message(const sref& msg) { Init(msg); } + + mstring from0,from,date,subject,to,msgid; + spile received; + time_t idate; + + void putHead(mstream& out) const; +protected: + int Special(sref line); + int Handle(const sref& name, + const sref& rawval, + const sref& val, + const rrpile& opts); +}; + +typedef msvec Mailbox; + +void AppendMessage(FILE* fp,const sref& msg); +void AppendMessages(FILE* fp,const Mailbox& box); + +int PutMessages(const Mailbox& box,const mstring& path); +int AppendMessages(const Mailbox& box,const mstring& path); + +int GetMessages(Mailbox& box,const mstring& path); + +#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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +const charset par_left("([{"),par_right("}])"); + +inline int is_field(const sref& s) { + sref p=s.left_first(':'); + while(cset_spaces.test(p.back())) p=p.popb(); + return p.nempty()&&p.find_of(cset_spaces)<0; +} + +inline int getquoted(const sref& s,char c) { + int i,quote=0,par=0; + for(i=0;ifirst,charset_tag)) cont_type_charset=p->second; + else if(eqn(p->first,name_tag)) cont_type_name=p->second; + else if(eqn(p->first,boundary_tag)) cont_type_boundary=p->second; + } + } + else if(eqn(name,cont_id_tag)) cont_id=val; + else if(eqn(name,cont_desc_tag)) cont_desc=val; + else if(eqn(name,cont_disp_tag)) { + cont_disp=val; + for(rrpile::const_iterator p=opts.begin();p!=opts.end();p++) { + if(eqn(p->first,name_tag)) cont_disp_name=p->second; + else if(eqn(p->first,file_tag)) cont_disp_file=p->second; + } + } + else if(eqn(name,cont_trans_enc_tag)) cont_trans_enc=val; + else if(eqn(name,cont_length_tag)) cont_length=val; + else return 0; + return 1; +} + +/////////////////////////////////////////////////////////////////////////// + +void Mime::putHead(mstream& out) const +{ + if(putval(out,mime_version_tag,mime_version)) putend(out); + if(putval(out,cont_type_tag,cont_type)) { + putopt(out,charset_tag,cont_type_charset); + putopt(out,name_tag,cont_type_name); + putopt(out,boundary_tag,cont_type_boundary); + putend(out); + } + if(putval(out,cont_id_tag,cont_id)) putend(out); + if(putval(out,cont_desc_tag,cont_desc)) putend(out); + if(putval(out,cont_disp_tag,cont_disp)) { + putopt(out,name_tag,cont_disp_name); + putopt(out,file_tag,cont_disp_file); + putend(out); + } + if(putval(out,cont_trans_enc_tag,cont_trans_enc)) putend(out); + if(putval(out,cont_length_tag,cont_length)) putend(out); +} + + +/////////////////////////////////////////////////////////////////////////// + +int Mime::Multipart(rpile& list) const +{ + if(cont_type_boundary.empty()) return 0; + mstring bound=sref("--")+cont_type_boundary; + sref rest=body.past_first(bound).past_nl(); + while(rest.nempty()) { + int pos=rest.find(bound); + if(pos>=0) { + sref first=rest.left(pos); + if(first.back()=='\n') { + first=first.popb(); + if(first.back()=='\r') first=first.popb(); + } + list.push_back(first); + rest=rest.right(pos).adv(bound.size()); + if(*rest=='-') rest.clear(); else rest=rest.past_nl(); + } + else { + list.push_back(rest); + rest.clear(); + } + } + return !list.empty(); +} + +void Mime::Pick(const sref& mime) +{ + rpile list; + if(Multipart(list)) { + if(eqn(cont_type,mime_multialt)) { + int pos=0; + for(int i=0;i + +// MIME Headers +const mstring mime_version_tag="MIME-Version"; +const mstring cont_type_tag="Content-Type"; +const mstring cont_trans_enc_tag="Content-Transfer-Encoding"; +const mstring cont_id_tag="Content-ID"; +const mstring cont_desc_tag="Content-Description"; +const mstring cont_disp_tag="Content-Disposition"; +const mstring cont_length_tag="Content-Length"; +// Option headers +const mstring name_tag="name"; +const mstring file_tag="filename"; +const mstring charset_tag="charset"; +const mstring boundary_tag="boundary"; +const mstring path_tag="path"; +// Some Content types +const mstring mime_textplain="text/plain"; +const mstring mime_texthtml="text/html"; +const mstring mime_texthtc="text/x-htc"; +const mstring mime_multialt="multipart/alternative"; + +///////////////////////////////////////////////////////////////// + +const sref* file2mime(const sref& file); + +///////////////////////////////////////////////////////////////// + +class Mime { +public: + sref head,body; + + mstring mime_version; + mstring cont_type,cont_type_charset,cont_type_name,cont_type_boundary; + mstring cont_id; + mstring cont_desc; + mstring cont_disp,cont_disp_name,cont_disp_file; + mstring cont_trans_enc; + mstring cont_length; + + virtual void putHead(mstream& out) const; + + void Init(const sref& in); + + int Multipart(rpile& list) const; + void Pick(const sref& mime); + + Mime(); + Mime(const sref& msg) { Init(msg); } + +protected: + virtual int Special(sref line); + virtual int Handle(const sref& name, + const sref& rawval, + const sref& val, + const rrpile& opts); +}; + +////////////////////////////////////////////////////////////////// + +inline int putval(mstream& out,const sref& tag,const sref& val) { + if(val.nempty()) { out<first); + out.put('='); + Pack(out,p->second); + out.put('&'); + } +} + +/////////////////////////////////////////////////////////////// + +void Unpack(mstream& out,const sref& in) +{ + static const charset tags("%+"); + sref e,p=in; + while(p.nempty()) { + p=p.adv(e=p.left_first_of(tags)); + out< +#include + +// Really mimefunctions, but needed here + +mstream& cashex(mstream& out,unsigned char c); +char hexasc(unsigned char c1,unsigned char c2); + +// Packing means application/x-www-form-urlencoded + +void Unpack(mstream& out,const sref& in); +void Unpack(spile& list,const sref& in); +void Unpack(sspile& list,const sref& in); + +void Pack(mstream& out,const sref& in); +void Pack(mstream& out,const rpile& list); +void Pack(mstream& out,const rrpile& list); + +// CR LF and CRLF business + +const mstring CRLF="\r\n"; + +void CRLF2LF(mstream& out,const sref& in); +void LF2CRLF(mstream& out,const sref& in); + +#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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +const charset special("=\"#$\\^`{|}~"); +//const charset special("=!\"#$@[\\]^`{|}~"); +const charset headspecial("_?"); +const charset printable=cset_printable&~special; +const charset printhead=printable&~headspecial; +const mstring beg_tag("=?"),end_tag("?="); +const mstring enc_qp_tag("Q"),enc_64_tag("B"); +const int WRAPAT=76; +const int HEADWRAP=WRAPAT-7; + +void decodeQP(mstream& out,const sref& in) +{ + const char* p=in.begin(); + while(p=WRAPAT) { out.put('=')< +#include +#include +#include + +static fp_stream mout(stdout),merr(stderr); + +static void Show(mstream& out,const Message& msg) +{ + if(msg.cont_type.empty()|| + eqn(msg.cont_type,mime_textplain)|| + eqn(msg.cont_type,mime_texthtml)) { + if(eqn(msg.cont_trans_enc,trans_quote)) { + //decodeQP(out,msg.body); + mswrite tmp; + decodeQP(tmp,msg.body); + encodeQP(out,tmp.str()); + } + else { + //out< [index]\n"; + return 1; + } + Mailbox box; + GetMessages(box,argv[1]); + merr<<"Found "<2) { + Message msg(box[atoi(argv[2])]); + //msg.Pick(mime_textplain); + + mswrite tmp; + encodeHeader(tmp,mime_default,msg.subject); + msg.subject=tmp.str(); + + msg.putHead(mout); + mout<<"-----------------------------------------\n"; + rpile part; + if(msg.Multipart(part)) { + for(int i=0;i\n"; + return 1; + } + mstring buffer; buffer.load(argv[1]); + merr< + +struct charset { + explicit charset(const char s[]) { + memset(negmap,0,256); while(*s) map[*s++]=1; + } + charset(char beg,char end) { + memset(negmap,0,256); while(beg<=end) map[beg++]=1; + } + int test(char c) const { return map[c]; } + int operator[](char c) const { return map[c]; } + char negmap[128],map[128]; +}; + +inline charset operator|(const charset& a,const charset& b) { + charset c(a); for(int i=-127;i<128;i++) c.map[i]|=b.map[i]; return c; +} +inline charset operator|(const charset& a,char b) { + charset c(a); c.map[b]=(b!=0); return c; +} +inline charset operator|(char a,const charset& b) { + charset c(b); c.map[a]=(a!=0); return c; +} +inline charset operator&(const charset& a,const charset& b) { + charset c(a); for(int i=-127;i<128;i++) c.map[i]&=b.map[i]; return c; +} +inline charset operator^(const charset& a,const charset& b) { + charset c(a); for(int i=-127;i<128;i++) c.map[i]^=b.map[i]; return c; +} +inline charset operator-(const charset& a,const charset& b) { + charset c(a); for(int i=-127;i<128;i++) c.map[i]&=~b.map[i]; return c; +} +inline charset operator-(const charset& a,char b) { + charset c(a); c.map[b]=0; return c; +} +inline charset operator~(const charset& a) { + charset c(a); for(int i=-127;i<128;i++) c.map[i]=!c.map[i]; c.map[0]=0; + return c; +} + +////////////////////////////////////////////////////////////////////////// + +struct charmap { + charmap() { for(int i=-127;i<128;i++) map[i]=i; } + charmap(const charset& a,const charset& b) { + for(int i=-127,j=-127;i<128;i++) { + if(a[i]) { while(j<128&&!b[j]) j++; map[i]=j++; } + else map[i]=i; + } + } + charmap(const charset& a,const char* b) { + for(int i=-127;i<128;i++) if(a[i]&&*b) map[i]=*b++; else map[i]=i; + } + char operator[](char c) const { return map[c]; } + char negmap[128],map[128]; +}; + +inline charmap operator<<(const charmap& a,const charmap& b) { + charmap c(a); + for(int i=-127;i<128;i++) if(b.map[i]!=i) c.map[i]=b.map[i]; + for(int i=-127;i<128;i++) c.map[i]=c.map[c.map[i]]; + return c; +} + +////////////////////////////////////////////////////////////////////////// + +struct bracket { + explicit bracket(const char s[]) { strncpy(&left,s,sizeof(bracket)); } + int test(char c) const { return c==left||c==right; } + char left,right,esc,end; +}; + +////////////////////////////////////////////////////////////////////////// + +const charset cset_spaces(" \t"); +const charset cset_newl("\r\n"); +const charset cset_ws=cset_spaces|cset_newl; +const charset cset_printable(' ','~'); +const charset cset_digit('0','9'); +const charset cset_real=cset_digit|'.'; +const charset cset_sign("+-"); +const charset cset_lalpha('a','z'); +const charset cset_ualpha('A','Z'); +const charset cset_alpha=cset_lalpha|cset_ualpha; +const charset cset_alphanum=cset_alpha|cset_digit; +const charset cset_alphareal=cset_alpha|cset_real; +const charset cset_lext1(-32,-10),cset_lext2(-8,-2); +const charset cset_uext1(-64,-42),cset_uext2(-40,-34); +const charset cset_liso=cset_lalpha|cset_lext1|cset_lext2; +const charset cset_uiso=cset_ualpha|cset_uext1|cset_uext2; + +const charmap cset_ident; +const charmap cset_leqv1(cset_lext1,"aaaaaaaceeeeiiiidnooooo"); +const charmap cset_leqv2(cset_lext2,"ouuuuyp"); +const charmap cset_ueqv1(cset_uext1,"AAAAAAACEEEEIIIIDNOOOOO"); +const charmap cset_ueqv2(cset_uext2,"OUUUUYP"); + +const charmap cset_lcase(cset_uiso,cset_liso); +const charmap cset_ucase(cset_liso,cset_uiso); +const charmap cset_sim=cset_lcase<\\"); + +#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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +mstring htchome() +{ + const char* p=getenv("HTCHOME"); + if(!p) { + fprintf(stderr,"env: HTCHOME not set, exiting\n"); + exit(-1); + } + mstring home=p; + if(home.back()=='/') home=home.popb(); + return home; +} + 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef CONFIGH +#define CONFIGH + +#include + +mstring htchome(); + +#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 @@ +ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +c +c HTCd - Copyright (C) 1998-2006 Henrik Rydberg +c +c This program is free software; you can redistribute it and/or modify +c it under the terms of the GNU General Public License as published by +c the Free Software Foundation; either version 2 of the License, or +c (at your option) any later version. +c +c This program is distributed in the hope that it will be useful, +c but WITHOUT ANY WARRANTY; without even the implied warranty of +c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +c GNU General Public License for more details. +c +c You should have received a copy of the GNU General Public License +c along with this program; if not, write to the Free Software +c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +c + + integer function crfind(s,n,c) + character s(0:1),c + integer i,m,n + m=mod(n,16) + do 10 i=n-16,m,-16 + if(s(i+15).eq.c)go to 115 + if(s(i+14).eq.c)go to 114 + if(s(i+13).eq.c)go to 113 + if(s(i+12).eq.c)go to 112 + if(s(i+11).eq.c)go to 111 + if(s(i+10).eq.c)go to 110 + if(s(i+9).eq.c)go to 109 + if(s(i+8).eq.c)go to 108 + if(s(i+7).eq.c)go to 107 + if(s(i+6).eq.c)go to 106 + if(s(i+5).eq.c)go to 105 + if(s(i+4).eq.c)go to 104 + if(s(i+3).eq.c)go to 103 + if(s(i+2).eq.c)go to 102 + if(s(i+1).eq.c)go to 101 + if(s(i).eq.c)go to 100 + 10 continue + do 20 i=m-1,0,-1 + if(s(i).eq.c)go to 100 + 20 continue + crfind=-1 + return + 100 crfind=i + return + 101 crfind=i+1 + return + 102 crfind=i+2 + return + 103 crfind=i+3 + return + 104 crfind=i+4 + return + 105 crfind=i+5 + return + 106 crfind=i+6 + return + 107 crfind=i+7 + return + 108 crfind=i+8 + return + 109 crfind=i+9 + return + 110 crfind=i+10 + return + 111 crfind=i+11 + return + 112 crfind=i+12 + return + 113 crfind=i+13 + return + 114 crfind=i+14 + return + 115 crfind=i+15 + return + end + 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +const mstring SWEEK[MAXLANG][7]={ + "Sun","Mon","Tue","Wed","Thu","Fri","Sat", + "Sön","Mån","Tis","Ons","Tor","Fre","Lör" +}; +const mstring SMONTH[MAXLANG][12]={ + "Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec", + "Jan","Feb","Mar","Apr","Maj","Jun","Jul","Aug","Sep","Okt","Nov","Dec" +}; +const mstring WEEK[MAXLANG][7]={ + "Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday", + "Söndag","Måndag","Tisdag","Onsdag","Torsdag","Fredag","Lördag" +}; +const mstring MONTH[MAXLANG][12]={ + "January","February","March","April","May","June", + "July","August","September","October","November","December", + "Januari","Februari","Mars","April","Maj","Juni", + "Juli","Augusti","September","Oktober","November","December" +}; + +time_t Today(time_t now) +{ + tm s; localtime_r(&now,&s); + s.tm_hour=0; + s.tm_min=0; + s.tm_sec=0; + return mktime(&s); +} + +time_t Sunday(time_t now) +{ + tm s; localtime_r(&now,&s); + s.tm_mday-=s.tm_wday; + return mktime(&s); +} + +const mstring& Week(int lang,time_t t) +{ + tm s; return WEEK[lang][localtime_r(&t,&s)->tm_wday]; +} + +const mstring& Month(int lang,time_t t) +{ + tm s; return MONTH[lang][localtime_r(&t,&s)->tm_mon]; +} + +const mstring& SWeek(int lang,time_t t) +{ + tm s; return SWEEK[lang][localtime_r(&t,&s)->tm_wday]; +} + +const mstring& SMonth(int lang,time_t t) +{ + tm s; return SMONTH[lang][localtime_r(&t,&s)->tm_mon]; +} + +mstring httpTime(time_t t) +{ + tm tt; gmtime_r(&t,&tt); + return mstring().convert("%s, %02d %s %4d %02d:%02d:%02d GMT", + SWEEK[0][tt.tm_wday].c_str(), + tt.tm_mday, + SMONTH[0][tt.tm_mon].c_str(), + tt.tm_year+1900, + tt.tm_hour, + tt.tm_min, + tt.tm_sec); +} + +mstring htcTime(int lang,time_t t) +{ + tm tt; localtime_r(&t,&tt); + mstring s(32); asctime_r(&tt,s.data()); s.resize(24); + if(lang) { + for(int i=0;i<7;i++) if(s(0,3)==SWEEK[0][i]) { + s.replace(0,3,SWEEK[lang][i]); + break; + } + for(int i=0;i<12;i++) if(s(4,3)==SMONTH[0][i]) { + s.replace(4,3,SMONTH[lang][i]); + break; + } + } + return s; +} + +static int Month(int& mon,const sref& st) +{ + mstring s=st; s.tolower(); s[0]=toupper(s[0]); + for(int lang=0;lang=0&&h<=24&&m>=0&&m<60&&s>=0&&s<60) { th=h; tmi=m; ts=s; return 1; } + return 0; +} + +static int Day(int& day,const sref& s) +{ + if(s.find_not_of(cset_digit)>=0) return 0; + int d=atoi(s); + if(d>0&&d<32) { day=d; return 1; } + return 0; +} + +static int Year(int& year,const sref& s) +{ + if(s.find_not_of(cset_digit)>=0) return 0; + int y=atoi(s); + if(y>=32&&y<9999) { year=y; return 1; } + return 0; +} + +time_t htcTime(int lang,const sref& date) +{ + sref week,month,day,when,year,rest=date; + Split(week,rest); + Split(month,rest); + Split(day,rest); + Split(when,rest); + Split(year,rest); + struct tm t; + Time(t.tm_hour,t.tm_min,t.tm_sec,when); + t.tm_mday=atoi(day); + Month(t.tm_mon,month); + t.tm_year=atoi(year)-1900; + Week(t.tm_wday,week); + t.tm_isdst=-1; + return mktime(&t); +} + +time_t cvtTime(const sref& code) +{ + time_t now=time(0); + tm t; localtime_r(&now,&t); + t.tm_hour=0;t.tm_min=0;t.tm_sec=0; + //Start with 00:00:00 today + sref first,rest=code; + int w=0,m=0,d=0,h=0,y=0; + while(Split(first,rest)) { + if(!w) w=Week(t.tm_wday,first); + if(!m) m=Month(t.tm_mon,first); + if(!h) h=Time(t.tm_hour,t.tm_min,t.tm_sec,first); + if(!d) d=Day(t.tm_mday,first); + if(!y) if(y=Year(t.tm_year,first)) t.tm_year-=1900; + } + t.tm_isdst=-1; + return mktime(&t); +} + +////////////////////////////// + +int Language(const sref& st) +{ + static const charset seps=cset_ws|charset(",;"); + mstring s=st; s.tolower(); + sref first,rest=s; + while(Split(first,rest,seps)) { + for(int i=0;i +#include + +const time_t SEC_PER_DAY=86400; +const int MAXLANG=2; +const mstring LANG[MAXLANG]={"en","sv"}; + +inline time_t Now() { return time(0); } +inline time_t Days(int days) { return days*SEC_PER_DAY; } + +time_t Today(time_t); +time_t Sunday(time_t); + +const mstring& Week(int lang,time_t t); +const mstring& Month(int lang,time_t t); + +const mstring& SWeek(int lang,time_t t); +const mstring& SMonth(int lang,time_t t); + +mstring httpTime(time_t t); +mstring htcTime(int lang,time_t t); +time_t htcTime(int lang,const sref& date); +time_t cvtTime(const sref& code); + +int Language(const sref& s); + +#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 @@ +ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +c +c HTCd - Copyright (C) 1998-2006 Henrik Rydberg +c +c This program is free software; you can redistribute it and/or modify +c it under the terms of the GNU General Public License as published by +c the Free Software Foundation; either version 2 of the License, or +c (at your option) any later version. +c +c This program is distributed in the hope that it will be useful, +c but WITHOUT ANY WARRANTY; without even the implied warranty of +c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +c GNU General Public License for more details. +c +c You should have received a copy of the GNU General Public License +c along with this program; if not, write to the Free Software +c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +c + + integer function find_not_of(s,n,c) + byte s(0:1),c(0:1) + integer i,m,n + m=mod(n,16) + do 10 i=0,m-1 + if(c(s(i)).eq.0)go to 100 + 10 continue + do 20 i=m,n-1,16 + if(c(s(i)).eq.0)go to 100 + if(c(s(i+1)).eq.0)go to 101 + if(c(s(i+2)).eq.0)go to 102 + if(c(s(i+3)).eq.0)go to 103 + if(c(s(i+4)).eq.0)go to 104 + if(c(s(i+5)).eq.0)go to 105 + if(c(s(i+6)).eq.0)go to 106 + if(c(s(i+7)).eq.0)go to 107 + if(c(s(i+8)).eq.0)go to 108 + if(c(s(i+9)).eq.0)go to 109 + if(c(s(i+10)).eq.0)go to 110 + if(c(s(i+11)).eq.0)go to 111 + if(c(s(i+12)).eq.0)go to 112 + if(c(s(i+13)).eq.0)go to 113 + if(c(s(i+14)).eq.0)go to 114 + if(c(s(i+15)).eq.0)go to 115 + 20 continue + find_not_of=-1 + return + 100 find_not_of=i + return + 101 find_not_of=i+1 + return + 102 find_not_of=i+2 + return + 103 find_not_of=i+3 + return + 104 find_not_of=i+4 + return + 105 find_not_of=i+5 + return + 106 find_not_of=i+6 + return + 107 find_not_of=i+7 + return + 108 find_not_of=i+8 + return + 109 find_not_of=i+9 + return + 110 find_not_of=i+10 + return + 111 find_not_of=i+11 + return + 112 find_not_of=i+12 + return + 113 find_not_of=i+13 + return + 114 find_not_of=i+14 + return + 115 find_not_of=i+15 + return + end + 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 @@ +ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +c +c HTCd - Copyright (C) 1998-2006 Henrik Rydberg +c +c This program is free software; you can redistribute it and/or modify +c it under the terms of the GNU General Public License as published by +c the Free Software Foundation; either version 2 of the License, or +c (at your option) any later version. +c +c This program is distributed in the hope that it will be useful, +c but WITHOUT ANY WARRANTY; without even the implied warranty of +c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +c GNU General Public License for more details. +c +c You should have received a copy of the GNU General Public License +c along with this program; if not, write to the Free Software +c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +c + + integer function find_of(s,n,c) + byte s(0:1),c(0:1) + integer i,m,n + m=mod(n,16) + do 10 i=0,m-1 + if(c(s(i)).ne.0)go to 100 + 10 continue + do 20 i=m,n-1,16 + if(c(s(i)).ne.0)go to 100 + if(c(s(i+1)).ne.0)go to 101 + if(c(s(i+2)).ne.0)go to 102 + if(c(s(i+3)).ne.0)go to 103 + if(c(s(i+4)).ne.0)go to 104 + if(c(s(i+5)).ne.0)go to 105 + if(c(s(i+6)).ne.0)go to 106 + if(c(s(i+7)).ne.0)go to 107 + if(c(s(i+8)).ne.0)go to 108 + if(c(s(i+9)).ne.0)go to 109 + if(c(s(i+10)).ne.0)go to 110 + if(c(s(i+11)).ne.0)go to 111 + if(c(s(i+12)).ne.0)go to 112 + if(c(s(i+13)).ne.0)go to 113 + if(c(s(i+14)).ne.0)go to 114 + if(c(s(i+15)).ne.0)go to 115 + 20 continue + find_of=-1 + return + 100 find_of=i + return + 101 find_of=i+1 + return + 102 find_of=i+2 + return + 103 find_of=i+3 + return + 104 find_of=i+4 + return + 105 find_of=i+5 + return + 106 find_of=i+6 + return + 107 find_of=i+7 + return + 108 find_of=i+8 + return + 109 find_of=i+9 + return + 110 find_of=i+10 + return + 111 find_of=i+11 + return + 112 find_of=i+12 + return + 113 find_of=i+13 + return + 114 find_of=i+14 + return + 115 find_of=i+15 + return + end + 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +void issue_t::run(mstream& out,const sref& in) throw(merror_t) +{ + int ip[2],op[2]; + pipe(ip); pipe(op); + sigignore(SIGPIPE); + int pid=fork(); + if(pid) { + close(ip[0]); + close(op[1]); + write(ip[1],in.data(),in.size()); + close(ip[1]); + sref_t buf; int n; + while((n=read(op[0],buf,sizeof(sref_t)))>0) out.write(buf,n); + close(op[0]); + if(wait(0)<0) kill(pid,SIGKILL); + } + else { + close(ip[1]); + close(op[0]); + dup2(ip[0],0); + close(ip[0]); + dup2(op[1],1); + close(op[1]); + execv(*argv(),argv()); + _exit(0); + } +} + 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef ISSUEH +#define ISSUEH + +#include +#include +#include + +// ISSUE A PIPED COMMAND +// +// This class is tuned to work in a mt environment. +// The aim is to make this work locally as if it was +// a single thread returning something to the stream out +// depending on the input in. + +struct issue_t { + mrvec arg; + + issue_t() {} + ~issue_t() { clear(); } + + issue_t(const sref& s,const charset& ws=cset_ws) { + sref first,rest=s; + while(Split(first,rest,ws)) arg.push_back(first.news()); + arg.push_back(0); + } + + void clear() { for(int i=0;i +#include +#include +#include +#include +#include +using namespace std; + +const mstring LOCK=".lock"; + +void LockFile(const mstring& path,int prot) throw(merror_t) +{ + mstring name=path+LOCK; int fd; + while((fd=open(name.c_str(),O_CREAT|O_WRONLY|O_TRUNC|O_EXCL,prot))==-1&& + errno==EEXIST) sleep(1); + if(fd<0) THROW("lock: could not create lock file "<=0) { + if(buf.nempty()&&buf!=sref(uts.nodename)) + THROW("nodelock: already locked on "<=0) while(!kill(atoi(buf),SIGTERM)) sleep(stime); +} + 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef LOCKH +#define LOCKH + +#include + +// OFFERS TWO LOCKING MECHANISMS + +void LockFile(const mstring& path,int prot=0660) throw(merror_t); +void UnlockFile(const mstring& path); + +// These functions create an exclusive lock on path by +// creating a file path.lock. +// Works well and is the same mechnism used by +// mailing systems. + +//////////////////////////////////////////// + +struct proclock_t { + pid_t pid; + mstring path; + proclock_t(const mstring& p,int prot=0660); + ~proclock_t(); +}; + +#define PROCLOCK(p) proclock_t proclock(p) + +// The proclock class creates a file named path.lock +// and stores the curent process id in it. +// once the destructor is called in the same +// process, the file is removed. + +//////////////////////////////////////////// + +struct nodelock_t { + pid_t pid; + mstring path; + nodelock_t(const mstring& p,int prot=0660); + ~nodelock_t(); +}; + +#define NODELOCK(p) nodelock_t nodelock(p) + +// The nodelock class creates a file named path.lock +// and stores the curent network node name in it. +// once the destructor is called in the same +// process, the file is removed. + +//////////////////////////////////////////// + +void ProcTerminate(const mstring& path,int stime=2); + +#endif + 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include + +const time_t VALIDSEC=120; +static msvec cache; +static mutex_t mutex; + +int Lookup(IPnode& node,const in_addr& ia) +{ + MLOCK(mutex); + IPnode* p=cache.begin(); + time_t now=time(0); + while(pp->valid) cache.erase(p); + else if(memcmp(&p->addr,&ia,sizeof(ia))==0) {p->valid=now+VALIDSEC;node=*p;return 1;} + else p++; + } + hostent hent; + sref_t buf; + int herr; + hostent* hp=0; + gethostbyaddr_r((const char*)&ia,sizeof(ia),AF_INET, + &hent, + buf,sizeof(sref_t), + &hp, + &herr); + if(!hp) return 0; + memcpy(&node.addr,hp->h_addr,sizeof(hp->h_length)); + node.ip=inet_ntoa(node.addr); + node.name=hp->h_name; + node.valid=now+VALIDSEC; + cache.push_back(node); + return 1; +} + +int Lookup(IPnode& node,const sref& s) +{ + MLOCK(mutex); + IPnode* p=cache.begin(); + time_t now=time(0); + while(pp->valid) cache.erase(p); + else if(p->ip==s||p->name==s) { p->valid=now+VALIDSEC; node=*p; return 1; } + else p++; + } + hostent hent; + sref_t sbuf,buf; + int herr; + hostent* hp=0; + for(int i=0;s[i];i++) if(s[i]!='.'&&(s[i]<'0'||s[i]>'9')) { + gethostbyname_r(s.copyto(sbuf),&hent,buf,sizeof(sref_t),&hp,&herr); + break; + } + if(!hp) { + unsigned long a=inet_addr(s.copyto(buf)); + gethostbyaddr_r((char*)&a,sizeof(a),AF_INET,&hent,buf,sizeof(sref_t),&hp,&herr); + } + if(!hp) return 0; + memcpy(&node.addr,hp->h_addr,sizeof(hp->h_length)); + node.ip=inet_ntoa(node.addr); + node.name=hp->h_name; + node.valid=now+VALIDSEC; + cache.push_back(node); + return 1; +} 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef LOOKUPH +#define LOOKUPH + +#include +#include +#include + +struct IPnode { time_t valid; in_addr addr; mstring ip,name; }; + +int Lookup(IPnode& node,const sref& s); +int Lookup(IPnode& node,const in_addr& ia); + +#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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef MLOCKH +#define MLOCKH + +#if 1 +#include +typedef pthread_mutex_t mutex_t; +typedef pthread_cond_t mtcond_t; +const mutex_t MUTEX_INIT=PTHREAD_MUTEX_INITIALIZER; +const mtcond_t MTCOND_INIT=PTHREAD_COND_INITIALIZER; +struct mlock_t { + mutex_t* lock; + + mlock_t(mutex_t& m) { pthread_mutex_lock(lock=&m); } + ~mlock_t() { if(lock) pthread_mutex_unlock(lock); } +}; +#define MLOCK(m) mlock_t mlock(m) +#define MSUSPEND(m,c) { MLOCK(m); pthread_cond_wait(&c,&m); } +#define MCONTINUE(c) pthread_cond_signal(&c) +#else +typedef int mutex_t; +typedef int mtcond_t; +const mutex_t MUTEX_INIT=0; +const mtcond_t MTCOND_INIT=0; +#define MLOCK(m) +#define MSUSPEND(m,c) +#define MCONTINUE(c) +#endif + +#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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include + +const int MSEC=4000; +const int RETRY=3; +const int TIMEOUT=2; + +////////////////////////////////////////////////////////////////////////// + +mread::mread() : fd(-1),buf() +{ +} + +mread::mread(int f) : fd(f),buf() +{ +} + +////////////////////////////////////////////////////////////////////////// + +void mread::clear() +{ + buf.clear(); +} + +int mread::poll() +{ + pollfd pfd={fd,POLLIN,0}; + return ::poll(&pfd,1,MSEC); +} + +int mread::read(char* s,int n) +{ + if(buf.empty()) { + int m=::read(fd,s,n); + for(int i=0;i=0;i++) m=::read(fd,s,n); + if(m<0&&n) *s=0; + return m; + } + else { + if(n>buf.size()) n=buf.size(); + memcpy(s,buf.data(),n); + buf.erase(0,n); + return n; + } +} + +void mread::putback(const sref& s) +{ + if(s.nempty()) buf.insert(0,s); +} + +////////////////////////////////////////////////////////////////////////// + +int mread::readx(char* s,int n) +{ + int tries=0,acc=0; + while(acc=TIMEOUT) return acc; + } + else { + acc+=m; + tries=0; + } + } + return acc; +} + +////////////////////////////////////////////////////////////////////////// + +int mread::readln(char* s,int n) +{ + int tries=0,acc=0; + while(acc=TIMEOUT) return acc?-1:0; + } + else { + int p=sref(s+acc,m).find('\n')+1; + if(p>0) { acc+=p; putback(sref(s+acc,m-p)); return acc; } + else { acc+=m; tries=0; } + } + } + return acc; +} + +int mread::readpara(char* s,int n) +{ + int tries=0,acc=0; + while(acc=TIMEOUT) return acc?-1:0; + } + else { + int found=0; + sref first,rest(s+acc,m); + while(Splitln(first,rest)) if(first.empty()) { found=1; break; } + if(found) { acc=rest.begin()-s; putback(rest); return acc; } + else { acc+=m; tries=0; } + } + } + return acc; +} + 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef MREADH +#define MREADH + +// These functions work with nonblocking pipes +// as well as normal devices, and does not produce +// any signals on pipe errors + +#include +#include +#include + +class mread { +public: + mread(); + mread(int f); + + void setfd(int f) { clear(); fd=f; } + int getfd() const { return fd; } + + void setflag(int f) { fcntl(fd,F_SETFL,f); } + int getflag() const { return fcntl(fd,F_GETFL,0); } + + // Basic, pipe-safe, normally non-blocking, reads + void clear(); + int poll(); + int read(char* s,int n); + void putback(const sref& s); + + // Buffered reads + int readx(char* s,int n); // may timeout and return less than wanted + int readln(char* s,int n); + int readpara(char* s,int n); + +private: + int fd; + mstring buf; +}; + +// All functions return number of bytes written, or -1 on error. +// Note that although ln and para continues to read until +// it finds a newline or a paragraph, it may read more than that. +// Use clear() to restore reading state + +#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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +using namespace std; + +mset::mset() : rpile() {} +mset::mset(const sref& in) : rpile() { + sref first,rest=in; + while(Split(first,rest)) insert(first); +} + +///////////////////////////////////////////////////////////////////////////// + +int mset::exist(const sref& t) const { + pair p=equal_range(begin(),end(),t); + return p.first!=p.second; +} +int mset::insert(const sref& t) { + pair p=equal_range(begin(),end(),t); + if(p.first==p.second) { rpile::insert(p.second,t); return 1; } + else return 0; +} + +///////////////////////////////////////////////////////////////////////////// + +void mset::Union(const mset& a,const mset& b) { + clear(); + for(int i=0;i p=equal_range(begin(),end(),t); + return p.first!=p.second; +} +int msset::insert(const mstring& t) { + pair p=equal_range(begin(),end(),t); + if(p.first==p.second) { spile::insert(p.second,t); return 1; } + else return 0; +} + +///////////////////////////////////////////////////////////////////////////// + +mstream& operator<<(mstream& out,const msset& m) { + for(int i=0;i +#include +#include + +typedef mrvec rpile; + +struct mset : public rpile +{ + typedef rpile::iterator iterator; + typedef rpile::const_iterator const_iterator; + + mset(); + mset(const sref& in); + + int exist(const sref& t) const; + int insert(const sref& t); + + void Union(const mset& a,const mset& b); + void Intersection(const mset& a,const mset& b); + void Difference(const mset& a,const mset& b); +}; + +mstream& operator<<(mstream& out,const mset& m); + +////////////////////////////////////////////////////////// + +typedef msvec spile; + +struct msset : public spile +{ + typedef spile::iterator iterator; + typedef spile::const_iterator const_iterator; + + int exist(const mstring& t) const; + int insert(const mstring& t); +}; + +mstream& operator<<(mstream& out,const mset& m); + +#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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +using namespace std; + +const sref* rrmap::get(const sref& t) const +{ + pair p=equal_range(begin(),end(),rrstring(t)); + return p.first!=p.second?&p.first->second:0; +} + +const sref* rrmap::add(const sref& t,const sref& s) +{ + rrstring tmp(t,s); + pair p=equal_range(begin(),end(),tmp); + if(p.first!=p.second) return &(*p.first=tmp).second; + else return &insert(p.second,tmp)->second; +} + +void rrmap::sort() +{ + ::sort(begin(),end()); +} + +//////////////////////////////////////////////////////////////// + +int rimap::get(const sref& t) const +{ + pair p=equal_range(begin(),end(),rimap_t(t)); + return p.first!=p.second?p.first->at:-1; +} + +int rimap::add(const sref& t,int at) +{ + rimap_t tmp(t,at); + pair p=equal_range(begin(),end(),tmp); + if(p.first!=p.second) return (*p.first=tmp).at; + else return insert(p.second,tmp)->at; +} + +void rimap::sort() +{ + ::sort(begin(),end()); +} + +//////////////////////////////////////////////////////////////// + +const mstring* ssmap::get(const mstring& t) const +{ + pair p=equal_range(begin(),end(),sstring(t)); + return p.first!=p.second?&p.first->second:0; +} + +const mstring* ssmap::add(const mstring& t,const mstring& s) +{ + sstring tmp(t,s); + pair p=equal_range(begin(),end(),tmp); + if(p.first!=p.second) return &(*p.first=tmp).second; + else return &insert(p.second,tmp)->second; +} + +void ssmap::sort() +{ + ::sort(begin(),end()); +} + 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef MSMAPH +#define MSMAPH + +#include +#include + +struct rrstring { + sref first,second; + rrstring() : first(),second() {} + explicit rrstring(const sref& a) : first(a),second() {} + rrstring(const sref& a,const sref& b) : first(a),second(b) {} +}; +inline bool operator<(const rrstring& a,const rrstring& b) { return a.first rrpile; + +struct rrmap : public rrpile +{ + typedef rrpile::iterator iterator; + typedef rrpile::const_iterator const_iterator; + + const sref* get(const sref& t) const; + const sref* add(const sref& t,const sref& s); + void sort(); +}; + +////////////////////////////////////////////////////////////////// + +struct rimap_t { + sref name; + int at; + rimap_t() : name(),at(0) {} + explicit rimap_t(const sref& a) : name(a),at(0) {} + rimap_t(const sref& a,int p) : name(a),at(p) {} +}; +inline bool operator<(const rimap_t& a,const rimap_t& b) { return a.name +{ + typedef mrvec::iterator iterator; + typedef mrvec::const_iterator const_iterator; + + int get(const sref& t) const; + int add(const sref& t,int at); + void sort(); +}; + +////////////////////////////////////////////////////////////////// + +struct sstring { + mstring first,second; + sstring() : first(),second() {} + explicit sstring(const mstring& a) : first(a),second() {} + sstring(const mstring& a,const mstring& b) : first(a),second(b) {} +}; +inline bool operator<(const sstring& a,const sstring& b) { return a.first sspile; + +struct ssmap : public sspile +{ + typedef sspile::iterator iterator; + typedef sspile::const_iterator const_iterator; + + const mstring* get(const mstring& t) const; + const mstring* add(const mstring& t,const mstring& s); + void sort(); +}; + +#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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +const char cvt_form_f[]="%#.12f"; +const int MSEC=4000; + +sref ftoa(sref_t& buf,double f) +{ + char* e=buf+sprintf(buf,cvt_form_f,f)-1; + while(*e=='0') e--; if(*e=='.') e--; + return sref(buf,e-buf+1); +} + +/////////////////////////////////////////////////////////// + +int mstream::appc(char c) { return -1; } +int mstream::appi(int i) { return -1; } +int mstream::appf(double f) { return -1; } +int mstream::apps(const sref& s) { return -1; } + +/////////////////////////////////////////////////////////// + +int cvt_stream::appi(int i) { sref_t buf; return apps(itoa(buf,i)); } +int cvt_stream::appf(double f) { sref_t buf; return apps(ftoa(buf,f)); } + +/////////////////////////////////////////////////////////// + +int fp_stream::appc(char c) { return putc(c,fp)<0?-1:1; } +int fp_stream::apps(const sref& s) { return fwrite(s.data(),s.size(),1,fp); } + +/////////////////////////////////////////////////////////// + +int fd_stream::appc(char c) { return ::write(fd,&c,1); } +int fd_stream::apps(const sref& s) { return ::write(fd,s.data(),s.size()); } + +/////////////////////////////////////////////////////////// + +int pipe_stream::appc(char c) { return mwrite(&c,1); } +int pipe_stream::apps(const sref& s) { return mwrite(s.data(),s.size()); } + +int pipe_stream::mwrite(const char* s,int n) +{ + int old=n; + while(n>0&&!hup) { + pollfd pfd={fd,POLLOUT,0}; + if(::poll(&pfd,1,MSEC)<0) return hup=-1; + int m=::write(fd,s,n); + if(m<0) return hup=-1; + s+=m; n-=m; + } + return hup?-1:old; +} 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef MSTREAMH +#define MSTREAMH + +#include +#include +#include + +/////////////////////////////////////////////////////////// + +const char cvt_form_i[]="%d"; + +/////////////////////////////////////////////////////////// + +inline sref itoa(sref_t& buf,int i) { return sref(buf,sprintf(buf,cvt_form_i,i)); } +sref ftoa(sref_t& buf,double f); + +/////////////////////////////////////////////////////////// + +struct mstream { + virtual int appc(char c); + virtual int appi(int i); + virtual int appf(double f); + virtual int apps(const sref& s); + + mstream& put(char c) { return appc(c),*this; } + int write(const char* s,int n) { return apps(sref(s,n)); } +}; + +inline mstream& operator<<(mstream& out,int i) { return out.appi(i),out; } +inline mstream& operator<<(mstream& out,long l) { return out.appi(l),out; } +inline mstream& operator<<(mstream& out,unsigned u) { return out.appi(u),out; } +inline mstream& operator<<(mstream& out,unsigned long ul) { return out.appi(ul),out; } +inline mstream& operator<<(mstream& out,double f) { return out.appf(f),out; } + +inline mstream& operator<<(mstream& out,const sref& s) { return out.apps(s),out; } +inline mstream& operator<<(mstream& out,const char* s) { return out.apps(sref(s)),out; } + +/////////////////////////////////////////////////////////// + +struct cvt_stream : public mstream { + int appi(int i); + int appf(double f); +}; + +/////////////////////////////////////////////////////////// + +struct fp_stream : public cvt_stream { + FILE* fp; + + int appc(char c); + int apps(const sref& s); + + fp_stream(FILE* f) : fp(f) {} + + int flush() { return fflush(fp); } +}; + +/////////////////////////////////////////////////////////// + +struct fd_stream : public cvt_stream { + int fd; + + int appc(char c); + int apps(const sref& s); + + fd_stream(int f) : fd(f) {} +}; + +/////////////////////////////////////////////////////////// + +struct pipe_stream : public cvt_stream { + int fd,hup; + + int appc(char c); + int apps(const sref& s); + + pipe_stream(int f) : fd(f),hup(0) {} + + int mwrite(const char* s,int n); +}; + +/////////////////////////////////////////////////////////// + +#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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include + +uniheap mstring::heap; + +/////////////////////////////////////////////////////////////////// + +mstring::mstring() : sref(heap.push(),0),caps(ms_mincaps) { + map[dim]=0; +} +mstring::mstring(int n) : sref(heap.push(),0),caps(ms_mincaps) { + if(caps=dim-pos) map[dim=pos]=0; + else { memmove(map+pos,map+pos+n,dim-pos-n); map[dim-=n]=0; } + } +} + +void mstring::reserve(int n) { + if(caps<=n) { + if(caps==ms_mincaps) { + while(caps<=n) caps<<=1; + char* p=(char*)memcpy(malloc(caps),map,dim); + heap.pop(map); + map=p; + } + else { + while(caps<=n) caps<<=1; + map=(char*)realloc(map,caps); + } + } +} + +/////////////////////////////////////////////////////////////////// + +int mstring::load(const mstring& path) +{ + int fd=open(path.c_str(),O_RDONLY); + if(fd<0) return -1; + struct stat fs; fstat(fd,&fs); + resize(fs.st_size); + read(fd,map,dim); + close(fd); + return dim; +} + +/////////////////////////////////////////////////////////////////// + +mstring& mstring::convert(const char* format,...) +{ + sref_t buf; + va_list ap; + va_start(ap,format); + resize(vsprintf(buf,format,ap)); + memcpy(map,buf,dim); + va_end(ap); + return *this; +} + +/////////////////////////////////////////////////////////////////// + +int swrite::appc(char c) { return mp->put(c),1; } +int swrite::apps(const sref& s) { return mp->put(s),s.size(); } + +/////////////////////////////////////////////////////////////////// + +int mswrite::appc(char c) { return m.put(c),1; } +int mswrite::apps(const sref& s) { return m.put(s),s.size(); } + +/////////////////////////////////////////////////////////////////// + +int merror_t::appc(char c) { return desc.put(c),1; } +int merror_t::apps(const sref& s) { return desc.put(s),s.size(); } + +/////////////////////////////////////////////////////////////////// + +void getline(mstring& m,FILE* fp,char end) +{ + m.clear(); + int c=getc(fp); + while(c!=end&&c!=EOF) { m.append(1,c); c=getc(fp); } +} + + 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef MSTRINGH +#define MSTRINGH + +#include +#include + +const int ms_mincaps=32; + +class mstring : public sref { +public: + mstring(); + explicit mstring(int n); + mstring(int n,char c); + mstring(const char* s); + mstring(const char* s,int n); + mstring(const sref& s); + mstring(const mstring& s); + ~mstring(); + + //////////////////////////////////////////////////////////////// + + const char* c_str() const { return map; } + int capacity() const { return caps; } + + void clear() { map[dim=0]=0; } + + int own(const sref& s) const { int p=s.data()-map; return p>=0&&p=caps) reserve(dim+1); map[dim++]=c; map[dim]=0; } + void put(const sref& s) { + reserve(dim+s.size()); + memcpy(map+dim,s.data(),s.size()); + map[dim+=s.size()]=0; + } + + mstring& append(int sdim,char c) { + reserve(dim+sdim); + memset(map+dim,c,sdim); + map[dim+=sdim]=0; + return *this; + } + + mstring& append(const sref& s) { + reserve(dim+s.size()); + memmove(map+dim,s.data(),s.size()); + map[dim+=s.size()]=0; + return *this; + } + + int insert(int pos,int n) { + if(pos<0||pos>dim) return 0; + if(n) { reserve(dim+n); memmove(map+pos+n,map+pos,dim-pos); map[dim+=n]=0; } + return 1; + } + + mstring& insert(int pos,int sdim,char c) { + if(insert(pos,sdim)) memset(map+pos,c,sdim); + return *this; + } + mstring& insert(int pos,const sref& s) { + if(insert(pos,s.size())) memcpy(map+pos,s.data(),s.size()); + return *this; + } + + mstring& replace(int pos,int n,int sdim,char c) { + if(insert(pos+n,sdim-n)) memset(map+pos,c,sdim); + return *this; + } + mstring& replace(int pos,int n,const sref& s) { + if(insert(pos+n,s.size()-n)) memcpy(map+pos,s.data(),s.size()); + return *this; + } + + //////////////////////////////////////////////////////////////// + + void erase(int pos,int n=-1); + void reserve(int n); + void resize(int n) { reserve(n); map[dim=n]=0; } + + //////////////////////////////////////////////////////////////// + + mstring& operator=(const mstring& s) { assign(s); return *this; } + mstring& operator=(const sref& s) { assign(s); return *this; } + mstring& operator=(char c) { assign(1,c); return *this; } + + mstring& operator+=(const sref& s) { return append(s); } + mstring& operator+=(char c) { return append(1,c); } + + //////////////////////////////////////////////////////////////// + + int load(const mstring& path); + + //////////////////////////////////////////////////////////////// + + // NOTE: if you apply convert to %s or any unbound data, + // you're in trouble. Internal buffer is sref_t. + + mstring& convert(const char* format,...); + +protected: + static uniheap heap; +private: + int caps; +}; + +/////////////////////////////////////////////////////////////////// + +inline void swap(mstring& a,mstring& b) +{ + char buf[sizeof(mstring)]; + memcpy(buf,&a,sizeof(mstring)); + memcpy(&a,&b,sizeof(mstring)); + memcpy(&b,buf,sizeof(mstring)); +} + +/////////////////////////////////////////////////////////////////// + +inline mstring operator+(const sref& a,const sref& b) +{ + return mstring(a).append(b); +} +inline mstring operator+(const sref& a,char b) { + return mstring(a).append(1,b); +} +inline mstring operator+(char a,const sref& b) { + return mstring(1,a).append(b); +} + +/////////////////////////////////////////////////////////////////// + +inline mstring btoa(int b) { return mstring(1,b?'1':'0'); } +inline mstring itoa(int i) { sref_t buf; return mstring(itoa(buf,i)); } +inline mstring ftoa(double f) { sref_t buf; return mstring(ftoa(buf,f)); } + +/////////////////////////////////////////////////////////////////// + +const mstring ms_empty; + +/////////////////////////////////////////////////////////////////// + +struct swrite : public cvt_stream { + mstring* mp; + + int appc(char c); + int apps(const sref& s); + + swrite() : mp(0) {} + swrite(mstring& m) : mp(&m) { mp->clear(); } + + swrite& operator()(mstring& m) { (mp=&m)->clear(); return *this; } + swrite& hold(mstring& m) { mp=&m; return *this; } +}; + +/////////////////////////////////////////////////////////////////// + +class mswrite : public cvt_stream { +public: + mstring m; + + int appc(char c); + int apps(const sref& s); + + const mstring& str() const { return m; } // compatibility + void clear() { m.clear(); } + + mswrite() : m() {} +private: + mswrite(mstring&) {} // make no mistakes due to similarity with swrite +}; + +/////////////////////////////////////////////////////////////////// + +struct merror_t : public cvt_stream { + int num; + mstring desc; + + int appc(char c); + int apps(const sref& s); + + merror_t(int n) : num(n),desc() {} +}; + +#define THROW(x) { merror_t merr(0); merr< +#include +#include + +const int mv_mincaps=16; + +template class mrvec { +public: + typedef T* iterator; + typedef const T* const_iterator; + + mrvec(): + map((T*)malloc(mv_mincaps*sizeof(T))),dim(0),caps(mv_mincaps) {} + mrvec(int n): + map((T*)malloc(mv_mincaps*sizeof(T))),dim(0),caps(mv_mincaps) { resize(n); } + ~mrvec() { free(map); } + + int size() const { return dim; } + int capacity() const { return caps; } + + bool empty() const { return dim==0; } + bool nempty() const { return dim!=0; } + + T& at(int pos) { return map[pos]; } + const T& at(int pos) const { return map[pos]; } + + T& operator[](int pos) { return map[pos]; } + const T& operator[](int pos) const { return map[pos]; } + + iterator begin() { return map; } + const_iterator begin() const { return map; } + + iterator end() { return map+dim; } + const_iterator end() const { return map+dim; } + + T& front() { return map[0]; } + const T& front() const { return map[0]; } + + T& back() { return map[dim?dim-1:0]; } + const T& back() const { return map[dim?dim-1:0]; } + + //////////////////////////////////////////////////////////////// + + void clear() { dim=0; } + + iterator insert(iterator it,const T& s) { + int pos=it-map; ins(pos,1); return &(map[pos]=s); + } + void insert(iterator it,int n,const T& s) { + int pos=it-map; ins(pos,n); while(n--) map[pos++]=s; + } + void insert(iterator it,const_iterator p,const_iterator e) { + int pos=it-map; ins(pos,e-p); while(p class msvec : public mrvec { +public: + using mrvec::map; + using mrvec::dim; + typedef typename mrvec::iterator iterator; + typedef typename mrvec::const_iterator const_iterator; + + msvec() : mrvec() {} + msvec(int n) : mrvec(n) { for(int i=0;i::ins(pos,1); return new(map+pos) T(s); + } + void insert(iterator it,int n,const T& s) { + int pos=it-map; mrvec::ins(pos,n); while(n--) new(map+pos++) T(s); + } + void insert(iterator it,const_iterator p,const_iterator e) { + int pos=it-map; mrvec::ins(pos,e-p); while(p~T(); int pos=it-map; mrvec::ins(pos+1,-1); return map+pos; + } + + void push_back(const T& s) { reserve(dim+1); new(map+dim++) T(s); } + void pop_back(const T& s) { if(dim) map[--dim].~T(); } + + //////////////////////////////////////////////////////////////// + + void resize(int n) { + while(dim>n) map[--dim].~T(); + mrvec::reserve(n); + while(dim + +inline double QUniform(unsigned long& q) { + q=1664525L*q+1013904223L; + unsigned long long s=q;s<<=20;s|=(1023ULL<<52);return *(double*)&s-1; +} +inline int QRanBit(unsigned long& q) { + if(q&131072U) { q=((q^19U)<<1)|1U; return 1; } + else { q<<=1; return 0; } +} + +#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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +////////////////////////////////////////////////////// +// +// This file implements some routines from NumRec +// + +const int NTAB=32; // NOTE: change in header if changing this + +const int IA=16807; +const int IM=2147483647; +const float AM=1/float(IM); +const int IQ=127773; +const int IR=2836; +const int NDIV=1+(IM-1)/NTAB; +const float EPS=1.2e-7; +const float RNMX=1-EPS; + +static int idum,iy,iv[32],flag; +static float extra; +static int inited; +static mutex_t mutex; + +unsigned long RandomInit(unsigned long seed) +{ + inited=1; + idum=seed?seed:1; + for(int j=NTAB+7;j>=0;j--) { + int k=idum/IQ; + idum=IA*(idum-k*IQ)-IR*k; + if(idum<0) idum+=IM; + if(jRNMX) temp=RNMX; + return temp; +} + +float Exponential() +{ + return -log(Uniform()); +} + +float Gaussian() +{ + MLOCK(mutex); + float v1,v2,rsq; + if(flag) { + flag=0; + return extra; + } else { + do { + v1=2*Uniform()-1; + v2=2*Uniform()-1; + rsq=v1*v1+v2*v2; + } while(rsq>=1||rsq<=0); + float fac=sqrt(-2*log(rsq)/rsq); + flag=1; extra=v1*fac; + return v2*fac; + } +} 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef RANDOMH +#define RANDOMH + +#include + +/////////////////////////////////////////////////////////////////// +// +// Uniform distribution ]x0..x1[ +// +// Granularity approx 1.2e-7, ie more than 1e6 different values +// Perodicity approx 1e8 +// + +unsigned long RandomInit(unsigned long seed); + +float Uniform(); +float Exponential(); +float Gaussian(); + +#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 @@ +ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +c +c HTCd - Copyright (C) 1998-2006 Henrik Rydberg +c +c This program is free software; you can redistribute it and/or modify +c it under the terms of the GNU General Public License as published by +c the Free Software Foundation; either version 2 of the License, or +c (at your option) any later version. +c +c This program is distributed in the hope that it will be useful, +c but WITHOUT ANY WARRANTY; without even the implied warranty of +c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +c GNU General Public License for more details. +c +c You should have received a copy of the GNU General Public License +c along with this program; if not, write to the Free Software +c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +c + + integer function rfind_not_of(s,n,c) + byte s(0:1),c(0:1) + integer i,m,n + m=mod(n,16) + do 10 i=n-16,m,-16 + if(c(s(i+15)).eq.0)go to 115 + if(c(s(i+14)).eq.0)go to 114 + if(c(s(i+13)).eq.0)go to 113 + if(c(s(i+12)).eq.0)go to 112 + if(c(s(i+11)).eq.0)go to 111 + if(c(s(i+10)).eq.0)go to 110 + if(c(s(i+9)).eq.0)go to 109 + if(c(s(i+8)).eq.0)go to 108 + if(c(s(i+7)).eq.0)go to 107 + if(c(s(i+6)).eq.0)go to 106 + if(c(s(i+5)).eq.0)go to 105 + if(c(s(i+4)).eq.0)go to 104 + if(c(s(i+3)).eq.0)go to 103 + if(c(s(i+2)).eq.0)go to 102 + if(c(s(i+1)).eq.0)go to 101 + if(c(s(i)).eq.0)go to 100 + 10 continue + do 20 i=m-1,0,-1 + if(c(s(i)).eq.0)go to 100 + 20 continue + rfind_not_of=-1 + return + 100 rfind_not_of=i + return + 101 rfind_not_of=i+1 + return + 102 rfind_not_of=i+2 + return + 103 rfind_not_of=i+3 + return + 104 rfind_not_of=i+4 + return + 105 rfind_not_of=i+5 + return + 106 rfind_not_of=i+6 + return + 107 rfind_not_of=i+7 + return + 108 rfind_not_of=i+8 + return + 109 rfind_not_of=i+9 + return + 110 rfind_not_of=i+10 + return + 111 rfind_not_of=i+11 + return + 112 rfind_not_of=i+12 + return + 113 rfind_not_of=i+13 + return + 114 rfind_not_of=i+14 + return + 115 rfind_not_of=i+15 + return + end + 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 @@ +ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +c +c HTCd - Copyright (C) 1998-2006 Henrik Rydberg +c +c This program is free software; you can redistribute it and/or modify +c it under the terms of the GNU General Public License as published by +c the Free Software Foundation; either version 2 of the License, or +c (at your option) any later version. +c +c This program is distributed in the hope that it will be useful, +c but WITHOUT ANY WARRANTY; without even the implied warranty of +c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +c GNU General Public License for more details. +c +c You should have received a copy of the GNU General Public License +c along with this program; if not, write to the Free Software +c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +c + + integer function rfind_of(s,n,c) + byte s(0:1),c(0:1) + integer i,m,n + m=mod(n,16) + do 10 i=n-16,m,-16 + if(c(s(i+15)).ne.0)go to 115 + if(c(s(i+14)).ne.0)go to 114 + if(c(s(i+13)).ne.0)go to 113 + if(c(s(i+12)).ne.0)go to 112 + if(c(s(i+11)).ne.0)go to 111 + if(c(s(i+10)).ne.0)go to 110 + if(c(s(i+9)).ne.0)go to 109 + if(c(s(i+8)).ne.0)go to 108 + if(c(s(i+7)).ne.0)go to 107 + if(c(s(i+6)).ne.0)go to 106 + if(c(s(i+5)).ne.0)go to 105 + if(c(s(i+4)).ne.0)go to 104 + if(c(s(i+3)).ne.0)go to 103 + if(c(s(i+2)).ne.0)go to 102 + if(c(s(i+1)).ne.0)go to 101 + if(c(s(i)).ne.0)go to 100 + 10 continue + do 20 i=m-1,0,-1 + if(c(s(i)).ne.0)go to 100 + 20 continue + rfind_of=-1 + return + 100 rfind_of=i + return + 101 rfind_of=i+1 + return + 102 rfind_of=i+2 + return + 103 rfind_of=i+3 + return + 104 rfind_of=i+4 + return + 105 rfind_of=i+5 + return + 106 rfind_of=i+6 + return + 107 rfind_of=i+7 + return + 108 rfind_of=i+8 + return + 109 rfind_of=i+9 + return + 110 rfind_of=i+10 + return + 111 rfind_of=i+11 + return + 112 rfind_of=i+12 + return + 113 rfind_of=i+13 + return + 114 rfind_of=i+14 + return + 115 rfind_of=i+15 + return + end + 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 @@ +ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +c +c HTCd - Copyright (C) 1998-2006 Henrik Rydberg +c +c This program is free software; you can redistribute it and/or modify +c it under the terms of the GNU General Public License as published by +c the Free Software Foundation; either version 2 of the License, or +c (at your option) any later version. +c +c This program is distributed in the hope that it will be useful, +c but WITHOUT ANY WARRANTY; without even the implied warranty of +c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +c GNU General Public License for more details. +c +c You should have received a copy of the GNU General Public License +c along with this program; if not, write to the Free Software +c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +c + + integer function scomptab(s,c,n,tab) + byte s(0:1),c(0:1),tab(0:1) + integer i,m,n + m=mod(n,4) + do 10 i=0,m-1 + if(tab(s(i)).ne.tab(c(i)))go to 100 + 10 continue + do 20 i=m,n-1,4 + if(tab(s(i)).ne.tab(c(i)))go to 100 + if(tab(s(i+1)).ne.tab(c(i+1)))go to 101 + if(tab(s(i+2)).ne.tab(c(i+2)))go to 102 + if(tab(s(i+3)).ne.tab(c(i+3)))go to 103 + 20 continue + scomptab=0 + return + 100 scomptab=tab(s(i))-tab(c(i)) + return + 101 scomptab=tab(s(i+1))-tab(c(i+1)) + return + 102 scomptab=tab(s(i+2))-tab(c(i+2)) + return + 103 scomptab=tab(s(i+3))-tab(c(i+3)) + return + end + 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 @@ +ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +c +c HTCd - Copyright (C) 1998-2006 Henrik Rydberg +c +c This program is free software; you can redistribute it and/or modify +c it under the terms of the GNU General Public License as published by +c the Free Software Foundation; either version 2 of the License, or +c (at your option) any later version. +c +c This program is distributed in the hope that it will be useful, +c but WITHOUT ANY WARRANTY; without even the implied warranty of +c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +c GNU General Public License for more details. +c +c You should have received a copy of the GNU General Public License +c along with this program; if not, write to the Free Software +c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +c + + subroutine sconvert(s,sn,tab) + byte s(0:1),tab(0:1) + integer i,m,sn + m=mod(sn,4) + do 10 i=0,m-1 + s(i)=tab(s(i)) + 10 continue + do 20 i=m,sn-1,4 + s(i)=tab(s(i)) + s(i+1)=tab(s(i+1)) + s(i+2)=tab(s(i+2)) + s(i+3)=tab(s(i+3)) + 20 continue + return + end + 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 @@ +ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +c +c HTCd - Copyright (C) 1998-2006 Henrik Rydberg +c +c This program is free software; you can redistribute it and/or modify +c it under the terms of the GNU General Public License as published by +c the Free Software Foundation; either version 2 of the License, or +c (at your option) any later version. +c +c This program is distributed in the hope that it will be useful, +c but WITHOUT ANY WARRANTY; without even the implied warranty of +c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +c GNU General Public License for more details. +c +c You should have received a copy of the GNU General Public License +c along with this program; if not, write to the Free Software +c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +c + + integer function sfind(s,sn,c,cn) + character s(0:1),c(0:1) + integer i,j,m,sn,cn + m=mod(cn,4) + do 10 i=0,sn-1 + do 20 j=0,m-1 + if(s(i+j).ne.c(j))go to 50 + 20 continue + do 30 j=m,cn-1,4 + if(s(i+j).ne.c(j))go to 50 + if(s(i+j+1).ne.c(j+1))go to 50 + if(s(i+j+2).ne.c(j+2))go to 50 + if(s(i+j+3).ne.c(j+3))go to 50 + 30 continue + 50 if(j.eq.cn)go to 100 + 10 continue + sfind=-1 + return + 100 sfind=i + return + 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 @@ +ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +c +c HTCd - Copyright (C) 1998-2006 Henrik Rydberg +c +c This program is free software; you can redistribute it and/or modify +c it under the terms of the GNU General Public License as published by +c the Free Software Foundation; either version 2 of the License, or +c (at your option) any later version. +c +c This program is distributed in the hope that it will be useful, +c but WITHOUT ANY WARRANTY; without even the implied warranty of +c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +c GNU General Public License for more details. +c +c You should have received a copy of the GNU General Public License +c along with this program; if not, write to the Free Software +c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +c + + integer function sfindtab(s,sn,c,cn,tab) + byte s(0:1),c(0:1),tab(0:1) + integer i,j,m,sn,cn + m=mod(cn,4) + do 10 i=0,sn-1 + do 20 j=0,m-1 + if(tab(s(i+j)).ne.tab(c(j)))go to 50 + 20 continue + do 30 j=m,cn-1,4 + if(tab(s(i+j)).ne.tab(c(j)))go to 50 + if(tab(s(i+j+1)).ne.tab(c(j+1)))go to 50 + if(tab(s(i+j+2)).ne.tab(c(j+2)))go to 50 + if(tab(s(i+j+3)).ne.tab(c(j+3)))go to 50 + 30 continue + 50 if(j.eq.cn)go to 100 + 10 continue + sfindtab=-1 + return + 100 sfindtab=i + return + 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 @@ +ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +c +c HTCd - Copyright (C) 1998-2006 Henrik Rydberg +c +c This program is free software; you can redistribute it and/or modify +c it under the terms of the GNU General Public License as published by +c the Free Software Foundation; either version 2 of the License, or +c (at your option) any later version. +c +c This program is distributed in the hope that it will be useful, +c but WITHOUT ANY WARRANTY; without even the implied warranty of +c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +c GNU General Public License for more details. +c +c You should have received a copy of the GNU General Public License +c along with this program; if not, write to the Free Software +c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +c + + integer function skip_parentesis(s,n,left,right,esc) + character s(0:1),left,right,esc + integer i,n,cnt + if(n.eq.0)go to 40 + if(s(0).ne.left)go to 40 + cnt=1 + do 10 i=1,n-1 + if(s(i-1).eq.esc)go to 10 + if(s(i).eq.right)then + cnt=cnt-1 + if(cnt.eq.0)go to 30 + else if(s(i).eq.left)then + cnt=cnt+1 + end if + 10 continue + 20 skip_parentesis=-1 + return + 30 skip_parentesis=i+1 + return + 40 skip_parentesis=0 + return + end + 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef MSPLITH +#define MSPLITH + +#include + +inline sref Skip(const sref& a,const charset& ws=cset_ws) { + return a.right_first_not_of(ws); +} + +inline sref Trim(const sref& a,const charset& ws=cset_ws) { + return a.right_first_not_of(ws).leftand_last_not_of(ws); +} + +inline sref Trim(const sref& a,const bracket& enc,const charset& ws=cset_ws) { + sref s=a.right_first_not_of(ws).leftand_last_not_of(ws); + while(s.nempty()&&s.skip(enc)==s.size()) + s=s(1,-3).right_first_not_of(ws).leftand_last_not_of(ws); + return s; +} + +inline sref First(const sref& a,const charset& ws=cset_ws) { + return a.right_first_not_of(ws).left_first_of(ws); +} + +inline sref Rest(const sref& a,const charset& ws=cset_ws) { + return a.right_first_not_of(ws).right_first_of(ws).right_first_not_of(ws); +} + +inline sref Last(const sref& a,const charset& ws=cset_ws) { + sref p=a.leftand_last_not_of(ws); + sref e=p.past_last_of(ws); + return e.nempty()?e:p; +} + +inline int Split(sref& first,sref& rest,const charset& ws=cset_ws) { + rest=rest.right_first_not_of(ws); + int s=rest.find_of(ws); + first=rest.left(s); + rest=rest.right(s); + return first.nempty(); +} + +inline int Splitln(sref& first,sref& rest) { + int s=rest.find_of(cset_newl); + first=rest.left(s); + rest=rest.right(s).past_nl(); + return first.begin()!=rest.begin(); +} + +typedef int (*split_t)(sref& first,sref& rest); + +#endif + 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 @@ +ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +c +c HTCd - Copyright (C) 1998-2006 Henrik Rydberg +c +c This program is free software; you can redistribute it and/or modify +c it under the terms of the GNU General Public License as published by +c the Free Software Foundation; either version 2 of the License, or +c (at your option) any later version. +c +c This program is distributed in the hope that it will be useful, +c but WITHOUT ANY WARRANTY; without even the implied warranty of +c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +c GNU General Public License for more details. +c +c You should have received a copy of the GNU General Public License +c along with this program; if not, write to the Free Software +c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +c + + integer function srfind(s,sn,c,cn) + character s(0:1),c(0:1) + integer i,j,m,sn,cn + m=mod(cn,4) + do 10 i=sn-1,0,-1 + do 20 j=0,m-1 + if(s(i+j).ne.c(j))go to 50 + 20 continue + do 30 j=m,cn-1,4 + if(s(i+j).ne.c(j))go to 50 + if(s(i+j+1).ne.c(j+1))go to 50 + if(s(i+j+2).ne.c(j+2))go to 50 + if(s(i+j+3).ne.c(j+3))go to 50 + 30 continue + 50 if(j.eq.cn)go to 100 + 10 continue + srfind=-1 + return + 100 srfind=i + return + 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 @@ +ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +c +c HTCd - Copyright (C) 1998-2006 Henrik Rydberg +c +c This program is free software; you can redistribute it and/or modify +c it under the terms of the GNU General Public License as published by +c the Free Software Foundation; either version 2 of the License, or +c (at your option) any later version. +c +c This program is distributed in the hope that it will be useful, +c but WITHOUT ANY WARRANTY; without even the implied warranty of +c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +c GNU General Public License for more details. +c +c You should have received a copy of the GNU General Public License +c along with this program; if not, write to the Free Software +c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +c + + integer function srfindtab(s,sn,c,cn,tab) + byte s(0:1),c(0:1),tab(0:1) + integer i,j,m,sn,cn + m=mod(cn,4) + do 10 i=sn-1,0,-1 + do 20 j=0,m-1 + if(tab(s(i+j)).ne.tab(c(j)))go to 50 + 20 continue + do 30 j=m,cn-1,4 + if(tab(s(i+j)).ne.tab(c(j)))go to 50 + if(tab(s(i+j+1)).ne.tab(c(j+1)))go to 50 + if(tab(s(i+j+2)).ne.tab(c(j+2)))go to 50 + if(tab(s(i+j+3)).ne.tab(c(j+3)))go to 50 + 30 continue + 50 if(j.eq.cn)go to 100 + 10 continue + srfindtab=-1 + return + 100 srfindtab=i + return + 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef STACKQUEH +#define STACKQUEH + +#include +#include + +template class stackque { +public: + stackque(int m) { + put=get=n=0; + base=new T[caps=m]; + memset(&mutex,0,sizeof(mutex_t)); + } + ~stackque() { delete base; } + + int push(const T& a) throw(merror_t) { + MLOCK(mutex); + if(n>=caps) THROW("stackque: Full"); + base[put++]=a; + if(put==caps) put=0; + return ++n; + } + + int pop(T& a) { + MLOCK(mutex); + if(n) { + a=base[get++]; + if(get==caps) get=0; + return n--; + } + else return 0; + } + + int capacity() const { return caps; } + int size() const { return n; } + int empty() const { return n==0; } + int full() const { return n==caps; } + void clear() { put=get=n=0; } +private: + int put,get,n,caps; + T* base; + mutex_t mutex; +}; + +#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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +extern "C" { + int cfind_(const char* s,const int& sn,const char& c); + int crfind_(const char* s,const int& sn,const char& c); + int sfind_(const char* s,const int& sn,const char* c,const int& cn); + int srfind_(const char* s,const int& sn,const char* c,const int& cn); + int sfindtab_(const char* s,const int& sn,const char* c,const int& cn,const char* tab); + int srfindtab_(const char* s,const int& sn,const char* c,const int& cn,const char* tab); + int scomptab_(const char* s,const char* c,const int& n,const char* tab); + void sconvert_(char* s,const int& sn,const char* tab); + int find_of__(const char* s,const int& sn,const char* set); + int rfind_of__(const char* s,const int& sn,const char* set); + int find_not_of__(const char* s,const int& sn,const char* set); + int rfind_not_of__(const char* s,const int& sn,const char* set); + int skip_parentesis__(const char* s,const int& sn, + const char& left,const char& right,const char& esc); + int strip_(char* s,const char* c,const int& cn,const char& esc); +} + +//////////////////////////////////////////////////// + +char* sref::copyto(char* buf,int max) const { + if(!dim) buf[0]=0; + else if(dim=dim) return sref(map+dim,0); + else { + if(n<0) { n+=dim+1; if(n<0) n=0; } + if(n>=dim-pos) return sref(map+pos,dim-pos); + else return sref(map+pos,n); + } +} + +sref sref::left(int n) const { + if(n<0) { n+=dim+1; if(n<0) n=0; } + if(n>dim) return sref(map,dim); + else return sref(map,n); +} +sref sref::leftand(int n,int m) const { + if(n<0) { n+=dim+1; if(n<0) n=0; } + if((n+=m)>dim) return sref(map,dim); + else return sref(map,n); +} +sref sref::right(int n) const { + if(n<0) { n+=dim+1; if(n<0) n=0; } + if(n>dim) return sref(map+dim,0); + else return sref(map+n,dim-n); +} +sref sref::past(int n,int m) const { + if(n<0) { n+=dim+1; if(n<0) n=0; } + if((n+=m)>dim) return sref(map+dim,0); + else return sref(map+n,dim-n); +} + +//////////////////////////////////////////////////////////////// + +int sref::find(char c) const { return cfind_(map,dim,c); } +int sref::rfind(char c) const { return crfind_(map,dim,c); } +int sref::find(const sref& s) const { return sfind_(map,dim,s.map,s.dim); } +int sref::rfind(const sref& s) const { return srfind_(map,dim,s.map,s.dim); } +int sref::find(const sref& s,const charmap& tab) const { + return sfindtab_(map,dim,s.map,s.dim,tab.map); +} +int sref::rfind(const sref& s,const charmap& tab) const { + return srfindtab_(map,dim,s.map,s.dim,tab.map); +} + +int sref::find_of(const charset& s) const { return find_of__(map,dim,s.map); } +int sref::rfind_of(const charset& s) const { return rfind_of__(map,dim,s.map); } +int sref::find_not_of(const charset& s) const { return find_not_of__(map,dim,s.map); } +int sref::rfind_not_of(const charset& s) const { return rfind_not_of__(map,dim,s.map); } + +int sref::skip(const bracket& bra) const { + return skip_parentesis__(map,dim,bra.left,bra.right,bra.esc); +} + +//////////////////////////////////////////////////////////////// + +int sref::save(const sref& s,int prot) const { + sref_t path; s.copyto(path); + int fd=open(path,O_WRONLY|O_CREAT,prot); + if(fd<0) return -1; + write(fd,map,dim); + close(fd); + return dim; +} 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef SREFH +#define SREFH + +#include +#include + +typedef char sref_t[1024]; + +class sref { +public: + sref() : map((char*)&dim),dim(0) {} + explicit sref(char* p) : map(p),dim(strlen(p)) {} + explicit sref(const char* p) : map((char*)p),dim(strlen(p)) {} + sref(char* p,int n) : map(p),dim(n) {} + sref(const char* p,int n) : map((char*)p),dim(n) {} + + int size() const { return dim; } + bool empty() const { return dim==0; } + bool nempty() const { return dim!=0; } + + char* data() { return map; } + const char* data() const { return map; } + + char& operator[](int pos) { return map[pos]; } + const char& operator[](int pos) const { return map[pos]; } + + char* begin() { return map; } + const char* begin() const { return map; } + + char* end() { return map+dim; } + const char* end() const { return map+dim; } + + int operator*() const { return dim?*map:0; } + int front() const { return dim?*map:0; } + int back() const { return dim?map[dim-1]:0; } + + //////////////////////////////////////////////////////////////// + + sref popf() const { return dim?sref(map+1,dim-1):*this; } + sref popb() const { return dim?sref(map,dim-1):*this; } + + sref adv(int n) const { return n>0?(n=(const sref& a,const sref& b) { + return a.compare(b)>=0; +} +inline bool operator>(const sref& a,const sref& b) { + return a.compare(b)>0; +} + +////////////////////////////////////////////////////////////////////////// + +inline int operator-(const sref& a,const sref& b) { return a.data()-b.data(); } + +////////////////////////////////////////////////////////////////////////// + +inline int ltn(const sref& a,const sref& b) { + return a.compare(b,cset_lcase)<0; +} +inline int len(const sref& a,const sref& b) { + return a.compare(b,cset_lcase)<=0; +} +inline int eqn(const sref& a,const sref& b) { + return a.compare(b,cset_lcase)==0; +} +inline int nen(const sref& a,const sref& b) { + return a.compare(b,cset_lcase)!=0; +} +inline int gen(const sref& a,const sref& b) { + return a.compare(b,cset_lcase)>=0; +} +inline int gtn(const sref& a,const sref& b) { + return a.compare(b,cset_lcase)>0; +} + +////////////////////////////////////////////////////////////////////////// + +inline int atob(const sref& s) { sref_t buf; return atoi(s.copyto(buf))!=0; } +inline int atoi(const sref& s) { sref_t buf; return atoi(s.copyto(buf)); } +inline double atof(const sref& s) { sref_t buf; return atof(s.copyto(buf)); } + +#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 @@ +ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc +c +c HTCd - Copyright (C) 1998-2006 Henrik Rydberg +c +c This program is free software; you can redistribute it and/or modify +c it under the terms of the GNU General Public License as published by +c the Free Software Foundation; either version 2 of the License, or +c (at your option) any later version. +c +c This program is distributed in the hope that it will be useful, +c but WITHOUT ANY WARRANTY; without even the implied warranty of +c MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +c GNU General Public License for more details. +c +c You should have received a copy of the GNU General Public License +c along with this program; if not, write to the Free Software +c Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +c + + integer function strip(s,c,cn,esc) + character s(0:1),c(0:1),esc + integer i,j,cn + j=0 + do 10 i=0,cn-1 + if(c(i).eq.esc)go to 10 + s(j)=c(i) + j=j+1 + 10 continue + strip=j + return + 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define GENERAL 0 +#define STREAM 1 +#define HEAPS 0 +#define CHARSET 0 +#define RANDOM 0 +#define LOOKUP 0 +#define ISSUE 1 +#define MSET 0 +#define CVTS 0 +#define VECTOR 0 +#define MSMAP 0 + +static fp_stream mout(stdout),merr(stderr); + +main(int argc,char* argv[]) +{ + mstring s; +#if GENERAL + s="asdfwerfindfindis?? asdf wert nnvnbn\n"; + + mout<<"["< stack; stack.init(); + for(int i=0;i<48;i++) { + //stack.pop(stack.push()); + stack.push(); + } + mout<<"--\n"; + mout< que(8); + for(int i=0;i<8;i++) que.push(i); + + try { + que.push(5); + } + catch(const merror_t& e) { + merr<"; + getline(ip,stdin); + IPnode node; + for(int i=0;i<4;i++) { + if(Lookup(node,ip)) { + merr< v(4); + for(int i=0;ifirst<<" "<second<<"\n"; + } + + const mstring* p=map.get("one"); + if(p) merr<<"got "<<*p<<"\n"; + +#endif + + return 0; +} 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef UNIHEAPH +#define UNIHEAPH + +#include +#include +#include + +// NOTE - must be in extern/static scope, or zeroed before use +// by a call to init. constructors will fail badly. +// A minimum of sizeof(T)==4 is required. +// Furthermore, the upper limit of heap space is 1Gb. + +template class uniheap { +public: + static const int maxchunks=24; + + void init() { + head=0; + chunk=0; + nchunks=0; + memset(&mutex,0,sizeof(mutex_t)); + } + + char* push() { MLOCK(mutex); char* p=news(); head=*(char**)p; return p; } + void pop(void* p) { MLOCK(mutex); *((char**)p)=head; head=(char*)p; } + int chunksize() const { return chunk; } +protected: + char* news() { + if(!head) { + if(!chunk) chunk=N<<4; + if(nchunks>=maxchunks) throw((int)0); + head=chunks[nchunks++]=(char*)malloc(chunk); + if(!head) throw((int)0); + for(int i=0;i + +static fp_stream merr(stderr); + +static mstring PATH; +static htcServ* SERV; + +const mstring PIDURI="/sys/htcd"; + +const int BACKLOG=4; +const int SERVERS=9; +const int LOWER=3; +const int UPPER=6; +const int KEEPALIVE=300; +const int SNDBUFSIZE=16384; +const int RCVBUFSIZE=16384; + +/////////////////////////////////////////////////////////// + +static thrServ* server[SERVERS]; +static thrCron* crontab; + +extern "C" { + static void* thr_handler(void* p) { ((thrServ*)p)->enter(); return 0; } + static void* thr_cron(void* p) { ((thrCron*)p)->enter(); return 0; } + static void onTERM(int sig) { SERV->htcd.running=0; } + static void onHUP(int sig) { if(crontab) crontab->running=0; } + typedef void (*disp_t)(int); +} + +static void MainProc(isocket& sock) +{ + int keep=1; + while(SERV->htcd.running) { + int nvacant=0; for(int i=0;ivacant()) nvacant++; + if(nvacant>UPPER) keep=1; else if(nvacant<=LOWER) keep=0; + if(!keep) for(int i=0;ishutdown(); + time_t timeout=time(0)-KEEPALIVE; + for(int i=0;iserver[i]->last) server[i]->disconnect(); + int test=sock.test(); + if(test>0) { + thrServ* p=0; + for(int i=0;ivacant()) { p=server[i]; break; } + if(!p) for(int i=0;ifirstfirst) p=server[i]; + if(p->shutdown()) { + try { + isocket* s=sock.accept(); + if(s) p->reset(s,keep); + } + catch(const merror_t& e) { + merr<<"SOCKET: "<htcd.running=0; + } + for(int i=0;iterm(); + pthread_join(server[i]->ptid,0); + } + pthread_kill(crontab->tid,SIGHUP); + pthread_join(crontab->ptid,0); +} + +/////////////////////////////////////////////////////////////// + +static void httpServer(int overport) +{ + isocket sock(SERV->htcd.node.addr,overport,BACKLOG); + sock.keepalive(1); + sock.sendbufsize(SNDBUFSIZE); + sock.recvbufsize(RCVBUFSIZE); + + sigignore(SIGPIPE); + disp_t onterm=signal(SIGTERM,onTERM); + disp_t onint=signal(SIGINT,onTERM); + disp_t onhup=signal(SIGHUP,onHUP); + MainProc(sock); + signal(SIGHUP,onhup); + signal(SIGINT,onint); + signal(SIGTERM,onterm); +} + +static void Daemon(int overport) try +{ + PROCLOCK(PATH+PIDURI); + SERV=new htcServ(PATH); + crontab=new thrCron(*SERV); + pthread_create(&crontab->ptid,0,thr_cron,crontab); + for(int i=0;iptid,0,thr_handler,server[i]); + } + merr<<"htcd: "<htcd.port:overport); + merr<<"htcd: "<htcd.errlog<<"["<htcd.errlog<<"["< [-1|0|1]\n"; + return -1; + } + PATH=argv[1]; if(PATH.back()=='/') PATH=PATH.popb(); + setenv("DOCROOT",PATH.c_str(),1); + int overport=atoi(argv[2]); + int cmd=argc>3?atoi(argv[3]):0; + if(cmd) ProcTerminate(PATH+PIDURI); + if(cmd>=0) { if(fork()==0) Daemon(overport); } + delete SERV; + return 0; +} +catch(const merror_t& e) { + merr<<"ERROR: ["< +#include + +isocket::isocket(const in_addr& ia,int port,int backlog): + pipe_stream(-1),rd(-1) +{ + if(port) { + fd=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP); + if(fd<0) THROW("isocket: Could not create"); + reuse(1); + } + else fd=0; + sa.sin_family=2; + sa.sin_port=htons(port); + sa.sin_addr=ia; + if(port) { + if(bind(fd,(sockaddr*)&sa,sizeof(sa))==-1) THROW("isocket: Could not bind"); + } + if(listen(fd,backlog)==-1) THROW("isocket: Could not listen"); + rd.setfd(fd); +} + +isocket::isocket(int f,const sockaddr_in& ia): + pipe_stream(f),rd(f) +{ + sa=ia; + setflag(O_NONBLOCK|O_NDELAY); + nodelay(1); +} + +isocket* isocket::accept() throw(merror_t) +{ + sockaddr_in tsa; socklen_t tsalen; + memset(&tsa,0,tsalen=sizeof(tsa)); + int tfd=::accept(fd,(sockaddr*)&tsa,&tsalen); + if(tfd>0) return new isocket(tfd,tsa); + if(errno!=EAGAIN) THROW("isocket: could not accept"); + return 0; +} 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef ISOCKETH +#define ISOCKETH + +#include +#include +#include +#include +#include +#include + +class isocket : public pipe_stream { +public: + isocket(const in_addr& ia,int port,int backlog); + isocket(int f,const sockaddr_in& ia); + ~isocket() { close(); } + + void close() { if(fd>=0) { ::close(fd); fd=-1; }} + + int getfd() const { return fd; } + int family() const { return sa.sin_family; } + int port() const { return ntohs(sa.sin_port); } + in_addr address() const { return sa.sin_addr; } + + void reuse(int ok) { set(SOL_SOCKET,SO_REUSEADDR,ok); } + void nodelay(int ok) { set(IPPROTO_TCP,TCP_NODELAY,ok); } + void keepalive(int ok) { set(SOL_SOCKET,SO_KEEPALIVE,ok); } + void sendbufsize(int s) { set(SOL_SOCKET,SO_SNDBUF,s); } + void recvbufsize(int s) { set(SOL_SOCKET,SO_RCVBUF,s); } + + isocket* accept() throw(merror_t); + + int test() { return rd.poll(); } + int getsome(char* s,int n) { return rd.read(s,n); } + int gethead(char* s,int n) { return rd.readpara(s,n); } + int getbody(char* s,int n) { return rd.readx(s,n); } + +protected: + void setflag(int f) { fcntl(fd,F_SETFL,f); } + int getflag() const { return fcntl(fd,F_GETFL,0); } + void set(int lev,int opt,int ok) throw(merror_t) { + if(setsockopt(fd,lev,opt,(char*)&ok,sizeof(ok))<0) + THROW("isocket: Could not set option"); + } +private: + sockaddr_in sa; + mread rd; +}; + +#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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +#include +#include +#include + +static fp_stream merr(stderr); +static IPnode NODE; +static int PORT; +static mstring URL,PATH,SERVER,URL1,URL2; +static int volatile RUNNING; + +const mstring REDIRECT="/tmp/redirect."; +const int BACKLOG=4; +const int SNDBUFSIZE=16384; +const int RCVBUFSIZE=16384; +const int MAXHEAD=16384; +const int SAFEZONE=4096; + +static void BreakURL() +{ + static const mstring pre="//"; + int p=URL.find(pre); + if(p>=0) { + p+=pre.size(); + int q=p+URL.right(p).find('/'); + if(q>=p) { + URL1=URL.left(q); + URL2=URL.right(q); + } + else { + URL1=URL; + URL2.clear(); + } + } + else throw(0); +} + +static mstring Combine(const sref& uri) +{ + const int ncvt=3; + static const mstring cvt[ncvt]={"/BODY","/en","/sv"}; + mstring d=uri; + mstring s=URL1; + for(int i=0;i=0) { + d.erase(p,cvt[i].size()); + s+=cvt[i]; + } + } + s+=URL2; + s+=d; + return s; +} + +static int Handle(isocket& sock) +{ + mstring buffer(MAXHEAD+SAFEZONE); + int nhead=sock.gethead(buffer.data(),MAXHEAD); + if(nhead<=0) return 0; + httpReq req(sref(buffer.data(),nhead)); + httpResp resp; + resp.status=HTTP_301; + //resp.location=URL+req.uri; + resp.location=Combine(req.uri); + if(req.arg.nempty()) { resp.location.append(1,'?'); resp.location+=req.arg; } + resp.putHead(sock); + putend(sock); + sock.close(); + return 1; +} + +/////////////////////////////////////////////////////////////// + +extern "C" { + static void onTERM(int sig) { RUNNING=0; } + typedef void (*disp_t)(int); +} + +static void MainProc(isocket& sock) +{ + RUNNING=1; + while(RUNNING) { + int test=sock.test(); + if(test>0) { + try { + isocket* s=sock.accept(); + if(s) Handle(*s); + } + catch(const merror_t& e) { + merr<<"SOCKET: "< "< [-1|0|1]\n"; + return -1; + } + sref s(argv[1]); + mstring host=s.left_last(':'); + mstring sport=s.past_last(':'); + if(sport.empty()) { + sport=host; + host.clear(); + } + PORT=atoi(sport); + URL=argv[2]; + if(URL.back()=='/') URL=URL.popb(); + BreakURL(); + if(host.empty()) { + struct utsname u; uname(&u); + host=u.nodename; + } + Lookup(NODE,host); + SERVER=NODE.name; SERVER.append(1,'-'); SERVER+=itoa(PORT); + PATH=REDIRECT; PATH+=SERVER; + int cmd=argc>3?atoi(argv[3]):0; + if(cmd) ProcTerminate(PATH); + if(cmd>=0) { if(fork()==0) Daemon(); } + return 0; +} +catch(const merror_t& e) { + merr<<"ERROR: ["< +#include +#include + +static fp_stream merr(stderr); +static IPnode NODE; +static mstring PATH; +static int PORT; + +const int BACKLOG=4; +const int SNDBUFSIZE=16384; +const int RCVBUFSIZE=16384; + +/////////////////////////////////////////////////////////////// + +static void MainProc(isocket& sock) +{ + int fd=dup2(sock.fd,0); + if(fd!=0) { merr<<"Not right\n"; return; } + execl("htcd","htcd",PATH.c_str(),"-1",0); +} + +/////////////////////////////////////////////////////////////// + +static void httpServer() +{ + isocket sock(NODE.addr,PORT,BACKLOG); + sock.keepalive(1); + sock.sendbufsize(SNDBUFSIZE); + sock.recvbufsize(RCVBUFSIZE); + MainProc(sock); +} + +main(int argc,char* argv[]) +{ + if(argc<3) { merr<<"Usage: "< \n"; return -1; } + PATH=argv[1]; if(PATH.back()=='/') PATH=PATH.popb(); + PORT=atoi(argv[2]); + struct utsname u; uname(&u); + Lookup(NODE,sref(u.nodename)); + httpServer(); + return 0; +} + + 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +const mstring SERVURI="/htc/server.htc"; + +htcServ::htcServ(const sref& path) : htcd(path),user(htcd.toks) +{ + Setup(user,htcd); + LoadBuffer(server,path+SERVURI); +} + +/////////////////////////////////////////////////////// + +static void Log(fp_stream& tlog,htcd_req& R,const sref& status) +{ + MLOCK(R.htcd()->mutex); + tlog<<"["<node.ip<<"][" + <node.name<<":"<port<<"][" + <method<<"][" + <uri<<"]["<arg<<"]\n"; + tlog.flush(); +} + +/////////////////////////////////////////////////////// + +int SendStatus(isocket& out,htcd_req& R,int keep,const sref& status,const sref& msg) +{ + R.resp.status=status; + if(atof(R.req->version.past_first(http_ver))method,HTTP_HEAD)) { + R.resp.cont_type.clear(); + R.resp.cont_length.clear(); + } + else { + if(R.resp.cont_type.empty()) R.resp.cont_type=http_mime_default; + R.resp.cont_length=itoa(msg.size()); + } + Log(R.htcd()->logger,R,status); + R.resp.putHead(out); + putend(out); + out< +#include +#include +#include +#include + +const mstring http_ver="HTTP/"; +const double http_minor=1.0,http_major=1.1; + +const mstring keep_tag="Keep-Alive"; +const mstring close_tag="Close"; +const mstring expect_continue_tag="100-continue"; + +struct htcServ { + HTCd htcd; + tokmap user; + mstring server; + htcServ(const sref& path); +}; + +int SendStatus(isocket& out,htcd_req& R,int keep, + const sref& status,const sref& msg=ms_empty); + +#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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +using namespace std; + +static mutex_t mutex; +static mtcond_t cond; + +static void* thread(void* a) +{ + cerr<<"thread "< +#include + +const mstring cron_tag="\\run.cron"; +const mstring FATAL="FATAL ERROR"; +const mstring UNKNOWN="UNKNOWN"; +const mstring REJECTED="REJECTED"; + +const int MAXHEAD=16384; +const int MAXBODY=2<<21; +const int MAXURI=4096; +const int MAXARG=4096; +const int SAFEZONE=4096; + +/////////////////////////////////////////////////////////////// + +thrServ::thrServ(htcServ& server): + pmutex(MUTEX_INIT), + pcond(MTCOND_INIT), + keepalive(0),running(0),termok(0), + first(time(0)),last(time(0)), + serv(&server), + sock(0), + user(server.user,server.htcd.docroot) +{ +} + +thrServ::~thrServ() +{ + delete sock; +} + +void thrServ::reset(isocket* s,int keep) +{ + keepalive=keep; + running=1; + termok=0; + first=time(0); + last=time(0); + sock=s; + while(!tid); + if(MCONTINUE(pcond)) throw((int)0); +} + +void thrServ::Log(const sref& msg) +{ + MLOCK(serv->htcd.mutex); + if(sock) serv->htcd.errlog<<"["<address())<<":"<port()<<"][" + <htcd.errlog<<"["<htcd.errlog.flush(); +} + +void thrServ::enter() +{ + tid=pthread_self(); + MSUSPEND(pmutex,pcond) + while(serv->htcd.running&&!termok) { + session(); + delete sock; + sock=0; + if(serv->htcd.running&&!termok) { + MSUSPEND(pmutex,pcond) + } + } +} + +void thrServ::session() try +{ + int keep=1; + while(sock&&keep&&running) { + int test=sock->test(); + if(test>0) { last=time(0); keep=handle(); } + else if(test<0) keep=0; + } +} +catch(const merror_t& e) { + Log(e.desc); +} +catch(...) { + Log(FATAL); +} + +/////////////////////////////////////////////////////////////// + +thrCron::thrCron(htcServ& server): + tid(0),running(0),serv(&server),user(server.user,server.htcd.docroot) +{ +} + +void thrCron::Log(const sref& msg) +{ + MLOCK(serv->htcd.mutex); + serv->htcd.errlog<<"["<htcd.errlog.flush(); +} + +void thrCron::enter() try +{ + tid=pthread_self(); + tcpReq tcp; tcp.port=0; + httpReq req; + mstream devnull; + htcd_req R(serv->htcd,user.toks,devnull,tcp,req); + Env env(serv->htcd.ops,R,XSYSTEM); + env.req->running=&running; + running=1; + mstream m; + env.parse(m,cron_tag); +} +catch(const merror_t& e) { + Log(e.desc); +} +catch(...) { + Log(FATAL); +} + + +/////////////////////////////////////////////////////////////// + +int thrServ::handle() +{ + tcpReq tcp; + tcp.port=sock->port(); + if(!Lookup(tcp.node,sock->address())) { + Log(REJECTED); + return 0; + } + + ////////////////////////////////////////////////////////////////// + + mstring buffer(MAXHEAD+MAXBODY+SAFEZONE); + int nhead=sock->gethead(buffer.data(),MAXHEAD); + if(nhead==0) return 0; + else if(nhead<0) return 0; + + sref message(buffer.data(),nhead); + +#if 0 + static fp_stream merr(stderr); + merr<<"QQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQQ\n"; + merr<htcd,user.toks,cache,tcp,req); + + ////////////////////////////////////////////////////////////////// + + if(nhead>=MAXHEAD) return SendStatus(*sock,R,keep,HTTP_413); + + if(eqn(req.method,HTTP_TRACE)) { + R.resp.cont_type="message/http"; + return SendStatus(*sock,R,keep,HTTP_200,buffer.left(nhead)); + } + + if(req.expect.nempty()) { + if(eqn(req.expect,expect_continue_tag)) SendStatus(*sock,R,keep,HTTP_100); + else return SendStatus(*sock,R,keep,HTTP_417); + } + + if(req.trans_enc.nempty()||req.cont_enc.nempty()) return SendStatus(*sock,R,0,HTTP_501); + + ////////////////////////////////////////////////////////////////// + + int ilength=atoi(req.cont_length); + if(ilength>MAXBODY) return SendStatus(*sock,R,0,HTTP_413); + else if(ilength>0) { + int nbody=sock->getbody(buffer.data()+nhead,ilength); + if(nbody<0) return 0; + else { + sref sbody(buffer.data()+nhead,nbody); +#if 0 + static fp_stream merr(stderr); + merr<<"PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP\n"; + merr<htcd.ops,R,XSYSTEM); + env.req->running=&running; + mstream m; + env.parse(m,serv->server); + if(!env.req->is_running()) THROW("htc: "< +#include +#include + +//////////////////////////////////////////////////////// +// +// MT - safe +// Note that mutexes aren't needed here, since control +// is flowing from main to child, with possible child +// override in local variables. + +struct thrServ { + pthread_t ptid; + mutex_t pmutex; + mtcond_t pcond; + volatile int tid,keepalive,running,termok; + time_t first,last; + htcServ* serv; + isocket* sock; + htcd_user user; + + thrServ(htcServ& server); + ~thrServ(); + + void Log(const sref& msg); + void reset(isocket* s,int keep); + + int vacant() const { return sock==0; } + int shutdown() { keepalive=0; return sock==0; } + void disconnect() { keepalive=0; running=0; } + void term() { + keepalive=0; + running=0; + termok=1; + MCONTINUE(pcond); + } + + void enter(); + void session(); + int handle(); +}; + +//////////////////////////////////////////////////////// + +struct thrCron { + pthread_t ptid; + volatile int tid,running; + htcServ* serv; + htcd_user user; + + thrCron(htcServ& server); + + void Log(const sref& msg); + void enter(); +}; + +#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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +OP1_IMPL(exp) { out<>atoi(R));} + +OP1_IMPL(bitnot) {out<<~atoi(a);} +OP2_IMPL(bitand) {out<<(atoi(L)&atoi(R)); } +OP2_IMPL(bitor) {out<<(atoi(L)|atoi(R)); } +OP2_IMPL(bitxor) {out<<(atoi(L)^atoi(R)); } + +OP2_IMPL(SP) {out<>, + "C style\n" + "Shift right\n" + "Syntax: (int) >> (int)\n" + "Returns: (int)\n" + ); + + OP_ADD(18,eq, + "Lexicographic equal\n" + "Syntax: (string) eq (string)\n" + "Returns: (int)\n" + ); + OP_ADD(18,eqn, + "Lexicographic equal, case insensitive\n" + "Syntax: (string) eqn (string)\n" + "Returns: (int)\n" + ); + OP_ADDN(18,eqf,==, + "Arithmetic equal\n" + "Syntax: (real) == (real)\n" + "Returns: (int)\n" + ); + OP_ADD(18,ne, + "Lexicographic not equal\n" + "Syntax: (string) ne (string)\n" + "Returns: (int)\n" + ); + OP_ADD(18,nen, + "Lexicographic not equal, case insensitive\n" + "Syntax: (string) nen (string)\n" + "Returns: (int)\n" + ); + OP_ADDN(18,nef,!=, + "Arithmetic not equal\n" + "Syntax: (real) != (real)\n" + "Returns: (int)\n" + ); + + OP_ADDN(16,bitand,&, + "C style\n" + "Bitwise AND\n" + "Syntax: (int) & (int)\n" + "Returns: (int)\n" + ); + OP_ADDN(14,bitxor,^, + "C style\n" + "Bitwise XOR\n" + "Syntax: (int) ^ (int)\n" + "Returns: (int)\n" + ); + OP_ADDN(12,bitor,|, + "C style\n" + "Bitwise OR\n" + "Syntax: (int) | (int)\n" + "Returns: (int)\n" + ); + + OP_ADDN(10,and,&&, + "C style\n" + "Logical AND\n" + "Syntax: (int) && (int)\n" + "Returns: (int)\n" + ); + OP_ADDN(9,xor,^^, + "Logical XOR\n" + "Syntax: (int) ^^ (int)\n" + "Returns: (int)\n" + ); + OP_ADDN(8,or,||, + "C style\n" + "Logical OR\n" + "Syntax: (int) || (int)\n" + "Returns: (int)\n" + ); + + /* + OP_ADD(3,SP, + "Whitespace padding\n" + "Syntax: a ws OR ws a OR a ws b\n" + "Returns: a b\n" + ); + */ + + M.add(new op_t(",",2,impl_comma, + "C style\n" + "Separate expression\n" + "Syntax: a , b\n" + "Returns: b\n" + )); + OP_ADD2(1,1,semi,;, + "C style\n" + "End expression\n" + "Syntax: a ; OR a ; b\n" + "Returns: nothing\n" + ); +} 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +OP2_IMPL(lt) {out<<(L=R);} +OP2_IMPL(gt) {out<<(L>R);} +OP2_IMPL(ltn) {out<<(L.compare(R,cset_lcase)<0);} +OP2_IMPL(len) {out<<(L.compare(R,cset_lcase)<=0);} +OP2_IMPL(gen) {out<<(L.compare(R,cset_lcase)>=0);} +OP2_IMPL(gtn) {out<<(L.compare(R,cset_lcase)>0);} +OP2_IMPL(ltnn) {out<<(nncomp(L,R)<0);} +OP2_IMPL(lenn) {out<<(nncomp(L,R)<=0);} +OP2_IMPL(genn) {out<<(nncomp(L,R)>=0);} +OP2_IMPL(gtnn) {out<<(nncomp(L,R)>0);} +OP2_IMPL(ltf) {out<<(atof(L)=atof(R));} +OP2_IMPL(gtf) {out<<(atof(L)>atof(R));} + +void opAddComp(opmap& M) +{ + OP_ADD(20,lt, + "Lexicographic less than\n" + "Syntax: (string) lt (string)\n" + "Returns: (int)\n" + ); + OP_ADD(20,le, + "Lexicographic less or equal\n" + "Syntax: (string) le (string)\n" + "Returns: (int)\n" + ); + OP_ADD(20,ge, + "Lexicographic greater or equal\n" + "Syntax: (string) ge (string)\n" + "Returns: (int)\n" + ); + OP_ADD(20,gt, + "Lexicographic greater than\n" + "Syntax: (string) gt (string)\n" + "Returns: (int)\n" + ); + + OP_ADD(20,ltn, + "Lexicographic less than, case insensitive\n" + "Syntax: (string) ltn (string)\n" + "Returns: (int)\n" + ); + OP_ADD(20,len, + "Lexicographic less or equal, case insensitive\n" + "Syntax: (string) len (string)\n" + "Returns: (int)\n" + ); + OP_ADD(20,gen, + "Lexicographic greater or equal, case insensitive\n" + "Syntax: (string) gen (string)\n" + "Returns: (int)\n" + ); + OP_ADD(20,gtn, + "Lexicographic greater than, case insensitive\n" + "Syntax: (string) gtn (string)\n" + "Returns: (int)\n" + ); + + OP_ADD(20,ltnn, + "Lexicographic less than, NN-style\n" + "Syntax: (string) ltnn (string)\n" + "Returns: (int)\n" + "\n" + "NN-style compares names as \n" + ); + OP_ADD(20,lenn, + "Lexicographic less or equal, NN-style\n" + "Syntax: (string) lenn (string)\n" + "Returns: (int)\n" + "\n" + "NN-style compares names as \n" + ); + OP_ADD(20,genn, + "Lexicographic greater or equal, NN-style\n" + "Syntax: (string) genn (string)\n" + "Returns: (int)\n" + "\n" + "NN-style compares names as \n" + ); + OP_ADD(20,gtnn, + "Lexicographic greater than, NN-style\n" + "Syntax: (string) gtnn (string)\n" + "Returns: (int)\n" + "\n" + "NN-style compares names as \n" + ); + + OP_ADDN(20,ltf,<, + "Arithmetic less than\n" + "Syntax: (real) < (real)\n" + "Returns: (int)\n" + ); + OP_ADDN(20,lef,<=, + "Arithmetic less or equal\n" + "Syntax: (real) <= (real)\n" + "Returns: (int)\n" + ); + OP_ADDN(20,gef,>=, + "Arithmetic greater or equal\n" + "Syntax: (real) >= (real)\n" + "Returns: (int)\n" + ); + OP_ADDN(20,gtf,>, + "Arithmetic greater than\n" + "Syntax: (real) > (real)\n" + "Returns: (int)\n" + ); + +} 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +const mstring sp_tag="SP"; + +//////////////////////////////////////////////////////////////// + +uniheap expr_t::tree; +void* expr_t::operator new(size_t n) { return tree.push(); } +void expr_t::operator delete(void* p) { tree.pop(p); } + +//////////////////////////////////////////////////////////////// + +inline int precedence(const expr_t* root,const op_t* op) +{ + if(!root->op) return 1; + else if(!op) return 0; + else if(root->left) { + if(root->right) return op->pre2&&root->op->pre2>=op->pre2; + else return root->op->pre2>=op->pre1; + } + else { + if(root->right) return op->pre2&&root->op->pre1>=op->pre2; + else return root->op->pre1>=op->pre1; + } +} + +static int ins_node_sp(expr_t*& root,op_env& env, + const sref& in,const op_t* op) throw(merror_t) +{ + if(root==0) { root=new expr_t(in,op); root->expand(env); return 1; } + else if(precedence(root,op)) { + if(op) { root=new expr_t(in,op,root); return 1; } else return 0; + } + else return ins_node_sp(root->right,env,in,op); +} + +static void ins_node(expr_t*& root,op_env& env,const sref& in) throw(merror_t) +{ + const op_t* op=env.ops->get(in); + if(!ins_node_sp(root,env,in,op)) { + if(!ins_node_sp(root,env,sp_tag,env.ops->get(sp_tag))) + THROW("ops: ("<expr<<" ["<trav(out,n-1); + for(int i=0;i<3*n;i++) out.put(' '); + out<<"["< "<trav(out,n-1); +} + +void expr_t::expand(op_env& env) throw(merror_t) +{ + if(!op) { + sref first,rest=expr; + env.split(first,rest); + if(first!=expr) { + do ins_node(right,env,first); + while(env.split(first,rest)); + } + } +} + +/////////////////////////////////////////////////////////////// + +void expr_t::eval(mstream& out,op_env& env,int opt) throw(merror_t) +{ + if(op) { + if(left) { + if(op->left>1) { + if(left->status&opt) { + swrite sw(left->result); + left->eval(sw,env,opt); + } + } + else if(!op->left) + THROW("ops: ("<expr<<" ["<op) + THROW("ops: (["<expr<<"] "<status=OP_LOCAL; + left->result=left->expr; + } + } + if(right) { + if(op->right>1) { + if(right->status&opt) { + swrite sw(right->result); + right->eval(sw,env,opt); + } + } + else if(!op->right) + THROW("ops: ("<expr<<" ["<op) + THROW("ops: (["<expr<<"] "<status=OP_LOCAL; + right->result=right->expr; + } + } + if(left) { + if(right) { + status=left->status|right->status; + if((status&OP_NINIT)==0) op->f2(out,env,left->result,right->result); + } + else if(!op->f1) + THROW("ops: ("<expr<<" "<status; + if((status&OP_NINIT)==0) op->f1(out,env,left->result); + } + } + else if(right) { + if(!op->f1) + THROW("ops: ([L] "<expr<<"): missing L argument") + else { + status=right->status; + if((status&OP_NINIT)==0) op->f1(out,env,right->result); + } + } + else THROW("ops: ["<eval(out,env,opt); + status=right->status; + } + else env.term(out,this); + } + if(status&OP_NINIT) THROW("ops: unfinished expression ["< +#include +#include + +const int OP_LOCAL=1; +const int OP_GLOBAL=2; +const int OP_NINIT=4; +const int OP_ALL=OP_LOCAL|OP_GLOBAL|OP_NINIT; + +class expr_t { +public: + sref expr; + const op_t* op; + int status; + mstring result; + expr_t *left,*right; + + expr_t(): + expr(),op(0),status(OP_ALL),result(),left(0),right(0) {} + expr_t(const expr_t& x): + expr(),op(0),status(OP_ALL),result(),left(0),right(0) { copy(x); } + expr_t(const sref& s): + expr(s),op(0),status(OP_ALL),result(),left(0),right(0) {} + expr_t(const sref& s,const op_t* o): + expr(s),op(o),status(OP_ALL),result(),left(0),right(0) {} + expr_t(const sref& s,const op_t* o,expr_t* p): + expr(s),op(o),status(OP_ALL),result(),left(p),right(0) {} + ~expr_t() { delete left; delete right; } + + void clear(); + expr_t& operator=(const expr_t& x) { clear(); copy(x); return *this; } + expr_t& operator=(const sref& in) { clear(); expr=in; return *this; } + + void trav(mstream& out,int n); + void expand(op_env& env) throw(merror_t); + void eval(mstream& out,op_env& env,int opt) throw(merror_t); + + static void* operator new(size_t n); + static void operator delete(void* p); +protected: + void copy(const expr_t& x); + static uniheap<36> tree; +}; + +//////////////////////////////////////////////////////////// + +struct op_env { + opmap* ops; + + op_env() : ops(0) {} + op_env(opmap& map) : ops(&map) {} + + virtual int split(sref& first,sref& rest) throw(merror_t) { return 0; } + virtual void term(mstream& out,expr_t* x) throw(merror_t) { x->status=0; } +}; + +#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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include + +OP1_IMPL(minus) {out<<"-"<"<";} +OP1_IMPL(pow) {out<<""<";} +OP2_IMPL(sub) {out<"<";} +OP1_IMPL(sub) {out<<""<";} +OP2_IMPL(div) {out<"<=,"greater or equal"); + OP_ADDN(20,gt,>,"greater than"); + + OP_ADDN(18,eq,==,"equal"); + OP_ADDN(18,ne,!=,"not equal"); + OP_ADDN(18,equiv,===,"equivalent"); + OP_ADDN(18,sim,~,"similar"); + OP_ADDN(18,simeq,~=,"similar equal"); + + OP_ADD(10,and,"logic and"); + OP_ADD(9,xor,"logic xor"); + OP_ADD(8,or,"logic or"); + + OP_ADDN(4,assign,=,"assignment"); + + OP_ADD(3,SP,"Whitespace padding"); + + OP_ADD2(1,1,semi,;,"concatenation"); +} 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef NNSTYLEH +#define NNSTYLEH + +#include + +const charset cset_wsdot=cset_ws|'.'; + +inline mstring nncase(const sref& b) +{ + static const mstring comma_tag(","),and_tag("and"); + mstring acc,a,name; + sref next,first,rest=b; + while(Split(first,rest,cset_wsdot)) { + if(first==comma_tag||eqn(first,and_tag)) continue; + (name=first.left_first(comma_tag)).tosim(); + name[0]=cset_ucase[name[0]]; + next=First(rest); + if(first.back()==','||next.empty()||*next==','||eqn(next,and_tag)) { + a.insert(0,name); + if(acc.nempty()) { acc+=' '; acc+=and_tag; acc+=' '; } + acc+=a; + a.clear(); + } + else { a+=' '; a+=name[0]; a+='.'; } + } + return acc; +} + +inline int nncomp(const sref& L,const sref& R) +{ + return nncase(L).compare(nncase(R)); +} + +#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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +using namespace std; + +void opmap::clear() { + for(iterator p=begin();p!=end();p++) delete *p; + mrvec::clear(); +} +void opmap::erase(iterator p) { + delete *p; mrvec::erase(p); +} + +const op_t* opmap::get(const sref& t) const +{ + pair p= + equal_range(begin(),end(),(opmap_t)0,comp_t(t)); + return p.first!=p.second?*p.first:0; +} + +const op_t* opmap::add(op_t* op) +{ + pair p=equal_range(begin(),end(),(opmap_t)0,comp_t(op->name)); + if(p.first!=p.second) { delete *p.first; return *p.first=op; } + else return *insert(p.second,op); +} 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef OPERATORH +#define OPERATORH + +#include +#include + +const mstring lt_tag="lt"; + +/////////////////////////////////////////////// + +class op_env; +struct op_t { + typedef void (*op1_t)(mstream&,op_env&,const sref&); + typedef void (*op2_t)(mstream&,op_env&,const sref&,const sref&); + + mstring name,desc; + int pre1,pre2; + int left,right; + op1_t f1; op2_t f2; + + op_t(const mstring& s,int p1,int p2,int l,int r,op1_t op1,op2_t op2,const mstring& d): + name(s),pre1(p1),pre2(p2),left(l),right(r),f1(op1),f2(op2),desc(d) {} + op_t(const mstring& s,int p1,int p2,op1_t op1,op2_t op2,const mstring& d): + name(s),pre1(p1),pre2(p2),left(2),right(2),f1(op1),f2(op2),desc(d) {} + op_t(const mstring& s,int p,op1_t op,const mstring& d): + name(s),pre1(p),pre2(0),left(0),right(2),f1(op),f2(0),desc(d) {} + op_t(const mstring& s,int p,op2_t op,const mstring& d): + name(s),pre1(0),pre2(p),left(2),right(2),f1(0),f2(op),desc(d) {} +}; + +#define OP1_IMPL(n) \ +static void impl_##n(mstream& out,op_env& env,const sref& a) +#define OP2_IMPL(n) \ +static void impl_##n(mstream& out,op_env& env,const sref& L,const sref& R) + +//////////////////////////////////////////////////////////// + +typedef op_t* opmap_t; + +struct opmap : public mrvec { + typedef mrvec::iterator iterator; + typedef mrvec::const_iterator const_iterator; + + struct comp_t { + sref key; + comp_t(const sref& skey) : key(skey) {} + bool operator()(const op_t* a,const op_t* b) const { + return (a?((const sref&)a->name):key)<(b?((const sref&)b->name):key); + } + }; + + opmap() : mrvec() {} + ~opmap() { clear(); } + + void clear(); // overrides parent + void erase(iterator p); // overrides parent + + const op_t* get(const sref& t) const; + const op_t* add(op_t* op); +}; + +#define OP_ADD(p,f,d) M.add(new op_t(#f,p,impl_##f,d)) +#define OP_ADDN(p,f,n,d) M.add(new op_t(#n,p,impl_##f,d)) +#define OP_ADD2(p1,p2,f,n,d) M.add(new op_t(#n,p1,p2,impl_##f,impl_##f,d)) + +/////////////////////////////////////////// + +void opAddBasic(opmap& map); +void opAddComp(opmap& map); +void opAddString(opmap& map); +inline void opAddHEXP(opmap& map) { + opAddBasic(map); + opAddComp(map); + opAddString(map); +} +void opAddLatex(opmap& map); + +#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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include + +OP2_IMPL(intersect) { mset a(L),b(R),c; c.Intersection(a,b); out<0&&Split(first,rest)); + out<=0);} +OP2_IMPL(cntn) {out<<(L.find(R,cset_lcase)>=0);} + +OP2_IMPL(concat) {out< \n" + ); + OP_ADD(32,skipws, + "Skip whitespace\n" + "Syntax: skipws (string)\n" + "Returns: (string)\n" + "\n" + "Skips trailing whitespace\n" + ); + + OP_ADD(32,first, + "First element in list\n" + "Syntax: first (list)\n" + "Returns: (string)\n" + "\n" + "Elements are separated by whitespace\n" + ); + OP_ADD(32,last, + "Last element in list\n" + "Syntax: last (list)\n" + "Returns: (string)\n" + "\n" + "Elements are separated by whitespace\n" + ); + OP_ADD(32,rest, + "Rest of elements in list\n" + "Syntax: rest (list)\n" + "Returns: (list)\n" + "\n" + "Elements are separated by whitespace\n" + ); + OP_ADD(32,count, + "Count elements in list\n" + "Syntax: count (list)\n" + "Returns: (int)\n" + "\n" + "Elements are separated by whitespace\n" + ); + + OP_ADD(30,nth, + "Nth element in list\n" + "Syntax: (list) nth (int)\n" + "Returns: (string)\n" + "\n" + "First element is denoted 1\n" + "Elements out of range returns empty\n" + "Elements are separated by whitespace\n" + ); + OP_ADD(30,which, + "Which element in list\n" + "Syntax: (list) a which (string) b\n" + "Returns: (int)\n" + "\n" + "Which element in a is b (0 if not found)\n" + "First element is denoted 1\n" + "Elements are separated by whitespace\n" + ); + + OP_ADD(28,left, + "Left of substring\n" + "Syntax: (string) a left (string) b\n" + "Returns: (string)\n" + "\n" + "Everything in a to the left of first b, of a if b not found in a\n" + ); + OP_ADD(28,leftand, + "Left of substring inclusive\n" + "Syntax: (string) a leftand (string) b\n" + "Returns: (string)\n" + "\n" + "Everything in a to the left of first b inclusive, of a if b not found in a\n" + ); + OP_ADD(28,right, + "Right of substring inclusive\n" + "Syntax: (string) a right (string) b\n" + "Returns: (string)\n" + "\n" + "Everything in a to the right of first b inclusive, of empty if b not found in a\n" + ); + OP_ADD(28,past, + "Right of substring\n" + "Syntax: (string) a past (string) b\n" + "Returns: (string)\n" + "\n" + "Everything in a to the right of first b, of empty if b not found in a\n" + ); + + OP_ADD(28,rleft, + "Left of substring (reversed)\n" + "Syntax: (string) a rleft (string) b\n" + "Returns: (string)\n" + "\n" + "Everything in a to the left of last b, of a if b not found in a\n" + ); + OP_ADD(28,rleftand, + "Left of substring inclusive, (reversed)\n" + "Syntax: (string) a rleftand (string) b\n" + "Returns: (string)\n" + "\n" + "Everything in a to the left of last b inclusive, of a if b not found in a\n" + ); + OP_ADD(28,rright, + "Right of substring inclusive (reversed)\n" + "Syntax: (string) a rright (string) b\n" + "Returns: (string)\n" + "\n" + "Everything in a to the right of last b inclusive, of empty if b not found in a\n" + ); + OP_ADD(28,rpast, + "Right of substring (reversed)\n" + "Syntax: (string) a rpast (string) b\n" + "Returns: (string)\n" + "\n" + "Everything in a to the right of last b, of empty if b not found in a\n" + ); + + OP_ADDN(24,concat,++, + "String concatenation\n" + "Syntax: (string) ++ (string)\n" + "Returns: (string)\n" + ); + OP_ADDN(24,concats,+++, + "List concatenation\n" + "Syntax: (list) +++ (list)\n" + "Returns: (list)\n" + "\n" + "Lists are concatenated with space\n" + ); + + OP_ADD(18,cnt, + "Contains substring\n" + "Syntax: (string) a cnt (string) b\n" + "Returns: (int)\n" + "\n" + "Nonzero if b found in a\n" + ); + OP_ADD(18,cntn, + "Contains substring, case insensitive\n" + "Syntax: (string) a cnt (string) b\n" + "Returns: (int)\n" + "\n" + "Nonzero if b found in a\n" + ); + OP_ADD(18,eqnn, + "NN-style equal\n" + "Syntax: (string) eqnn (string)\n" + "Returns: (int)\n" + "\n" + "NN-style converts names to \n" + ); + OP_ADD(18,nenn, + "NN-style not equal\n" + "Syntax: (string) eqnn (string)\n" + "Returns: (int)\n" + "\n" + "NN-style converts names to \n" + ); + + OP_ADDN(10,intersect,&&&, + "List intersection\n" + "Syntax: (list) a &&& (list) b\n" + "Returns: (list)\n" + "\n" + "Finds the set intersection of a and b\n" + ); + OP_ADDN(9,difference,---, + "List difference\n" + "Syntax: (list) a &&& (list) b\n" + "Returns: (list)\n" + "\n" + "Finds the set difference of a and b\n" + ); + OP_ADDN(9,union,|||, + "List union\n" + "Syntax: (list) a &&& (list) b\n" + "Returns: (list)\n" + "\n" + "Finds the set union of a and b\n" + ); +} 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 @@ +/************************************************************************* + * + * HTCd - Copyright (C) 1998-2006 Henrik Rydberg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include +#include +#include +#include +using namespace std; + +static fp_stream mout(stdout),merr(stderr); + +struct tt_env : public op_env { + sspile var; + tt_env(opmap& map) : op_env(map) {} + int split(sref& first,sref& rest) throw(merror_t) { + static const charset spec("+-*%/<=>^_!~&|,?:;"); + static const charset delim("()\"\\"); + static const charset specws=spec|delim|cset_ws; + int s; + rest=rest.right_first_not_of(cset_ws); + if((s=rest.skip(cset_quotes))>0) { + first=rest.left(s); + rest=rest.right(s); + } + else if((s=rest.skip(cset_para))>0) { + first=Trim(rest.left(s),cset_para); + rest=rest.right(s); + } + else if((s=rest.skip(cset_braces))>0) { + first=rest.left(s); + rest=rest.right(s); + } + else if(spec.test(*rest)) { + first=rest.left_first_not_of(spec); + rest=rest.adv(first); + } + else { + first=rest.left_first_of(specws); + rest=rest.adv(first); + } + return first.nempty(); + } + void term(mstream& out,expr_t* x) throw(merror_t) { + if(x->expr.empty()) { + x->status=0; + } + else if(x->expr.skip(cset_quotes)==x->expr.size()) { + out<expr(1,-3); + x->status=0; + } + else if(x->expr.find_not_of(cset_real)<0) { + out<expr; + x->status=0; + } + else { + for(sspile::iterator s=var.begin();s!=var.end();s++) + if(s->first==x->expr) { out<second; x->status=OP_LOCAL; break; } + } + } +}; + +#define TT_IMPL(n) \ +static void impl_##n(mstream& out,tt_env& env,const sref& L,const sref& R) +#define TT_ADDN(p,f,n,d) \ +M.add(new op_t(#n,0,p,1,2,0,(op_t::op2_t)impl_##f,d)) + +TT_IMPL(assign) { + sspile& var=env.var; + for(sspile::iterator p=var.begin();p!=var.end();p++) + if(p->first==L) { p->second=R; return; } + var.push_back(sstring(L,R)); +} + +TT_IMPL(incr) { + sspile& var=env.var; + for(sspile::iterator p=var.begin();p!=var.end();p++) + if(p->first==L) { p->second=itoa(atoi(p->second)+atoi(R)); break; } +} + +TT_IMPL(decr) { + sspile& var=env.var; + for(sspile::iterator p=var.begin();p!=var.end();p++) + if(p->first==L) { p->second=itoa(atoi(p->second)-atoi(R)); break; } +} + +inline void opAddTT(opmap& M) { + TT_ADDN(4,assign,=,"C style"); + TT_ADDN(4,assign,:=,"new var"); + TT_ADDN(4,incr,+=,"C style"); + TT_ADDN(4,decr,-=,"C style"); +} + +main(int argc,char* argv[]) try +{ + opmap ops; + opAddHEXP(ops); + opAddTT(ops); + tt_env env(ops); + mstring buf; + sref_t line; + expr_t expr; + if(argc>1) { + buf.load(sref(argv[1])); + sref first,rest=buf; + Splitln(first,rest); + if(first.left(2)!=sref("#!")) rest=buf; + (expr=buf).expand(env); + expr.eval(mout,env,OP_ALL); + mout<<"\n"; + } + else { + while(1) { + merr<<"ops>"; + cin.getline(line,sizeof(sref_t)); + sref first,rest(line); + Split(first,rest); + if(first==sref("exit")) { + break; + } + else if(first==sref("tree")) { + expr.trav(mout,12); + } + else if(first==sref("eval")) { + expr.eval(mout,env,OP_ALL); + mout<<"\n"; + } + else { + buf=line; + try { + (expr=buf).expand(env); + expr.eval(mout,env,OP_ALL); + mout<<"\n"; + } + catch(const merror_t& e) { + merr< + +const mstring default_tag=".default"; + +///////////////////////////////////////////////////////////////// + +TOK_IMPL(remote_name) { out<tcp->node.name; } +TOK_IMPL(remote_address) { out<tcp->node.ip; } +TOK_IMPL(remote_port) { out<tcp->port; } + +///////////////////////////////////////////////////////////////// + +inline int match(const sref& rem,const sref& longrem,const sref& dom) +{ + if(rem==dom) return 1; + if(*dom!='.') return 0; + if(longrem.right_last(dom)==dom) return 1; + return 0; +} + +inline int allow(const sref& uname,const sref& list) +{ + mstring remote=First(uname); + mstring longrem=remote; if(longrem.find('.')<0) longrem+=default_tag; + if(remote.empty()) return 0; + if(First(list).empty()) return 1; + sref first,rest=list; + while(Split(first,rest)) if(match(remote,longrem,first)) return 1; + return 0; +} + +TOK_IMPL(remote_allow) { out<tcp->node.name,env[0]); } +TOK_IMPL(bindroot) { Reqd(env)->htcd()->bindroot=env[0]; } + +///////////////////////////////////////////////////////////////// + +TOK_IMPL(user_allow) { + htcd_req* htcd=Reqd(env); + mstring opt=env.parg(-1); + int now=opt.empty()?time(0):atoi(opt); + out<user.allow_list(env[0],now,htcd->RootAllowed()); +} + +TOK_IMPL(on_clear) { + htcd_req* htcd=Reqd(env); + if(htcd->user.allow_list(env[0],time(0),htcd->RootAllowed())) env.parg(out,1); + else env.parg(out,2); +} + +///////////////////////////////////////////////////////////////// + +TOK_IMPL(allowed) { + int ok=0; + if(!env.db) THROW("htc: no open database"); + if(env.dbat>=0&&env.dbatsize()) { + user_t user; + env.db->Get(env.dbat,user.list); + if(user.list.size()!=user_tabs) + THROW("htc: cannot test - probably not a users database"); + mstring opt=env.parg(-1); + int now=opt.empty()?time(0):atoi(opt); + ok=user.allow_list(env[0],now,Reqd(env)->RootAllowed()); + } + out<=0&&env.dbatsize()) { + user_t user; + env.db->Get(env.dbat,user.list); + if(user.list.size()!=user_tabs) + THROW("htc: cannot test - probably not a users database"); + mstring opt=env.parg(-1); + int now=opt.empty()?time(0):atoi(opt); + ok=user.allow_list(env[0],now,-1); + } + out<\n" + "%\n" + "%In case of several groups, all must be allowed.\n" + ); + TOK_ADD(on_clear,"xr?",tok_t::SYSONLY, + "%Do if user is allowed in all groups now\n" + "%Syntax: \\on.clear{groups}{body}\n" + ); + + ///////////////////////////////////////////////////////////// + + TOK_ADD(allowed,"x?",tok_t::SYSONLY, + "%True if the current record is allowed in all groups now\n" + "%Syntax: \\allowed{groups}